ia64/xen-unstable

changeset 10939:b33c08de3d98

[HVM] Add a concept of HVM parameters to the hypervisor.

Each HVM domain has a space of HVM parameters associated with it,
and these can be manipulated via a new hvm_op hypercall. This means
that the hypervisor no longer needs to parse the hvm_info table, so
remove that code.

Signed-off-by: Steven Smith <ssmith@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Aug 03 13:53:33 2006 +0100 (2006-08-03)
parents aa1ab056bfbf
children 3eb0f56d77c2
files linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c tools/libxc/xc_hvm_build.c xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_64/entry.S xen/include/asm-x86/hvm/domain.h xen/include/public/xen.h xen/include/xen/hypercall.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Wed Aug 02 17:42:38 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c	Thu Aug 03 13:53:33 2006 +0100
     1.3 @@ -270,6 +270,7 @@ static int __init privcmd_init(void)
     1.4  	set_bit(__HYPERVISOR_sched_op_compat,  hypercall_permission_map);
     1.5  	set_bit(__HYPERVISOR_event_channel_op_compat,
     1.6  		hypercall_permission_map);
     1.7 +	set_bit(__HYPERVISOR_hvm_op,           hypercall_permission_map);
     1.8  
     1.9  	privcmd_intf = create_xen_proc_entry("privcmd", 0400);
    1.10  	if (privcmd_intf != NULL)
     2.1 --- a/tools/libxc/xc_hvm_build.c	Wed Aug 02 17:42:38 2006 +0100
     2.2 +++ b/tools/libxc/xc_hvm_build.c	Thu Aug 03 13:53:33 2006 +0100
     2.3 @@ -6,12 +6,14 @@
     2.4  #include <stddef.h>
     2.5  #include <inttypes.h>
     2.6  #include "xg_private.h"
     2.7 +#include "xc_private.h"
     2.8  #include "xc_elf.h"
     2.9  #include <stdlib.h>
    2.10  #include <unistd.h>
    2.11  #include <zlib.h>
    2.12  #include <xen/hvm/hvm_info_table.h>
    2.13  #include <xen/hvm/ioreq.h>
    2.14 +#include <xen/hvm/params.h>
    2.15  
    2.16  #define HVM_LOADER_ENTR_ADDR  0x00100000
    2.17  
    2.18 @@ -43,6 +45,30 @@ loadelfimage(
    2.19      char *elfbase, int xch, uint32_t dom, unsigned long *parray,
    2.20      struct domain_setup_info *dsi);
    2.21  
    2.22 +static void xc_set_hvm_param(int handle,
    2.23 +                             domid_t dom, int param, unsigned long value)
    2.24 +{
    2.25 +    DECLARE_HYPERCALL;
    2.26 +    xen_hvm_param_t arg;
    2.27 +    int rc;
    2.28 +
    2.29 +    hypercall.op     = __HYPERVISOR_hvm_op;
    2.30 +    hypercall.arg[0] = HVMOP_set_param;
    2.31 +    hypercall.arg[1] = (unsigned long)&arg;
    2.32 +    arg.domid = dom;
    2.33 +    arg.index = param;
    2.34 +    arg.value = value;
    2.35 +    if ( mlock(&arg, sizeof(arg)) != 0 )
    2.36 +    {
    2.37 +        PERROR("Could not lock memory for set parameter");
    2.38 +        return;
    2.39 +    }
    2.40 +    rc = do_xen_hypercall(handle, &hypercall);
    2.41 +    safe_munlock(&arg, sizeof(arg));
    2.42 +    if (rc < 0)
    2.43 +        PERROR("set HVM parameter failed (%d)", rc);
    2.44 +}
    2.45 +
    2.46  static void build_e820map(void *e820_page, unsigned long long mem_size)
    2.47  {
    2.48      struct e820entry *e820entry =
    2.49 @@ -154,6 +180,9 @@ static int set_hvm_info(int xc_handle, u
    2.50  
    2.51      munmap(va_map, PAGE_SIZE);
    2.52  
    2.53 +    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_APIC_ENABLED, apic);
    2.54 +    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
    2.55 +
    2.56      return 0;
    2.57  }
    2.58  
    2.59 @@ -287,6 +316,9 @@ static int setup_guest(int xc_handle,
    2.60  
    2.61      munmap(sp, PAGE_SIZE);
    2.62  
    2.63 +    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, (v_end >> PAGE_SHIFT) - 2);
    2.64 +    xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn);
    2.65 +
    2.66      *store_mfn = page_array[(v_end >> PAGE_SHIFT) - 2];
    2.67      if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) )
    2.68          goto error_out;
     3.1 --- a/xen/arch/x86/hvm/hvm.c	Wed Aug 02 17:42:38 2006 +0100
     3.2 +++ b/xen/arch/x86/hvm/hvm.c	Thu Aug 03 13:53:33 2006 +0100
     3.3 @@ -46,6 +46,7 @@
     3.4  #include <public/sched.h>
     3.5  #include <public/hvm/ioreq.h>
     3.6  #include <public/hvm/hvm_info_table.h>
     3.7 +#include <xen/guest_access.h>
     3.8  
     3.9  int hvm_enabled = 0;
    3.10  
    3.11 @@ -128,61 +129,6 @@ static void hvm_map_io_shared_page(struc
    3.12      d->arch.hvm_domain.shared_page_va = (unsigned long)p;
    3.13  }
    3.14  
    3.15 -static int validate_hvm_info(struct hvm_info_table *t)
    3.16 -{
    3.17 -    char signature[] = "HVM INFO";
    3.18 -    uint8_t *ptr = (uint8_t *)t;
    3.19 -    uint8_t sum = 0;
    3.20 -    int i;
    3.21 -
    3.22 -    /* strncmp(t->signature, "HVM INFO", 8) */
    3.23 -    for ( i = 0; i < 8; i++ ) {
    3.24 -        if ( signature[i] != t->signature[i] ) {
    3.25 -            printk("Bad hvm info signature\n");
    3.26 -            return 0;
    3.27 -        }
    3.28 -    }
    3.29 -
    3.30 -    for ( i = 0; i < t->length; i++ )
    3.31 -        sum += ptr[i];
    3.32 -
    3.33 -    return (sum == 0);
    3.34 -}
    3.35 -
    3.36 -static void hvm_get_info(struct domain *d)
    3.37 -{
    3.38 -    unsigned char *p;
    3.39 -    unsigned long mfn;
    3.40 -    struct hvm_info_table *t;
    3.41 -
    3.42 -    mfn = get_mfn_from_gpfn(HVM_INFO_PFN);
    3.43 -    if ( mfn == INVALID_MFN ) {
    3.44 -        printk("Can not get info page mfn for HVM domain.\n");
    3.45 -        domain_crash_synchronous();
    3.46 -    }
    3.47 -
    3.48 -    p = map_domain_page(mfn);
    3.49 -    if ( p == NULL ) {
    3.50 -        printk("Can not map info page for HVM domain.\n");
    3.51 -        domain_crash_synchronous();
    3.52 -    }
    3.53 -
    3.54 -    t = (struct hvm_info_table *)(p + HVM_INFO_OFFSET);
    3.55 -
    3.56 -    if ( validate_hvm_info(t) ) {
    3.57 -        d->arch.hvm_domain.nr_vcpus = t->nr_vcpus;
    3.58 -        d->arch.hvm_domain.apic_enabled = t->apic_enabled;
    3.59 -        d->arch.hvm_domain.pae_enabled = t->pae_enabled;
    3.60 -    } else {
    3.61 -        printk("Bad hvm info table\n");
    3.62 -        d->arch.hvm_domain.nr_vcpus = 1;
    3.63 -        d->arch.hvm_domain.apic_enabled = 0;
    3.64 -        d->arch.hvm_domain.pae_enabled = 0;
    3.65 -    }
    3.66 -
    3.67 -    unmap_domain_page(p);
    3.68 -}
    3.69 -
    3.70  void hvm_setup_platform(struct domain* d)
    3.71  {
    3.72      struct hvm_domain *platform;
    3.73 @@ -198,7 +144,6 @@ void hvm_setup_platform(struct domain* d
    3.74      }
    3.75  
    3.76      hvm_map_io_shared_page(d);
    3.77 -    hvm_get_info(d);
    3.78  
    3.79      platform = &d->arch.hvm_domain;
    3.80      pic_init(&platform->vpic, pic_irq_request, &platform->interrupt_request);
    3.81 @@ -343,8 +288,8 @@ static hvm_hypercall_t *hvm_hypercall_ta
    3.82      HYPERCALL(event_channel_op_compat),
    3.83      HYPERCALL(xen_version),
    3.84      HYPERCALL(grant_table_op),
    3.85 -    HYPERCALL(event_channel_op)
    3.86 -    /*HYPERCALL(hvm_op)*/
    3.87 +    HYPERCALL(event_channel_op),
    3.88 +    HYPERCALL(hvm_op)
    3.89  };
    3.90  #undef HYPERCALL
    3.91  
    3.92 @@ -435,6 +380,65 @@ int hvm_bringup_ap(int vcpuid, int tramp
    3.93      return rc;
    3.94  }
    3.95  
    3.96 +long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
    3.97 +
    3.98 +{
    3.99 +    long rc = 0;
   3.100 +
   3.101 +    switch ( op )
   3.102 +    {
   3.103 +    case HVMOP_set_param:
   3.104 +    case HVMOP_get_param:
   3.105 +    {
   3.106 +        struct xen_hvm_param a;
   3.107 +        struct domain *d;
   3.108 +
   3.109 +        if ( copy_from_guest(&a, arg, 1) )
   3.110 +            return -EFAULT;
   3.111 +
   3.112 +        if ( a.index >= HVM_NR_PARAMS )
   3.113 +            return -EINVAL;
   3.114 +
   3.115 +        if ( a.domid == DOMID_SELF )
   3.116 +        {
   3.117 +            get_knownalive_domain(current->domain);
   3.118 +            d = current->domain;
   3.119 +        }
   3.120 +        else if ( IS_PRIV(current->domain) )
   3.121 +        {
   3.122 +            d = find_domain_by_id(a.domid);
   3.123 +            if ( !d )
   3.124 +                return -ESRCH;
   3.125 +        }
   3.126 +        else
   3.127 +        {
   3.128 +            return -EPERM;
   3.129 +        }
   3.130 +
   3.131 +        if ( op == HVMOP_set_param )
   3.132 +        {
   3.133 +            rc = 0;
   3.134 +            d->arch.hvm_domain.params[a.index] = a.value;
   3.135 +        }
   3.136 +        else
   3.137 +        {
   3.138 +            rc = d->arch.hvm_domain.params[a.index];
   3.139 +        }
   3.140 +
   3.141 +        put_domain(d);
   3.142 +        return rc;
   3.143 +    }
   3.144 +
   3.145 +    default:
   3.146 +    {
   3.147 +        DPRINTK("Bad HVM op %ld.\n", op);
   3.148 +        rc = -ENOSYS;
   3.149 +    }
   3.150 +    }
   3.151 +
   3.152 +    return rc;
   3.153 +}
   3.154 +
   3.155  /*
   3.156   * Local variables:
   3.157   * mode: C
     4.1 --- a/xen/arch/x86/hvm/svm/svm.c	Wed Aug 02 17:42:38 2006 +0100
     4.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Thu Aug 03 13:53:33 2006 +0100
     4.3 @@ -997,7 +997,7 @@ static void svm_vmexit_do_cpuid(struct v
     4.4  #else
     4.5          if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
     4.6          {
     4.7 -            if ( !v->domain->arch.hvm_domain.pae_enabled )
     4.8 +            if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
     4.9                  clear_bit(X86_FEATURE_PAE, &edx);
    4.10              clear_bit(X86_FEATURE_PSE, &edx);
    4.11              clear_bit(X86_FEATURE_PSE36, &edx);
    4.12 @@ -1060,7 +1060,7 @@ static void svm_vmexit_do_cpuid(struct v
    4.13  #else
    4.14          if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
    4.15          {
    4.16 -            if ( !v->domain->arch.hvm_domain.pae_enabled )
    4.17 +            if ( !v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
    4.18              {
    4.19                  clear_bit(X86_FEATURE_NX & 31, &edx);
    4.20                  clear_bit(X86_FEATURE_PAE, &edx);
     5.1 --- a/xen/arch/x86/hvm/vlapic.c	Wed Aug 02 17:42:38 2006 +0100
     5.2 +++ b/xen/arch/x86/hvm/vlapic.c	Thu Aug 03 13:53:33 2006 +0100
     5.3 @@ -33,6 +33,7 @@
     5.4  #include <xen/sched.h>
     5.5  #include <asm/current.h>
     5.6  #include <public/hvm/ioreq.h>
     5.7 +#include <public/hvm/params.h>
     5.8  
     5.9  /* XXX remove this definition after GFW enabled */
    5.10  #define VLAPIC_NO_BIOS
    5.11 @@ -57,7 +58,7 @@ static unsigned int vlapic_lvt_mask[VLAP
    5.12  
    5.13  int hvm_apic_support(struct domain *d)
    5.14  {
    5.15 -    return d->arch.hvm_domain.apic_enabled;
    5.16 +    return d->arch.hvm_domain.params[HVM_PARAM_APIC_ENABLED];
    5.17  }
    5.18  
    5.19  int vlapic_find_highest_irr(struct vlapic *vlapic)
     6.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Wed Aug 02 17:42:38 2006 +0100
     6.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Thu Aug 03 13:53:33 2006 +0100
     6.3 @@ -929,7 +929,7 @@ static void vmx_vmexit_do_cpuid(struct c
     6.4  #else
     6.5              if ( v->domain->arch.ops->guest_paging_levels == PAGING_L2 )
     6.6              {
     6.7 -                if ( v->domain->arch.hvm_domain.pae_enabled )
     6.8 +                if ( v->domain->arch.hvm_domain.params[HVM_PARAM_PAE_ENABLED] )
     6.9                      clear_bit(X86_FEATURE_PSE36, &edx);
    6.10                  else
    6.11                  {
     7.1 --- a/xen/arch/x86/x86_32/entry.S	Wed Aug 02 17:42:38 2006 +0100
     7.2 +++ b/xen/arch/x86/x86_32/entry.S	Thu Aug 03 13:53:33 2006 +0100
     7.3 @@ -656,6 +656,7 @@ ENTRY(hypercall_table)
     7.4          .long do_xenoprof_op
     7.5          .long do_event_channel_op
     7.6          .long do_physdev_op
     7.7 +        .long do_hvm_op             /* 34 */
     7.8          .rept NR_hypercalls-((.-hypercall_table)/4)
     7.9          .long do_ni_hypercall
    7.10          .endr
    7.11 @@ -695,6 +696,7 @@ ENTRY(hypercall_args_table)
    7.12          .byte 2 /* do_xenoprof_op       */
    7.13          .byte 2 /* do_event_channel_op  */
    7.14          .byte 2 /* do_physdev_op        */
    7.15 +        .byte 2 /* do_hvm_op            */  /* 34 */
    7.16          .rept NR_hypercalls-(.-hypercall_args_table)
    7.17          .byte 0 /* do_ni_hypercall      */
    7.18          .endr
     8.1 --- a/xen/arch/x86/x86_64/entry.S	Wed Aug 02 17:42:38 2006 +0100
     8.2 +++ b/xen/arch/x86/x86_64/entry.S	Thu Aug 03 13:53:33 2006 +0100
     8.3 @@ -568,6 +568,7 @@ ENTRY(hypercall_table)
     8.4          .quad do_xenoprof_op
     8.5          .quad do_event_channel_op
     8.6          .quad do_physdev_op
     8.7 +        .quad do_hvm_op
     8.8          .rept NR_hypercalls-((.-hypercall_table)/8)
     8.9          .quad do_ni_hypercall
    8.10          .endr
    8.11 @@ -607,6 +608,7 @@ ENTRY(hypercall_args_table)
    8.12          .byte 2 /* do_xenoprof_op       */
    8.13          .byte 2 /* do_event_channel_op  */
    8.14          .byte 2 /* do_physdev_op        */
    8.15 +        .byte 2 /* do_hvm_op            */
    8.16          .rept NR_hypercalls-(.-hypercall_args_table)
    8.17          .byte 0 /* do_ni_hypercall      */
    8.18          .endr
     9.1 --- a/xen/include/asm-x86/hvm/domain.h	Wed Aug 02 17:42:38 2006 +0100
     9.2 +++ b/xen/include/asm-x86/hvm/domain.h	Thu Aug 03 13:53:33 2006 +0100
     9.3 @@ -27,17 +27,15 @@
     9.4  #include <asm/hvm/vpit.h>
     9.5  #include <asm/hvm/vlapic.h>
     9.6  #include <asm/hvm/vioapic.h>
     9.7 +#include <public/hvm/params.h>
     9.8  
     9.9  #define HVM_PBUF_SIZE   80
    9.10  
    9.11  struct hvm_domain {
    9.12      unsigned long          shared_page_va;
    9.13 -    unsigned int           nr_vcpus;
    9.14 -    unsigned int           apic_enabled;
    9.15 -    unsigned int           pae_enabled;
    9.16      s64                    tsc_frequency;
    9.17      struct pl_time         pl_time;
    9.18 -    
    9.19 +
    9.20      struct hvm_virpic      vpic;
    9.21      struct hvm_vioapic     vioapic;
    9.22      struct hvm_io_handler  io_handler;
    9.23 @@ -48,6 +46,8 @@ struct hvm_domain {
    9.24  
    9.25      int                    pbuf_index;
    9.26      char                   pbuf[HVM_PBUF_SIZE];
    9.27 +
    9.28 +    uint64_t               params[HVM_NR_PARAMS];
    9.29  };
    9.30  
    9.31  #endif /* __ASM_X86_HVM_DOMAIN_H__ */
    10.1 --- a/xen/include/public/xen.h	Wed Aug 02 17:42:38 2006 +0100
    10.2 +++ b/xen/include/public/xen.h	Thu Aug 03 13:53:33 2006 +0100
    10.3 @@ -66,6 +66,7 @@
    10.4  #define __HYPERVISOR_xenoprof_op          31
    10.5  #define __HYPERVISOR_event_channel_op     32
    10.6  #define __HYPERVISOR_physdev_op           33
    10.7 +#define __HYPERVISOR_hvm_op               34
    10.8  
    10.9  /* Architecture-specific hypercall definitions. */
   10.10  #define __HYPERVISOR_arch_0               48
    11.1 --- a/xen/include/xen/hypercall.h	Wed Aug 02 17:42:38 2006 +0100
    11.2 +++ b/xen/include/xen/hypercall.h	Thu Aug 03 13:53:33 2006 +0100
    11.3 @@ -87,4 +87,9 @@ do_nmi_op(
    11.4      unsigned int cmd,
    11.5      XEN_GUEST_HANDLE(void) arg);
    11.6  
    11.7 +extern long
    11.8 +do_hvm_op(
    11.9 +    unsigned long op,
   11.10 +    XEN_GUEST_HANDLE(void) arg);
   11.11 +
   11.12  #endif /* __XEN_HYPERCALL_H__ */