[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 14 of 20] Extend VMCS control fields for n2 guest
# HG changeset patch # User Eddie Dong <eddie.dong@xxxxxxxxx> # Date 1307003601 -28800 # Node ID aacbe98da103be572c9f96d6c85788f74f574117 # Parent 279a27a3b1a90380c8fa579e87835cb58a8f4aac Extend VMCS control fields for n2 guest Signed-off-by: Qing He <qing.he@xxxxxxxxx> Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx> diff -r 279a27a3b1a9 -r aacbe98da103 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Thu Jun 02 16:33:21 2011 +0800 +++ b/xen/arch/x86/hvm/vmx/vmx.c Thu Jun 02 16:33:21 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 @@ long_mode_do_msr_write(unsigned int msr, 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 279a27a3b1a9 -r aacbe98da103 xen/arch/x86/hvm/vmx/vvmx.c --- a/xen/arch/x86/hvm/vmx/vvmx.c Thu Jun 02 16:33:21 2011 +0800 +++ b/xen/arch/x86/hvm/vmx/vvmx.c Thu Jun 02 16:33:21 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> int nvmx_vcpu_initialise(struct vcpu *v) { @@ -391,6 +392,93 @@ static void vmreturn(struct cpu_user_reg 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, unsigned long host_cntrl) +{ +#define PIO_CNTRL_BITS ( CPU_BASED_ACTIVATE_IO_BITMAP \ + | CPU_BASED_UNCOND_IO_EXITING) + u32 pio_cntrl = PIO_CNTRL_BITS; + unsigned long *bitmap; + u32 shadow_cntrl; + + shadow_cntrl = __n2_exec_control(v); + pio_cntrl &= shadow_cntrl; + /* Enforce the removed features */ +#define REMOVED_EXEC_CONTROL_BITS (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 &= ~REMOVED_EXEC_CONTROL_BITS; + 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 279a27a3b1a9 -r aacbe98da103 xen/include/asm-x86/hvm/vmx/vvmx.h --- a/xen/include/asm-x86/hvm/vmx/vvmx.h Thu Jun 02 16:33:21 2011 +0800 +++ b/xen/include/asm-x86/hvm/vmx/vvmx.h Thu Jun 02 16:33:21 2011 +0800 @@ -161,5 +161,10 @@ int nvmx_handle_vmwrite(struct cpu_user_ 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, unsigned long 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-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |