[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [VMX] __vmread() and __vmwrite() now BUG on failure, rather than



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 9f9f569b0a1db07697426d5ebeb175b07ef034ed
# Parent  6555ca56d844c149fd457aa4f38a340c321b8ec3
[VMX] __vmread() and __vmwrite() now BUG on failure, rather than
returning the error to the caller.

None of our vmcs reads/writes should fail. In fact many callers were
ignoring failures, which can hide bugs (in fact it hid one in
vmx_restore_dr(), which was incorrectly using __vmread() before
the vmcs was loaded).

__vmread_safe() is used by the vmcs dump function, which is the only
function which can legitimately fail a vmcs access.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/svm/svm.c        |   34 +-
 xen/arch/x86/hvm/svm/vmcb.c       |    5 
 xen/arch/x86/hvm/vmx/io.c         |   18 -
 xen/arch/x86/hvm/vmx/vmcs.c       |  215 ++++++++--------
 xen/arch/x86/hvm/vmx/vmx.c        |  485 ++++++++++++++++++--------------------
 xen/include/asm-x86/hvm/vmx/vmx.h |  107 +++-----
 6 files changed, 399 insertions(+), 465 deletions(-)

diff -r 6555ca56d844 -r 9f9f569b0a1d xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c        Wed Nov 08 15:11:18 2006 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c        Wed Nov 08 16:43:50 2006 +0000
@@ -424,17 +424,21 @@ static inline int long_mode_do_msr_write
 
 static inline void svm_save_dr(struct vcpu *v)
 {
-    if (v->arch.hvm_vcpu.flag_dr_dirty)
-    {
-        /* clear the DR dirty flag and re-enable intercepts for DR accesses */ 
-        v->arch.hvm_vcpu.flag_dr_dirty = 0;
-        v->arch.hvm_svm.vmcb->dr_intercepts = DR_INTERCEPT_ALL_WRITES;
-
-        savedebug(&v->arch.guest_context, 0);    
-        savedebug(&v->arch.guest_context, 1);    
-        savedebug(&v->arch.guest_context, 2);    
-        savedebug(&v->arch.guest_context, 3);    
-    }
+    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+
+    if ( !v->arch.hvm_vcpu.flag_dr_dirty )
+        return;
+
+    /* Clear the DR dirty flag and re-enable intercepts for DR accesses. */
+    v->arch.hvm_vcpu.flag_dr_dirty = 0;
+    v->arch.hvm_svm.vmcb->dr_intercepts = DR_INTERCEPT_ALL_WRITES;
+
+    savedebug(&v->arch.guest_context, 0);
+    savedebug(&v->arch.guest_context, 1);
+    savedebug(&v->arch.guest_context, 2);
+    savedebug(&v->arch.guest_context, 3);
+    v->arch.guest_context.debugreg[6] = vmcb->dr6;
+    v->arch.guest_context.debugreg[7] = vmcb->dr7;
 }
 
 
@@ -444,17 +448,13 @@ static inline void __restore_debug_regis
     loaddebug(&v->arch.guest_context, 1);
     loaddebug(&v->arch.guest_context, 2);
     loaddebug(&v->arch.guest_context, 3);
+    /* DR6 and DR7 are loaded from the VMCB. */
 }
 
 
 static inline void svm_restore_dr(struct vcpu *v)
 {
-    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
-    if (!vmcb)
-        return;
-
-    if (unlikely(vmcb->dr7 & 0xFF))
+    if ( unlikely(v->arch.guest_context.debugreg[7] & 0xFF) )
         __restore_debug_registers(v);
 }
 
diff -r 6555ca56d844 -r 9f9f569b0a1d xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c       Wed Nov 08 15:11:18 2006 +0000
+++ b/xen/arch/x86/hvm/svm/vmcb.c       Wed Nov 08 16:43:50 2006 +0000
@@ -91,7 +91,6 @@ static int construct_vmcb(struct vcpu *v
     struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
     struct vmcb_struct *vmcb = arch_svm->vmcb;
     segment_attributes_t attrib;
-    unsigned long dr7;
 
     /* Always flush the TLB on VMRUN. */
     vmcb->tlb_control = 1;
@@ -203,10 +202,6 @@ static int construct_vmcb(struct vcpu *v
     arch_svm->cpu_shadow_cr4 =
         read_cr4() & ~(X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE);
     vmcb->cr4 = arch_svm->cpu_shadow_cr4 | SVM_CR4_HOST_MASK;
-
-    /* Guest DR7. */
-    __asm__ __volatile__ ("mov %%dr7, %0\n" : "=r" (dr7));
-    vmcb->dr7 = dr7;
 
     shadow_update_paging_modes(v);
     vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
diff -r 6555ca56d844 -r 9f9f569b0a1d xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Wed Nov 08 15:11:18 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/io.c Wed Nov 08 16:43:50 2006 +0000
@@ -63,9 +63,7 @@ disable_irq_window(struct vcpu *v)
 
 static inline int is_interruptibility_state(void)
 {
-    int  interruptibility;
-    __vmread(GUEST_INTERRUPTIBILITY_INFO, &interruptibility);
-    return interruptibility;
+    return __vmread(GUEST_INTERRUPTIBILITY_INFO);
 }
 
 #ifdef __x86_64__
@@ -129,7 +127,7 @@ asmlinkage void vmx_intr_assist(void)
     }
 
     /* This could be moved earlier in the VMX resume sequence. */
-    __vmread(IDT_VECTORING_INFO_FIELD, &idtv_info_field);
+    idtv_info_field = __vmread(IDT_VECTORING_INFO_FIELD);
     if (unlikely(idtv_info_field & INTR_INFO_VALID_MASK)) {
         __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
 
@@ -138,14 +136,12 @@ asmlinkage void vmx_intr_assist(void)
          * and interrupts. If we get here then delivery of some event caused a
          * fault, and this always results in defined VM_EXIT_INSTRUCTION_LEN.
          */
-        __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len); /* Safe */
+        inst_len = __vmread(VM_EXIT_INSTRUCTION_LEN); /* Safe */
         __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
 
-        if (unlikely(idtv_info_field & 0x800)) { /* valid error code */
-            unsigned long error_code;
-            __vmread(IDT_VECTORING_ERROR_CODE, &error_code);
-            __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
-        }
+        if (unlikely(idtv_info_field & 0x800)) /* valid error code */
+            __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE,
+                      __vmread(IDT_VECTORING_ERROR_CODE));
         if (unlikely(has_ext_irq))
             enable_irq_window(v);
 
@@ -163,7 +159,7 @@ asmlinkage void vmx_intr_assist(void)
         return;
     }
 
-    __vmread(GUEST_RFLAGS, &eflags);
+    eflags = __vmread(GUEST_RFLAGS);
     if (irq_masked(eflags)) {
         enable_irq_window(v);
         return;
diff -r 6555ca56d844 -r 9f9f569b0a1d xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c       Wed Nov 08 15:11:18 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmcs.c       Wed Nov 08 16:43:50 2006 +0000
@@ -257,7 +257,7 @@ struct host_execution_env {
 
 static void vmx_set_host_env(struct vcpu *v)
 {
-    unsigned int tr, cpu, error = 0;
+    unsigned int tr, cpu;
     struct host_execution_env host_env;
     struct Xgt_desc_struct desc;
 
@@ -265,93 +265,95 @@ static void vmx_set_host_env(struct vcpu
     __asm__ __volatile__ ("sidt  (%0) \n" :: "a"(&desc) : "memory");
     host_env.idtr_limit = desc.size;
     host_env.idtr_base = desc.address;
-    error |= __vmwrite(HOST_IDTR_BASE, host_env.idtr_base);
+    __vmwrite(HOST_IDTR_BASE, host_env.idtr_base);
 
     __asm__ __volatile__ ("sgdt  (%0) \n" :: "a"(&desc) : "memory");
     host_env.gdtr_limit = desc.size;
     host_env.gdtr_base = desc.address;
-    error |= __vmwrite(HOST_GDTR_BASE, host_env.gdtr_base);
+    __vmwrite(HOST_GDTR_BASE, host_env.gdtr_base);
 
     __asm__ __volatile__ ("str  (%0) \n" :: "a"(&tr) : "memory");
     host_env.tr_selector = tr;
     host_env.tr_limit = sizeof(struct tss_struct);
     host_env.tr_base = (unsigned long) &init_tss[cpu];
-    error |= __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector);
-    error |= __vmwrite(HOST_TR_BASE, host_env.tr_base);
-    error |= __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
-}
-
-static int construct_vmcs(struct vcpu *v)
-{
-    int error = 0;
-    unsigned long tmp, cr0, cr4;
+    __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector);
+    __vmwrite(HOST_TR_BASE, host_env.tr_base);
+    __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom());
+}
+
+static void construct_vmcs(struct vcpu *v)
+{
+    unsigned long cr0, cr4;
     union vmcs_arbytes arbytes;
 
     vmx_vmcs_enter(v);
 
     /* VMCS controls. */
-    error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
-    error |= __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
-    error |= __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control);
-    error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmx_cpu_based_exec_control);
+    __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
+    __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
+    __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;
 
     /* Host data selectors. */
