ia64/xen-unstable

changeset 19172:2358b9fcd51b

libxc support for the new partial-HVM-save domctl.
This includes making the pagetable walker in xc_pagetab.c behave
correctly for 32-bit and 64-bit HVM guests.

Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Feb 05 12:17:08 2009 +0000 (2009-02-05)
parents 7eb8b094a207
children 5c1308e2ece3
files tools/libxc/xc_domain.c tools/libxc/xc_pagetab.c tools/libxc/xenctrl.h
line diff
     1.1 --- a/tools/libxc/xc_domain.c	Thu Feb 05 12:16:53 2009 +0000
     1.2 +++ b/tools/libxc/xc_domain.c	Thu Feb 05 12:17:08 2009 +0000
     1.3 @@ -271,6 +271,38 @@ int xc_domain_hvm_getcontext(int xc_hand
     1.4      return (ret < 0 ? -1 : domctl.u.hvmcontext.size);
     1.5  }
     1.6  
     1.7 +/* Get just one element of the HVM guest context.
     1.8 + * size must be >= HVM_SAVE_LENGTH(type) */
     1.9 +int xc_domain_hvm_getcontext_partial(int xc_handle,
    1.10 +                                     uint32_t domid,
    1.11 +                                     uint16_t typecode,
    1.12 +                                     uint16_t instance,
    1.13 +                                     void *ctxt_buf,
    1.14 +                                     uint32_t size)
    1.15 +{
    1.16 +    int ret;
    1.17 +    DECLARE_DOMCTL;
    1.18 +
    1.19 +    if ( !ctxt_buf ) 
    1.20 +        return -EINVAL;
    1.21 +
    1.22 +    domctl.cmd = XEN_DOMCTL_gethvmcontext_partial;
    1.23 +    domctl.domain = (domid_t) domid;
    1.24 +    domctl.u.hvmcontext_partial.type = typecode;
    1.25 +    domctl.u.hvmcontext_partial.instance = instance;
    1.26 +    set_xen_guest_handle(domctl.u.hvmcontext_partial.buffer, ctxt_buf);
    1.27 +
    1.28 +    if ( (ret = lock_pages(ctxt_buf, size)) != 0 )
    1.29 +        return ret;
    1.30 +    
    1.31 +    ret = do_domctl(xc_handle, &domctl);
    1.32 +
    1.33 +    if ( ctxt_buf ) 
    1.34 +        unlock_pages(ctxt_buf, size);
    1.35 +
    1.36 +    return ret ? -1 : 0;
    1.37 +}
    1.38 +
    1.39  /* set info to hvm guest for restore */
    1.40  int xc_domain_hvm_setcontext(int xc_handle,
    1.41                               uint32_t domid,
     2.1 --- a/tools/libxc/xc_pagetab.c	Thu Feb 05 12:16:53 2009 +0000
     2.2 +++ b/tools/libxc/xc_pagetab.c	Thu Feb 05 12:17:08 2009 +0000
     2.3 @@ -4,50 +4,42 @@
     2.4   * Function to translate virtual to physical addresses.
     2.5   */
     2.6  #include "xc_private.h"
     2.7 +#include <xen/hvm/save.h>
     2.8  
     2.9  #define CR0_PG  0x80000000
    2.10  #define CR4_PAE 0x20
    2.11  #define PTE_PSE 0x80
    2.12 +#define EFER_LMA 0x400
    2.13 +
    2.14  
    2.15  unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
    2.16                                             int vcpu, unsigned long long virt)
    2.17  {
    2.18      xc_dominfo_t dominfo;
    2.19 -    vcpu_guest_context_any_t ctx;
    2.20      uint64_t paddr, mask, pte = 0;
    2.21      int size, level, pt_levels = 2;
    2.22      void *map;
    2.23  
    2.24      if (xc_domain_getinfo(xc_handle, dom, 1, &dominfo) != 1 
    2.25 -        || dominfo.domid != dom
    2.26 -        || xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0)
    2.27 +        || dominfo.domid != dom)
    2.28          return 0;
    2.29  
    2.30      /* What kind of paging are we dealing with? */
    2.31      if (dominfo.hvm) {
    2.32 -        unsigned long cr0, cr3, cr4;
    2.33 -        xen_capabilities_info_t xen_caps = "";
    2.34 -        if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0)
    2.35 +        struct hvm_hw_cpu ctx;
    2.36 +        if (xc_domain_hvm_getcontext_partial(xc_handle, dom,
    2.37 +                                             HVM_SAVE_CODE(CPU), vcpu,
    2.38 +                                             &ctx, sizeof ctx) != 0)
    2.39              return 0;
    2.40 -        /* HVM context records are always host-sized */
    2.41 -        if (strstr(xen_caps, "xen-3.0-x86_64")) {
    2.42 -            cr0 = ctx.x64.ctrlreg[0];
    2.43 -            cr3 = ctx.x64.ctrlreg[3];
    2.44 -            cr4 = ctx.x64.ctrlreg[4];
    2.45 -        } else {
    2.46 -            cr0 = ctx.x32.ctrlreg[0];
    2.47 -            cr3 = ctx.x32.ctrlreg[3];
    2.48 -            cr4 = ctx.x32.ctrlreg[4];
    2.49 -        }
    2.50 -        if (!(cr0 & CR0_PG))
    2.51 +        if (!(ctx.cr0 & CR0_PG))
    2.52              return virt;
    2.53 -        if (0 /* XXX how to get EFER.LMA? */) 
    2.54 -            pt_levels = 4;
    2.55 -        else
    2.56 -            pt_levels = (cr4 & CR4_PAE) ? 3 : 2;
    2.57 -        paddr = cr3 & ((pt_levels == 3) ? ~0x1full : ~0xfffull);
    2.58 +        pt_levels = (ctx.msr_efer&EFER_LMA) ? 4 : (ctx.cr4&CR4_PAE) ? 3 : 2;
    2.59 +        paddr = ctx.cr3 & ((pt_levels == 3) ? ~0x1full : ~0xfffull);
    2.60      } else {
    2.61          DECLARE_DOMCTL;
    2.62 +        vcpu_guest_context_any_t ctx;
    2.63 +        if (xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0)
    2.64 +            return 0;
    2.65          domctl.domain = dom;
    2.66          domctl.cmd = XEN_DOMCTL_get_address_size;
    2.67          if ( do_domctl(xc_handle, &domctl) != 0 )
     3.1 --- a/tools/libxc/xenctrl.h	Thu Feb 05 12:16:53 2009 +0000
     3.2 +++ b/tools/libxc/xenctrl.h	Thu Feb 05 12:17:08 2009 +0000
     3.3 @@ -375,6 +375,25 @@ int xc_domain_hvm_getcontext(int xc_hand
     3.4                               uint8_t *ctxt_buf,
     3.5                               uint32_t size);
     3.6  
     3.7 +
     3.8 +/**
     3.9 + * This function returns one element of the context of a hvm domain
    3.10 + * @parm xc_handle a handle to an open hypervisor interface
    3.11 + * @parm domid the domain to get information from
    3.12 + * @parm typecode which type of elemnt required 
    3.13 + * @parm instance which instance of the type
    3.14 + * @parm ctxt_buf a pointer to a structure to store the execution context of
    3.15 + *            the hvm domain
    3.16 + * @parm size the size of ctxt_buf (must be >= HVM_SAVE_LENGTH(typecode))
    3.17 + * @return 0 on success, -1 on failure
    3.18 + */
    3.19 +int xc_domain_hvm_getcontext_partial(int xc_handle,
    3.20 +                                     uint32_t domid,
    3.21 +                                     uint16_t typecode,
    3.22 +                                     uint16_t instance,
    3.23 +                                     void *ctxt_buf,
    3.24 +                                     uint32_t size);
    3.25 +
    3.26  /**
    3.27   * This function will set the context for hvm domain
    3.28   *