ia64/xen-unstable

changeset 13542:dccdc3ee0efc

[HVM] Save/restore cleanups 02: VCPU
Save/restore vcpu state therough the streaming interface
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
author Tim Deegan <Tim.Deegan@xensource.com>
date Sat Jan 20 11:17:39 2007 +0000 (2007-01-20)
parents 56228886421d
children 2457741f4ec3
files xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/hvm.h xen/include/public/arch-x86/xen.h xen/include/public/hvm/save.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hvm.c	Sat Jan 20 11:17:38 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/hvm.c	Sat Jan 20 11:17:39 2007 +0000
     1.3 @@ -174,6 +174,10 @@ int hvm_vcpu_initialise(struct vcpu *v)
     1.4  {
     1.5      int rc;
     1.6  
     1.7 +    hvm_register_savevm(v->domain, "xen_hvm_cpu", v->vcpu_id, 1,
     1.8 +                        hvm_funcs.save_cpu_ctxt, hvm_funcs.load_cpu_ctxt, 
     1.9 +                        (void *)v);
    1.10 +
    1.11      if ( (rc = vlapic_init(v)) != 0 )
    1.12          return rc;
    1.13  
     2.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Sat Jan 20 11:17:38 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Sat Jan 20 11:17:39 2007 +0000
     2.3 @@ -47,6 +47,7 @@
     2.4  #include <asm/hvm/vlapic.h>
     2.5  #include <asm/x86_emulate.h>
     2.6  #include <asm/hvm/vpt.h>
     2.7 +#include <public/hvm/save.h>
     2.8  
     2.9  static void vmx_ctxt_switch_from(struct vcpu *v);
    2.10  static void vmx_ctxt_switch_to(struct vcpu *v);
    2.11 @@ -364,7 +365,7 @@ static inline void __restore_debug_regis
    2.12  }
    2.13  
    2.14  static int __get_instruction_length(void);
    2.15 -int vmx_vmcs_save(struct vcpu *v, struct vmcs_data *c)
    2.16 +int vmx_vmcs_save(struct vcpu *v, struct hvm_hw_cpu *c)
    2.17  {
    2.18      unsigned long inst_len;
    2.19  
    2.20 @@ -443,7 +444,7 @@ int vmx_vmcs_save(struct vcpu *v, struct
    2.21      return 1;
    2.22  }
    2.23  
    2.24 -int vmx_vmcs_restore(struct vcpu *v, struct vmcs_data *c)
    2.25 +int vmx_vmcs_restore(struct vcpu *v, struct hvm_hw_cpu *c)
    2.26  {
    2.27      unsigned long mfn, old_base_mfn;
    2.28  
    2.29 @@ -590,9 +591,8 @@ static void dump_msr_state(struct vmx_ms
    2.30  }
    2.31  #endif
    2.32          
    2.33 -void vmx_save_cpu_state(struct vcpu *v, struct hvmcpu_context *ctxt)
    2.34 +void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
    2.35  {
    2.36 -    struct vmcs_data *data = &ctxt->data;
    2.37      struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
    2.38      unsigned long guest_flags = guest_state->flags;
    2.39      int i = 0;
    2.40 @@ -603,14 +603,15 @@ void vmx_save_cpu_state(struct vcpu *v, 
    2.41      data->flags = guest_flags;
    2.42      for (i = 0; i < VMX_MSR_COUNT; i++)
    2.43          data->msr_items[i] = guest_state->msrs[i];
    2.44 -
    2.45 +    
    2.46 +    data->tsc = hvm_get_guest_time(v);
    2.47 +    
    2.48      dump_msr_state(guest_state);
    2.49  }
    2.50  
    2.51 -void vmx_load_cpu_state(struct vcpu *v, struct hvmcpu_context *ctxt)
    2.52 +void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
    2.53  {
    2.54      int i = 0;
    2.55 -    struct vmcs_data *data = &ctxt->data;
    2.56      struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
    2.57  
    2.58      /* restore msrs */
    2.59 @@ -625,35 +626,42 @@ void vmx_load_cpu_state(struct vcpu *v, 
    2.60  
    2.61      v->arch.hvm_vmx.vmxassist_enabled = data->vmxassist_enabled;
    2.62  
    2.63 +    hvm_set_guest_time(v, data->tsc);
    2.64 +
    2.65      dump_msr_state(guest_state);
    2.66  }
    2.67  
    2.68 -void vmx_save_vmcs_ctxt(struct vcpu *v, struct hvmcpu_context *ctxt)
    2.69 +
    2.70 +void vmx_save_vmcs_ctxt(hvm_domain_context_t *h, void *opaque)
    2.71  {
    2.72 -    struct vmcs_data *data = &ctxt->data;
    2.73 -
    2.74 -    vmx_save_cpu_state(v, ctxt);
    2.75 -
    2.76 +    struct vcpu *v = opaque;
    2.77 +    struct hvm_hw_cpu ctxt;
    2.78 +
    2.79 +    vmx_save_cpu_state(v, &ctxt);
    2.80      vmx_vmcs_enter(v);
    2.81 -
    2.82 -    vmx_vmcs_save(v, data);
    2.83 -
    2.84 +    vmx_vmcs_save(v, &ctxt);
    2.85      vmx_vmcs_exit(v);
    2.86  
    2.87 +    hvm_put_struct(h, &ctxt);
    2.88  }
    2.89  
    2.90 -void vmx_load_vmcs_ctxt(struct vcpu *v, struct hvmcpu_context *ctxt)
    2.91 +int vmx_load_vmcs_ctxt(hvm_domain_context_t *h, void *opaque, int version)
    2.92  {
    2.93 -    vmx_load_cpu_state(v, ctxt);
    2.94 -
    2.95 -    if (vmx_vmcs_restore(v, &ctxt->data)) {
    2.96 +    struct vcpu *v = opaque;
    2.97 +    struct hvm_hw_cpu ctxt;
    2.98 +
    2.99 +    if (version != 1)
   2.100 +        return -EINVAL;
   2.101 +
   2.102 +    hvm_get_struct(h, &ctxt);
   2.103 +    vmx_load_cpu_state(v, &ctxt);
   2.104 +    if (vmx_vmcs_restore(v, &ctxt)) {
   2.105          printk("vmx_vmcs restore failed!\n");
   2.106          domain_crash(v->domain);
   2.107 +        return -EINVAL;
   2.108      }
   2.109  
   2.110 -    /* only load vmcs once */
   2.111 -    ctxt->valid = 0;
   2.112 -
   2.113 +    return 0;
   2.114  }
   2.115  
   2.116  /*
     3.1 --- a/xen/include/asm-x86/hvm/hvm.h	Sat Jan 20 11:17:38 2007 +0000
     3.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Sat Jan 20 11:17:39 2007 +0000
     3.3 @@ -22,6 +22,8 @@
     3.4  #define __ASM_X86_HVM_HVM_H__
     3.5  
     3.6  #include <asm/x86_emulate.h>
     3.7 +#include <public/domctl.h>
     3.8 +#include <public/hvm/save.h>
     3.9  
    3.10  /* 
    3.11   * Attribute for segment selector. This is a copy of bit 40:47 & 52:55 of the
    3.12 @@ -81,10 +83,8 @@ struct hvm_function_table {
    3.13          struct vcpu *v, struct cpu_user_regs *r);
    3.14  
    3.15      /* save and load hvm guest cpu context for save/restore */
    3.16 -    void (*save_cpu_ctxt)(
    3.17 -        struct vcpu *v, struct hvmcpu_context *ctxt);
    3.18 -    void (*load_cpu_ctxt)(
    3.19 -        struct vcpu *v, struct hvmcpu_context *ctxt);
    3.20 +    void (*save_cpu_ctxt)(hvm_domain_context_t *h, void *opaque);
    3.21 +    int (*load_cpu_ctxt)(hvm_domain_context_t *h, void *opaque, int version);
    3.22  
    3.23      /*
    3.24       * Examine specifics of the guest state:
    3.25 @@ -167,32 +167,6 @@ hvm_load_cpu_guest_regs(struct vcpu *v, 
    3.26  void hvm_set_guest_time(struct vcpu *v, u64 gtime);
    3.27  u64 hvm_get_guest_time(struct vcpu *v);
    3.28  
    3.29 -static inline void
    3.30 -hvm_save_cpu_context(
    3.31 -        struct vcpu *v, struct hvmcpu_context *ctxt)
    3.32 -{
    3.33 -    hvm_funcs.save_cpu_ctxt(v, ctxt);
    3.34 -
    3.35 -    /* save guest time */
    3.36 -    ctxt->gtime = hvm_get_guest_time(v);
    3.37 -
    3.38 -    /* set valid flag to recover whole vmcs when restore */
    3.39 -    ctxt->valid = 0x55885588;
    3.40 -}
    3.41 -
    3.42 -static inline void
    3.43 -hvm_load_cpu_context(
    3.44 -        struct vcpu *v, struct hvmcpu_context *ctxt)
    3.45 -{
    3.46 -    if ( ctxt->valid != 0x55885588)
    3.47 -        return;
    3.48 -
    3.49 -    hvm_funcs.load_cpu_ctxt(v, ctxt);
    3.50 -
    3.51 -    /* restore guest time*/
    3.52 -    hvm_set_guest_time(v, ctxt->gtime);
    3.53 -}
    3.54 -
    3.55  static inline int
    3.56  hvm_paging_enabled(struct vcpu *v)
    3.57  {
     4.1 --- a/xen/include/public/arch-x86/xen.h	Sat Jan 20 11:17:38 2007 +0000
     4.2 +++ b/xen/include/public/arch-x86/xen.h	Sat Jan 20 11:17:39 2007 +0000
     4.3 @@ -109,70 +109,6 @@ DEFINE_XEN_GUEST_HANDLE(trap_info_t);
     4.4  typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
     4.5  
     4.6  /*
     4.7 - * World vmcs state
     4.8 - */
     4.9 -struct vmcs_data {
    4.10 -    uint64_t  eip;        /* execution pointer */
    4.11 -    uint64_t  esp;        /* stack pointer */
    4.12 -    uint64_t  eflags;     /* flags register */
    4.13 -    uint64_t  cr0;
    4.14 -    uint64_t  cr3;        /* page table directory */
    4.15 -    uint64_t  cr4;
    4.16 -    uint32_t  idtr_limit; /* idt */
    4.17 -    uint64_t  idtr_base;
    4.18 -    uint32_t  gdtr_limit; /* gdt */
    4.19 -    uint64_t  gdtr_base;
    4.20 -    uint32_t  cs_sel;     /* cs selector */
    4.21 -    uint32_t  cs_limit;
    4.22 -    uint64_t  cs_base;
    4.23 -    uint32_t  cs_arbytes;
    4.24 -    uint32_t  ds_sel;     /* ds selector */
    4.25 -    uint32_t  ds_limit;
    4.26 -    uint64_t  ds_base;
    4.27 -    uint32_t  ds_arbytes;
    4.28 -    uint32_t  es_sel;     /* es selector */
    4.29 -    uint32_t  es_limit;
    4.30 -    uint64_t  es_base;
    4.31 -    uint32_t  es_arbytes;
    4.32 -    uint32_t  ss_sel;     /* ss selector */
    4.33 -    uint32_t  ss_limit;
    4.34 -    uint64_t  ss_base;
    4.35 -    uint32_t  ss_arbytes;
    4.36 -    uint32_t  fs_sel;     /* fs selector */
    4.37 -    uint32_t  fs_limit;
    4.38 -    uint64_t  fs_base;
    4.39 -    uint32_t  fs_arbytes;
    4.40 -    uint32_t  gs_sel;     /* gs selector */
    4.41 -    uint32_t  gs_limit;
    4.42 -    uint64_t  gs_base;
    4.43 -    uint32_t  gs_arbytes;
    4.44 -    uint32_t  tr_sel;     /* task selector */
    4.45 -    uint32_t  tr_limit;
    4.46 -    uint64_t  tr_base;
    4.47 -    uint32_t  tr_arbytes;
    4.48 -    uint32_t  ldtr_sel;   /* ldtr selector */
    4.49 -    uint32_t  ldtr_limit;
    4.50 -    uint64_t  ldtr_base;
    4.51 -    uint32_t  ldtr_arbytes;
    4.52 -    uint32_t  sysenter_cs;
    4.53 -    uint64_t  sysenter_esp;
    4.54 -    uint64_t  sysenter_eip;
    4.55 -    /* msr for em64t */
    4.56 -    uint64_t shadow_gs;
    4.57 -    uint64_t flags;
    4.58 -    /* same size as VMX_MSR_COUNT */
    4.59 -    uint64_t msr_items[6];
    4.60 -    uint64_t vmxassist_enabled;
    4.61 -};
    4.62 -typedef struct vmcs_data vmcs_data_t;
    4.63 -
    4.64 -struct hvmcpu_context {
    4.65 -    uint32_t valid;
    4.66 -    struct vmcs_data data;
    4.67 -    uint64_t gtime;
    4.68 -};
    4.69 -
    4.70 -/*
    4.71   * The following is all CPU context. Note that the fpu_ctxt block is filled 
    4.72   * in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
    4.73   */
     5.1 --- a/xen/include/public/hvm/save.h	Sat Jan 20 11:17:38 2007 +0000
     5.2 +++ b/xen/include/public/hvm/save.h	Sat Jan 20 11:17:39 2007 +0000
     5.3 @@ -107,6 +107,9 @@ struct hvm_hw_cpu {
     5.4      /* same size as VMX_MSR_COUNT */
     5.5      uint64_t msr_items[6];
     5.6      uint64_t vmxassist_enabled;
     5.7 +
     5.8 +    /* guest's idea of what rdtsc() would return */
     5.9 +    uint64_t tsc;
    5.10  };
    5.11  
    5.12