Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/xen/hvm.c
Show First 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | |||||
#include <xen/interface/arch-x86/cpuid.h> | #include <xen/interface/arch-x86/cpuid.h> | ||||
#include <xen/interface/hvm/params.h> | #include <xen/interface/hvm/params.h> | ||||
#include <xen/interface/vcpu.h> | #include <xen/interface/vcpu.h> | ||||
/*--------------------------- Forward Declarations ---------------------------*/ | /*--------------------------- Forward Declarations ---------------------------*/ | ||||
static void xen_hvm_cpu_init(void); | static void xen_hvm_cpu_init(void); | ||||
/*-------------------------------- Global Data -------------------------------*/ | /*-------------------------------- Global Data -------------------------------*/ | ||||
enum xen_domain_type xen_domain_type = XEN_NATIVE; | |||||
#ifdef SMP | #ifdef SMP | ||||
struct cpu_ops xen_hvm_cpu_ops = { | struct cpu_ops xen_hvm_cpu_ops = { | ||||
.cpu_init = xen_hvm_cpu_init, | .cpu_init = xen_hvm_cpu_init, | ||||
.cpu_resume = xen_hvm_cpu_init | .cpu_resume = xen_hvm_cpu_init | ||||
}; | }; | ||||
#endif | #endif | ||||
static MALLOC_DEFINE(M_XENHVM, "xen_hvm", "Xen HVM PV Support"); | static MALLOC_DEFINE(M_XENHVM, "xen_hvm", "Xen HVM PV Support"); | ||||
/** | /** | ||||
* If non-zero, the hypervisor has been configured to use a direct | * If non-zero, the hypervisor has been configured to use a direct | ||||
* IDT event callback for interrupt injection. | * IDT event callback for interrupt injection. | ||||
*/ | */ | ||||
int xen_vector_callback_enabled; | int xen_vector_callback_enabled; | ||||
/** | /** | ||||
* Start info flags. ATM this only used to store the initial domain flag for | |||||
* PVHv2, and it's always empty for HVM guests. | |||||
*/ | |||||
uint32_t hvm_start_flags; | |||||
/** | |||||
* Signal whether the vector injected for the event channel upcall requires to | * Signal whether the vector injected for the event channel upcall requires to | ||||
* be EOI'ed on the local APIC. | * be EOI'ed on the local APIC. | ||||
*/ | */ | ||||
bool xen_evtchn_needs_ack; | bool xen_evtchn_needs_ack; | ||||
/*------------------------------- Per-CPU Data -------------------------------*/ | /*------------------------------- Per-CPU Data -------------------------------*/ | ||||
DPCPU_DEFINE(struct vcpu_info, vcpu_local_info); | DPCPU_DEFINE(struct vcpu_info, vcpu_local_info); | ||||
DPCPU_DEFINE(struct vcpu_info *, vcpu_info); | DPCPU_DEFINE(struct vcpu_info *, vcpu_info); | ||||
/*------------------ Hypervisor Access Shared Memory Regions -----------------*/ | |||||
shared_info_t *HYPERVISOR_shared_info; | |||||
/*------------------------------ Sysctl tunables -----------------------------*/ | /*------------------------------ Sysctl tunables -----------------------------*/ | ||||
int xen_disable_pv_disks = 0; | int xen_disable_pv_disks = 0; | ||||
int xen_disable_pv_nics = 0; | int xen_disable_pv_nics = 0; | ||||
TUNABLE_INT("hw.xen.disable_pv_disks", &xen_disable_pv_disks); | TUNABLE_INT("hw.xen.disable_pv_disks", &xen_disable_pv_disks); | ||||
TUNABLE_INT("hw.xen.disable_pv_nics", &xen_disable_pv_nics); | TUNABLE_INT("hw.xen.disable_pv_nics", &xen_disable_pv_nics); | ||||
/*---------------------- XEN Hypervisor Probe and Setup ----------------------*/ | /*---------------------- XEN Hypervisor Probe and Setup ----------------------*/ | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | xen_hvm_init_hypercall_stubs(enum xen_hvm_init_type init_type) | ||||
wrmsr(regs[1], (init_type == XEN_HVM_INIT_EARLY) | wrmsr(regs[1], (init_type == XEN_HVM_INIT_EARLY) | ||||
? ((vm_paddr_t)&hypercall_page - KERNBASE) | ? ((vm_paddr_t)&hypercall_page - KERNBASE) | ||||
: vtophys(&hypercall_page)); | : vtophys(&hypercall_page)); | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | |||||
xen_hvm_init_shared_info_page(void) | |||||
{ | |||||
struct xen_add_to_physmap xatp; | |||||
if (xen_pv_domain()) { | |||||
/* | |||||
* Already setup in the PV case, shared_info is passed inside | |||||
* of the start_info struct at start of day. | |||||
*/ | |||||
return; | |||||
} | |||||
if (HYPERVISOR_shared_info == NULL) { | |||||
HYPERVISOR_shared_info = malloc(PAGE_SIZE, M_XENHVM, M_NOWAIT); | |||||
if (HYPERVISOR_shared_info == NULL) | |||||
panic("Unable to allocate Xen shared info page"); | |||||
} | |||||
xatp.domid = DOMID_SELF; | |||||
xatp.idx = 0; | |||||
xatp.space = XENMAPSPACE_shared_info; | |||||
xatp.gpfn = vtophys(HYPERVISOR_shared_info) >> PAGE_SHIFT; | |||||
if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) | |||||
panic("HYPERVISOR_memory_op failed"); | |||||
} | |||||
static int | static int | ||||
set_percpu_callback(unsigned int vcpu) | set_percpu_callback(unsigned int vcpu) | ||||
{ | { | ||||
struct xen_hvm_evtchn_upcall_vector vec; | struct xen_hvm_evtchn_upcall_vector vec; | ||||
int error; | int error; | ||||
vec.vcpu = vcpu; | vec.vcpu = vcpu; | ||||
vec.vector = IDT_EVTCHN; | vec.vector = IDT_EVTCHN; | ||||
▲ Show 20 Lines • Show All 151 Lines • ▼ Show 20 Lines | #endif | ||||
xen_hvm_set_callback(NULL); | xen_hvm_set_callback(NULL); | ||||
/* | /* | ||||
* On (PV)HVM domains we need to request the hypervisor to | * On (PV)HVM domains we need to request the hypervisor to | ||||
* fill the shared info page, for PVH guest the shared_info page | * fill the shared info page, for PVH guest the shared_info page | ||||
* is passed inside the start_info struct and is already set, so this | * is passed inside the start_info struct and is already set, so this | ||||
* functions are no-ops. | * functions are no-ops. | ||||
*/ | */ | ||||
xen_hvm_init_shared_info_page(); | xen_handle_shared_info(); | ||||
xen_hvm_disable_emulated_devices(); | xen_hvm_disable_emulated_devices(); | ||||
} | } | ||||
void | void | ||||
xen_hvm_suspend(void) | xen_hvm_suspend(void) | ||||
{ | { | ||||
} | } | ||||
▲ Show 20 Lines • Show All 83 Lines • Show Last 20 Lines |