[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Nested VMX: Extend VMCS control fields for n2 guest
# HG changeset patch # User Eddie Dong <eddie.dong@xxxxxxxxx> # Date 1307607849 -28800 # Node ID b2b400ec30816e237d427e94c50fd8e169cbd943 # Parent 3b59181a388e41a225ba194a57225e335e031a17 Nested VMX: Extend VMCS control fields for n2 guest Signed-off-by: Qing He <qing.he@xxxxxxxxx> Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx> Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx> Committed-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx> --- diff -r 3b59181a388e -r b2b400ec3081 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Thu Jun 09 16:24:09 2011 +0800 +++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Jun 09 16:24:09 2011 +0800 @@ -54,6 +54,7 @@ #include <asm/xenoprof.h> #include <asm/debugger.h> #include <asm/apic.h> +#include <asm/hvm/nestedhvm.h> enum handler_return { HNDL_done, HNDL_unhandled, HNDL_exception_raised }; @@ -361,18 +362,28 @@ void vmx_update_cpu_exec_control(struct vcpu *v) { - __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control); + if ( nestedhvm_vcpu_in_guestmode(v) ) + nvmx_update_exec_control(v, v->arch.hvm_vmx.exec_control); + else + __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control); } static void vmx_update_secondary_exec_control(struct vcpu *v) { - __vmwrite(SECONDARY_VM_EXEC_CONTROL, - v->arch.hvm_vmx.secondary_exec_control); + if ( nestedhvm_vcpu_in_guestmode(v) ) + nvmx_update_secondary_exec_control(v, + v->arch.hvm_vmx.secondary_exec_control); + else + __vmwrite(SECONDARY_VM_EXEC_CONTROL, + v->arch.hvm_vmx.secondary_exec_control); } void vmx_update_exception_bitmap(struct vcpu *v) { - __vmwrite(EXCEPTION_BITMAP, v->arch.hvm_vmx.exception_bitmap); + if ( nestedhvm_vcpu_in_guestmode(v) ) + nvmx_update_exception_bitmap(v, v->arch.hvm_vmx.exception_bitmap); + else + __vmwrite(EXCEPTION_BITMAP, v->arch.hvm_vmx.exception_bitmap); } static int vmx_guest_x86_mode(struct vcpu *v) diff -r 3b59181a388e -r b2b400ec3081 xen/arch/x86/hvm/vmx/vvmx.c --- a/xen/arch/x86/hvm/vmx/vvmx.c Thu Jun 09 16:24:09 2011 +0800 +++ b/xen/arch/x86/hvm/vmx/vvmx.c Thu Jun 09 16:24:09 2011 +0800 @@ -25,6 +25,7 @@ #include <asm/p2m.h> #include <asm/hvm/vmx/vmx.h> #include <asm/hvm/vmx/vvmx.h> +#include <asm/hvm/nestedhvm.h> static void nvmx_purge_vvmcs(struct vcpu *v); @@ -392,6 +393,91 @@ regs->eflags = eflags; } +/* + * Nested VMX uses "strict" condition to exit from + * L2 guest if either L1 VMM or L0 VMM expect to exit. + */ +static inline u32 __shadow_control(struct vcpu *v, + unsigned int field, + u32 host_value) +{ + struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v); + + return (u32) __get_vvmcs(nvcpu->nv_vvmcx, field) | host_value; +} + +static void set_shadow_control(struct vcpu *v, + unsigned int field, + u32 host_value) +{ + __vmwrite(field, __shadow_control(v, field, host_value)); +} + +unsigned long *_shadow_io_bitmap(struct vcpu *v) +{ + struct nestedvmx *nvmx = &vcpu_2_nvmx(v); + int port80, portED; + u8 *bitmap; + + bitmap = nvmx->iobitmap[0]; + port80 = bitmap[0x80 >> 3] & (1 << (0x80 & 0x7)) ? 1 : 0; + portED = bitmap[0xed >> 3] & (1 << (0xed & 0x7)) ? 1 : 0; + + return nestedhvm_vcpu_iomap_get(port80, portED); +} + +void nvmx_update_exec_control(struct vcpu *v, u32 host_cntrl) +{ + u32 pio_cntrl = (CPU_BASED_ACTIVATE_IO_BITMAP + | CPU_BASED_UNCOND_IO_EXITING); + unsigned long *bitmap; + u32 shadow_cntrl; + + shadow_cntrl = __n2_exec_control(v); + pio_cntrl &= shadow_cntrl; + /* Enforce the removed features */ + shadow_cntrl &= ~(CPU_BASED_TPR_SHADOW + | CPU_BASED_ACTIVATE_MSR_BITMAP + | CPU_BASED_ACTIVATE_SECONDARY_CONTROLS + | CPU_BASED_ACTIVATE_IO_BITMAP + | CPU_BASED_UNCOND_IO_EXITING); + shadow_cntrl |= host_cntrl; + if ( pio_cntrl == CPU_BASED_UNCOND_IO_EXITING ) { + /* L1 VMM intercepts all I/O instructions */ + shadow_cntrl |= CPU_BASED_UNCOND_IO_EXITING; + shadow_cntrl &= ~CPU_BASED_ACTIVATE_IO_BITMAP; + } + else { + /* Use IO_BITMAP in shadow */ + if ( pio_cntrl == 0 ) { + /* + * L1 VMM doesn't intercept IO instruction. + * Use host configuration and reset IO_BITMAP + */ + bitmap = hvm_io_bitmap; + } + else { + /* use IO bitmap */ + bitmap = _shadow_io_bitmap(v); + } + __vmwrite(IO_BITMAP_A, virt_to_maddr(bitmap)); + __vmwrite(IO_BITMAP_B, virt_to_maddr(bitmap) + PAGE_SIZE); + } + + __vmwrite(CPU_BASED_VM_EXEC_CONTROL, shadow_cntrl); +} + +void nvmx_update_secondary_exec_control(struct vcpu *v, + unsigned long value) +{ + set_shadow_control(v, SECONDARY_VM_EXEC_CONTROL, value); +} + +void nvmx_update_exception_bitmap(struct vcpu *v, unsigned long value) +{ + set_shadow_control(v, EXCEPTION_BITMAP, value); +} + static void __clear_current_vvmcs(struct vcpu *v) { struct nestedvcpu *nvcpu = &vcpu_nestedhvm(v); diff -r 3b59181a388e -r b2b400ec3081 xen/include/asm-x86/hvm/vmx/vvmx.h --- a/xen/include/asm-x86/hvm/vmx/vvmx.h Thu Jun 09 16:24:09 2011 +0800 +++ b/xen/include/asm-x86/hvm/vmx/vvmx.h Thu Jun 09 16:24:09 2011 +0800 @@ -161,5 +161,10 @@ int nvmx_handle_vmresume(struct cpu_user_regs *regs); int nvmx_handle_vmlaunch(struct cpu_user_regs *regs); +void nvmx_update_exec_control(struct vcpu *v, u32 value); +void nvmx_update_secondary_exec_control(struct vcpu *v, + unsigned long value); +void nvmx_update_exception_bitmap(struct vcpu *v, unsigned long value); + #endif /* __ASM_X86_HVM_VVMX_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |