ia64/xen-unstable

changeset 12268:f8ffeb540ec1

[HVM][SVM] Start moving SVM launch code to domain/vcpu initialisation.
This first patch is just enough to get SVM guests working again after
I broke SVM support earlier today.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@localhost.localdomain
date Mon Nov 06 18:57:33 2006 +0000 (2006-11-06)
parents bb6cd7ba259b
children 81c451bd398e
files xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/svm/vmcb.c
line diff
     1.1 --- a/xen/arch/x86/hvm/svm/svm.c	Mon Nov 06 17:32:00 2006 +0000
     1.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Mon Nov 06 18:57:33 2006 +0000
     1.3 @@ -773,6 +773,15 @@ static int svm_vcpu_initialise(struct vc
     1.4      v->arch.schedule_tail    = arch_svm_do_launch;
     1.5      v->arch.ctxt_switch_from = svm_ctxt_switch_from;
     1.6      v->arch.ctxt_switch_to   = svm_ctxt_switch_to;
     1.7 +
     1.8 +    if ( (v->arch.hvm_svm.vmcb = alloc_vmcb()) == NULL )
     1.9 +    {
    1.10 +        printk("Failed to create a new VMCB\n");
    1.11 +        return -ENOMEM;
    1.12 +    }
    1.13 +
    1.14 +    v->arch.hvm_svm.vmcb_pa = virt_to_maddr(v->arch.hvm_svm.vmcb);
    1.15 +
    1.16      return 0;
    1.17  }
    1.18  
     2.1 --- a/xen/arch/x86/hvm/svm/vmcb.c	Mon Nov 06 17:32:00 2006 +0000
     2.2 +++ b/xen/arch/x86/hvm/svm/vmcb.c	Mon Nov 06 18:57:33 2006 +0000
     2.3 @@ -38,71 +38,59 @@
     2.4  #include <xen/keyhandler.h>
     2.5  
     2.6  extern int svm_dbg_on;
     2.7 -extern int asidpool_assign_next( struct vmcb_struct *vmcb, int retire_current,
     2.8 -                                  int oldcore, int newcore);
     2.9 +extern int asidpool_assign_next(
    2.10 +    struct vmcb_struct *vmcb, int retire_current, int oldcore, int newcore);
    2.11  
    2.12  #define GUEST_SEGMENT_LIMIT 0xffffffff
    2.13  
    2.14  #define IOPM_SIZE   (12 * 1024)
    2.15  #define MSRPM_SIZE  (8  * 1024)
    2.16  
    2.17 -/* VMCBs and HSAs are architecturally defined to be a 4K page each */
    2.18 -#define VMCB_ORDER 0 
    2.19 -#define HSA_ORDER  0 
    2.20 -
    2.21 -
    2.22  struct vmcb_struct *alloc_vmcb(void) 
    2.23  {
    2.24 -    struct vmcb_struct *vmcb = alloc_xenheap_pages(VMCB_ORDER);
    2.25 +    struct vmcb_struct *vmcb;
    2.26  
    2.27 -    if (!vmcb) {
    2.28 -        printk("Warning: failed to allocate vmcb.\n");
    2.29 +    vmcb = alloc_xenheap_page();
    2.30 +    if ( vmcb == NULL )
    2.31 +    {
    2.32 +        printk(XENLOG_WARNING "Warning: failed to allocate vmcb.\n");
    2.33          return NULL;
    2.34      }
    2.35  
    2.36 -    memset(vmcb, 0, (PAGE_SIZE << VMCB_ORDER));
    2.37 +    memset(vmcb, 0, PAGE_SIZE);
    2.38      return vmcb;
    2.39  }
    2.40  
    2.41 -
    2.42  void free_vmcb(struct vmcb_struct *vmcb)
    2.43  {
    2.44 -    ASSERT(vmcb);
    2.45 -    free_xenheap_pages(vmcb, VMCB_ORDER);
    2.46 +    free_xenheap_page(vmcb);
    2.47  }
    2.48  
    2.49 -
    2.50  struct host_save_area *alloc_host_save_area(void)
    2.51  {
    2.52 -    struct host_save_area *hsa = alloc_xenheap_pages(HSA_ORDER);
    2.53 +    struct host_save_area *hsa;
    2.54  
    2.55 -    if (!hsa) {
    2.56 -        printk("Warning: failed to allocate vmcb.\n");
    2.57 +    hsa = alloc_xenheap_page();
    2.58 +    if ( hsa == NULL )
    2.59 +    {
    2.60 +        printk(XENLOG_WARNING "Warning: failed to allocate vmcb.\n");
    2.61          return NULL;
    2.62      }
    2.63  
    2.64 -    memset(hsa, 0, (PAGE_SIZE << HSA_ORDER));
    2.65 +    memset(hsa, 0, PAGE_SIZE);
    2.66      return hsa;
    2.67  }
    2.68  
    2.69 -
    2.70  void free_host_save_area(struct host_save_area *hsa)
    2.71  {
    2.72 -    ASSERT(hsa);
    2.73 -    free_xenheap_pages(hsa, HSA_ORDER);
    2.74 +    free_xenheap_page(hsa);
    2.75  }
    2.76  
    2.77 -
    2.78  /* Set up intercepts to exit the guest into the hypervisor when we want it. */
    2.79  static int construct_vmcb_controls(struct arch_svm_struct *arch_svm)
    2.80  {
    2.81 -    struct vmcb_struct *vmcb;
    2.82 -    u32 *iopm;
    2.83 -    u32 *msrpm;
    2.84 -
    2.85 -    vmcb = arch_svm->vmcb;
    2.86 -
    2.87 -    ASSERT(vmcb);
    2.88 +    struct vmcb_struct *vmcb = arch_svm->vmcb;
    2.89 +    u32 *iopm, *msrpm;
    2.90  
    2.91      /* mask off all general 1 intercepts except those listed here */
    2.92      vmcb->general1_intercepts = 
    2.93 @@ -128,19 +116,19 @@ static int construct_vmcb_controls(struc
    2.94  
    2.95      /* The following is for I/O and MSR permision map */
    2.96      iopm = alloc_xenheap_pages(get_order_from_bytes(IOPM_SIZE));
    2.97 -    if (iopm)
    2.98 +    if ( iopm != NULL )
    2.99      {
   2.100          memset(iopm, 0xff, IOPM_SIZE);
   2.101          clear_bit(PC_DEBUG_PORT, iopm);
   2.102      }
   2.103      msrpm = alloc_xenheap_pages(get_order_from_bytes(MSRPM_SIZE));
   2.104 -    if (msrpm)
   2.105 +    if ( msrpm != NULL )
   2.106          memset(msrpm, 0xff, MSRPM_SIZE);
   2.107  
   2.108      arch_svm->iopm = iopm;
   2.109      arch_svm->msrpm = msrpm;
   2.110  
   2.111 -    if (! iopm || ! msrpm)
   2.112 +    if ( !iopm || !msrpm )
   2.113          return 1;
   2.114  
   2.115      vmcb->iopm_base_pa = (u64) virt_to_maddr(iopm);
   2.116 @@ -261,78 +249,53 @@ static int construct_init_vmcb_guest(str
   2.117      return error;
   2.118  }
   2.119  
   2.120 -
   2.121 -/*
   2.122 - * destroy the vmcb.
   2.123 - */
   2.124 -
   2.125  void destroy_vmcb(struct arch_svm_struct *arch_svm)
   2.126  {
   2.127 -    if(arch_svm->vmcb != NULL)
   2.128 +    if ( arch_svm->vmcb != NULL )
   2.129      {
   2.130          asidpool_retire(arch_svm->vmcb, arch_svm->asid_core);
   2.131 -         free_vmcb(arch_svm->vmcb);
   2.132 +        free_vmcb(arch_svm->vmcb);
   2.133      }
   2.134 -    if(arch_svm->iopm != NULL) {
   2.135 +
   2.136 +    if ( arch_svm->iopm != NULL )
   2.137 +    {
   2.138          free_xenheap_pages(
   2.139              arch_svm->iopm, get_order_from_bytes(IOPM_SIZE));
   2.140          arch_svm->iopm = NULL;
   2.141      }
   2.142 -    if(arch_svm->msrpm != NULL) {
   2.143 +
   2.144 +    if ( arch_svm->msrpm != NULL )
   2.145 +    {
   2.146          free_xenheap_pages(
   2.147              arch_svm->msrpm, get_order_from_bytes(MSRPM_SIZE));
   2.148          arch_svm->msrpm = NULL;
   2.149      }
   2.150 +
   2.151      arch_svm->vmcb = NULL;
   2.152  }
   2.153  
   2.154 -
   2.155 -/*
   2.156 - * construct the vmcb.
   2.157 - */
   2.158 -
   2.159  int construct_vmcb(struct arch_svm_struct *arch_svm, 
   2.160                     struct cpu_user_regs *regs)
   2.161  {
   2.162 -    int error;
   2.163 -    long rc=0;
   2.164 -
   2.165 -    memset(arch_svm, 0, sizeof(struct arch_svm_struct));
   2.166 -
   2.167 -    if (!(arch_svm->vmcb = alloc_vmcb())) {
   2.168 -        printk("Failed to create a new VMCB\n");
   2.169 -        rc = -ENOMEM;
   2.170 -        goto err_out;
   2.171 +    if ( construct_vmcb_controls(arch_svm) != 0 )
   2.172 +    {
   2.173 +        printk("construct_vmcb: construct_vmcb_controls failed\n");
   2.174 +        return -EINVAL;
   2.175      }
   2.176  
   2.177 -    arch_svm->vmcb_pa  = (u64) virt_to_maddr(arch_svm->vmcb);
   2.178 -
   2.179 -    if ((error = construct_vmcb_controls(arch_svm))) 
   2.180 -    {
   2.181 -        printk("construct_vmcb: construct_vmcb_controls failed\n");
   2.182 -        rc = -EINVAL;         
   2.183 -        goto err_out;
   2.184 -    }
   2.185 -
   2.186 -    /* guest selectors */
   2.187 -    if ((error = construct_init_vmcb_guest(arch_svm, regs))) 
   2.188 +    if ( construct_init_vmcb_guest(arch_svm, regs) != 0 )
   2.189      {
   2.190          printk("construct_vmcb: construct_vmcb_guest failed\n");
   2.191 -        rc = -EINVAL;         
   2.192 -        goto err_out;
   2.193 +        return -EINVAL;
   2.194      }
   2.195  
   2.196      arch_svm->vmcb->exception_intercepts = MONITOR_DEFAULT_EXCEPTION_BITMAP;
   2.197 -    if (regs->eflags & EF_TF)
   2.198 +    if ( regs->eflags & EF_TF )
   2.199          arch_svm->vmcb->exception_intercepts |= EXCEPTION_BITMAP_DB;
   2.200      else
   2.201          arch_svm->vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_DB;
   2.202  
   2.203      return 0;
   2.204 -
   2.205 -err_out:
   2.206 -    destroy_vmcb(arch_svm);
   2.207 -    return rc;
   2.208  }
   2.209  
   2.210  
   2.211 @@ -340,7 +303,6 @@ void svm_do_launch(struct vcpu *v)
   2.212  {
   2.213      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
   2.214      int core = smp_processor_id();
   2.215 -    ASSERT(vmcb);
   2.216  
   2.217      /* Update CR3, GDT, LDT, TR */
   2.218      hvm_stts(v);
   2.219 @@ -348,7 +310,7 @@ void svm_do_launch(struct vcpu *v)
   2.220      /* current core is the one we intend to perform the VMRUN on */
   2.221      v->arch.hvm_svm.launch_core = v->arch.hvm_svm.asid_core = core;
   2.222      clear_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
   2.223 -    if ( !asidpool_assign_next( vmcb, 0, core, core ))
   2.224 +    if ( !asidpool_assign_next(vmcb, 0, core, core) )
   2.225          BUG();
   2.226  
   2.227      vmcb->ldtr.sel = 0;
   2.228 @@ -358,7 +320,7 @@ void svm_do_launch(struct vcpu *v)
   2.229  
   2.230      vmcb->efer = EFER_SVME; /* Make sure VMRUN won't return with -1 */
   2.231      
   2.232 -    if (svm_dbg_on) 
   2.233 +    if ( svm_dbg_on )
   2.234      {
   2.235          unsigned long pt;
   2.236          printk("%s: hw_cr3 = %llx\n", __func__, 
   2.237 @@ -372,13 +334,14 @@ void svm_do_launch(struct vcpu *v)
   2.238      /* Set cr3 from hw_cr3 even when guest-visible paging is not enabled */
   2.239      vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3; 
   2.240  
   2.241 -    if (svm_dbg_on) 
   2.242 +    if ( svm_dbg_on )
   2.243      {
   2.244          printk("%s: cr3 = %lx ", __func__, (unsigned long)vmcb->cr3);
   2.245 -        printk("init_guest_table: guest_table = 0x%08x, monitor_table = 0x%08x,"
   2.246 -                " hw_cr3 = 0x%16llx\n", (int)v->arch.guest_table.pfn, 
   2.247 +        printk("init_guest_table: guest_table = 0x%08x, "
   2.248 +               "monitor_table = 0x%08x, hw_cr3 = 0x%16llx\n",
   2.249 +               (int)v->arch.guest_table.pfn, 
   2.250                 (int)v->arch.monitor_table.pfn, 
   2.251 -               (unsigned long long) v->arch.hvm_vcpu.hw_cr3);
   2.252 +               (unsigned long long)v->arch.hvm_vcpu.hw_cr3);
   2.253      }
   2.254  
   2.255      v->arch.schedule_tail = arch_svm_do_resume;