-    error |= __vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS);
-    error |= __vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS);
-    error |= __vmwrite(HOST_ES_SELECTOR, __HYPERVISOR_DS);
+    __vmwrite(HOST_SS_SELECTOR, __HYPERVISOR_DS);
+    __vmwrite(HOST_DS_SELECTOR, __HYPERVISOR_DS);
+    __vmwrite(HOST_ES_SELECTOR, __HYPERVISOR_DS);
 #if defined(__i386__)
-    error |= __vmwrite(HOST_FS_SELECTOR, __HYPERVISOR_DS);
-    error |= __vmwrite(HOST_GS_SELECTOR, __HYPERVISOR_DS);
-    error |= __vmwrite(HOST_FS_BASE, 0);
-    error |= __vmwrite(HOST_GS_BASE, 0);
+    __vmwrite(HOST_FS_SELECTOR, __HYPERVISOR_DS);
+    __vmwrite(HOST_GS_SELECTOR, __HYPERVISOR_DS);
+    __vmwrite(HOST_FS_BASE, 0);
+    __vmwrite(HOST_GS_BASE, 0);
 #elif defined(__x86_64__)
-    rdmsrl(MSR_FS_BASE, tmp); error |= __vmwrite(HOST_FS_BASE, tmp);
-    rdmsrl(MSR_GS_BASE, tmp); error |= __vmwrite(HOST_GS_BASE, tmp);
+    {
+        unsigned long msr;
+        rdmsrl(MSR_FS_BASE, msr); __vmwrite(HOST_FS_BASE, msr);
+        rdmsrl(MSR_GS_BASE, msr); __vmwrite(HOST_GS_BASE, msr);
+    }
 #endif
 
     /* Host control registers. */
-    error |= __vmwrite(HOST_CR0, read_cr0());
-    error |= __vmwrite(HOST_CR4, read_cr4());
+    __vmwrite(HOST_CR0, read_cr0());
+    __vmwrite(HOST_CR4, read_cr4());
 
     /* Host CS:RIP. */
-    error |= __vmwrite(HOST_CS_SELECTOR, __HYPERVISOR_CS);
-    error |= __vmwrite(HOST_RIP, (unsigned long)vmx_asm_vmexit_handler);
+    __vmwrite(HOST_CS_SELECTOR, __HYPERVISOR_CS);
+    __vmwrite(HOST_RIP, (unsigned long)vmx_asm_vmexit_handler);
 
     /* MSR intercepts. */
-    error |= __vmwrite(VM_EXIT_MSR_LOAD_ADDR, 0);
-    error |= __vmwrite(VM_EXIT_MSR_STORE_ADDR, 0);
-    error |= __vmwrite(VM_EXIT_MSR_STORE_COUNT, 0);
-    error |= __vmwrite(VM_EXIT_MSR_LOAD_COUNT, 0);
-    error |= __vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
-
-    error |= __vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
-
-    error |= __vmwrite(CR0_GUEST_HOST_MASK, ~0UL);
-    error |= __vmwrite(CR4_GUEST_HOST_MASK, ~0UL);
-
-    error |= __vmwrite(PAGE_FAULT_ERROR_CODE_MASK, 0);
-    error |= __vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, 0);
-
-    error |= __vmwrite(CR3_TARGET_COUNT, 0);
-
-    error |= __vmwrite(GUEST_ACTIVITY_STATE, 0);
+    __vmwrite(VM_EXIT_MSR_LOAD_ADDR, 0);
+    __vmwrite(VM_EXIT_MSR_STORE_ADDR, 0);
+    __vmwrite(VM_EXIT_MSR_STORE_COUNT, 0);
+    __vmwrite(VM_EXIT_MSR_LOAD_COUNT, 0);
+    __vmwrite(VM_ENTRY_MSR_LOAD_COUNT, 0);
+
+    __vmwrite(VM_ENTRY_INTR_INFO_FIELD, 0);
+
+    __vmwrite(CR0_GUEST_HOST_MASK, ~0UL);
+    __vmwrite(CR4_GUEST_HOST_MASK, ~0UL);
+
+    __vmwrite(PAGE_FAULT_ERROR_CODE_MASK, 0);
+    __vmwrite(PAGE_FAULT_ERROR_CODE_MATCH, 0);
+
+    __vmwrite(CR3_TARGET_COUNT, 0);
+
+    __vmwrite(GUEST_ACTIVITY_STATE, 0);
 
     /* Guest segment bases. */
-    error |= __vmwrite(GUEST_ES_BASE, 0);
-    error |= __vmwrite(GUEST_SS_BASE, 0);
-    error |= __vmwrite(GUEST_DS_BASE, 0);
-    error |= __vmwrite(GUEST_FS_BASE, 0);
-    error |= __vmwrite(GUEST_GS_BASE, 0);
-    error |= __vmwrite(GUEST_CS_BASE, 0);
+    __vmwrite(GUEST_ES_BASE, 0);
+    __vmwrite(GUEST_SS_BASE, 0);
+    __vmwrite(GUEST_DS_BASE, 0);
+    __vmwrite(GUEST_FS_BASE, 0);
+    __vmwrite(GUEST_GS_BASE, 0);
+    __vmwrite(GUEST_CS_BASE, 0);
 
     /* Guest segment limits. */
-    error |= __vmwrite(GUEST_ES_LIMIT, GUEST_SEGMENT_LIMIT);
-    error |= __vmwrite(GUEST_SS_LIMIT, GUEST_SEGMENT_LIMIT);
-    error |= __vmwrite(GUEST_DS_LIMIT, GUEST_SEGMENT_LIMIT);
-    error |= __vmwrite(GUEST_FS_LIMIT, GUEST_SEGMENT_LIMIT);
-    error |= __vmwrite(GUEST_GS_LIMIT, GUEST_SEGMENT_LIMIT);
-    error |= __vmwrite(GUEST_CS_LIMIT, GUEST_SEGMENT_LIMIT);
+    __vmwrite(GUEST_ES_LIMIT, GUEST_SEGMENT_LIMIT);
+    __vmwrite(GUEST_SS_LIMIT, GUEST_SEGMENT_LIMIT);
+    __vmwrite(GUEST_DS_LIMIT, GUEST_SEGMENT_LIMIT);
+    __vmwrite(GUEST_FS_LIMIT, GUEST_SEGMENT_LIMIT);
+    __vmwrite(GUEST_GS_LIMIT, GUEST_SEGMENT_LIMIT);
+    __vmwrite(GUEST_CS_LIMIT, GUEST_SEGMENT_LIMIT);
 
     /* Guest segment AR bytes. */
     arbytes.bytes = 0;
@@ -362,82 +364,77 @@ static int construct_vmcs(struct vcpu *v
     arbytes.fields.default_ops_size = 1;    /* 32-bit */
     arbytes.fields.g = 1;
     arbytes.fields.null_bit = 0;            /* not null */
-    error |= __vmwrite(GUEST_ES_AR_BYTES, arbytes.bytes);
-    error |= __vmwrite(GUEST_SS_AR_BYTES, arbytes.bytes);
-    error |= __vmwrite(GUEST_DS_AR_BYTES, arbytes.bytes);
-    error |= __vmwrite(GUEST_FS_AR_BYTES, arbytes.bytes);
-    error |= __vmwrite(GUEST_GS_AR_BYTES, arbytes.bytes);
+    __vmwrite(GUEST_ES_AR_BYTES, arbytes.bytes);
+    __vmwrite(GUEST_SS_AR_BYTES, arbytes.bytes);
+    __vmwrite(GUEST_DS_AR_BYTES, arbytes.bytes);
+    __vmwrite(GUEST_FS_AR_BYTES, arbytes.bytes);
+    __vmwrite(GUEST_GS_AR_BYTES, arbytes.bytes);
     arbytes.fields.seg_type = 0xb;          /* type = 0xb */
-    error |= __vmwrite(GUEST_CS_AR_BYTES, arbytes.bytes);
+    __vmwrite(GUEST_CS_AR_BYTES, arbytes.bytes);
 
     /* Guest GDT. */
-    error |= __vmwrite(GUEST_GDTR_BASE, 0);
-    error |= __vmwrite(GUEST_GDTR_LIMIT, 0);
+    __vmwrite(GUEST_GDTR_BASE, 0);
+    __vmwrite(GUEST_GDTR_LIMIT, 0);
 
     /* Guest IDT. */
-    error |= __vmwrite(GUEST_IDTR_BASE, 0);
-    error |= __vmwrite(GUEST_IDTR_LIMIT, 0);
+    __vmwrite(GUEST_IDTR_BASE, 0);
+    __vmwrite(GUEST_IDTR_LIMIT, 0);
 
     /* Guest LDT and TSS. */
     arbytes.fields.s = 0;                   /* not code or data segement */
     arbytes.fields.seg_type = 0x2;          /* LTD */
     arbytes.fields.default_ops_size = 0;    /* 16-bit */
     arbytes.fields.g = 0;
-    error |= __vmwrite(GUEST_LDTR_AR_BYTES, arbytes.bytes);
+    __vmwrite(GUEST_LDTR_AR_BYTES, arbytes.bytes);
     arbytes.fields.seg_type = 0xb;          /* 32-bit TSS (busy) */
-    error |= __vmwrite(GUEST_TR_AR_BYTES, arbytes.bytes);
-
-    error |= __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
-    __asm__ __volatile__ ("mov %%dr7, %0\n" : "=r" (tmp));
-    error |= __vmwrite(GUEST_DR7, tmp);
-    error |= __vmwrite(VMCS_LINK_POINTER, ~0UL);
+    __vmwrite(GUEST_TR_AR_BYTES, arbytes.bytes);
+
+    __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
+    __vmwrite(GUEST_DR7, 0);
+    __vmwrite(VMCS_LINK_POINTER, ~0UL);
 #if defined(__i386__)
-    error |= __vmwrite(VMCS_LINK_POINTER_HIGH, ~0UL);
-#endif
-
-    error |= __vmwrite(EXCEPTION_BITMAP,
-                       MONITOR_DEFAULT_EXCEPTION_BITMAP);
+    __vmwrite(VMCS_LINK_POINTER_HIGH, ~0UL);
+#endif
+
+    __vmwrite(EXCEPTION_BITMAP, MONITOR_DEFAULT_EXCEPTION_BITMAP);
 
     /* Guest CR0. */
     cr0 = read_cr0();
     v->arch.hvm_vmx.cpu_cr0 = cr0;
-    error |= __vmwrite(GUEST_CR0, v->arch.hvm_vmx.cpu_cr0);
+    __vmwrite(GUEST_CR0, v->arch.hvm_vmx.cpu_cr0);
     v->arch.hvm_vmx.cpu_shadow_cr0 = cr0 & ~(X86_CR0_PG | X86_CR0_TS);
-    error |= __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr0);
+    __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr0);
 
     /* Guest CR4. */
     cr4 = read_cr4();
