aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-05-30 17:01:26 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-05-30 17:01:26 +0100
commit4ae289712c3c680955f31b0055d7ed71f447a8ef (patch)
tree3ccdfa53749629960d73366834b82438d368f08d
parent9d2eebd1f15e102181fcf9043489c71dd01bd7a2 (diff)
downloadxen-4ae289712c3c680955f31b0055d7ed71f447a8ef.tar.gz
xen-4ae289712c3c680955f31b0055d7ed71f447a8ef.tar.bz2
xen-4ae289712c3c680955f31b0055d7ed71f447a8ef.zip
Simplify APIC_ACCESS VMX support.
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r--xen/arch/x86/domain.c6
-rw-r--r--xen/arch/x86/hvm/hvm.c38
-rw-r--r--xen/arch/x86/hvm/svm/svm.c11
-rw-r--r--xen/arch/x86/hvm/vmx/intr.c5
-rw-r--r--xen/arch/x86/hvm/vmx/vmcs.c69
-rw-r--r--xen/arch/x86/hvm/vmx/vmx.c160
-rw-r--r--xen/include/asm-x86/hvm/domain.h7
-rw-r--r--xen/include/asm-x86/hvm/hvm.h4
-rw-r--r--xen/include/asm-x86/hvm/vlapic.h6
-rw-r--r--xen/include/asm-x86/hvm/vmx/vmcs.h37
-rw-r--r--xen/include/asm-x86/hvm/vmx/vmx.h3
-rw-r--r--xen/include/asm-x86/msr.h12
12 files changed, 157 insertions, 201 deletions
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 085e90d4da..c0e0b0c56e 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -393,7 +393,7 @@ int arch_domain_create(struct domain *d)
int i;
#endif
l1_pgentry_t gdt_l1e;
- int vcpuid, pdpt_order;
+ int vcpuid, pdpt_order, paging_initialised = 0;
int rc = -ENOMEM;
pdpt_order = get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t));
@@ -442,6 +442,7 @@ int arch_domain_create(struct domain *d)
#endif
paging_domain_init(d);
+ paging_initialised = 1;
if ( !is_idle_domain(d) )
{
@@ -469,12 +470,13 @@ int arch_domain_create(struct domain *d)
d->arch.is_32bit_pv = d->arch.has_32bit_shinfo =
(CONFIG_PAGING_LEVELS != 4);
}
-
return 0;
fail:
free_xenheap_page(d->shared_info);
+ if ( paging_initialised )
+ paging_final_teardown(d);
#ifdef __x86_64__
if ( d->arch.mm_perdomain_l2 )
free_domheap_page(virt_to_page(d->arch.mm_perdomain_l2));
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index c3e5ebe3e6..464e9fdb87 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -226,7 +226,6 @@ int hvm_domain_initialise(struct domain *d)
spin_lock_init(&d->arch.hvm_domain.pbuf_lock);
spin_lock_init(&d->arch.hvm_domain.irq_lock);
- spin_lock_init(&d->arch.hvm_domain.vapic_access_lock);
rc = paging_enable(d, PG_refcounts|PG_translate|PG_external);
if ( rc != 0 )
@@ -238,7 +237,7 @@ int hvm_domain_initialise(struct domain *d)
hvm_init_ioreq_page(d, &d->arch.hvm_domain.ioreq);
hvm_init_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
- return 0;
+ return hvm_funcs.domain_initialise(d);
}
void hvm_domain_relinquish_resources(struct domain *d)
@@ -249,10 +248,7 @@ void hvm_domain_relinquish_resources(struct domain *d)
void hvm_domain_destroy(struct domain *d)
{
- pit_deinit(d);
- rtc_deinit(d);
- pmtimer_deinit(d);
- hpet_deinit(d);
+ hvm_funcs.domain_destroy(d);
}
static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
@@ -409,27 +405,39 @@ int hvm_vcpu_initialise(struct vcpu *v)
INIT_LIST_HEAD(&v->arch.hvm_vcpu.tm_list);
- if ( v->vcpu_id != 0 )
- return 0;
-
- pit_init(v, cpu_khz);
- rtc_init(v, RTC_PORT(0));
- pmtimer_init(v);
- hpet_init(v);
+ if ( v->vcpu_id == 0 )
+ {
+ /* NB. All these really belong in hvm_domain_initialise(). */
+ pit_init(v, cpu_khz);
+ rtc_init(v, RTC_PORT(0));
+ pmtimer_init(v);
+ hpet_init(v);
- /* Init guest TSC to start from zero. */
- hvm_set_guest_time(v, 0);
+ /* Init guest TSC to start from zero. */
+ hvm_set_guest_time(v, 0);
+ }
return 0;
}
void hvm_vcpu_destroy(struct vcpu *v)
{
+ struct domain *d = v->domain;
+
vlapic_destroy(v);
hvm_funcs.vcpu_destroy(v);
/* Event channel is already freed by evtchn_destroy(). */
/*free_xen_event_channel(v, v->arch.hvm_vcpu.xen_port);*/
+
+ if ( v->vcpu_id == 0 )
+ {
+ /* NB. All these really belong in hvm_domain_destroy(). */
+ pit_deinit(d);
+ rtc_deinit(d);
+ pmtimer_deinit(d);
+ hpet_deinit(d);
+ }
}
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 669fa4b7db..27e6d1c8f6 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -876,6 +876,15 @@ static void svm_do_resume(struct vcpu *v)
reset_stack_and_jump(svm_asm_do_resume);
}
+static int svm_domain_initialise(struct domain *d)
+{
+ return 0;
+}
+
+static void svm_domain_destroy(struct domain *d)
+{
+}
+
static int svm_vcpu_initialise(struct vcpu *v)
{
int rc;
@@ -920,6 +929,8 @@ static int svm_event_injection_faulted(struct vcpu *v)
static struct hvm_function_table svm_function_table = {
.name = "SVM",
.disable = stop_svm,
+ .domain_initialise = svm_domain_initialise,
+ .domain_destroy = svm_domain_destroy,
.vcpu_initialise = svm_vcpu_initialise,
.vcpu_destroy = svm_vcpu_destroy,
.store_cpu_guest_regs = svm_store_cpu_guest_regs,
diff --git a/xen/arch/x86/hvm/vmx/intr.c b/xen/arch/x86/hvm/vmx/intr.c
index 9119cfbf22..b50dcf868a 100644
--- a/xen/arch/x86/hvm/vmx/intr.c
+++ b/xen/arch/x86/hvm/vmx/intr.c
@@ -74,11 +74,6 @@ static void update_tpr_threshold(struct vlapic *vlapic)
if ( !cpu_has_vmx_tpr_shadow )
return;
-#ifdef __i386__
- if ( !vlapic->mmap_vtpr_enabled )
- return;
-#endif
-
if ( !vlapic_enabled(vlapic) ||
((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
{
diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index ee5f437797..7d263985f8 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -61,9 +61,6 @@ static u32 adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, u32 msr)
return ctl;
}
-#define vmx_has_secondary_exec_ctls \
- (_vmx_cpu_based_exec_control & ACTIVATE_SECONDARY_CONTROLS)
-
void vmx_init_vmcs_config(void)
{
u32 vmx_msr_low, vmx_msr_high, min, opt;
@@ -76,7 +73,7 @@ void vmx_init_vmcs_config(void)
min = PIN_BASED_EXT_INTR_MASK | PIN_BASED_NMI_EXITING;
opt = 0;
_vmx_pin_based_exec_control = adjust_vmx_controls(
- min, opt, MSR_IA32_VMX_PINBASED_CTLS_MSR);
+ min, opt, MSR_IA32_VMX_PINBASED_CTLS);
min = (CPU_BASED_HLT_EXITING |
CPU_BASED_INVDPG_EXITING |
@@ -84,24 +81,21 @@ void vmx_init_vmcs_config(void)
CPU_BASED_MOV_DR_EXITING |
CPU_BASED_ACTIVATE_IO_BITMAP |
CPU_BASED_USE_TSC_OFFSETING);
- opt = CPU_BASED_ACTIVATE_MSR_BITMAP;
+ opt = CPU_BASED_ACTIVATE_MSR_BITMAP;
opt |= CPU_BASED_TPR_SHADOW;
- opt |= ACTIVATE_SECONDARY_CONTROLS;
+ opt |= CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
_vmx_cpu_based_exec_control = adjust_vmx_controls(
- min, opt, MSR_IA32_VMX_PROCBASED_CTLS_MSR);
+ min, opt, MSR_IA32_VMX_PROCBASED_CTLS);
#ifdef __x86_64__
if ( !(_vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW) )
{
min |= CPU_BASED_CR8_LOAD_EXITING | CPU_BASED_CR8_STORE_EXITING;
_vmx_cpu_based_exec_control = adjust_vmx_controls(
- min, opt, MSR_IA32_VMX_PROCBASED_CTLS_MSR);
+ min, opt, MSR_IA32_VMX_PROCBASED_CTLS);
}
-#elif defined(__i386__)
- if ( !vmx_has_secondary_exec_ctls )
- _vmx_cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW;
#endif
- if ( vmx_has_secondary_exec_ctls )
+ if ( _vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS )
{
min = 0;
opt = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
@@ -109,27 +103,33 @@ void vmx_init_vmcs_config(void)
min, opt, MSR_IA32_VMX_PROCBASED_CTLS2);
}
+#if defined(__i386__)
+ /* If we can't virtualise APIC accesses, the TPR shadow is pointless. */
+ if ( !(_vmx_secondary_exec_control &
+ SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES) )
+ _vmx_cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW;
+#endif
+
min = VM_EXIT_ACK_INTR_ON_EXIT;
opt = 0;
#ifdef __x86_64__
min |= VM_EXIT_IA32E_MODE;
#endif
_vmx_vmexit_control = adjust_vmx_controls(
- min, opt, MSR_IA32_VMX_EXIT_CTLS_MSR);
+ min, opt, MSR_IA32_VMX_EXIT_CTLS);
min = opt = 0;
_vmx_vmentry_control = adjust_vmx_controls(
- min, opt, MSR_IA32_VMX_ENTRY_CTLS_MSR);
+ min, opt, MSR_IA32_VMX_ENTRY_CTLS);
- rdmsr(MSR_IA32_VMX_BASIC_MSR, vmx_msr_low, vmx_msr_high);
+ rdmsr(MSR_IA32_VMX_BASIC, vmx_msr_low, vmx_msr_high);
if ( smp_processor_id() == 0 )
{
vmcs_revision_id = vmx_msr_low;
vmx_pin_based_exec_control = _vmx_pin_based_exec_control;
vmx_cpu_based_exec_control = _vmx_cpu_based_exec_control;
- if ( vmx_has_secondary_exec_ctls )
- vmx_secondary_exec_control = _vmx_secondary_exec_control;
+ vmx_secondary_exec_control = _vmx_secondary_exec_control;
vmx_vmexit_control = _vmx_vmexit_control;
vmx_vmentry_control = _vmx_vmentry_control;
}
@@ -138,8 +138,7 @@ void vmx_init_vmcs_config(void)
BUG_ON(vmcs_revision_id != vmx_msr_low);
BUG_ON(vmx_pin_based_exec_control != _vmx_pin_based_exec_control);
BUG_ON(vmx_cpu_based_exec_control != _vmx_cpu_based_exec_control);
- if ( vmx_has_secondary_exec_ctls )
- BUG_ON(vmx_secondary_exec_control != _vmx_secondary_exec_control);
+ BUG_ON(vmx_secondary_exec_control != _vmx_secondary_exec_control);
BUG_ON(vmx_vmexit_control != _vmx_vmexit_control);
BUG_ON(vmx_vmentry_control != _vmx_vmentry_control);
}
@@ -310,7 +309,7 @@ static void construct_vmcs(struct vcpu *v)
__vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control);
__vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmx_cpu_based_exec_control);
v->arch.hvm_vcpu.u.vmx.exec_control = vmx_cpu_based_exec_control;
- if ( vmx_cpu_based_exec_control & ACTIVATE_SECONDARY_CONTROLS )
+ if ( vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS )
__vmwrite(SECONDARY_VM_EXEC_CONTROL, vmx_secondary_exec_control);
if ( cpu_has_vmx_msr_bitmap )
@@ -437,24 +436,14 @@ static void construct_vmcs(struct vcpu *v)
cr4 & ~(X86_CR4_PGE | X86_CR4_VMXE | X86_CR4_PAE);
__vmwrite(CR4_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr4);
-#ifdef __x86_64__
- /* CR8 based VLAPIC TPR optimization. */
if ( cpu_has_vmx_tpr_shadow )
{
- __vmwrite(VIRTUAL_APIC_PAGE_ADDR,
- page_to_maddr(vcpu_vlapic(v)->regs_page));
- __vmwrite(TPR_THRESHOLD, 0);
- }
+ uint64_t virt_page_ma = page_to_maddr(vcpu_vlapic(v)->regs_page);
+ __vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma);
+#if defined (__i386__)
+ __vmwrite(VIRTUAL_APIC_PAGE_ADDR_HIGH, virt_page_ma >> 32);
#endif
-
- /* Memory-mapped based VLAPIC TPR optimization. */
- if ( cpu_has_vmx_mmap_vtpr_optimization )
- {
- __vmwrite(VIRTUAL_APIC_PAGE_ADDR,
- page_to_maddr(vcpu_vlapic(v)->regs_page));
__vmwrite(TPR_THRESHOLD, 0);
-
- vcpu_vlapic(v)->mmap_vtpr_enabled = 1;
}
__vmwrite(GUEST_LDTR_SELECTOR, 0);
@@ -527,18 +516,6 @@ void vmx_do_resume(struct vcpu *v)
vmx_set_host_env(v);
}
- if ( !v->arch.hvm_vmx.launched && vcpu_vlapic(v)->mmap_vtpr_enabled )
- {
- struct page_info *pg = change_guest_physmap_for_vtpr(v->domain, 1);
-
- if ( pg == NULL )
- {
- gdprintk(XENLOG_ERR, "change_guest_physmap_for_vtpr failed!\n");
- domain_crash_synchronous();
- }
- __vmwrite(APIC_ACCESS_ADDR, page_to_maddr(pg));
- }
-
debug_state = v->domain->debugger_attached;
if ( unlikely(v->arch.hvm_vcpu.debug_state_latch != debug_state) )
{
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index c77092204f..9d8ba90d0f 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -56,6 +56,20 @@ char *vmx_msr_bitmap;
static void vmx_ctxt_switch_from(struct vcpu *v);
static void vmx_ctxt_switch_to(struct vcpu *v);
+static int vmx_alloc_vlapic_mapping(struct domain *d);
+static void vmx_free_vlapic_mapping(struct domain *d);
+static void vmx_install_vlapic_mapping(struct vcpu *v);
+
+static int vmx_domain_initialise(struct domain *d)
+{
+ return vmx_alloc_vlapic_mapping(d);
+}
+
+static void vmx_domain_destroy(struct domain *d)
+{
+ vmx_free_vlapic_mapping(d);
+}
+
static int vmx_vcpu_initialise(struct vcpu *v)
{
int rc;
@@ -74,6 +88,8 @@ static int vmx_vcpu_initialise(struct vcpu *v)
return rc;
}
+ vmx_install_vlapic_mapping(v);
+
return 0;
}
@@ -1168,6 +1184,8 @@ static void disable_intercept_for_msr(u32 msr)
static struct hvm_function_table vmx_function_table = {
.name = "VMX",
.disable = stop_vmx,
+ .domain_initialise = vmx_domain_initialise,
+ .domain_destroy = vmx_domain_destroy,
.vcpu_initialise = vmx_vcpu_initialise,
.vcpu_destroy = vmx_vcpu_destroy,
.store_cpu_guest_regs = vmx_store_cpu_guest_regs,
@@ -2483,112 +2501,66 @@ done:
return 1;
}
-struct page_info * change_guest_physmap_for_vtpr(struct domain *d,
- int enable_vtpr)
+static int vmx_alloc_vlapic_mapping(struct domain *d)
{
- struct page_info *pg;
- unsigned long pfn, mfn;
-
- spin_lock(&d->arch.hvm_domain.vapic_access_lock);
-
- pg = d->arch.hvm_domain.apic_access_page;
- pfn = paddr_to_pfn(APIC_DEFAULT_PHYS_BASE);
-
- if ( enable_vtpr )
- {
- if ( d->arch.hvm_domain.physmap_changed_for_vlapic_access )
- goto out;
-
- if ( pg == NULL )
- pg = alloc_domheap_page(d);
- if ( pg == NULL )
- {
- gdprintk(XENLOG_ERR, "alloc_domheap_pages() failed!\n");
- goto out;
- }
+ void *apic_va;
- mfn = page_to_mfn(pg);
- d->arch.hvm_domain.apic_access_page = pg;
-
- guest_physmap_add_page(d, pfn, mfn);
+ if ( !cpu_has_vmx_virtualize_apic_accesses )
+ return 0;
- d->arch.hvm_domain.physmap_changed_for_vlapic_access = 1;
+ apic_va = alloc_xenheap_page();
+ if ( apic_va == NULL )
+ return -ENOMEM;
+ share_xen_page_with_guest(virt_to_page(apic_va), d, XENSHARE_writable);
+ guest_physmap_add_page(
+ d, paddr_to_pfn(APIC_DEFAULT_PHYS_BASE), virt_to_mfn(apic_va));
+ d->arch.hvm_domain.vmx_apic_access_mfn = virt_to_mfn(apic_va);
- goto out;
- }
- else
- {
- if ( d->arch.hvm_domain.physmap_changed_for_vlapic_access )
- {
- mfn = page_to_mfn(pg);
- guest_physmap_remove_page(d, pfn, mfn);
- flush_tlb_mask(d->domain_dirty_cpumask);
-
- d->arch.hvm_domain.physmap_changed_for_vlapic_access = 0;
- }
- pg = NULL;
- goto out;
- }
+ return 0;
+}
-out:
- spin_unlock(&d->arch.hvm_domain.vapic_access_lock);
- return pg;
+static void vmx_free_vlapic_mapping(struct domain *d)
+{
+ unsigned long mfn = d->arch.hvm_domain.vmx_apic_access_mfn;
+ if ( mfn != 0 )
+ free_xenheap_page(mfn_to_virt(mfn));
}
-static void check_vlapic_msr_for_vtpr(struct vcpu *v)
+static void vmx_install_vlapic_mapping(struct vcpu *v)
{
- struct vlapic *vlapic = vcpu_vlapic(v);
- int mmap_vtpr_enabled = vcpu_vlapic(v)->mmap_vtpr_enabled;
- uint32_t tmp;
+ paddr_t virt_page_ma, apic_page_ma;
+ if ( !cpu_has_vmx_virtualize_apic_accesses )
+ return;
- if ( vlapic_hw_disabled(vlapic) && mmap_vtpr_enabled )
- {
- vcpu_vlapic(v)->mmap_vtpr_enabled = 0;
+ virt_page_ma = page_to_maddr(vcpu_vlapic(v)->regs_page);
+ apic_page_ma = v->domain->arch.hvm_domain.vmx_apic_access_mfn;
+ apic_page_ma <<= PAGE_SHIFT;
-#ifdef __i386__
- v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_TPR_SHADOW;
- __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
- v->arch.hvm_vcpu.u.vmx.exec_control);
-#elif defined(__x86_64__)
- if ( !cpu_has_vmx_tpr_shadow )
- {
- v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_TPR_SHADOW;
- __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
- v->arch.hvm_vcpu.u.vmx.exec_control);
- }
+ vmx_vmcs_enter(v);
+ __vmwrite(VIRTUAL_APIC_PAGE_ADDR, virt_page_ma);
+ __vmwrite(APIC_ACCESS_ADDR, apic_page_ma);
+#if defined (__i386__)
+ __vmwrite(VIRTUAL_APIC_PAGE_ADDR_HIGH, virt_page_ma >> 32);
+ __vmwrite(APIC_ACCESS_ADDR_HIGH, apic_page_ma >> 32);
#endif
- tmp = __vmread(SECONDARY_VM_EXEC_CONTROL);
- tmp &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
- __vmwrite(SECONDARY_VM_EXEC_CONTROL, tmp);
-
- change_guest_physmap_for_vtpr(v->domain, 0);
- }
- else if ( !vlapic_hw_disabled(vlapic) && !mmap_vtpr_enabled &&
- cpu_has_vmx_mmap_vtpr_optimization )
- {
- vcpu_vlapic(v)->mmap_vtpr_enabled = 1;
+ vmx_vmcs_exit(v);
+}
- v->arch.hvm_vcpu.u.vmx.exec_control |=
- ( ACTIVATE_SECONDARY_CONTROLS | CPU_BASED_TPR_SHADOW );
- __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
- v->arch.hvm_vcpu.u.vmx.exec_control);
- tmp = __vmread(SECONDARY_VM_EXEC_CONTROL);
- tmp |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
- __vmwrite(SECONDARY_VM_EXEC_CONTROL, tmp);
+static void vmx_check_vlapic_msr(struct vcpu *v)
+{
+ struct vlapic *vlapic = vcpu_vlapic(v);
+ uint32_t ctl;
- change_guest_physmap_for_vtpr(v->domain, 1);
- }
+ if ( !cpu_has_vmx_virtualize_apic_accesses )
+ return;
- if ( vcpu_vlapic(v)->mmap_vtpr_enabled &&
- !vlapic_hw_disabled(vlapic) &&
- (vlapic_base_address(vlapic) != APIC_DEFAULT_PHYS_BASE) )
- {
- gdprintk(XENLOG_ERR,
- "Local APIC base address is set to 0x%016"PRIx64"!\n",
- vlapic_base_address(vlapic));
- domain_crash_synchronous();
- }
+ ctl = __vmread(SECONDARY_VM_EXEC_CONTROL);
+ ctl &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+ if ( !vlapic_hw_disabled(vlapic) &&
+ (vlapic_base_address(vlapic) == APIC_DEFAULT_PHYS_BASE) )
+ ctl |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+ __vmwrite(SECONDARY_VM_EXEC_CONTROL, ctl);
}
static inline int vmx_do_msr_write(struct cpu_user_regs *regs)
@@ -2619,7 +2591,7 @@ static inline int vmx_do_msr_write(struct cpu_user_regs *regs)
break;
case MSR_IA32_APICBASE:
vlapic_msr_set(vcpu_vlapic(v), msr_content);
- check_vlapic_msr_for_vtpr(v);
+ vmx_check_vlapic_msr(v);
break;
default:
if ( !long_mode_do_msr_write(regs) )
@@ -2932,12 +2904,12 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
case EXIT_REASON_TPR_BELOW_THRESHOLD:
break;
+
case EXIT_REASON_APIC_ACCESS:
{
unsigned long offset;
-
exit_qualification = __vmread(EXIT_QUALIFICATION);
- offset = exit_qualification & 0x0fffUL;
+ offset = exit_qualification & 0x0fffUL;
handle_mmio(APIC_DEFAULT_PHYS_BASE | offset);
break;
}
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index 191deac381..20fca664b5 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -41,11 +41,6 @@ struct hvm_domain {
s64 tsc_frequency;
struct pl_time pl_time;
- /* For memory-mapped vLAPIC/vTPR access optimization */
- spinlock_t vapic_access_lock;
- int physmap_changed_for_vlapic_access : 1;
- struct page_info *apic_access_page;
-
struct hvm_io_handler io_handler;
/* Lock protects access to irq, vpic and vioapic. */
@@ -60,6 +55,8 @@ struct hvm_domain {
spinlock_t pbuf_lock;
uint64_t params[HVM_NR_PARAMS];
+
+ unsigned long vmx_apic_access_mfn;
};
#endif /* __ASM_X86_HVM_DOMAIN_H__ */
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index a89f242cbe..0a976e67b2 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -69,8 +69,10 @@ struct hvm_function_table {
void (*disable)(void);
/*
- * Initialise/destroy HVM VCPU resources
+ * Initialise/destroy HVM domain/vcpu resources
*/
+ int (*domain_initialise)(struct domain *d);
+ void (*domain_destroy)(struct domain *d);
int (*vcpu_initialise)(struct vcpu *v);
void (*vcpu_destroy)(struct vcpu *v);
diff --git a/xen/include/asm-x86/hvm/vlapic.h b/xen/include/asm-x86/hvm/vlapic.h
index 80cd32ec56..ed4fe172b7 100644
--- a/xen/include/asm-x86/hvm/vlapic.h
+++ b/xen/include/asm-x86/hvm/vlapic.h
@@ -33,7 +33,7 @@
#define vlapic_domain(vpic) (vlapic_vcpu(vlapic)->domain)
#define VLAPIC_ID(vlapic) \
- (GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID)))
+ (GET_APIC_ID(vlapic_get_reg((vlapic), APIC_ID)))
/*
* APIC can be disabled in two ways:
@@ -50,7 +50,7 @@
#define vlapic_enabled(vlapic) (!vlapic_disabled(vlapic))
#define vlapic_base_address(vlapic) \
- (vlapic->hw.apic_base_msr & MSR_IA32_APICBASE_BASE)
+ ((vlapic)->hw.apic_base_msr & MSR_IA32_APICBASE_BASE)
struct vlapic {
struct hvm_hw_lapic hw;
@@ -58,8 +58,6 @@ struct vlapic {
struct periodic_time pt;
s_time_t timer_last_update;
struct page_info *regs_page;
-
- int mmap_vtpr_enabled : 1;
};
static inline uint32_t vlapic_get_reg(struct vlapic *vlapic, uint32_t reg)
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h b/xen/include/asm-x86/hvm/vmx/vmcs.h
index 449afd11cf..93383559c5 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -90,23 +90,23 @@ void vmx_destroy_vmcs(struct vcpu *v);
void vmx_vmcs_enter(struct vcpu *v);
void vmx_vmcs_exit(struct vcpu *v);
-#define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004
-#define CPU_BASED_USE_TSC_OFFSETING 0x00000008
-#define CPU_BASED_HLT_EXITING 0x00000080
-#define CPU_BASED_INVDPG_EXITING 0x00000200
-#define CPU_BASED_MWAIT_EXITING 0x00000400
-#define CPU_BASED_RDPMC_EXITING 0x00000800
-#define CPU_BASED_RDTSC_EXITING 0x00001000
-#define CPU_BASED_CR8_LOAD_EXITING 0x00080000
-#define CPU_BASED_CR8_STORE_EXITING 0x00100000
-#define CPU_BASED_TPR_SHADOW 0x00200000
-#define CPU_BASED_MOV_DR_EXITING 0x00800000
-#define CPU_BASED_UNCOND_IO_EXITING 0x01000000
-#define CPU_BASED_ACTIVATE_IO_BITMAP 0x02000000
-#define CPU_BASED_ACTIVATE_MSR_BITMAP 0x10000000
-#define CPU_BASED_MONITOR_EXITING 0x20000000
-#define CPU_BASED_PAUSE_EXITING 0x40000000
-#define ACTIVATE_SECONDARY_CONTROLS 0x80000000
+#define CPU_BASED_VIRTUAL_INTR_PENDING 0x00000004
+#define CPU_BASED_USE_TSC_OFFSETING 0x00000008
+#define CPU_BASED_HLT_EXITING 0x00000080
+#define CPU_BASED_INVDPG_EXITING 0x00000200
+#define CPU_BASED_MWAIT_EXITING 0x00000400
+#define CPU_BASED_RDPMC_EXITING 0x00000800
+#define CPU_BASED_RDTSC_EXITING 0x00001000
+#define CPU_BASED_CR8_LOAD_EXITING 0x00080000
+#define CPU_BASED_CR8_STORE_EXITING 0x00100000
+#define CPU_BASED_TPR_SHADOW 0x00200000
+#define CPU_BASED_MOV_DR_EXITING 0x00800000
+#define CPU_BASED_UNCOND_IO_EXITING 0x01000000
+#define CPU_BASED_ACTIVATE_IO_BITMAP 0x02000000
+#define CPU_BASED_ACTIVATE_MSR_BITMAP 0x10000000
+#define CPU_BASED_MONITOR_EXITING 0x20000000
+#define CPU_BASED_PAUSE_EXITING 0x40000000
+#define CPU_BASED_ACTIVATE_SECONDARY_CONTROLS 0x80000000
extern u32 vmx_cpu_based_exec_control;
#define PIN_BASED_EXT_INTR_MASK 0x00000001
@@ -129,9 +129,6 @@ extern u32 vmx_secondary_exec_control;
(vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)
#define cpu_has_vmx_tpr_shadow \
(vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW)
-#define cpu_has_vmx_mmap_vtpr_optimization \
- (cpu_has_vmx_virtualize_apic_accesses && cpu_has_vmx_tpr_shadow)
-
#define cpu_has_vmx_msr_bitmap \
(vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP)
extern char *vmx_msr_bitmap;
diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h
index 63af4bfe8f..d1bdd3b95e 100644
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -33,9 +33,6 @@ void vmx_intr_assist(void);
void vmx_do_resume(struct vcpu *);
void set_guest_time(struct vcpu *v, u64 gtime);
-extern struct page_info *change_guest_physmap_for_vtpr(struct domain *d,
- int enable_vtpr);
-
/*
* Exit Reasons
*/
diff --git a/xen/include/asm-x86/msr.h b/xen/include/asm-x86/msr.h
index 2cd8b27952..80e9da6576 100644
--- a/xen/include/asm-x86/msr.h
+++ b/xen/include/asm-x86/msr.h
@@ -109,12 +109,12 @@ static inline void wrmsrl(unsigned int msr, __u64 val)
#define MSR_P6_PERFCTR1 0xc2
/* MSRs & bits used for VMX enabling */
-#define MSR_IA32_VMX_BASIC_MSR 0x480
-#define MSR_IA32_VMX_PINBASED_CTLS_MSR 0x481
-#define MSR_IA32_VMX_PROCBASED_CTLS_MSR 0x482
-#define MSR_IA32_VMX_EXIT_CTLS_MSR 0x483
-#define MSR_IA32_VMX_ENTRY_CTLS_MSR 0x484
-#define MSR_IA32_VMX_MISC_MSR 0x485
+#define MSR_IA32_VMX_BASIC 0x480
+#define MSR_IA32_VMX_PINBASED_CTLS 0x481
+#define MSR_IA32_VMX_PROCBASED_CTLS 0x482
+#define MSR_IA32_VMX_EXIT_CTLS 0x483
+#define MSR_IA32_VMX_ENTRY_CTLS 0x484
+#define MSR_IA32_VMX_MISC 0x485
#define MSR_IA32_VMX_CR0_FIXED0 0x486
#define MSR_IA32_VMX_CR0_FIXED1 0x487
#define MSR_IA32_VMX_CR4_FIXED0 0x488