diff mbox series

[v3,2/2] nvmx: always trap accesses to x2APIC MSRs

Message ID 20200203173728.18135-3-roger.pau@citrix.com (mailing list archive)
State Superseded
Headers show
Series nvmx: implement support for MSR bitmaps | expand

Commit Message

Roger Pau Monné Feb. 3, 2020, 5:37 p.m. UTC
Nested VMX doesn't expose support for
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE,
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY or
SECONDARY_EXEC_APIC_REGISTER_VIRT, and hence the x2APIC MSRs should
always be trapped in the nested guest MSR bitmap, or else a nested
guest could access the hardware x2APIC MSRs given certain conditions.

Accessing the hardware MSRs could be achieved by forcing the L0 Xen to
use SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE and
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY or
SECONDARY_EXEC_APIC_REGISTER_VIRT (if supported), and then creating a
L2 guest with a MSR bitmap that doesn't trap accesses to the x2APIC
MSR range. Then OR'ing both L0 and L1 MSR bitmaps would result in a
bitmap that doesn't trap certain x2APIC MSRs and a VMCS that doesn't
have SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE and
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY or
SECONDARY_EXEC_APIC_REGISTER_VIRT set either.

Fix this by making sure x2APIC MSRs are always trapped in the nested
MSR bitmap.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
---
Changes since v1:
 - New in this version (split from #1 patch).
 - Use non-locked set_bit.
---
 xen/arch/x86/hvm/vmx/vvmx.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

Comments

Jan Beulich Feb. 4, 2020, 9:42 a.m. UTC | #1
On 03.02.2020 18:37, Roger Pau Monne wrote:
> @@ -587,6 +588,16 @@ static void update_msrbitmap(struct vcpu *v, uint32_t shadow_ctrl)
>                v->arch.hvm.vmx.msr_bitmap->write_high,
>                sizeof(msr_bitmap->write_high) * 8);
>  
> +    /*
> +     * Nested VMX doesn't support any x2APIC hardware virtualization, so
> +     * make sure all the x2APIC MSRs are trapped.
> +     */
> +    for ( msr = MSR_X2APIC_FIRST; msr <= MSR_X2APIC_FIRST + 0xff; msr++ )
> +    {
> +        __set_bit(msr, msr_bitmap->read_low);
> +        __set_bit(msr, msr_bitmap->write_low);
> +    }

Pull in bitmap_set() (and then also bitmap_clear()) from Linux
for doing this more efficiently?

Jan
diff mbox series

Patch

diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index f118f88683..89ba2a80d5 100644
--- a/xen/arch/x86/hvm/vmx/vvmx.c
+++ b/xen/arch/x86/hvm/vmx/vvmx.c
@@ -567,6 +567,7 @@  static void update_msrbitmap(struct vcpu *v, uint32_t shadow_ctrl)
 {
     struct nestedvmx *nvmx = &vcpu_2_nvmx(v);
     struct vmx_msr_bitmap *msr_bitmap;
+    unsigned int msr;
 
     if ( !(shadow_ctrl & CPU_BASED_ACTIVATE_MSR_BITMAP) ||
          !nvmx->msrbitmap )
@@ -587,6 +588,16 @@  static void update_msrbitmap(struct vcpu *v, uint32_t shadow_ctrl)
               v->arch.hvm.vmx.msr_bitmap->write_high,
               sizeof(msr_bitmap->write_high) * 8);
 
+    /*
+     * Nested VMX doesn't support any x2APIC hardware virtualization, so
+     * make sure all the x2APIC MSRs are trapped.
+     */
+    for ( msr = MSR_X2APIC_FIRST; msr <= MSR_X2APIC_FIRST + 0xff; msr++ )
+    {
+        __set_bit(msr, msr_bitmap->read_low);
+        __set_bit(msr, msr_bitmap->write_low);
+    }
+
     unmap_domain_page(msr_bitmap);
 
     __vmwrite(MSR_BITMAP, page_to_maddr(nvmx->msr_merged));