ia64/xen-unstable

changeset 5837:6e11af443eb1

Fix problem of can not create two or more vmx guest.

The original gdb server patch will cause the new vmx guest break the=20
old one. This patch make the arch_set_guest_info modify the correct
vmcs and also skip modifying during creating.


Signed-off-by: Xiaofeng Ling <xiaofeng.ling@intel.com>^
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Jul 21 14:15:35 2005 +0000 (2005-07-21)
parents 07884fe7c5ce
children 9038a369268d
files xen/arch/x86/domain.c xen/arch/x86/vmx_io.c xen/arch/x86/vmx_vmcs.c xen/include/asm-x86/vmx.h xen/include/asm-x86/vmx_vmcs.h
line diff
     1.1 --- a/xen/arch/x86/domain.c	Thu Jul 21 13:59:49 2005 +0000
     1.2 +++ b/xen/arch/x86/domain.c	Thu Jul 21 14:15:35 2005 +0000
     1.3 @@ -417,12 +417,12 @@ int arch_set_info_guest(
     1.4  
     1.5          /* Ensure real hardware interrupts are enabled. */
     1.6          v->arch.guest_context.user_regs.eflags |= EF_IE;
     1.7 -    } else {
     1.8 -        __vmwrite(GUEST_RFLAGS, v->arch.guest_context.user_regs.eflags);
     1.9 -        if (v->arch.guest_context.user_regs.eflags & EF_TF)
    1.10 -                __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
    1.11 -        else 
    1.12 -                __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
    1.13 +    }
    1.14 +    else if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
    1.15 +    {
    1.16 +        return modify_vmcs(
    1.17 +            &v->arch.arch_vmx,
    1.18 +            &v->arch.guest_context.user_regs);
    1.19      }
    1.20  
    1.21      if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
     2.1 --- a/xen/arch/x86/vmx_io.c	Thu Jul 21 13:59:49 2005 +0000
     2.2 +++ b/xen/arch/x86/vmx_io.c	Thu Jul 21 14:15:35 2005 +0000
     2.3 @@ -39,14 +39,20 @@
     2.4  
     2.5  #ifdef CONFIG_VMX
     2.6  #if defined (__i386__)
     2.7 -static void load_cpu_user_regs(struct cpu_user_regs *regs)
     2.8 +void load_cpu_user_regs(struct cpu_user_regs *regs)
     2.9  { 
    2.10      /*
    2.11       * Write the guest register value into VMCS
    2.12       */
    2.13      __vmwrite(GUEST_SS_SELECTOR, regs->ss);
    2.14      __vmwrite(GUEST_RSP, regs->esp);
    2.15 +
    2.16      __vmwrite(GUEST_RFLAGS, regs->eflags);
    2.17 +    if (regs->eflags & EF_TF)
    2.18 +        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
    2.19 +    else 
    2.20 +        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
    2.21 +
    2.22      __vmwrite(GUEST_CS_SELECTOR, regs->cs);
    2.23      __vmwrite(GUEST_RIP, regs->eip);
    2.24  }
    2.25 @@ -175,11 +181,17 @@ static void set_reg_value (int size, int
    2.26      }
    2.27  }
    2.28  #else
    2.29 -static void load_cpu_user_regs(struct cpu_user_regs *regs)
    2.30 +void load_cpu_user_regs(struct cpu_user_regs *regs)
    2.31  {
    2.32      __vmwrite(GUEST_SS_SELECTOR, regs->ss);
    2.33      __vmwrite(GUEST_RSP, regs->rsp);
    2.34 +
    2.35      __vmwrite(GUEST_RFLAGS, regs->rflags);
    2.36 +    if (regs->rflags & EF_TF)
    2.37 +        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
    2.38 +    else 
    2.39 +        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
    2.40 +
    2.41      __vmwrite(GUEST_CS_SELECTOR, regs->cs);
    2.42      __vmwrite(GUEST_RIP, regs->rip);
    2.43  }
     3.1 --- a/xen/arch/x86/vmx_vmcs.c	Thu Jul 21 13:59:49 2005 +0000
     3.2 +++ b/xen/arch/x86/vmx_vmcs.c	Thu Jul 21 14:15:35 2005 +0000
     3.3 @@ -453,6 +453,35 @@ int construct_vmcs(struct arch_vmx_struc
     3.4          return -EINVAL;         
     3.5      }
     3.6  
     3.7 +    if (regs->eflags & EF_TF)
     3.8 +        __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
     3.9 +    else 
    3.10 +        __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB);
    3.11 +
    3.12 +    return 0;
    3.13 +}
    3.14 +
    3.15 +/*
    3.16 + * modify guest eflags and execption bitmap for gdb
    3.17 + */
    3.18 +int modify_vmcs(struct arch_vmx_struct *arch_vmx,
    3.19 +                struct cpu_user_regs *regs)
    3.20 +{
    3.21 +    int error;
    3.22 +    u64 vmcs_phys_ptr, old, old_phys_ptr;
    3.23 +    vmcs_phys_ptr = (u64) virt_to_phys(arch_vmx->vmcs);
    3.24 +
    3.25 +    old_phys_ptr = virt_to_phys(&old);
    3.26 +    __vmptrst(old_phys_ptr);
    3.27 +    if ((error = load_vmcs(arch_vmx, vmcs_phys_ptr))) {
    3.28 +        printk("modify_vmcs: load_vmcs failed: VMCS = %lx\n",
    3.29 +                (unsigned long) vmcs_phys_ptr);
    3.30 +        return -EINVAL; 
    3.31 +    }
    3.32 +    load_cpu_user_regs(regs);
    3.33 +
    3.34 +    __vmptrld(old_phys_ptr);
    3.35 +
    3.36      return 0;
    3.37  }
    3.38  
     4.1 --- a/xen/include/asm-x86/vmx.h	Thu Jul 21 13:59:49 2005 +0000
     4.2 +++ b/xen/include/asm-x86/vmx.h	Thu Jul 21 14:15:35 2005 +0000
     4.3 @@ -447,4 +447,8 @@ static inline int iopacket_port(struct d
     4.4      return get_sp(d)->sp_global.eport;
     4.5  }
     4.6  
     4.7 +/* Prototypes */
     4.8 +void load_cpu_user_regs(struct cpu_user_regs *regs);
     4.9 +void store_cpu_user_regs(struct cpu_user_regs *regs);
    4.10 +
    4.11  #endif /* __ASM_X86_VMX_H__ */
     5.1 --- a/xen/include/asm-x86/vmx_vmcs.h	Thu Jul 21 13:59:49 2005 +0000
     5.2 +++ b/xen/include/asm-x86/vmx_vmcs.h	Thu Jul 21 14:15:35 2005 +0000
     5.3 @@ -97,6 +97,8 @@ int  load_vmcs(struct arch_vmx_struct *,
     5.4  int  store_vmcs(struct arch_vmx_struct *, u64);
     5.5  int  construct_vmcs(struct arch_vmx_struct *, struct cpu_user_regs *, 
     5.6                      struct vcpu_guest_context *, int);
     5.7 +int modify_vmcs(struct arch_vmx_struct *arch_vmx,
     5.8 +                struct cpu_user_regs *regs);
     5.9  
    5.10  #define VMCS_USE_HOST_ENV       1
    5.11  #define VMCS_USE_SEPARATE_ENV   0