ia64/xen-unstable

changeset 10892:0d2ba35c0cf2

[XEN] Add hypercall support for HVM guests. This is
fairly useless at the moment, since all of the hypercalls
fail, since copy_from_user doesn't work correctly in HVM
domains.

Signed-off-by: Steven Smith <ssmith@xensource.com>

Add a CPUID hypervisor platform interface at leaf
0x40000000. Allow hypercall transfer page to be filled
in via MSR 0x40000000.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Aug 01 17:18:05 2006 +0100 (2006-08-01)
parents e351aace191e
children 2e3b121662dc
files xen/arch/x86/dom0_ops.c xen/arch/x86/domain.c xen/arch/x86/domain_build.c xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/traps.c xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/traps.c xen/include/asm-x86/domain.h xen/include/asm-x86/hvm/hvm.h xen/include/asm-x86/hvm/support.h xen/include/asm-x86/processor.h
line diff
     1.1 --- a/xen/arch/x86/dom0_ops.c	Tue Aug 01 15:48:48 2006 +0100
     1.2 +++ b/xen/arch/x86/dom0_ops.c	Tue Aug 01 17:18:05 2006 +0100
     1.3 @@ -429,7 +429,7 @@ long arch_do_dom0_op(struct dom0_op *op,
     1.4          ret = 0;
     1.5  
     1.6          hypercall_page = map_domain_page(mfn);
     1.7 -        hypercall_page_initialise(hypercall_page);
     1.8 +        hypercall_page_initialise(d, hypercall_page);
     1.9          unmap_domain_page(hypercall_page);
    1.10  
    1.11          put_page_and_type(mfn_to_page(mfn));
     2.1 --- a/xen/arch/x86/domain.c	Tue Aug 01 15:48:48 2006 +0100
     2.2 +++ b/xen/arch/x86/domain.c	Tue Aug 01 17:18:05 2006 +0100
     2.3 @@ -819,7 +819,7 @@ unsigned long hypercall_create_continuat
     2.4  #if defined(__i386__)
     2.5          regs->eax  = op;
     2.6  
     2.7 -        if ( supervisor_mode_kernel )
     2.8 +        if ( supervisor_mode_kernel || hvm_guest(current) )
     2.9              regs->eip &= ~31; /* re-execute entire hypercall entry stub */
    2.10          else
    2.11              regs->eip -= 2;   /* re-execute 'int 0x82' */
     3.1 --- a/xen/arch/x86/domain_build.c	Tue Aug 01 15:48:48 2006 +0100
     3.2 +++ b/xen/arch/x86/domain_build.c	Tue Aug 01 17:18:05 2006 +0100
     3.3 @@ -704,7 +704,7 @@ int construct_dom0(struct domain *d,
     3.4              return -1;
     3.5          }
     3.6  
     3.7 -        hypercall_page_initialise((void *)hypercall_page);
     3.8 +        hypercall_page_initialise(d, (void *)hypercall_page);
     3.9      }
    3.10  
    3.11      /* Copy the initial ramdisk. */
     4.1 --- a/xen/arch/x86/hvm/hvm.c	Tue Aug 01 15:48:48 2006 +0100
     4.2 +++ b/xen/arch/x86/hvm/hvm.c	Tue Aug 01 17:18:05 2006 +0100
     4.3 @@ -27,6 +27,7 @@
     4.4  #include <xen/softirq.h>
     4.5  #include <xen/domain.h>
     4.6  #include <xen/domain_page.h>
     4.7 +#include <xen/hypercall.h>
     4.8  #include <asm/current.h>
     4.9  #include <asm/io.h>
    4.10  #include <asm/shadow.h>
    4.11 @@ -329,6 +330,65 @@ void hvm_print_line(struct vcpu *v, cons
    4.12  	pbuf[(*index)++] = c;
    4.13  }
    4.14  
    4.15 +#if defined(__i386__)
    4.16 +
    4.17 +typedef unsigned long hvm_hypercall_t(
    4.18 +    unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
    4.19 +#define HYPERCALL(x) [ __HYPERVISOR_ ## x ] = (hvm_hypercall_t *) do_ ## x
    4.20 +static hvm_hypercall_handler *hvm_hypercall_table[] = {
    4.21 +    HYPERCALL(mmu_update),
    4.22 +    HYPERCALL(memory_op),
    4.23 +    HYPERCALL(multicall),
    4.24 +    HYPERCALL(update_va_mapping),
    4.25 +    HYPERCALL(event_channel_op_compat),
    4.26 +    HYPERCALL(xen_version),
    4.27 +    HYPERCALL(grant_table_op),
    4.28 +    HYPERCALL(event_channel_op),
    4.29 +    HYPERCALL(hvm_op)
    4.30 +};
    4.31 +#undef HYPERCALL
    4.32 +
    4.33 +void hvm_do_hypercall(struct cpu_user_regs *pregs)
    4.34 +{
    4.35 +    if ( ring_3(pregs) )
    4.36 +    {
    4.37 +        pregs->eax = -EPERM;
    4.38 +        return;
    4.39 +    }
    4.40 +
    4.41 +    if ( pregs->eax > ARRAY_SIZE(hvm_hypercall_table) ||
    4.42 +         !hvm_hypercall_table[pregs->eax] )
    4.43 +    {
    4.44 +        DPRINTK("HVM vcpu %d:%d did a bad hypercall %d.\n",
    4.45 +                current->domain->domain_id, current->vcpu_id,
    4.46 +                pregs->eax);
    4.47 +        pregs->eax = -ENOSYS;
    4.48 +    }
    4.49 +    else
    4.50 +    {
    4.51 +        pregs->eax = hvm_hypercall_table[pregs->eax](
    4.52 +            pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi);
    4.53 +    }
    4.54 +}
    4.55 +
    4.56 +#else /* __x86_64__ */
    4.57 +
    4.58 +void hvm_do_hypercall(struct cpu_user_regs *pregs)
    4.59 +{
    4.60 +    printk("not supported yet!\n");
    4.61 +}
    4.62 +
    4.63 +#endif
    4.64 +
    4.65 +/* Initialise a hypercall transfer page for a VMX domain using
    4.66 +   paravirtualised drivers. */
    4.67 +void hvm_hypercall_page_initialise(struct domain *d,
    4.68 +                                   void *hypercall_page)
    4.69 +{
    4.70 +    hvm_funcs.init_hypercall_page(d, hypercall_page);
    4.71 +}
    4.72 +
    4.73 +
    4.74  /*
    4.75   * only called in HVM domain BSP context
    4.76   * when booting, vcpuid is always equal to apic_id
     5.1 --- a/xen/arch/x86/hvm/svm/svm.c	Tue Aug 01 15:48:48 2006 +0100
     5.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Tue Aug 01 17:18:05 2006 +0100
     5.3 @@ -456,6 +456,28 @@ void svm_init_ap_context(struct vcpu_gue
     5.4      ctxt->flags = VGCF_HVM_GUEST;
     5.5  }
     5.6  
     5.7 +static void svm_init_hypercall_page(struct domain *d, void *hypercall_page)
     5.8 +{
     5.9 +    char *p;
    5.10 +    int i;
    5.11 +
    5.12 +    memset(hypercall_page, 0, PAGE_SIZE);
    5.13 +
    5.14 +    for ( i = 0; i < (PAGE_SIZE / 32); i++ )
    5.15 +    {
    5.16 +        p = (char *)(hypercall_page + (i * 32));
    5.17 +        *(u8  *)(p + 0) = 0xb8; /* mov imm32, %eax */
    5.18 +        *(u32 *)(p + 1) = i;
    5.19 +        *(u8  *)(p + 5) = 0x0f; /* vmmcall */
    5.20 +        *(u8  *)(p + 6) = 0x01;
    5.21 +        *(u8  *)(p + 7) = 0xd9;
    5.22 +        *(u8  *)(p + 8) = 0xc3; /* ret */
    5.23 +    }
    5.24 +
    5.25 +    /* Don't support HYPERVISOR_iret at the moment */
    5.26 +    *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
    5.27 +}
    5.28 +
    5.29  int start_svm(void)
    5.30  {
    5.31      u32 eax, ecx, edx;
    5.32 @@ -504,6 +526,8 @@ int start_svm(void)
    5.33      hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
    5.34      hvm_funcs.init_ap_context = svm_init_ap_context;
    5.35  
    5.36 +    hvm_funcs.init_hypercall_page = svm_init_hypercall_page;
    5.37 +
    5.38      hvm_enabled = 1;    
    5.39  
    5.40      return 1;
    5.41 @@ -1980,11 +2004,13 @@ static int svm_cr_access(struct vcpu *v,
    5.42      return result;
    5.43  }
    5.44  
    5.45 -static inline void svm_do_msr_access(struct vcpu *v, struct cpu_user_regs *regs)
    5.46 +static inline void svm_do_msr_access(
    5.47 +    struct vcpu *v, struct cpu_user_regs *regs)
    5.48  {
    5.49      struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
    5.50      int  inst_len;
    5.51      u64 msr_content=0;
    5.52 +    u32 eax, edx;
    5.53  
    5.54      ASSERT(vmcb);
    5.55  
    5.56 @@ -2018,6 +2044,14 @@ static inline void svm_do_msr_access(str
    5.57          default:
    5.58              if (long_mode_do_msr_read(regs))
    5.59                  goto done;
    5.60 +
    5.61 +            if ( rdmsr_hypervisor_regs(regs->ecx, &eax, &edx) )
    5.62 +            {
    5.63 +                regs->eax = eax;
    5.64 +                regs->edx = edx;
    5.65 +                goto done;
    5.66 +            }
    5.67 +
    5.68              rdmsr_safe(regs->ecx, regs->eax, regs->edx);
    5.69              break;
    5.70          }
    5.71 @@ -2047,7 +2081,8 @@ static inline void svm_do_msr_access(str
    5.72              vlapic_msr_set(VLAPIC(v), msr_content);
    5.73              break;
    5.74          default:
    5.75 -            long_mode_do_msr_write(regs);
    5.76 +            if ( !long_mode_do_msr_write(regs) )
    5.77 +                wrmsr_hypervisor_regs(regs->ecx, regs->eax, regs->edx);
    5.78              break;
    5.79          }
    5.80      }
     6.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Tue Aug 01 15:48:48 2006 +0100
     6.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Tue Aug 01 17:18:05 2006 +0100
     6.3 @@ -669,6 +669,28 @@ static int check_vmx_controls(u32 ctrls,
     6.4      return 1;
     6.5  }
     6.6  
     6.7 +static void vmx_init_hypercall_page(struct domain *d, void *hypercall_page)
     6.8 +{
     6.9 +    char *p;
    6.10 +    int i;
    6.11 +
    6.12 +    memset(hypercall_page, 0, PAGE_SIZE);
    6.13 +
    6.14 +    for ( i = 0; i < (PAGE_SIZE / 32); i++ )
    6.15 +    {
    6.16 +        p = (char *)(hypercall_page + (i * 32));
    6.17 +        *(u8  *)(p + 0) = 0xb8; /* mov imm32, %eax */
    6.18 +        *(u32 *)(p + 1) = i;
    6.19 +        *(u8  *)(p + 5) = 0x0f; /* vmcall */
    6.20 +        *(u8  *)(p + 6) = 0x01;
    6.21 +        *(u8  *)(p + 7) = 0xc1;
    6.22 +        *(u8  *)(p + 8) = 0xc3; /* ret */
    6.23 +    }
    6.24 +
    6.25 +    /* Don't support HYPERVISOR_iret at the moment */
    6.26 +    *(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
    6.27 +}
    6.28 +
    6.29  int start_vmx(void)
    6.30  {
    6.31      u32 eax, edx;
    6.32 @@ -749,6 +771,8 @@ int start_vmx(void)
    6.33  
    6.34      hvm_funcs.init_ap_context = vmx_init_ap_context;
    6.35  
    6.36 +    hvm_funcs.init_hypercall_page = vmx_init_hypercall_page;
    6.37 +
    6.38      hvm_enabled = 1;
    6.39  
    6.40      return 1;
    6.41 @@ -1877,6 +1901,7 @@ static int vmx_cr_access(unsigned long e
    6.42  static inline void vmx_do_msr_read(struct cpu_user_regs *regs)
    6.43  {
    6.44      u64 msr_content = 0;
    6.45 +    u32 eax, edx;
    6.46      struct vcpu *v = current;
    6.47  
    6.48      HVM_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_read: ecx=%lx, eax=%lx, edx=%lx",
    6.49 @@ -1899,8 +1924,16 @@ static inline void vmx_do_msr_read(struc
    6.50          msr_content = VLAPIC(v) ? VLAPIC(v)->apic_base_msr : 0;
    6.51          break;
    6.52      default:
    6.53 -        if(long_mode_do_msr_read(regs))
    6.54 +        if (long_mode_do_msr_read(regs))
    6.55              return;
    6.56 +
    6.57 +        if ( rdmsr_hypervisor_regs(regs->ecx, &eax, &edx) )
    6.58 +        {
    6.59 +            regs->eax = eax;
    6.60 +            regs->edx = edx;
    6.61 +            return;
    6.62 +        }
    6.63 +
    6.64          rdmsr_safe(regs->ecx, regs->eax, regs->edx);
    6.65          break;
    6.66      }
    6.67 @@ -1942,7 +1975,8 @@ static inline void vmx_do_msr_write(stru
    6.68          vlapic_msr_set(VLAPIC(v), msr_content);
    6.69          break;
    6.70      default:
    6.71 -        long_mode_do_msr_write(regs);
    6.72 +        if ( !long_mode_do_msr_write(regs) )
    6.73 +            wrmsr_hypervisor_regs(regs->ecx, regs->eax, regs->edx);
    6.74          break;
    6.75      }
    6.76  
    6.77 @@ -2273,16 +2307,16 @@ asmlinkage void vmx_vmexit_handler(struc
    6.78          __update_guest_eip(inst_len);
    6.79          break;
    6.80      }
    6.81 -#if 0 /* keep this for debugging */
    6.82      case EXIT_REASON_VMCALL:
    6.83 +    {
    6.84          __get_instruction_length(inst_len);
    6.85          __vmread(GUEST_RIP, &eip);
    6.86          __vmread(EXIT_QUALIFICATION, &exit_qualification);
    6.87  
    6.88 -        hvm_print_line(v, regs.eax); /* provides the current domain */
    6.89 +        hvm_do_hypercall(&regs);
    6.90          __update_guest_eip(inst_len);
    6.91          break;
    6.92 -#endif
    6.93 +    }
    6.94      case EXIT_REASON_CR_ACCESS:
    6.95      {
    6.96          __vmread(GUEST_RIP, &eip);
    6.97 @@ -2323,7 +2357,6 @@ asmlinkage void vmx_vmexit_handler(struc
    6.98      case EXIT_REASON_MWAIT_INSTRUCTION:
    6.99          __hvm_bug(&regs);
   6.100          break;
   6.101 -    case EXIT_REASON_VMCALL:
   6.102      case EXIT_REASON_VMCLEAR:
   6.103      case EXIT_REASON_VMLAUNCH:
   6.104      case EXIT_REASON_VMPTRLD:
     7.1 --- a/xen/arch/x86/traps.c	Tue Aug 01 15:48:48 2006 +0100
     7.2 +++ b/xen/arch/x86/traps.c	Tue Aug 01 17:18:05 2006 +0100
     7.3 @@ -44,6 +44,7 @@
     7.4  #include <xen/symbols.h>
     7.5  #include <xen/iocap.h>
     7.6  #include <xen/nmi.h>
     7.7 +#include <xen/version.h>
     7.8  #include <asm/shadow.h>
     7.9  #include <asm/system.h>
    7.10  #include <asm/io.h>
    7.11 @@ -429,18 +430,95 @@ DO_ERROR_NOCODE(16, "fpu error", coproce
    7.12  DO_ERROR(17, "alignment check", alignment_check)
    7.13  DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error)
    7.14  
    7.15 +int rdmsr_hypervisor_regs(
    7.16 +    uint32_t idx, uint32_t *eax, uint32_t *edx)
    7.17 +{
    7.18 +    idx -= 0x40000000;
    7.19 +    if ( idx > 0 )
    7.20 +        return 0;
    7.21 +
    7.22 +    *eax = *edx = 0;
    7.23 +    return 1;
    7.24 +}
    7.25 +
    7.26 +int wrmsr_hypervisor_regs(
    7.27 +    uint32_t idx, uint32_t eax, uint32_t edx)
    7.28 +{
    7.29 +    struct domain *d = current->domain;
    7.30 +
    7.31 +    idx -= 0x40000000;
    7.32 +    if ( idx > 0 )
    7.33 +        return 0;
    7.34 +
    7.35 +    switch ( idx )
    7.36 +    {
    7.37 +    case 0:
    7.38 +    {
    7.39 +        void         *hypercall_page;
    7.40 +        unsigned long mfn;
    7.41 +        unsigned long gmfn = ((unsigned long)edx << 20) | (eax >> 12);
    7.42 +        unsigned int  idx  = eax & 0xfff;
    7.43 +
    7.44 +        if ( idx > 0 )
    7.45 +        {
    7.46 +            DPRINTK("Dom%d: Out of range index %u to MSR %08x\n",
    7.47 +                    d->domain_id, idx, 0x40000000);
    7.48 +            return 0;
    7.49 +        }
    7.50 +
    7.51 +        mfn = gmfn_to_mfn(d, gmfn);
    7.52 +
    7.53 +        if ( !mfn_valid(mfn) ||
    7.54 +             !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) )
    7.55 +        {
    7.56 +            DPRINTK("Dom%d: Bad GMFN %lx (MFN %lx) to MSR %08x\n",
    7.57 +                    d->domain_id, gmfn, mfn, 0x40000000);
    7.58 +            return 0;
    7.59 +        }
    7.60 +
    7.61 +        hypercall_page = map_domain_page(mfn);
    7.62 +        hypercall_page_initialise(d, hypercall_page);
    7.63 +        unmap_domain_page(hypercall_page);
    7.64 +
    7.65 +        put_page_and_type(mfn_to_page(mfn));
    7.66 +        break;
    7.67 +    }
    7.68 +
    7.69 +    default:
    7.70 +        BUG();
    7.71 +    }
    7.72 +
    7.73 +    return 1;
    7.74 +}
    7.75 +
    7.76  int cpuid_hypervisor_leaves(
    7.77      uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
    7.78  {
    7.79 -    if ( (idx < 0x40000000) || (idx > 0x40000000) )
    7.80 +    idx -= 0x40000000;
    7.81 +    if ( idx > 2 )
    7.82          return 0;
    7.83  
    7.84 -    switch ( idx - 0x40000000 )
    7.85 +    switch ( idx )
    7.86      {
    7.87      case 0:
    7.88 -        *eax = 0x40000000;
    7.89 -        *ebx = 0x006e6558; /* "Xen\0" */
    7.90 -        *ecx = *edx = 0;
    7.91 +        *eax = 0x40000002; /* Largest leaf        */
    7.92 +        *ebx = 0x566e6558; /* Signature 1: "XenV" */
    7.93 +        *ecx = 0x65584d4d; /* Signature 2: "MMXe" */
    7.94 +        *edx = 0x4d4d566e; /* Signature 3: "nVMM" */
    7.95 +        break;
    7.96 +
    7.97 +    case 1:
    7.98 +        *eax = (xen_major_version() << 16) | xen_minor_version();
    7.99 +        *ebx = 0;          /* Reserved */
   7.100 +        *ecx = 0;          /* Reserved */
   7.101 +        *edx = 0;          /* Reserved */
   7.102 +        break;
   7.103 +
   7.104 +    case 2:
   7.105 +        *eax = 1;          /* Number of hypercall-transfer pages */
   7.106 +        *ebx = 0x40000000; /* MSR base address */
   7.107 +        *ecx = 0;          /* Features 1 */
   7.108 +        *edx = 0;          /* Features 2 */
   7.109          break;
   7.110  
   7.111      default:
   7.112 @@ -1297,6 +1375,9 @@ static int emulate_privileged_op(struct 
   7.113              break;
   7.114  #endif
   7.115          default:
   7.116 +            if ( wrmsr_hypervisor_regs(regs->ecx, regs->eax, regs->edx) )
   7.117 +                break;
   7.118 +
   7.119              if ( (rdmsr_safe(regs->ecx, l, h) != 0) ||
   7.120                   (regs->eax != l) || (regs->edx != h) )
   7.121                  DPRINTK("Domain attempted WRMSR %p from "
   7.122 @@ -1328,6 +1409,12 @@ static int emulate_privileged_op(struct 
   7.123                  goto fail;
   7.124              break;
   7.125          default:
   7.126 +            if ( rdmsr_hypervisor_regs(regs->ecx, &l, &h) )
   7.127 +            {
   7.128 +                regs->eax = l;
   7.129 +                regs->edx = h;
   7.130 +                break;
   7.131 +            }
   7.132              /* Everyone can read the MSR space. */
   7.133              /*DPRINTK("Domain attempted RDMSR %p.\n", _p(regs->ecx));*/
   7.134              if ( rdmsr_safe(regs->ecx, regs->eax, regs->edx) )
     8.1 --- a/xen/arch/x86/x86_32/traps.c	Tue Aug 01 15:48:48 2006 +0100
     8.2 +++ b/xen/arch/x86/x86_32/traps.c	Tue Aug 01 17:18:05 2006 +0100
     8.3 @@ -490,9 +490,11 @@ static void hypercall_page_initialise_ri
     8.4      *(u16 *)(p+ 6) = 0x82cd;  /* int  $0x82 */
     8.5  }
     8.6  
     8.7 -void hypercall_page_initialise(void *hypercall_page)
     8.8 +void hypercall_page_initialise(struct domain *d, void *hypercall_page)
     8.9  {
    8.10 -    if ( supervisor_mode_kernel )
    8.11 +    if ( hvm_guest(d->vcpu[0]) )
    8.12 +        hvm_hypercall_page_initialise(d, hypercall_page);
    8.13 +    else if ( supervisor_mode_kernel )
    8.14          hypercall_page_initialise_ring0_kernel(hypercall_page);
    8.15      else
    8.16          hypercall_page_initialise_ring1_kernel(hypercall_page);
     9.1 --- a/xen/arch/x86/x86_64/traps.c	Tue Aug 01 15:48:48 2006 +0100
     9.2 +++ b/xen/arch/x86/x86_64/traps.c	Tue Aug 01 17:18:05 2006 +0100
     9.3 @@ -432,7 +432,7 @@ long do_set_callbacks(unsigned long even
     9.4      return 0;
     9.5  }
     9.6  
     9.7 -void hypercall_page_initialise(void *hypercall_page)
     9.8 +static void hypercall_page_initialise_ring3_kernel(void *hypercall_page)
     9.9  {
    9.10      char *p;
    9.11      int i;
    9.12 @@ -465,6 +465,14 @@ void hypercall_page_initialise(void *hyp
    9.13      *(u16 *)(p+ 9) = 0x050f;  /* syscall */
    9.14  }
    9.15  
    9.16 +void hypercall_page_initialise(struct domain *d, void *hypercall_page)
    9.17 +{
    9.18 +    if ( hvm_guest(d->vcpu[0]) )
    9.19 +        hvm_hypercall_page_initialise(d, hypercall_page);
    9.20 +    else
    9.21 +        hypercall_page_initialise_ring3_kernel(hypercall_page);
    9.22 +}
    9.23 +
    9.24  /*
    9.25   * Local variables:
    9.26   * mode: C
    10.1 --- a/xen/include/asm-x86/domain.h	Tue Aug 01 15:48:48 2006 +0100
    10.2 +++ b/xen/include/asm-x86/domain.h	Tue Aug 01 17:18:05 2006 +0100
    10.3 @@ -55,7 +55,7 @@ extern void toggle_guest_mode(struct vcp
    10.4   * Initialise a hypercall-transfer page. The given pointer must be mapped
    10.5   * in Xen virtual address space (accesses are not validated or checked).
    10.6   */
    10.7 -extern void hypercall_page_initialise(void *);
    10.8 +extern void hypercall_page_initialise(struct domain *d, void *);
    10.9  
   10.10  struct arch_domain
   10.11  {
    11.1 --- a/xen/include/asm-x86/hvm/hvm.h	Tue Aug 01 15:48:48 2006 +0100
    11.2 +++ b/xen/include/asm-x86/hvm/hvm.h	Tue Aug 01 17:18:05 2006 +0100
    11.3 @@ -61,6 +61,8 @@ struct hvm_function_table {
    11.4  
    11.5      void (*init_ap_context)(struct vcpu_guest_context *ctxt,
    11.6                              int vcpuid, int trampoline_vector);
    11.7 +
    11.8 +    void (*init_hypercall_page)(struct domain *d, void *hypercall_page);
    11.9  };
   11.10  
   11.11  extern struct hvm_function_table hvm_funcs;
   11.12 @@ -121,6 +123,9 @@ hvm_instruction_length(struct vcpu *v)
   11.13      return hvm_funcs.instruction_length(v);
   11.14  }
   11.15  
   11.16 +void hvm_hypercall_page_initialise(struct domain *d,
   11.17 +                                   void *hypercall_page);
   11.18 +
   11.19  static inline unsigned long
   11.20  hvm_get_guest_ctrl_reg(struct vcpu *v, unsigned int num)
   11.21  {
    12.1 --- a/xen/include/asm-x86/hvm/support.h	Tue Aug 01 15:48:48 2006 +0100
    12.2 +++ b/xen/include/asm-x86/hvm/support.h	Tue Aug 01 17:18:05 2006 +0100
    12.3 @@ -148,4 +148,6 @@ extern void hvm_hooks_assist(struct vcpu
    12.4  extern void hvm_print_line(struct vcpu *v, const char c);
    12.5  extern void hlt_timer_fn(void *data);
    12.6  
    12.7 +void hvm_do_hypercall(struct cpu_user_regs *pregs);
    12.8 +
    12.9  #endif /* __ASM_X86_HVM_SUPPORT_H__ */
    13.1 --- a/xen/include/asm-x86/processor.h	Tue Aug 01 15:48:48 2006 +0100
    13.2 +++ b/xen/include/asm-x86/processor.h	Tue Aug 01 17:18:05 2006 +0100
    13.3 @@ -547,6 +547,10 @@ extern void mcheck_init(struct cpuinfo_x
    13.4  
    13.5  int cpuid_hypervisor_leaves(
    13.6      uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
    13.7 +int rdmsr_hypervisor_regs(
    13.8 +    uint32_t idx, uint32_t *eax, uint32_t *edx);
    13.9 +int wrmsr_hypervisor_regs(
   13.10 +    uint32_t idx, uint32_t eax, uint32_t edx);
   13.11  
   13.12  #endif /* !__ASSEMBLY__ */
   13.13