-    error |= __vmwrite(GUEST_CR4, cr4 & ~X86_CR4_PSE);
+    __vmwrite(GUEST_CR4, cr4 & ~X86_CR4_PSE);
     v->arch.hvm_vmx.cpu_shadow_cr4 =
         cr4 & ~(X86_CR4_PGE | X86_CR4_VMXE | X86_CR4_PAE);
-    error |= __vmwrite(CR4_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr4);
+    __vmwrite(CR4_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr4);
 
 #ifdef __x86_64__ 
     /* VLAPIC TPR optimisation. */
     v->arch.hvm_vcpu.u.vmx.exec_control |= CPU_BASED_TPR_SHADOW;
     v->arch.hvm_vcpu.u.vmx.exec_control &=
         ~(CPU_BASED_CR8_STORE_EXITING | CPU_BASED_CR8_LOAD_EXITING);
-    error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
-                       v->arch.hvm_vcpu.u.vmx.exec_control);
-    error |= __vmwrite(VIRTUAL_APIC_PAGE_ADDR,
-                       page_to_maddr(vcpu_vlapic(v)->regs_page));
-    error |= __vmwrite(TPR_THRESHOLD, 0);
-#endif
-
-    error |= __vmwrite(GUEST_LDTR_SELECTOR, 0);
-    error |= __vmwrite(GUEST_LDTR_BASE, 0);
-    error |= __vmwrite(GUEST_LDTR_LIMIT, 0);
-
-    error |= __vmwrite(GUEST_TR_BASE, 0);
-    error |= __vmwrite(GUEST_TR_LIMIT, 0xff);
+    __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vcpu.u.vmx.exec_control);
+    __vmwrite(VIRTUAL_APIC_PAGE_ADDR,
+              page_to_maddr(vcpu_vlapic(v)->regs_page));
+    __vmwrite(TPR_THRESHOLD, 0);
+#endif
+
+    __vmwrite(GUEST_LDTR_SELECTOR, 0);
+    __vmwrite(GUEST_LDTR_BASE, 0);
+    __vmwrite(GUEST_LDTR_LIMIT, 0);
+
+    __vmwrite(GUEST_TR_BASE, 0);
+    __vmwrite(GUEST_TR_LIMIT, 0xff);
 
     shadow_update_paging_modes(v);
     __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
     __vmwrite(HOST_CR3, v->arch.cr3);
 
     vmx_vmcs_exit(v);
-
-    return error;
 }
 
 int vmx_create_vmcs(struct vcpu *v)
@@ -446,13 +443,8 @@ int vmx_create_vmcs(struct vcpu *v)
         return -ENOMEM;
  
     __vmx_clear_vmcs(v);
-    
-    if ( construct_vmcs(v) != 0 )
-    {
-        vmx_free_vmcs(v->arch.hvm_vmx.vmcs);
-        v->arch.hvm_vmx.vmcs = NULL;
-        return -EINVAL;
-    }
+
+    construct_vmcs(v);
 
     return 0;
 }
@@ -472,16 +464,14 @@ void vmx_destroy_vmcs(struct vcpu *v)
 
 void vm_launch_fail(unsigned long eflags)
 {
-    unsigned long error;
-    __vmread(VM_INSTRUCTION_ERROR, &error);
+    unsigned long error = __vmread(VM_INSTRUCTION_ERROR);
     printk("<vm_launch_fail> error code %lx\n", error);
     __hvm_bug(guest_cpu_user_regs());
 }
 
 void vm_resume_fail(unsigned long eflags)
 {
-    unsigned long error;
-    __vmread(VM_INSTRUCTION_ERROR, &error);
+    unsigned long error = __vmread(VM_INSTRUCTION_ERROR);
     printk("<vm_resume_fail> error code %lx\n", error);
     __hvm_bug(guest_cpu_user_regs());
 }
@@ -510,7 +500,7 @@ static void print_section(char *header, 
 {
     uint32_t addr, j;
     unsigned long val;
-    int code;
+    int code, rc;
     char *fmt[4] = {"0x%04lx ", "0x%016lx ", "0x%08lx ", "0x%016lx "};
     char *err[4] = {"------ ", "------------------ ", 
                     "---------- ", "------------------ "};
@@ -526,7 +516,8 @@ static void print_section(char *header, 
         if (!(j&3))
             printk("\n\t\t0x%08x: ", addr);
 
-        if (!__vmread(addr, &val))
+        val = __vmread_safe(addr, &rc);
+        if (rc == 0)
             printk(fmt[code], val);
         else
             printk("%s", err[code]);
diff -r 6555ca56d844 -r 9f9f569b0a1d xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Wed Nov 08 15:11:18 2006 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Wed Nov 08 16:43:50 2006 +0000
@@ -154,14 +154,14 @@ static inline int long_mode_do_msr_read(
             /* XXX should it be GP fault */
             domain_crash_synchronous();
 
-        __vmread(GUEST_FS_BASE, &msr_content);
+        msr_content = __vmread(GUEST_FS_BASE);
         break;
 
     case MSR_GS_BASE:
         if ( !(vmx_long_mode_enabled(v)) )
             domain_crash_synchronous();
 
-        __vmread(GUEST_GS_BASE, &msr_content);
+        msr_content = __vmread(GUEST_GS_BASE);
         break;
 
     case MSR_SHADOW_GS_BASE:
@@ -323,20 +323,20 @@ static inline int long_mode_do_msr_write
 
 static inline void vmx_save_dr(struct vcpu *v)
 {
-    if ( v->arch.hvm_vcpu.flag_dr_dirty )
-    {
-        savedebug(&v->arch.guest_context, 0);
-        savedebug(&v->arch.guest_context, 1);
-        savedebug(&v->arch.guest_context, 2);
-        savedebug(&v->arch.guest_context, 3);
-        savedebug(&v->arch.guest_context, 6);
-        
-        v->arch.hvm_vcpu.flag_dr_dirty = 0;
-
-        v->arch.hvm_vcpu.u.vmx.exec_control |= CPU_BASED_MOV_DR_EXITING;
-        __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
-                  v->arch.hvm_vcpu.u.vmx.exec_control);
-    }
+    if ( !v->arch.hvm_vcpu.flag_dr_dirty )
+        return;
+
+    /* Clear the DR dirty flag and re-enable intercepts for DR accesses. */
+    v->arch.hvm_vcpu.flag_dr_dirty = 0;
+    v->arch.hvm_vcpu.u.vmx.exec_control |= CPU_BASED_MOV_DR_EXITING;
+    __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vcpu.u.vmx.exec_control);
+
+    savedebug(&v->arch.guest_context, 0);
+    savedebug(&v->arch.guest_context, 1);
+    savedebug(&v->arch.guest_context, 2);
+    savedebug(&v->arch.guest_context, 3);
+    savedebug(&v->arch.guest_context, 6);
+    v->arch.guest_context.debugreg[7] = __vmread(GUEST_DR7);
 }
 
 static inline void __restore_debug_registers(struct vcpu *v)
@@ -347,7 +347,7 @@ static inline void __restore_debug_regis
     loaddebug(&v->arch.guest_context, 3);
     /* No 4 and 5 */
     loaddebug(&v->arch.guest_context, 6);
-    /* DR7 is loaded from the vmcs. */
+    /* DR7 is loaded from the VMCS. */
 }
 
 /*
@@ -355,21 +355,13 @@ static inline void __restore_debug_regis
  * need to be restored if their value is going to affect execution -- i.e.,
  * if one of the breakpoints is enabled.  So mask out all bits that don't
  * enable some breakpoint functionality.
- *
- * This is in part necessary because bit 10 of DR7 is hardwired to 1, so a
- * simple if( guest_dr7 ) will always return true.  As long as we're masking,
- * we might as well do it right.
  */
 #define DR7_ACTIVE_MASK 0xff
 
 static inline void vmx_restore_dr(struct vcpu *v)
 {
-    unsigned long guest_dr7;
-
-    __vmread(GUEST_DR7, &guest_dr7);
-
-    /* Assumes guest does not have DR access at time of context switch. */
-    if ( unlikely(guest_dr7 & DR7_ACTIVE_MASK) )
+    /* NB. __vmread() is not usable here, so we cannot read from the VMCS. */
+    if ( unlikely(v->arch.guest_context.debugreg[7] & DR7_ACTIVE_MASK) )
         __restore_debug_registers(v);
 }
 
@@ -430,22 +422,22 @@ static void vmx_store_cpu_guest_regs(
 
     if ( regs != NULL )
     {
-        __vmread(GUEST_RFLAGS, &regs->eflags);
-        __vmread(GUEST_SS_SELECTOR, &regs->ss);
-        __vmread(GUEST_CS_SELECTOR, &regs->cs);
-        __vmread(GUEST_DS_SELECTOR, &regs->ds);
-        __vmread(GUEST_ES_SELECTOR, &regs->es);
-        __vmread(GUEST_GS_SELECTOR, &regs->gs);
-        __vmread(GUEST_FS_SELECTOR, &regs->fs);
-        __vmread(GUEST_RIP, &regs->eip);
-        __vmread(GUEST_RSP, &regs->esp);
+        regs->eflags = __vmread(GUEST_RFLAGS);
+        regs->ss = __vmread(GUEST_SS_SELECTOR);
+        regs->cs = __vmread(GUEST_CS_SELECTOR);
+        regs->ds = __vmread(GUEST_DS_SELECTOR);
+        regs->es = __vmread(GUEST_ES_SELECTOR);
+        regs->gs = __vmread(GUEST_GS_SELECTOR);
+        regs->fs = __vmread(GUEST_FS_SELECTOR);
+        regs->eip = __vmread(GUEST_RIP);
+        regs->esp = __vmread(GUEST_RSP);
     }
 
     if ( crs != NULL )
     {
         crs[0] = v->arch.hvm_vmx.cpu_shadow_cr0;
         crs[2] = v->arch.hvm_vmx.cpu_cr2;
-        __vmread(GUEST_CR3, &crs[3]);
+        crs[3] = __vmread(GUEST_CR3);
         crs[4] = v->arch.hvm_vmx.cpu_shadow_cr4;
     }
 
@@ -466,29 +458,26 @@ static void vmx_store_cpu_guest_regs(
  */
 static void fixup_vm86_seg_bases(struct cpu_user_regs *regs)
 {
-    int err = 0;
     unsigned long base;
 
-    err |= __vmread(GUEST_ES_BASE, &base);
+    base = __vmread(GUEST_ES_BASE);
     if (regs->es << 4 != base)
-        err |= __vmwrite(GUEST_ES_BASE, regs->es << 4);
-    err |= __vmread(GUEST_CS_BASE, &base);
+        __vmwrite(GUEST_ES_BASE, regs->es << 4);
+    base = __vmread(GUEST_CS_BASE);
     if (regs->cs << 4 != base)
-        err |= __vmwrite(GUEST_CS_BASE, regs->cs << 4);
-    err |= __vmread(GUEST_SS_BASE, &base);
+        __vmwrite(GUEST_CS_BASE, regs->cs << 4);
+    base = __vmread(GUEST_SS_BASE);
     if (regs->ss << 4 != base)
-        err |= __vmwrite(GUEST_SS_BASE, regs->ss << 4);
-    err |= __vmread(GUEST_DS_BASE, &base);
+        __vmwrite(GUEST_SS_BASE, regs->ss << 4);
+    base = __vmread(GUEST_DS_BASE);
     if (regs->ds << 4 != base)
-        err |= __vmwrite(GUEST_DS_BASE, regs->ds << 4);
-    err |= __vmread(GUEST_FS_BASE, &base);
+        __vmwrite(GUEST_DS_BASE, regs->ds << 4);
+    base = __vmread(GUEST_FS_BASE);
     if (regs->fs << 4 != base)
-        err |= __vmwrite(GUEST_FS_BASE, regs->fs << 4);
-    err |= __vmread(GUEST_GS_BASE, &base);
+        __vmwrite(GUEST_FS_BASE, regs->fs << 4);
+    base = __vmread(GUEST_GS_BASE);
     if (regs->gs << 4 != base)
-        err |= __vmwrite(GUEST_GS_BASE, regs->gs << 4);
-
-    BUG_ON(err);
+        __vmwrite(GUEST_GS_BASE, regs->gs << 4);
 }
 
 static void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
@@ -605,7 +594,7 @@ static int vmx_realmode(struct vcpu *v)
 
     ASSERT(v == current);
 
-    __vmread(GUEST_RFLAGS, &rflags);
+    rflags = __vmread(GUEST_RFLAGS);
     return rflags & X86_EFLAGS_VM;
 }
 
@@ -615,7 +604,7 @@ static int vmx_guest_x86_mode(struct vcp
 
     ASSERT(v == current);
 
-    __vmread(GUEST_CS_AR_BYTES, &cs_ar_bytes);
+    cs_ar_bytes = __vmread(GUEST_CS_AR_BYTES);
 
     if ( vmx_long_mode_enabled(v) )
         return ((cs_ar_bytes & (1u<<13)) ?
@@ -735,7 +724,7 @@ static int __get_instruction_length(void
 static int __get_instruction_length(void)
 {
     int len;
-    __vmread(VM_EXIT_INSTRUCTION_LEN, &len); /* Safe: callers audited */
+    len = __vmread(VM_EXIT_INSTRUCTION_LEN); /* Safe: callers audited */
     if ( (len < 1) || (len > 15) )
         __hvm_bug(guest_cpu_user_regs());
     return len;
@@ -745,7 +734,7 @@ static void inline __update_guest_eip(un
 {
     unsigned long current_eip;
 
-    __vmread(GUEST_RIP, &current_eip);
+    current_eip = __vmread(GUEST_RIP);
     __vmwrite(GUEST_RIP, current_eip + inst_len);
     __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
 }
@@ -758,8 +747,8 @@ static int vmx_do_page_fault(unsigned lo
     {
         unsigned long eip, cs;
 
-        __vmread(GUEST_CS_BASE, &cs);
-        __vmread(GUEST_RIP, &eip);
+        cs = __vmread(GUEST_CS_BASE);
+        eip = __vmread(GUEST_RIP);
         HVM_DBG_LOG(DBG_LEVEL_VMMU,
                     "vmx_do_page_fault = 0x%lx, cs_base=%lx, "
                     "eip = %lx, error_code = %lx\n",
@@ -773,7 +762,7 @@ static int vmx_do_page_fault(unsigned lo
 #if 0
     if ( !result )
     {
-        __vmread(GUEST_RIP, &eip);
+        eip = __vmread(GUEST_RIP);
         printk("vmx pgfault to guest va=%lx eip=%lx\n", va, eip);
     }
 #endif
@@ -805,7 +794,7 @@ static void vmx_do_cpuid(struct cpu_user
     unsigned long eip;
     struct vcpu *v = current;
 
-    __vmread(GUEST_RIP, &eip);
+    eip = __vmread(GUEST_RIP);
 
     HVM_DBG_LOG(DBG_LEVEL_3, "(eax) 0x%08lx, (ebx) 0x%08lx, "
                 "(ecx) 0x%08lx, (edx) 0x%08lx, (esi) 0x%08lx, (edi) 0x%08lx",
@@ -946,7 +935,7 @@ static void vmx_do_invlpg(unsigned long 
     unsigned long eip;
     struct vcpu *v = current;
 
-    __vmread(GUEST_RIP, &eip);
+    eip = __vmread(GUEST_RIP);
 
     HVM_DBG_LOG(DBG_LEVEL_VMMU, "eip=%lx, va=%lx",
                 eip, va);
@@ -969,7 +958,7 @@ static int check_for_null_selector(unsig
     /* INS can only use ES segment register, and it can't be overridden */
     if ( dir == IOREQ_READ )
     {
-        __vmread(GUEST_ES_SELECTOR, &sel);
+        sel = __vmread(GUEST_ES_SELECTOR);
         return sel == 0 ? 1 : 0;
     }
 
@@ -991,25 +980,25 @@ static int check_for_null_selector(unsig
         case 0x67: /* addr32 */
             continue;
         case 0x2e: /* CS */
-            __vmread(GUEST_CS_SELECTOR, &sel);
+            sel = __vmread(GUEST_CS_SELECTOR);
             break;
         case 0x36: /* SS */
-            __vmread(GUEST_SS_SELECTOR, &sel);
+            sel = __vmread(GUEST_SS_SELECTOR);
             break;
         case 0x26: /* ES */
-            __vmread(GUEST_ES_SELECTOR, &sel);
+            sel = __vmread(GUEST_ES_SELECTOR);
             break;
         case 0x64: /* FS */
-            __vmread(GUEST_FS_SELECTOR, &sel);
+            sel = __vmread(GUEST_FS_SELECTOR);
             break;
         case 0x65: /* GS */
-            __vmread(GUEST_GS_SELECTOR, &sel);
+            sel = __vmread(GUEST_GS_SELECTOR);
             break;
         case 0x3e: /* DS */
             /* FALLTHROUGH */
         default:
             /* DS is the default */
-            __vmread(GUEST_DS_SELECTOR, &sel);
+            sel = __vmread(GUEST_DS_SELECTOR);
         }
         return sel == 0 ? 1 : 0;
     }
@@ -1056,7 +1045,7 @@ static void vmx_io_instruction(unsigned 
         unsigned long addr, count = 1;
         int sign = regs->eflags & X86_EFLAGS_DF ? -1 : 1;
 
-        __vmread(GUEST_LINEAR_ADDRESS, &addr);
+        addr = __vmread(GUEST_LINEAR_ADDRESS);
 
         /*
          * In protected mode, guest linear address is invalid if the
@@ -1119,98 +1108,96 @@ static void vmx_io_instruction(unsigned 
     }
 }
 
-static int vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
-{
-    int error = 0;
-
+static void vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
+{
     /* NB. Skip transition instruction. */
-    error |= __vmread(GUEST_RIP, &c->eip);
+    c->eip = __vmread(GUEST_RIP);
     c->eip += __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
 
-    error |= __vmread(GUEST_RSP, &c->esp);
-    error |= __vmread(GUEST_RFLAGS, &c->eflags);
+    c->esp = __vmread(GUEST_RSP);
+    c->eflags = __vmread(GUEST_RFLAGS);
 
     c->cr0 = v->arch.hvm_vmx.cpu_shadow_cr0;
     c->cr3 = v->arch.hvm_vmx.cpu_cr3;
     c->cr4 = v->arch.hvm_vmx.cpu_shadow_cr4;
 
-    error |= __vmread(GUEST_IDTR_LIMIT, &c->idtr_limit);
-    error |= __vmread(GUEST_IDTR_BASE, &c->idtr_base);
-
-    error |= __vmread(GUEST_GDTR_LIMIT, &c->gdtr_limit);
-    error |= __vmread(GUEST_GDTR_BASE, &c->gdtr_base);
-
-    error |= __vmread(GUEST_CS_SELECTOR, &c->cs_sel);
-    error |= __vmread(GUEST_CS_LIMIT, &c->cs_limit);
-    error |= __vmread(GUEST_CS_BASE, &c->cs_base);
-    error |= __vmread(GUEST_CS_AR_BYTES, &c->cs_arbytes.bytes);
-
-    error |= __vmread(GUEST_DS_SELECTOR, &c->ds_sel);
-    error |= __vmread(GUEST_DS_LIMIT, &c->ds_limit);
-    error |= __vmread(GUEST_DS_BASE, &c->ds_base);
-    error |= __vmread(GUEST_DS_AR_BYTES, &c->ds_arbytes.bytes);
-
-    error |= __vmread(GUEST_ES_SELECTOR, &c->es_sel);
-    error |= __vmread(GUEST_ES_LIMIT, &c->es_limit);
-    error |= __vmread(GUEST_ES_BASE, &c->es_base);
-    error |= __vmread(GUEST_ES_AR_BYTES, &c->es_arbytes.bytes);
-
-    error |= __vmread(GUEST_SS_SELECTOR, &c->ss_sel);
-    error |= __vmread(GUEST_SS_LIMIT, &c->ss_limit);
-    error |= __vmread(GUEST_SS_BASE, &c->ss_base);
-    error |= __vmread(GUEST_SS_AR_BYTES, &c->ss_arbytes.bytes);
-
-    error |= __vmread(GUEST_FS_SELECTOR, &c->fs_sel);
-    error |= __vmread(GUEST_FS_LIMIT, &c->fs_limit);
-    error |= __vmread(GUEST_FS_BASE, &c->fs_base);
-    error |= __vmread(GUEST_FS_AR_BYTES, &c->fs_arbytes.bytes);
-
-    error |= __vmread(GUEST_GS_SELECTOR, &c->gs_sel);
-    error |= __vmread(GUEST_GS_LIMIT, &c->gs_limit);
-    error |= __vmread(GUEST_GS_BASE, &c->gs_base);
-    error |= __vmread(GUEST_GS_AR_BYTES, &c->gs_arbytes.bytes);
-
-    error |= __vmread(GUEST_TR_SELECTOR, &c->tr_sel);
-    error |= __vmread(GUEST_TR_LIMIT, &c->tr_limit);
-    error |= __vmread(GUEST_TR_BASE, &c->tr_base);
-    error |= __vmread(GUEST_TR_AR_BYTES, &c->tr_arbytes.bytes);
-
-    error |= __vmread(GUEST_LDTR_SELECTOR, &c->ldtr_sel);
-    error |= __vmread(GUEST_LDTR_LIMIT, &c->ldtr_limit);
-    error |= __vmread(GUEST_LDTR_BASE, &c->ldtr_base);
-    error |= __vmread(GUEST_LDTR_AR_BYTES, &c->ldtr_arbytes.bytes);
-
-    return !error;
-}
-
-static int vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
+    c->idtr_limit = __vmread(GUEST_IDTR_LIMIT);
+    c->idtr_base = __vmread(GUEST_IDTR_BASE);
+
+    c->gdtr_limit = __vmread(GUEST_GDTR_LIMIT);
+    c->gdtr_base = __vmread(GUEST_GDTR_BASE);
+
+    c->cs_sel = __vmread(GUEST_CS_SELECTOR);
+    c->cs_limit = __vmread(GUEST_CS_LIMIT);
+    c->cs_base = __vmread(GUEST_CS_BASE);
+    c->cs_arbytes.bytes = __vmread(GUEST_CS_AR_BYTES);
+
+    c->ds_sel = __vmread(GUEST_DS_SELECTOR);
+    c->ds_limit = __vmread(GUEST_DS_LIMIT);
+    c->ds_base = __vmread(GUEST_DS_BASE);
+    c->ds_arbytes.bytes = __vmread(GUEST_DS_AR_BYTES);
+
+    c->es_sel = __vmread(GUEST_ES_SELECTOR);
+    c->es_limit = __vmread(GUEST_ES_LIMIT);
+    c->es_base = __vmread(GUEST_ES_BASE);
+    c->es_arbytes.bytes = __vmread(GUEST_ES_AR_BYTES);
+
+    c->ss_sel = __vmread(GUEST_SS_SELECTOR);
+    c->ss_limit = __vmread(GUEST_SS_LIMIT);
+    c->ss_base = __vmread(GUEST_SS_BASE);
+    c->ss_arbytes.bytes = __vmread(GUEST_SS_AR_BYTES);
+
+    c->fs_sel = __vmread(GUEST_FS_SELECTOR);
+    c->fs_limit = __vmread(GUEST_FS_LIMIT);
+    c->fs_base = __vmread(GUEST_FS_BASE);
+    c->fs_arbytes.bytes = __vmread(GUEST_FS_AR_BYTES);
+
+    c->gs_sel = __vmread(GUEST_GS_SELECTOR);
+    c->gs_limit = __vmread(GUEST_GS_LIMIT);
+    c->gs_base = __vmread(GUEST_GS_BASE);
+    c->gs_arbytes.bytes = __vmread(GUEST_GS_AR_BYTES);
+
+    c->tr_sel = __vmread(GUEST_TR_SELECTOR);
+    c->tr_limit = __vmread(GUEST_TR_LIMIT);
+    c->tr_base = __vmread(GUEST_TR_BASE);
+    c->tr_arbytes.bytes = __vmread(GUEST_TR_AR_BYTES);
+
+    c->ldtr_sel = __vmread(GUEST_LDTR_SELECTOR);
+    c->ldtr_limit = __vmread(GUEST_LDTR_LIMIT);
+    c->ldtr_base = __vmread(GUEST_LDTR_BASE);
+    c->ldtr_arbytes.bytes = __vmread(GUEST_LDTR_AR_BYTES);
+}
+
+static void vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
 {
     unsigned long mfn, old_base_mfn;
-    int error = 0;
-
-    error |= __vmwrite(GUEST_RIP, c->eip);
-    error |= __vmwrite(GUEST_RSP, c->esp);
-    error |= __vmwrite(GUEST_RFLAGS, c->eflags);
+
+    __vmwrite(GUEST_RIP, c->eip);
+    __vmwrite(GUEST_RSP, c->esp);
+    __vmwrite(GUEST_RFLAGS, c->eflags);
 
     v->arch.hvm_vmx.cpu_shadow_cr0 = c->cr0;
-    error |= __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr0);
-
-    if (!vmx_paging_enabled(v))
+    __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr0);
+
+    if ( !vmx_paging_enabled(v) )
         goto skip_cr3;
 
-    if (c->cr3 == v->arch.hvm_vmx.cpu_cr3) {
+    if ( c->cr3 == v->arch.hvm_vmx.cpu_cr3 )
+    {
         /*
          * This is simple TLB flush, implying the guest has
          * removed some translation or changed page attributes.
          * We simply invalidate the shadow.
          */
         mfn = get_mfn_from_gpfn(c->cr3 >> PAGE_SHIFT);
-        if (mfn != pagetable_get_pfn(v->arch.guest_table)) {
+        if ( mfn != pagetable_get_pfn(v->arch.guest_table) )
+        {
             printk("Invalid CR3 value=%x", c->cr3);
             domain_crash_synchronous();
-            return 0;
-        }
-    } else {
+        }
+    }
+    else
+    {
         /*
          * If different, make a shadow. Check if the PDBR is valid
          * first.
@@ -1221,10 +1208,9 @@ static int vmx_world_restore(struct vcpu
         {
             printk("Invalid CR3 value=%x", c->cr3);
             domain_crash_synchronous();
-            return 0;
-        }
-        if(!get_page(mfn_to_page(mfn), v->domain))
-                return 0;
+        }
+        if ( !get_page(mfn_to_page(mfn), v->domain) )
+            domain_crash_synchronous();
         old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
         v->arch.guest_table = pagetable_from_pfn(mfn);
         if (old_base_mfn)
@@ -1236,66 +1222,63 @@ static int vmx_world_restore(struct vcpu
     }
 
  skip_cr3:
-
-    if (!vmx_paging_enabled(v))
+    if ( !vmx_paging_enabled(v) )
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "switching to vmxassist. use phys table");
     else
         HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %x", c->cr3);
 
-    error |= __vmwrite(GUEST_CR4, (c->cr4 | VMX_CR4_HOST_MASK));
+    __vmwrite(GUEST_CR4, (c->cr4 | VMX_CR4_HOST_MASK));
     v->arch.hvm_vmx.cpu_shadow_cr4 = c->cr4;
-    error |= __vmwrite(CR4_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr4);
-
-    error |= __vmwrite(GUEST_IDTR_LIMIT, c->idtr_limit);
-    error |= __vmwrite(GUEST_IDTR_BASE, c->idtr_base);
-
-    error |= __vmwrite(GUEST_GDTR_LIMIT, c->gdtr_limit);
-    error |= __vmwrite(GUEST_GDTR_BASE, c->gdtr_base);
-
-    error |= __vmwrite(GUEST_CS_SELECTOR, c->cs_sel);
-    error |= __vmwrite(GUEST_CS_LIMIT, c->cs_limit);
-    error |= __vmwrite(GUEST_CS_BASE, c->cs_base);
-    error |= __vmwrite(GUEST_CS_AR_BYTES, c->cs_arbytes.bytes);
-
-    error |= __vmwrite(GUEST_DS_SELECTOR, c->ds_sel);
-    error |= __vmwrite(GUEST_DS_LIMIT, c->ds_limit);
-    error |= __vmwrite(GUEST_DS_BASE, c->ds_base);
-    error |= __vmwrite(GUEST_DS_AR_BYTES, c->ds_arbytes.bytes);
-
-    error |= __vmwrite(GUEST_ES_SELECTOR, c->es_sel);
-    error |= __vmwrite(GUEST_ES_LIMIT, c->es_limit);
-    error |= __vmwrite(GUEST_ES_BASE, c->es_base);
-    error |= __vmwrite(GUEST_ES_AR_BYTES, c->es_arbytes.bytes);
-
-    error |= __vmwrite(GUEST_SS_SELECTOR, c->ss_sel);
-    error |= __vmwrite(GUEST_SS_LIMIT, c->ss_limit);
-    error |= __vmwrite(GUEST_SS_BASE, c->ss_base);
-    error |= __vmwrite(GUEST_SS_AR_BYTES, c->ss_arbytes.bytes);
-
-    error |= __vmwrite(GUEST_FS_SELECTOR, c->fs_sel);
-    error |= __vmwrite(GUEST_FS_LIMIT, c->fs_limit);
-    error |= __vmwrite(GUEST_FS_BASE, c->fs_base);
-    error |= __vmwrite(GUEST_FS_AR_BYTES, c->fs_arbytes.bytes);
-
-    error |= __vmwrite(GUEST_GS_SELECTOR, c->gs_sel);
-    error |= __vmwrite(GUEST_GS_LIMIT, c->gs_limit);
-    error |= __vmwrite(GUEST_GS_BASE, c->gs_base);
-    error |= __vmwrite(GUEST_GS_AR_BYTES, c->gs_arbytes.bytes);
-
-    error |= __vmwrite(GUEST_TR_SELECTOR, c->tr_sel);
-    error |= __vmwrite(GUEST_TR_LIMIT, c->tr_limit);
-    error |= __vmwrite(GUEST_TR_BASE, c->tr_base);
-    error |= __vmwrite(GUEST_TR_AR_BYTES, c->tr_arbytes.bytes);
-
-    error |= __vmwrite(GUEST_LDTR_SELECTOR, c->ldtr_sel);
-    error |= __vmwrite(GUEST_LDTR_LIMIT, c->ldtr_limit);
-    error |= __vmwrite(GUEST_LDTR_BASE, c->ldtr_base);
-    error |= __vmwrite(GUEST_LDTR_AR_BYTES, c->ldtr_arbytes.bytes);
+    __vmwrite(CR4_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr4);
+
+    __vmwrite(GUEST_IDTR_LIMIT, c->idtr_limit);
+    __vmwrite(GUEST_IDTR_BASE, c->idtr_base);
+
+    __vmwrite(GUEST_GDTR_LIMIT, c->gdtr_limit);
+    __vmwrite(GUEST_GDTR_BASE, c->gdtr_base);
+
+    __vmwrite(GUEST_CS_SELECTOR, c->cs_sel);
+    __vmwrite(GUEST_CS_LIMIT, c->cs_limit);
+    __vmwrite(GUEST_CS_BASE, c->cs_base);
+    __vmwrite(GUEST_CS_AR_BYTES, c->cs_arbytes.bytes);
+
+    __vmwrite(GUEST_DS_SELECTOR, c->ds_sel);
+    __vmwrite(GUEST_DS_LIMIT, c->ds_limit);
+    __vmwrite(GUEST_DS_BASE, c->ds_base);
+    __vmwrite(GUEST_DS_AR_BYTES, c->ds_arbytes.bytes);
+
+    __vmwrite(GUEST_ES_SELECTOR, c->es_sel);
+    __vmwrite(GUEST_ES_LIMIT, c->es_limit);
+    __vmwrite(GUEST_ES_BASE, c->es_base);
+    __vmwrite(GUEST_ES_AR_BYTES, c->es_arbytes.bytes);
+
+    __vmwrite(GUEST_SS_SELECTOR, c->ss_sel);
+    __vmwrite(GUEST_SS_LIMIT, c->ss_limit);
+    __vmwrite(GUEST_SS_BASE, c->ss_base);
+    __vmwrite(GUEST_SS_AR_BYTES, c->ss_arbytes.bytes);
+
+    __vmwrite(GUEST_FS_SELECTOR, c->fs_sel);
+    __vmwrite(GUEST_FS_LIMIT, c->fs_limit);
+    __vmwrite(GUEST_FS_BASE, c->fs_base);
+    __vmwrite(GUEST_FS_AR_BYTES, c->fs_arbytes.bytes);
+
+    __vmwrite(GUEST_GS_SELECTOR, c->gs_sel);
+    __vmwrite(GUEST_GS_LIMIT, c->gs_limit);
+    __vmwrite(GUEST_GS_BASE, c->gs_base);
+    __vmwrite(GUEST_GS_AR_BYTES, c->gs_arbytes.bytes);
+
+    __vmwrite(GUEST_TR_SELECTOR, c->tr_sel);
+    __vmwrite(GUEST_TR_LIMIT, c->tr_limit);
+    __vmwrite(GUEST_TR_BASE, c->tr_base);
+    __vmwrite(GUEST_TR_AR_BYTES, c->tr_arbytes.bytes);
+
+    __vmwrite(GUEST_LDTR_SELECTOR, c->ldtr_sel);
+    __vmwrite(GUEST_LDTR_LIMIT, c->ldtr_limit);
+    __vmwrite(GUEST_LDTR_BASE, c->ldtr_base);
+    __vmwrite(GUEST_LDTR_AR_BYTES, c->ldtr_arbytes.bytes);
 
     shadow_update_paging_modes(v);
     __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
-
-    return !error;
 }
 
 enum { VMX_ASSIST_INVOKE = 0, VMX_ASSIST_RESTORE };
@@ -1325,8 +1308,7 @@ static int vmx_assist(struct vcpu *v, in
         if (hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)))
             goto error;
         if (cp != 0) {
-            if (!vmx_world_save(v, &c))
-                goto error;
+            vmx_world_save(v, &c);
             if (hvm_copy_to_guest_phys(cp, &c, sizeof(c)))
                 goto error;
         }
@@ -1337,8 +1319,7 @@ static int vmx_assist(struct vcpu *v, in
         if (cp != 0) {
             if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
                 goto error;
-            if (!vmx_world_restore(v, &c))
-                goto error;
+            vmx_world_restore(v, &c);
             v->arch.hvm_vmx.vmxassist_enabled = 1;            
             return 1;
         }
@@ -1355,8 +1336,7 @@ static int vmx_assist(struct vcpu *v, in
         if (cp != 0) {
             if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
                 goto error;
-            if (!vmx_world_restore(v, &c))
-                goto error;
+            vmx_world_restore(v, &c);
             v->arch.hvm_vmx.vmxassist_enabled = 0;
             return 1;
         }
@@ -1428,7 +1408,7 @@ static int vmx_set_cr0(unsigned long val
                 HVM_DBG_LOG(DBG_LEVEL_1, "Enabling long mode\n");
                 v->arch.hvm_vmx.msr_content.msr_items[VMX_INDEX_MSR_EFER]
                     |= EFER_LMA;
-                __vmread(VM_ENTRY_CONTROLS, &vm_entry_value);
+                vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
                 vm_entry_value |= VM_ENTRY_IA32E_MODE;
                 __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
             }
@@ -1482,7 +1462,7 @@ static int vmx_set_cr0(unsigned long val
             {
                 v->arch.hvm_vmx.msr_content.msr_items[VMX_INDEX_MSR_EFER]
                     &= ~EFER_LMA;
-                __vmread(VM_ENTRY_CONTROLS, &vm_entry_value);
+                vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
                 vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
                 __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
             }
@@ -1490,7 +1470,7 @@ static int vmx_set_cr0(unsigned long val
 
         if ( vmx_assist(v, VMX_ASSIST_INVOKE) )
         {
-            __vmread(GUEST_RIP, &eip);
+            eip = __vmread(GUEST_RIP);
             HVM_DBG_LOG(DBG_LEVEL_1,
                         "Transfering control to vmxassist %%eip 0x%lx\n", eip);
             return 0; /* do not update eip! */
@@ -1498,12 +1478,12 @@ static int vmx_set_cr0(unsigned long val
     }
     else if ( v->arch.hvm_vmx.vmxassist_enabled )
     {
-        __vmread(GUEST_RIP, &eip);
+        eip = __vmread(GUEST_RIP);
         HVM_DBG_LOG(DBG_LEVEL_1,
                     "Enabling CR0.PE at %%eip 0x%lx\n", eip);
         if ( vmx_assist(v, VMX_ASSIST_RESTORE) )
         {
-            __vmread(GUEST_RIP, &eip);
+            eip = __vmread(GUEST_RIP);
             HVM_DBG_LOG(DBG_LEVEL_1,
                         "Restoring to %%eip 0x%lx\n", eip);
             return 0; /* do not update eip! */
@@ -1515,7 +1495,7 @@ static int vmx_set_cr0(unsigned long val
         {
             v->arch.hvm_vmx.msr_content.msr_items[VMX_INDEX_MSR_EFER]
               &= ~EFER_LMA;
-            __vmread(VM_ENTRY_CONTROLS, &vm_entry_value);
+            vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
             vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
             __vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
         }
@@ -1570,7 +1550,7 @@ static int mov_to_cr(int gp, int cr, str
     CASE_GET_REG(EDI, edi);
     CASE_EXTEND_GET_REG;
     case REG_ESP:
-        __vmread(GUEST_RSP, &value);
+        value = __vmread(GUEST_RSP);
         break;
     default:
         printk("invalid gp: %d\n", gp);
@@ -1821,13 +1801,13 @@ static inline void vmx_do_msr_read(struc
         msr_content = hvm_get_guest_time(v);
         break;
     case MSR_IA32_SYSENTER_CS:
-        __vmread(GUEST_SYSENTER_CS, (u32 *)&msr_content);
+        msr_content = (u32)__vmread(GUEST_SYSENTER_CS);
         break;
     case MSR_IA32_SYSENTER_ESP:
-        __vmread(GUEST_SYSENTER_ESP, &msr_content);
+        msr_content = __vmread(GUEST_SYSENTER_ESP);
         break;
     case MSR_IA32_SYSENTER_EIP:
-        __vmread(GUEST_SYSENTER_EIP, &msr_content);
+        msr_content = __vmread(GUEST_SYSENTER_EIP);
         break;
     case MSR_IA32_APICBASE:
         msr_content = vcpu_vlapic(v)->apic_base_msr;
@@ -1903,14 +1883,13 @@ static void vmx_do_hlt(void)
 static void vmx_do_hlt(void)
 {
     unsigned long rflags;
-    __vmread(GUEST_RFLAGS, &rflags);
+    rflags = __vmread(GUEST_RFLAGS);
     hvm_hlt(rflags);
 }
 
 static inline void vmx_do_extint(struct cpu_user_regs *regs)
 {
     unsigned int vector;
-    int error;
 
     asmlinkage void do_IRQ(struct cpu_user_regs *);
     fastcall void smp_apic_timer_interrupt(struct cpu_user_regs *);
@@ -1923,9 +1902,8 @@ static inline void vmx_do_extint(struct 
     fastcall void smp_thermal_interrupt(struct cpu_user_regs *regs);
 #endif
 
-    if ((error = __vmread(VM_EXIT_INTR_INFO, &vector))
-        && !(vector & INTR_INFO_VALID_MASK))
-        __hvm_bug(regs);
+    vector = __vmread(VM_EXIT_INTR_INFO);
+    BUG_ON(!(vector & INTR_INFO_VALID_MASK));
 
     vector &= INTR_INFO_VECTOR_MASK;
     TRACE_VMEXIT(1, vector);
@@ -1964,40 +1942,40 @@ static inline void vmx_do_extint(struct 
 #if defined (__x86_64__)
 void store_cpu_user_regs(struct cpu_user_regs *regs)
 {
-    __vmread(GUEST_SS_SELECTOR, &regs->ss);
-    __vmread(GUEST_RSP, &regs->rsp);
-    __vmread(GUEST_RFLAGS, &regs->rflags);
-    __vmread(GUEST_CS_SELECTOR, &regs->cs);
-    __vmread(GUEST_DS_SELECTOR, &regs->ds);
-    __vmread(GUEST_ES_SELECTOR, &regs->es);
-    __vmread(GUEST_RIP, &regs->rip);
+    regs->ss = __vmread(GUEST_SS_SELECTOR);
+    regs->rsp = __vmread(GUEST_RSP);
+    regs->rflags = __vmread(GUEST_RFLAGS);
+    regs->cs = __vmread(GUEST_CS_SELECTOR);
+    regs->ds = __vmread(GUEST_DS_SELECTOR);
+    regs->es = __vmread(GUEST_ES_SELECTOR);
+    regs->rip = __vmread(GUEST_RIP);
 }
 #elif defined (__i386__)
 void store_cpu_user_regs(struct cpu_user_regs *regs)
 {
-    __vmread(GUEST_SS_SELECTOR, &regs->ss);
-    __vmread(GUEST_RSP, &regs->esp);
-    __vmread(GUEST_RFLAGS, &regs->eflags);
-    __vmread(GUEST_CS_SELECTOR, &regs->cs);
-    __vmread(GUEST_DS_SELECTOR, &regs->ds);
-    __vmread(GUEST_ES_SELECTOR, &regs->es);
-    __vmread(GUEST_RIP, &regs->eip);
+    regs->ss = __vmread(GUEST_SS_SELECTOR);
+    regs->esp = __vmread(GUEST_RSP);
+    regs->eflags = __vmread(GUEST_RFLAGS);
+    regs->cs = __vmread(GUEST_CS_SELECTOR);
+    regs->ds = __vmread(GUEST_DS_SELECTOR);
+    regs->es = __vmread(GUEST_ES_SELECTOR);
+    regs->eip = __vmread(GUEST_RIP);
 }
 #endif 
 
 #ifdef XEN_DEBUGGER
 void save_cpu_user_regs(struct cpu_user_regs *regs)
 {
-    __vmread(GUEST_SS_SELECTOR, &regs->xss);
-    __vmread(GUEST_RSP, &regs->esp);
-    __vmread(GUEST_RFLAGS, &regs->eflags);
-    __vmread(GUEST_CS_SELECTOR, &regs->xcs);
-    __vmread(GUEST_RIP, &regs->eip);
-
-    __vmread(GUEST_GS_SELECTOR, &regs->xgs);
-    __vmread(GUEST_FS_SELECTOR, &regs->xfs);
-    __vmread(GUEST_ES_SELECTOR, &regs->xes);
-    __vmread(GUEST_DS_SELECTOR, &regs->xds);
+    regs->xss = __vmread(GUEST_SS_SELECTOR);
+    regs->esp = __vmread(GUEST_RSP);
+    regs->eflags = __vmread(GUEST_RFLAGS);
+    regs->xcs = __vmread(GUEST_CS_SELECTOR);
+    regs->eip = __vmread(GUEST_RIP);
+
+    regs->xgs = __vmread(GUEST_GS_SELECTOR);
+    regs->xfs = __vmread(GUEST_FS_SELECTOR);
+    regs->xes = __vmread(GUEST_ES_SELECTOR);
+    regs->xds = __vmread(GUEST_DS_SELECTOR);
 }
 
 void restore_cpu_user_regs(struct cpu_user_regs *regs)
@@ -2019,10 +1997,10 @@ static void vmx_reflect_exception(struct
 {
     int error_code, intr_info, vector;
 
-    __vmread(VM_EXIT_INTR_INFO, &intr_info);
+    intr_info = __vmread(VM_EXIT_INTR_INFO);
     vector = intr_info & 0xff;
     if ( intr_info & INTR_INFO_DELIVER_CODE_MASK )
-        __vmread(VM_EXIT_INTR_ERROR_CODE, &error_code);
+        error_code = __vmread(VM_EXIT_INTR_ERROR_CODE);
     else
         error_code = VMX_DELIVER_NO_ERROR_CODE;
 
@@ -2030,7 +2008,7 @@ static void vmx_reflect_exception(struct
     {
         unsigned long rip;
 
-        __vmread(GUEST_RIP, &rip);
+        rip = __vmread(GUEST_RIP);
         HVM_DBG_LOG(DBG_LEVEL_1, "rip = %lx, error_code = %x",
                     rip, error_code);
     }
@@ -2062,7 +2040,7 @@ asmlinkage void vmx_vmexit_handler(struc
     unsigned long exit_qualification, inst_len = 0;
     struct vcpu *v = current;
 
-    __vmread(VM_EXIT_REASON, &exit_reason);
+    exit_reason = __vmread(VM_EXIT_REASON);
 
     perfc_incra(vmexits, exit_reason);
 
@@ -2078,7 +2056,7 @@ asmlinkage void vmx_vmexit_handler(struc
     {
         unsigned int failed_vmentry_reason = exit_reason & 0xFFFF;
 
-        __vmread(EXIT_QUALIFICATION, &exit_qualification);
+        exit_qualification = __vmread(EXIT_QUALIFICATION);
         printk("Failed vm entry (exit reason 0x%x) ", exit_reason);
         switch ( failed_vmentry_reason ) {
         case EXIT_REASON_INVALID_GUEST_STATE:
@@ -2114,9 +2092,8 @@ asmlinkage void vmx_vmexit_handler(struc
          */
         unsigned int intr_info, vector;
 
-        if ( __vmread(VM_EXIT_INTR_INFO, &intr_info) ||
-             !(intr_info & INTR_INFO_VALID_MASK) )
-            __hvm_bug(regs);
+        intr_info = __vmread(VM_EXIT_INTR_INFO);
+        BUG_ON(!(intr_info & INTR_INFO_VALID_MASK));
 
         vector = intr_info & INTR_INFO_VECTOR_MASK;
 
@@ -2177,8 +2154,8 @@ asmlinkage void vmx_vmexit_handler(struc
         }
         case TRAP_page_fault:
         {
-            __vmread(EXIT_QUALIFICATION, &exit_qualification);
-            __vmread(VM_EXIT_INTR_ERROR_CODE, &regs->error_code);
+            exit_qualification = __vmread(EXIT_QUALIFICATION);
+            regs->error_code = __vmread(VM_EXIT_INTR_ERROR_CODE);
 
             TRACE_VMEXIT(3, regs->error_code);
             TRACE_VMEXIT(4, exit_qualification);
@@ -2240,7 +2217,7 @@ asmlinkage void vmx_vmexit_handler(struc
     {
         inst_len = __get_instruction_length(); /* Safe: INVLPG */
         __update_guest_eip(inst_len);
-        __vmread(EXIT_QUALIFICATION, &exit_qualification);
+        exit_qualification = __vmread(EXIT_QUALIFICATION);
         vmx_do_invlpg(exit_qualification);
         TRACE_VMEXIT(4, exit_qualification);
         break;
@@ -2254,7 +2231,7 @@ asmlinkage void vmx_vmexit_handler(struc
     }
     case EXIT_REASON_CR_ACCESS:
     {
-        __vmread(EXIT_QUALIFICATION, &exit_qualification);
+        exit_qualification = __vmread(EXIT_QUALIFICATION);
         inst_len = __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
         if ( vmx_cr_access(exit_qualification, regs) )
             __update_guest_eip(inst_len);
@@ -2262,11 +2239,11 @@ asmlinkage void vmx_vmexit_handler(struc
         break;
     }
     case EXIT_REASON_DR_ACCESS:
-        __vmread(EXIT_QUALIFICATION, &exit_qualification);
+        exit_qualification = __vmread(EXIT_QUALIFICATION);
         vmx_dr_access(exit_qualification, regs);
         break;
     case EXIT_REASON_IO_INSTRUCTION:
-        __vmread(EXIT_QUALIFICATION, &exit_qualification);
+        exit_qualification = __vmread(EXIT_QUALIFICATION);
         inst_len = __get_instruction_length(); /* Safe: IN, INS, OUT, OUTS */
         vmx_io_instruction(exit_qualification, inst_len);
         TRACE_VMEXIT(4, exit_qualification);
diff -r 6555ca56d844 -r 9f9f569b0a1d xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Wed Nov 08 15:11:18 2006 +0000
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Wed Nov 08 16:43:50 2006 +0000
@@ -183,80 +183,55 @@ static inline void __vmpclear(u64 addr)
                            : "memory");
 }
 
-#define __vmread(x, ptr) ___vmread((x), (ptr), sizeof(*(ptr)))
-
-static always_inline int ___vmread(
-    const unsigned long field, void *ptr, const int size)
-{
-    unsigned long ecx = 0;
-    int rc;
+static inline unsigned long __vmread(unsigned long field)
+{
+    unsigned long ecx;
+
+    __asm__ __volatile__ ( VMREAD_OPCODE
+                           MODRM_EAX_ECX
+                           /* CF==1 or ZF==1 --> crash (ud2) */
+                           "ja 1f ; ud2 ; 1:\n"
+                           : "=c" (ecx)
+                           : "a" (field)
+                           : "memory");
+
+    return ecx;
+}
+
+static inline void __vmwrite(unsigned long field, unsigned long value)
+{
+    __asm__ __volatile__ ( VMWRITE_OPCODE
+                           MODRM_EAX_ECX
+                           /* CF==1 or ZF==1 --> crash (ud2) */
+                           "ja 1f ; ud2 ; 1:\n"
+                           : 
+                           : "a" (field) , "c" (value)
+                           : "memory");
+}
+
+static inline unsigned long __vmread_safe(unsigned long field, int *error)
+{
+    unsigned long ecx;
 
     __asm__ __volatile__ ( VMREAD_OPCODE
                            MODRM_EAX_ECX
                            /* CF==1 or ZF==1 --> rc = -1 */
                            "setna %b0 ; neg %0"
-                           : "=q" (rc), "=c" (ecx)
+                           : "=q" (*error), "=c" (ecx)
                            : "0" (0), "a" (field)
                            : "memory");
 
-    switch ( size ) {
-    case 1:
-        *((u8 *) (ptr)) = ecx;
-        break;
-    case 2:
-        *((u16 *) (ptr)) = ecx;
-        break;
-    case 4:
-        *((u32 *) (ptr)) = ecx;
-        break;
-    case 8:
-        *((u64 *) (ptr)) = ecx;
-        break;
-    default:
-        domain_crash_synchronous();
-        break;
-    }
-
-    return rc;
-}
-
-static inline int __vmwrite(unsigned long field, unsigned long value)
-{
-    int rc;
-
-    __asm__ __volatile__ ( VMWRITE_OPCODE
-                           MODRM_EAX_ECX
-                           /* CF==1 or ZF==1 --> rc = -1 */
-                           "setna %b0 ; neg %0"
-                           : "=q" (rc)
-                           : "0" (0), "a" (field) , "c" (value)
-                           : "memory");
-
-    return rc;
-}
-
-static inline int __vm_set_bit(unsigned long field, unsigned long mask)
-{
-    unsigned long tmp;
-    int err = 0;
-
-    err |= __vmread(field, &tmp);
-    tmp |= mask;
-    err |= __vmwrite(field, tmp);
-
-    return err;
-}
-
-static inline int __vm_clear_bit(unsigned long field, unsigned long mask)
-{
-    unsigned long tmp;
-    int err = 0;
-
-    err |= __vmread(field, &tmp);
-    tmp &= ~mask;
-    err |= __vmwrite(field, tmp);
-
-    return err;
+    return ecx;
+}
+
+static inline void __vm_set_bit(unsigned long field, unsigned long mask)
+{
+    __vmwrite(field, __vmread(field) | mask);
+}
+
+static inline void __vm_clear_bit(unsigned long field, unsigned long mask)
+{
+    __vmwrite(field, __vmread(field) & ~mask);
 }
 
 static inline void __vmxoff (void)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.