0d71e75f73
26369-libxl-devid.patch - fate##313584: pass bios information to XEN HVM guest 26554-hvm-firmware-passthrough.patch 26555-hvm-firmware-passthrough.patch 26556-hvm-firmware-passthrough.patch - Upstream patches from Jan 26516-ACPI-parse-table-retval.patch (Replaces CVE-2013-0153-xsa36.patch) 26517-AMD-IOMMU-clear-irtes.patch (Replaces CVE-2013-0153-xsa36.patch) 26518-AMD-IOMMU-disable-if-SATA-combined-mode.patch (Replaces CVE-2013-0153-xsa36.patch) 26519-AMD-IOMMU-perdev-intremap-default.patch (Replaces CVE-2013-0153-xsa36.patch) 26526-pvdrv-no-devinit.patch 26529-gcc48-build-fix.patch 26531-AMD-IOMMU-IVHD-special-missing.patch (Replaces CVE-2013-0153-xsa36.patch) 26532-AMD-IOMMU-phantom-MSI.patch 26536-xenoprof-div-by-0.patch 26576-x86-APICV-migration.patch 26577-x86-APICV-x2APIC.patch 26578-AMD-IOMMU-replace-BUG_ON.patch - bnc#797014 - no way to control live migrations 26547-tools-xc_fix_logic_error_in_stdiostream_progress.patch 26548-tools-xc_handle_tty_output_differently_in_stdiostream_progress.patch 26549-tools-xc_turn_XCFLAGS_*_into_shifts.patch 26550-tools-xc_restore_logging_in_xc_save.patch 26551-tools-xc_log_pid_in_xc_save-xc_restore_output.patch - PVonHVM: __devinit was removed in linux-3.8 OBS-URL: https://build.opensuse.org/package/show/Virtualization/xen?expand=0&rev=229
241 lines
9.8 KiB
Diff
241 lines
9.8 KiB
Diff
References: FATE#313605
|
|
|
|
# HG changeset patch
|
|
# User Jiongxi Li <jiongxi.li@intel.com>
|
|
# Date 1361176458 -3600
|
|
# Node ID 45d59b822ed187c535b127679e32853b148ed411
|
|
# Parent 4c3355d776e115f979fd2abc135bb77ba710f0d4
|
|
x86/VMX: fix VMCS setting for x2APIC mode guest while enabling APICV
|
|
|
|
The "APIC-register virtualization" and "virtual-interrupt deliver"
|
|
VM-execution control has no effect on the behavior of RDMSR/WRMSR if
|
|
the "virtualize x2APIC mode" VM-execution control is 0.
|
|
When guest uses x2APIC mode, we should enable "virtualize x2APIC mode"
|
|
for APICV first.
|
|
|
|
Signed-off-by: Jiongxi Li <jiongxi.li@intel.com>
|
|
Acked-by: Eddie Dong <eddie.dong@intel.com>
|
|
Acked-by: Jun Nakajima <jun.nakajima@intel.com>
|
|
Committed-by: Jan Beulich <jbeulich@suse.com>
|
|
|
|
--- a/xen/arch/x86/hvm/vmx/vmcs.c
|
|
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
|
|
@@ -194,7 +194,8 @@ static int vmx_init_vmcs_config(void)
|
|
*/
|
|
if ( _vmx_cpu_based_exec_control & CPU_BASED_TPR_SHADOW )
|
|
opt |= SECONDARY_EXEC_APIC_REGISTER_VIRT |
|
|
- SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY;
|
|
+ SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY |
|
|
+ SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
|
|
|
|
|
|
_vmx_secondary_exec_control = adjust_vmx_controls(
|
|
@@ -673,19 +674,59 @@ void vmx_disable_intercept_for_msr(struc
|
|
*/
|
|
if ( msr <= 0x1fff )
|
|
{
|
|
- if (type & MSR_TYPE_R)
|
|
- __clear_bit(msr, msr_bitmap + 0x000/BYTES_PER_LONG); /* read-low */
|
|
- if (type & MSR_TYPE_W)
|
|
- __clear_bit(msr, msr_bitmap + 0x800/BYTES_PER_LONG); /* write-low */
|
|
+ if ( type & MSR_TYPE_R )
|
|
+ clear_bit(msr, msr_bitmap + 0x000/BYTES_PER_LONG); /* read-low */
|
|
+ if ( type & MSR_TYPE_W )
|
|
+ clear_bit(msr, msr_bitmap + 0x800/BYTES_PER_LONG); /* write-low */
|
|
}
|
|
else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
|
|
{
|
|
msr &= 0x1fff;
|
|
- if (type & MSR_TYPE_R)
|
|
- __clear_bit(msr, msr_bitmap + 0x400/BYTES_PER_LONG); /* read-high */
|
|
- if (type & MSR_TYPE_W)
|
|
- __clear_bit(msr, msr_bitmap + 0xc00/BYTES_PER_LONG); /* write-high */
|
|
+ if ( type & MSR_TYPE_R )
|
|
+ clear_bit(msr, msr_bitmap + 0x400/BYTES_PER_LONG); /* read-high */
|
|
+ if ( type & MSR_TYPE_W )
|
|
+ clear_bit(msr, msr_bitmap + 0xc00/BYTES_PER_LONG); /* write-high */
|
|
}
|
|
+ else
|
|
+ HVM_DBG_LOG(DBG_LEVEL_0,
|
|
+ "msr %x is out of the control range"
|
|
+ "0x00000000-0x00001fff and 0xc0000000-0xc0001fff"
|
|
+ "RDMSR or WRMSR will cause a VM exit", msr);
|
|
+}
|
|
+
|
|
+void vmx_enable_intercept_for_msr(struct vcpu *v, u32 msr, int type)
|
|
+{
|
|
+ unsigned long *msr_bitmap = v->arch.hvm_vmx.msr_bitmap;
|
|
+
|
|
+ /* VMX MSR bitmap supported? */
|
|
+ if ( msr_bitmap == NULL )
|
|
+ return;
|
|
+
|
|
+ /*
|
|
+ * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals
|
|
+ * have the write-low and read-high bitmap offsets the wrong way round.
|
|
+ * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff.
|
|
+ */
|
|
+ if ( msr <= 0x1fff )
|
|
+ {
|
|
+ if ( type & MSR_TYPE_R )
|
|
+ set_bit(msr, msr_bitmap + 0x000/BYTES_PER_LONG); /* read-low */
|
|
+ if ( type & MSR_TYPE_W )
|
|
+ set_bit(msr, msr_bitmap + 0x800/BYTES_PER_LONG); /* write-low */
|
|
+ }
|
|
+ else if ( (msr >= 0xc0000000) && (msr <= 0xc0001fff) )
|
|
+ {
|
|
+ msr &= 0x1fff;
|
|
+ if ( type & MSR_TYPE_R )
|
|
+ set_bit(msr, msr_bitmap + 0x400/BYTES_PER_LONG); /* read-high */
|
|
+ if ( type & MSR_TYPE_W )
|
|
+ set_bit(msr, msr_bitmap + 0xc00/BYTES_PER_LONG); /* write-high */
|
|
+ }
|
|
+ else
|
|
+ HVM_DBG_LOG(DBG_LEVEL_0,
|
|
+ "msr %x is out of the control range"
|
|
+ "0x00000000-0x00001fff and 0xc0000000-0xc0001fff"
|
|
+ "RDMSR or WRMSR will cause a VM exit", msr);
|
|
}
|
|
|
|
/*
|
|
@@ -751,6 +792,10 @@ static int construct_vmcs(struct vcpu *v
|
|
vmentry_ctl &= ~VM_ENTRY_LOAD_GUEST_PAT;
|
|
}
|
|
|
|
+ /* Disable Virtualize x2APIC mode by default. */
|
|
+ v->arch.hvm_vmx.secondary_exec_control &=
|
|
+ ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
|
|
+
|
|
/* Do not enable Monitor Trap Flag unless start single step debug */
|
|
v->arch.hvm_vmx.exec_control &= ~CPU_BASED_MONITOR_TRAP_FLAG;
|
|
|
|
@@ -787,18 +832,6 @@ static int construct_vmcs(struct vcpu *v
|
|
vmx_disable_intercept_for_msr(v, MSR_IA32_SYSENTER_EIP, MSR_TYPE_R | MSR_TYPE_W);
|
|
if ( cpu_has_vmx_pat && paging_mode_hap(d) )
|
|
vmx_disable_intercept_for_msr(v, MSR_IA32_CR_PAT, MSR_TYPE_R | MSR_TYPE_W);
|
|
- if ( cpu_has_vmx_apic_reg_virt )
|
|
- {
|
|
- int msr;
|
|
- for (msr = MSR_IA32_APICBASE_MSR; msr <= MSR_IA32_APICBASE_MSR + 0xff; msr++)
|
|
- vmx_disable_intercept_for_msr(v, msr, MSR_TYPE_R);
|
|
- }
|
|
- if ( cpu_has_vmx_virtual_intr_delivery )
|
|
- {
|
|
- vmx_disable_intercept_for_msr(v, MSR_IA32_APICTPR_MSR, MSR_TYPE_W);
|
|
- vmx_disable_intercept_for_msr(v, MSR_IA32_APICEOI_MSR, MSR_TYPE_W);
|
|
- vmx_disable_intercept_for_msr(v, MSR_IA32_APICSELF_MSR, MSR_TYPE_W);
|
|
- }
|
|
}
|
|
|
|
/* I/O access bitmap. */
|
|
--- a/xen/arch/x86/hvm/vmx/vmx.c
|
|
+++ b/xen/arch/x86/hvm/vmx/vmx.c
|
|
@@ -2009,18 +2009,63 @@ static void vmx_install_vlapic_mapping(s
|
|
|
|
void vmx_vlapic_msr_changed(struct vcpu *v)
|
|
{
|
|
+ int virtualize_x2apic_mode;
|
|
struct vlapic *vlapic = vcpu_vlapic(v);
|
|
|
|
- if ( !cpu_has_vmx_virtualize_apic_accesses )
|
|
+ virtualize_x2apic_mode = ( (cpu_has_vmx_apic_reg_virt ||
|
|
+ cpu_has_vmx_virtual_intr_delivery) &&
|
|
+ cpu_has_vmx_virtualize_x2apic_mode );
|
|
+
|
|
+ if ( !cpu_has_vmx_virtualize_apic_accesses &&
|
|
+ !virtualize_x2apic_mode )
|
|
return;
|
|
|
|
vmx_vmcs_enter(v);
|
|
v->arch.hvm_vmx.secondary_exec_control &=
|
|
- ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
|
|
+ ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
|
|
+ SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE);
|
|
if ( !vlapic_hw_disabled(vlapic) &&
|
|
(vlapic_base_address(vlapic) == APIC_DEFAULT_PHYS_BASE) )
|
|
- v->arch.hvm_vmx.secondary_exec_control |=
|
|
- SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
|
|
+ {
|
|
+ unsigned int msr;
|
|
+
|
|
+ if ( virtualize_x2apic_mode && vlapic_x2apic_mode(vlapic) )
|
|
+ {
|
|
+ v->arch.hvm_vmx.secondary_exec_control |=
|
|
+ SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
|
|
+ if ( cpu_has_vmx_apic_reg_virt )
|
|
+ {
|
|
+ for ( msr = MSR_IA32_APICBASE_MSR;
|
|
+ msr <= MSR_IA32_APICBASE_MSR + 0xff; msr++ )
|
|
+ vmx_disable_intercept_for_msr(v, msr, MSR_TYPE_R);
|
|
+
|
|
+ vmx_enable_intercept_for_msr(v, MSR_IA32_APICPPR_MSR,
|
|
+ MSR_TYPE_R);
|
|
+ vmx_enable_intercept_for_msr(v, MSR_IA32_APICTMICT_MSR,
|
|
+ MSR_TYPE_R);
|
|
+ vmx_enable_intercept_for_msr(v, MSR_IA32_APICTMCCT_MSR,
|
|
+ MSR_TYPE_R);
|
|
+ }
|
|
+ if ( cpu_has_vmx_virtual_intr_delivery )
|
|
+ {
|
|
+ vmx_disable_intercept_for_msr(v, MSR_IA32_APICTPR_MSR,
|
|
+ MSR_TYPE_W);
|
|
+ vmx_disable_intercept_for_msr(v, MSR_IA32_APICEOI_MSR,
|
|
+ MSR_TYPE_W);
|
|
+ vmx_disable_intercept_for_msr(v, MSR_IA32_APICSELF_MSR,
|
|
+ MSR_TYPE_W);
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ v->arch.hvm_vmx.secondary_exec_control |=
|
|
+ SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
|
|
+ for ( msr = MSR_IA32_APICBASE_MSR;
|
|
+ msr <= MSR_IA32_APICBASE_MSR + 0xff; msr++ )
|
|
+ vmx_enable_intercept_for_msr(v, msr,
|
|
+ MSR_TYPE_R | MSR_TYPE_W);
|
|
+ }
|
|
+ }
|
|
vmx_update_secondary_exec_control(v);
|
|
vmx_vmcs_exit(v);
|
|
}
|
|
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
|
|
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
|
|
@@ -182,6 +182,7 @@ extern u32 vmx_vmentry_control;
|
|
#define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
|
|
#define SECONDARY_EXEC_ENABLE_EPT 0x00000002
|
|
#define SECONDARY_EXEC_ENABLE_RDTSCP 0x00000008
|
|
+#define SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE 0x00000010
|
|
#define SECONDARY_EXEC_ENABLE_VPID 0x00000020
|
|
#define SECONDARY_EXEC_WBINVD_EXITING 0x00000040
|
|
#define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080
|
|
@@ -239,6 +240,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr
|
|
(vmx_secondary_exec_control & SECONDARY_EXEC_APIC_REGISTER_VIRT)
|
|
#define cpu_has_vmx_virtual_intr_delivery \
|
|
(vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY)
|
|
+#define cpu_has_vmx_virtualize_x2apic_mode \
|
|
+ (vmx_secondary_exec_control & SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE)
|
|
|
|
/* GUEST_INTERRUPTIBILITY_INFO flags. */
|
|
#define VMX_INTR_SHADOW_STI 0x00000001
|
|
@@ -414,6 +417,7 @@ enum vmcs_field {
|
|
#define MSR_TYPE_R 1
|
|
#define MSR_TYPE_W 2
|
|
void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr, int type);
|
|
+void vmx_enable_intercept_for_msr(struct vcpu *v, u32 msr, int type);
|
|
int vmx_read_guest_msr(u32 msr, u64 *val);
|
|
int vmx_write_guest_msr(u32 msr, u64 val);
|
|
int vmx_add_guest_msr(u32 msr);
|
|
--- a/xen/include/asm-x86/msr-index.h
|
|
+++ b/xen/include/asm-x86/msr-index.h
|
|
@@ -295,7 +295,10 @@
|
|
#define MSR_IA32_APICBASE_BASE (0xfffff<<12)
|
|
#define MSR_IA32_APICBASE_MSR 0x800
|
|
#define MSR_IA32_APICTPR_MSR 0x808
|
|
+#define MSR_IA32_APICPPR_MSR 0x80a
|
|
#define MSR_IA32_APICEOI_MSR 0x80b
|
|
+#define MSR_IA32_APICTMICT_MSR 0x838
|
|
+#define MSR_IA32_APICTMCCT_MSR 0x839
|
|
#define MSR_IA32_APICSELF_MSR 0x83f
|
|
|
|
#define MSR_IA32_UCODE_WRITE 0x00000079
|