ia64/xen-unstable

changeset 13308:5442b2458e1b

Enable compatibility mode operation for HYPERVISOR_domctl. Also add logic
to switch a domain to/from compatibility mode (supposed to happen early
after domain creation only).

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Emmanuel Ackaouy <ack@xensource.com>
date Fri Jan 05 17:34:39 2007 +0000 (2007-01-05)
parents d80684d19ef4
children 762cb69ce3be
files xen/arch/ia64/xen/domain.c xen/arch/powerpc/domain.c xen/arch/powerpc/domctl.c xen/arch/x86/domain.c xen/arch/x86/domctl.c xen/arch/x86/mm/shadow/common.c xen/arch/x86/x86_32/traps.c xen/arch/x86/x86_64/Makefile xen/arch/x86/x86_64/compat/entry.S xen/arch/x86/x86_64/compat/traps.c xen/arch/x86/x86_64/domctl.c xen/common/compat/Makefile xen/common/compat/domain.c xen/common/compat/domctl.c xen/common/compat/sysctl.c xen/common/domain.c xen/common/domctl.c xen/common/schedule.c xen/include/asm-x86/shadow.h xen/include/public/domctl.h xen/include/xen/compat.h xen/include/xen/domain.h xen/include/xen/sched.h xen/include/xlat.lst
line diff
     1.1 --- a/xen/arch/ia64/xen/domain.c	Fri Jan 05 17:34:38 2007 +0000
     1.2 +++ b/xen/arch/ia64/xen/domain.c	Fri Jan 05 17:34:39 2007 +0000
     1.3 @@ -522,14 +522,14 @@ void arch_domain_destroy(struct domain *
     1.4  	deallocate_rid_range(d);
     1.5  }
     1.6  
     1.7 -void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c)
     1.8 +void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
     1.9  {
    1.10  	int i;
    1.11 -	struct vcpu_extra_regs *er = &c->extra_regs;
    1.12 +	struct vcpu_extra_regs *er = &c.nat->extra_regs;
    1.13  
    1.14 -	c->user_regs = *vcpu_regs (v);
    1.15 - 	c->privregs_pfn = get_gpfn_from_mfn(virt_to_maddr(v->arch.privregs) >>
    1.16 -                                           PAGE_SHIFT);
    1.17 +	c.nat->user_regs = *vcpu_regs(v);
    1.18 + 	c.nat->privregs_pfn = get_gpfn_from_mfn(virt_to_maddr(v->arch.privregs) >>
    1.19 +                                                PAGE_SHIFT);
    1.20  
    1.21  	/* Fill extra regs.  */
    1.22  	for (i = 0; i < 8; i++) {
    1.23 @@ -549,12 +549,12 @@ void arch_getdomaininfo_ctxt(struct vcpu
    1.24  	er->iva = v->arch.iva;
    1.25  }
    1.26  
    1.27 -int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c)
    1.28 +int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
    1.29  {
    1.30  	struct pt_regs *regs = vcpu_regs (v);
    1.31  	struct domain *d = v->domain;
    1.32  	
    1.33 -	*regs = c->user_regs;
    1.34 +	*regs = c.nat->user_regs;
    1.35   	
    1.36   	if (!d->arch.is_vti) {
    1.37   		/* domain runs at PL2/3 */
    1.38 @@ -562,9 +562,9 @@ int arch_set_info_guest(struct vcpu *v, 
    1.39   		regs->ar_rsc |= (2 << 2); /* force PL2/3 */
    1.40   	}
    1.41  
    1.42 -	if (c->flags & VGCF_EXTRA_REGS) {
    1.43 +	if (c.nat->flags & VGCF_EXTRA_REGS) {
    1.44  		int i;
    1.45 -		struct vcpu_extra_regs *er = &c->extra_regs;
    1.46 +		struct vcpu_extra_regs *er = &c.nat->extra_regs;
    1.47  
    1.48  		for (i = 0; i < 8; i++) {
    1.49  			vcpu_set_itr(v, i, er->itrs[i].pte,
     2.1 --- a/xen/arch/powerpc/domain.c	Fri Jan 05 17:34:38 2007 +0000
     2.2 +++ b/xen/arch/powerpc/domain.c	Fri Jan 05 17:34:39 2007 +0000
     2.3 @@ -150,9 +150,9 @@ void vcpu_destroy(struct vcpu *v)
     2.4  {
     2.5  }
     2.6  
     2.7 -int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_t *c)
     2.8 +int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
     2.9  { 
    2.10 -    memcpy(&v->arch.ctxt, &c->user_regs, sizeof(c->user_regs));
    2.11 +    memcpy(&v->arch.ctxt, &c.nat->user_regs, sizeof(c.nat->user_regs));
    2.12  
    2.13      printk("Domain[%d].%d: initializing\n",
    2.14             v->domain->domain_id, v->vcpu_id);
     3.1 --- a/xen/arch/powerpc/domctl.c	Fri Jan 05 17:34:38 2007 +0000
     3.2 +++ b/xen/arch/powerpc/domctl.c	Fri Jan 05 17:34:39 2007 +0000
     3.3 @@ -22,6 +22,7 @@
     3.4  #include <xen/types.h>
     3.5  #include <xen/lib.h>
     3.6  #include <xen/sched.h>
     3.7 +#include <xen/domain.h>
     3.8  #include <xen/guest_access.h>
     3.9  #include <xen/shadow.h>
    3.10  #include <public/xen.h>
    3.11 @@ -29,10 +30,9 @@
    3.12  #include <public/sysctl.h>
    3.13  #include <asm/processor.h>
    3.14  
    3.15 -void arch_getdomaininfo_ctxt(struct vcpu *, vcpu_guest_context_t *);
    3.16 -void arch_getdomaininfo_ctxt(struct vcpu *v, vcpu_guest_context_t *c)
    3.17 +void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
    3.18  { 
    3.19 -    memcpy(&c->user_regs, &v->arch.ctxt, sizeof(struct cpu_user_regs));
    3.20 +    memcpy(&c.nat->user_regs, &v->arch.ctxt, sizeof(struct cpu_user_regs));
    3.21      /* XXX fill in rest of vcpu_guest_context_t */
    3.22  }
    3.23  
     4.1 --- a/xen/arch/x86/domain.c	Fri Jan 05 17:34:38 2007 +0000
     4.2 +++ b/xen/arch/x86/domain.c	Fri Jan 05 17:34:39 2007 +0000
     4.3 @@ -16,6 +16,7 @@
     4.4  #include <xen/lib.h>
     4.5  #include <xen/errno.h>
     4.6  #include <xen/sched.h>
     4.7 +#include <xen/domain.h>
     4.8  #include <xen/smp.h>
     4.9  #include <xen/delay.h>
    4.10  #include <xen/softirq.h>
    4.11 @@ -250,6 +251,69 @@ static void release_compat_l4(struct vcp
    4.12      v->arch.guest_table_user = pagetable_null();
    4.13  }
    4.14  
    4.15 +static inline int may_switch_mode(struct domain *d)
    4.16 +{
    4.17 +    return 1; /* XXX */
    4.18 +}
    4.19 +
    4.20 +int switch_native(struct domain *d)
    4.21 +{
    4.22 +    l1_pgentry_t gdt_l1e;
    4.23 +    unsigned int vcpuid;
    4.24 +
    4.25 +    if ( !d )
    4.26 +        return -EINVAL;
    4.27 +    if ( !may_switch_mode(d) )
    4.28 +        return -EACCES;
    4.29 +    if ( !IS_COMPAT(d) )
    4.30 +        return 0;
    4.31 +
    4.32 +    clear_bit(_DOMF_compat, &d->domain_flags);
    4.33 +    release_arg_xlat_area(d);
    4.34 +
    4.35 +    /* switch gdt */
    4.36 +    gdt_l1e = l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR);
    4.37 +    for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ )
    4.38 +    {
    4.39 +        d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
    4.40 +                                 FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
    4.41 +        if (d->vcpu[vcpuid])
    4.42 +            release_compat_l4(d->vcpu[vcpuid]);
    4.43 +    }
    4.44 +
    4.45 +    return 0;
    4.46 +}
    4.47 +
    4.48 +int switch_compat(struct domain *d)
    4.49 +{
    4.50 +    l1_pgentry_t gdt_l1e;
    4.51 +    unsigned int vcpuid;
    4.52 +
    4.53 +    if ( !d )
    4.54 +        return -EINVAL;
    4.55 +    if ( compat_disabled )
    4.56 +        return -ENOSYS;
    4.57 +    if ( !may_switch_mode(d) )
    4.58 +        return -EACCES;
    4.59 +    if ( IS_COMPAT(d) )
    4.60 +        return 0;
    4.61 +
    4.62 +    set_bit(_DOMF_compat, &d->domain_flags);
    4.63 +
    4.64 +    /* switch gdt */
    4.65 +    gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR);
    4.66 +    for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ )
    4.67 +    {
    4.68 +        d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
    4.69 +                                 FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
    4.70 +        if (d->vcpu[vcpuid]
    4.71 +            && setup_compat_l4(d->vcpu[vcpuid]) != 0)
    4.72 +            return -ENOMEM;
    4.73 +    }
    4.74 +
    4.75 +    return 0;
    4.76 +}
    4.77 +
    4.78  #else
    4.79  #define release_arg_xlat_area(d) ((void)0)
    4.80  #define setup_compat_l4(v) 0
    4.81 @@ -416,43 +480,80 @@ void arch_domain_destroy(struct domain *
    4.82  
    4.83  /* This is called by arch_final_setup_guest and do_boot_vcpu */
    4.84  int arch_set_info_guest(
    4.85 -    struct vcpu *v, struct vcpu_guest_context *c)
    4.86 +    struct vcpu *v, vcpu_guest_context_u c)
    4.87  {
    4.88      struct domain *d = v->domain;
    4.89 +#ifdef CONFIG_COMPAT
    4.90 +#define c(fld) (!IS_COMPAT(d) ? (c.nat->fld) : (c.cmp->fld))
    4.91 +#else
    4.92 +#define c(fld) (c.nat->fld)
    4.93 +#endif
    4.94      unsigned long cr3_pfn = INVALID_MFN;
    4.95 +    unsigned long flags = c(flags);
    4.96      int i, rc;
    4.97  
    4.98      if ( !is_hvm_vcpu(v) )
    4.99      {
   4.100 -        fixup_guest_stack_selector(d, c->user_regs.ss);
   4.101 -        fixup_guest_stack_selector(d, c->kernel_ss);
   4.102 -        fixup_guest_code_selector(d, c->user_regs.cs);
   4.103 +        if ( !IS_COMPAT(d) )
   4.104 +        {
   4.105 +            fixup_guest_stack_selector(d, c.nat->user_regs.ss);
   4.106 +            fixup_guest_stack_selector(d, c.nat->kernel_ss);
   4.107 +            fixup_guest_code_selector(d, c.nat->user_regs.cs);
   4.108 +#ifdef __i386__
   4.109 +            fixup_guest_code_selector(d, c.nat->event_callback_cs);
   4.110 +            fixup_guest_code_selector(d, c.nat->failsafe_callback_cs);
   4.111 +#endif
   4.112  
   4.113 -        if ( CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d) )
   4.114 -        {
   4.115 -            fixup_guest_code_selector(d, c->event_callback_cs);
   4.116 -            fixup_guest_code_selector(d, c->failsafe_callback_cs);
   4.117 +            for ( i = 0; i < 256; i++ )
   4.118 +                fixup_guest_code_selector(d, c.nat->trap_ctxt[i].cs);
   4.119 +
   4.120 +            /* LDT safety checks. */
   4.121 +            if ( ((c.nat->ldt_base & (PAGE_SIZE-1)) != 0) ||
   4.122 +                 (c.nat->ldt_ents > 8192) ||
   4.123 +                 !array_access_ok(c.nat->ldt_base,
   4.124 +                                  c.nat->ldt_ents,
   4.125 +                                  LDT_ENTRY_SIZE) )
   4.126 +                return -EINVAL;
   4.127          }
   4.128 -
   4.129 -        for ( i = 0; i < 256; i++ )
   4.130 -            fixup_guest_code_selector(d, c->trap_ctxt[i].cs);
   4.131 +#ifdef CONFIG_COMPAT
   4.132 +        else
   4.133 +        {
   4.134 +            fixup_guest_stack_selector(d, c.cmp->user_regs.ss);
   4.135 +            fixup_guest_stack_selector(d, c.cmp->kernel_ss);
   4.136 +            fixup_guest_code_selector(d, c.cmp->user_regs.cs);
   4.137 +            fixup_guest_code_selector(d, c.cmp->event_callback_cs);
   4.138 +            fixup_guest_code_selector(d, c.cmp->failsafe_callback_cs);
   4.139  
   4.140 -        /* LDT safety checks. */
   4.141 -        if ( ((c->ldt_base & (PAGE_SIZE-1)) != 0) || 
   4.142 -             (c->ldt_ents > 8192) ||
   4.143 -             !array_access_ok(c->ldt_base, c->ldt_ents, LDT_ENTRY_SIZE) )
   4.144 -            return -EINVAL;
   4.145 +            for ( i = 0; i < 256; i++ )
   4.146 +                fixup_guest_code_selector(d, c.cmp->trap_ctxt[i].cs);
   4.147 +
   4.148 +            /* LDT safety checks. */
   4.149 +            if ( ((c.cmp->ldt_base & (PAGE_SIZE-1)) != 0) ||
   4.150 +                 (c.cmp->ldt_ents > 8192) ||
   4.151 +                 !compat_array_access_ok(c.cmp->ldt_base,
   4.152 +                                         c.cmp->ldt_ents,
   4.153 +                                         LDT_ENTRY_SIZE) )
   4.154 +                return -EINVAL;
   4.155 +        }
   4.156 +#endif
   4.157      }
   4.158  
   4.159      clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
   4.160 -    if ( c->flags & VGCF_i387_valid )
   4.161 +    if ( flags & VGCF_I387_VALID )
   4.162          set_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
   4.163  
   4.164      v->arch.flags &= ~TF_kernel_mode;
   4.165 -    if ( (c->flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ )
   4.166 +    if ( (flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ )
   4.167          v->arch.flags |= TF_kernel_mode;
   4.168  
   4.169 -    memcpy(&v->arch.guest_context, c, sizeof(*c));
   4.170 +    if ( !IS_COMPAT(v->domain) )
   4.171 +        memcpy(&v->arch.guest_context, c.nat, sizeof(*c.nat));
   4.172 +#ifdef CONFIG_COMPAT
   4.173 +    else
   4.174 +    {
   4.175 +        XLAT_vcpu_guest_context(&v->arch.guest_context, c.cmp);
   4.176 +    }
   4.177 +#endif
   4.178  
   4.179      /* Only CR0.TS is modifiable by guest or admin. */
   4.180      v->arch.guest_context.ctrlreg[0] &= X86_CR0_TS;
   4.181 @@ -480,19 +581,34 @@ int arch_set_info_guest(
   4.182      memset(v->arch.guest_context.debugreg, 0,
   4.183             sizeof(v->arch.guest_context.debugreg));
   4.184      for ( i = 0; i < 8; i++ )
   4.185 -        (void)set_debugreg(v, i, c->debugreg[i]);
   4.186 +        (void)set_debugreg(v, i, c(debugreg[i]));
   4.187  
   4.188      if ( v->vcpu_id == 0 )
   4.189 -        d->vm_assist = c->vm_assist;
   4.190 +        d->vm_assist = c(vm_assist);
   4.191  
   4.192      if ( !is_hvm_vcpu(v) )
   4.193      {
   4.194 -        if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 )
   4.195 +        if ( !IS_COMPAT(d) )
   4.196 +            rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents);
   4.197 +#ifdef CONFIG_COMPAT
   4.198 +        else
   4.199 +        {
   4.200 +            unsigned long gdt_frames[ARRAY_SIZE(c.cmp->gdt_frames)];
   4.201 +            unsigned int i, n = (c.cmp->gdt_ents + 511) / 512;
   4.202 +
   4.203 +            if ( n > ARRAY_SIZE(c.cmp->gdt_frames) )
   4.204 +                return -EINVAL;
   4.205 +            for ( i = 0; i < n; ++i )
   4.206 +                gdt_frames[i] = c.cmp->gdt_frames[i];
   4.207 +            rc = (int)set_gdt(v, gdt_frames, c.cmp->gdt_ents);
   4.208 +        }
   4.209 +#endif
   4.210 +        if ( rc != 0 )
   4.211              return rc;
   4.212  
   4.213          if ( !IS_COMPAT(d) )
   4.214          {
   4.215 -            cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c->ctrlreg[3]));
   4.216 +            cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3]));
   4.217  
   4.218              if ( shadow_mode_refcounts(d)
   4.219                   ? !get_page(mfn_to_page(cr3_pfn), d)
   4.220 @@ -510,7 +626,7 @@ int arch_set_info_guest(
   4.221          {
   4.222              l4_pgentry_t *l4tab;
   4.223  
   4.224 -            cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c->ctrlreg[3]));
   4.225 +            cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3]));
   4.226  
   4.227              if ( shadow_mode_refcounts(d)
   4.228                   ? !get_page(mfn_to_page(cr3_pfn), d)
   4.229 @@ -539,6 +655,7 @@ int arch_set_info_guest(
   4.230      update_cr3(v);
   4.231  
   4.232      return 0;
   4.233 +#undef c
   4.234  }
   4.235  
   4.236  long
     5.1 --- a/xen/arch/x86/domctl.c	Fri Jan 05 17:34:38 2007 +0000
     5.2 +++ b/xen/arch/x86/domctl.c	Fri Jan 05 17:34:39 2007 +0000
     5.3 @@ -11,6 +11,7 @@
     5.4  #include <xen/guest_access.h>
     5.5  #include <public/domctl.h>
     5.6  #include <xen/sched.h>
     5.7 +#include <xen/domain.h>
     5.8  #include <xen/event.h>
     5.9  #include <xen/domain_page.h>
    5.10  #include <asm/msr.h>
    5.11 @@ -23,12 +24,21 @@
    5.12  #include <asm/hvm/support.h>
    5.13  #include <asm/processor.h>
    5.14  #include <public/hvm/e820.h>
    5.15 +#ifdef CONFIG_COMPAT
    5.16 +#include <compat/xen.h>
    5.17 +#endif
    5.18  
    5.19 -long arch_do_domctl(
    5.20 +#ifndef COMPAT
    5.21 +#define _long                long
    5.22 +#define copy_from_xxx_offset copy_from_guest_offset
    5.23 +#define copy_to_xxx_offset   copy_to_guest_offset
    5.24 +#endif
    5.25 +
    5.26 +_long arch_do_domctl(
    5.27      struct xen_domctl *domctl,
    5.28      XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
    5.29  {
    5.30 -    long ret = 0;
    5.31 +    _long ret = 0;
    5.32  
    5.33      switch ( domctl->cmd )
    5.34      {
    5.35 @@ -40,7 +50,9 @@ long arch_do_domctl(
    5.36          d = find_domain_by_id(domctl->domain);
    5.37          if ( d != NULL )
    5.38          {
    5.39 -            ret = shadow_domctl(d, &domctl->u.shadow_op, u_domctl);
    5.40 +            ret = shadow_domctl(d,
    5.41 +                                &domctl->u.shadow_op,
    5.42 +                                guest_handle_cast(u_domctl, void));
    5.43              put_domain(d);
    5.44              copy_to_guest(u_domctl, domctl, 1);
    5.45          } 
    5.46 @@ -123,12 +135,12 @@ long arch_do_domctl(
    5.47  
    5.48      case XEN_DOMCTL_getpageframeinfo2:
    5.49      {
    5.50 -#define GPF2_BATCH (PAGE_SIZE / sizeof(long))
    5.51 +#define GPF2_BATCH (PAGE_SIZE / sizeof(_long))
    5.52          int n,j;
    5.53          int num = domctl->u.getpageframeinfo2.num;
    5.54          domid_t dom = domctl->domain;
    5.55          struct domain *d;
    5.56 -        unsigned long *l_arr;
    5.57 +        unsigned _long *l_arr;
    5.58          ret = -ESRCH;
    5.59  
    5.60          if ( unlikely((d = find_domain_by_id(dom)) == NULL) )
    5.61 @@ -148,9 +160,9 @@ long arch_do_domctl(
    5.62          {
    5.63              int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n);
    5.64  
    5.65 -            if ( copy_from_guest_offset(l_arr,
    5.66 -                                        domctl->u.getpageframeinfo2.array,
    5.67 -                                        n, k) )
    5.68 +            if ( copy_from_xxx_offset(l_arr,
    5.69 +                                      domctl->u.getpageframeinfo2.array,
    5.70 +                                      n, k) )
    5.71              {
    5.72                  ret = -EINVAL;
    5.73                  break;
    5.74 @@ -159,13 +171,13 @@ long arch_do_domctl(
    5.75              for ( j = 0; j < k; j++ )
    5.76              {      
    5.77                  struct page_info *page;
    5.78 -                unsigned long mfn = l_arr[j];
    5.79 +                unsigned _long mfn = l_arr[j];
    5.80  
    5.81                  page = mfn_to_page(mfn);
    5.82  
    5.83                  if ( likely(mfn_valid(mfn) && get_page(page, d)) ) 
    5.84                  {
    5.85 -                    unsigned long type = 0;
    5.86 +                    unsigned _long type = 0;
    5.87  
    5.88                      switch( page->u.inuse.type_info & PGT_type_mask )
    5.89                      {
    5.90 @@ -193,8 +205,8 @@ long arch_do_domctl(
    5.91  
    5.92              }
    5.93  
    5.94 -            if ( copy_to_guest_offset(domctl->u.getpageframeinfo2.array,
    5.95 -                                      n, l_arr, k) )
    5.96 +            if ( copy_to_xxx_offset(domctl->u.getpageframeinfo2.array,
    5.97 +                                    n, l_arr, k) )
    5.98              {
    5.99                  ret = -EINVAL;
   5.100                  break;
   5.101 @@ -214,7 +226,7 @@ long arch_do_domctl(
   5.102          int i;
   5.103          struct domain *d = find_domain_by_id(domctl->domain);
   5.104          unsigned long max_pfns = domctl->u.getmemlist.max_pfns;
   5.105 -        unsigned long mfn;
   5.106 +        xen_pfn_t mfn;
   5.107          struct list_head *list_ent;
   5.108  
   5.109          ret = -EINVAL;
   5.110 @@ -229,8 +241,8 @@ long arch_do_domctl(
   5.111              {
   5.112                  mfn = page_to_mfn(list_entry(
   5.113                      list_ent, struct page_info, list));
   5.114 -                if ( copy_to_guest_offset(domctl->u.getmemlist.buffer,
   5.115 -                                          i, &mfn, 1) )
   5.116 +                if ( copy_to_xxx_offset(domctl->u.getmemlist.buffer,
   5.117 +                                        i, &mfn, 1) )
   5.118                  {
   5.119                      ret = -EFAULT;
   5.120                      break;
   5.121 @@ -289,37 +301,68 @@ long arch_do_domctl(
   5.122      return ret;
   5.123  }
   5.124  
   5.125 -void arch_getdomaininfo_ctxt(
   5.126 -    struct vcpu *v, struct vcpu_guest_context *c)
   5.127 +#ifndef COMPAT
   5.128 +void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
   5.129  {
   5.130 -    memcpy(c, &v->arch.guest_context, sizeof(*c));
   5.131 +#ifdef CONFIG_COMPAT
   5.132 +#define c(fld) (!IS_COMPAT(v->domain) ? (c.nat->fld) : (c.cmp->fld))
   5.133 +#else
   5.134 +#define c(fld) (c.nat->fld)
   5.135 +#endif
   5.136 +    unsigned long flags;
   5.137 +
   5.138 +    if ( !IS_COMPAT(v->domain) )
   5.139 +        memcpy(c.nat, &v->arch.guest_context, sizeof(*c.nat));
   5.140 +#ifdef CONFIG_COMPAT
   5.141 +    else
   5.142 +    {
   5.143 +        XLAT_vcpu_guest_context(c.cmp, &v->arch.guest_context);
   5.144 +    }
   5.145 +#endif
   5.146  
   5.147      if ( is_hvm_vcpu(v) )
   5.148      {
   5.149 -        hvm_store_cpu_guest_regs(v, &c->user_regs, c->ctrlreg);
   5.150 +        if ( !IS_COMPAT(v->domain) )
   5.151 +            hvm_store_cpu_guest_regs(v, &c.nat->user_regs, c.nat->ctrlreg);
   5.152 +#ifdef CONFIG_COMPAT
   5.153 +        else
   5.154 +        {
   5.155 +            struct cpu_user_regs user_regs;
   5.156 +            typeof(c.nat->ctrlreg) ctrlreg;
   5.157 +            unsigned i;
   5.158 +
   5.159 +            hvm_store_cpu_guest_regs(v, &user_regs, ctrlreg);
   5.160 +            XLAT_cpu_user_regs(&c.cmp->user_regs, &user_regs);
   5.161 +            for ( i = 0; i < ARRAY_SIZE(c.cmp->ctrlreg); ++i )
   5.162 +                c.cmp->ctrlreg[i] = ctrlreg[i];
   5.163 +        }
   5.164 +#endif
   5.165      }
   5.166      else
   5.167      {
   5.168          /* IOPL privileges are virtualised: merge back into returned eflags. */
   5.169 -        BUG_ON((c->user_regs.eflags & EF_IOPL) != 0);
   5.170 -        c->user_regs.eflags |= v->arch.iopl << 12;
   5.171 +        BUG_ON((c(user_regs.eflags) & EF_IOPL) != 0);
   5.172 +        c(user_regs.eflags |= v->arch.iopl << 12);
   5.173      }
   5.174  
   5.175 -    c->flags = 0;
   5.176 +    flags = 0;
   5.177      if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
   5.178 -        c->flags |= VGCF_i387_valid;
   5.179 +        flags |= VGCF_i387_valid;
   5.180      if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) )
   5.181 -        c->flags |= VGCF_in_kernel;
   5.182 +        flags |= VGCF_in_kernel;
   5.183 +    c(flags = flags);
   5.184  
   5.185      if ( !IS_COMPAT(v->domain) )
   5.186 -        c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
   5.187 +        c.nat->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
   5.188  #ifdef CONFIG_COMPAT
   5.189      else
   5.190 -        c->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
   5.191 +        c.cmp->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
   5.192  #endif
   5.193  
   5.194 -    c->vm_assist = v->domain->vm_assist;
   5.195 +    c(vm_assist = v->domain->vm_assist);
   5.196 +#undef c
   5.197  }
   5.198 +#endif
   5.199  
   5.200  /*
   5.201   * Local variables:
     6.1 --- a/xen/arch/x86/mm/shadow/common.c	Fri Jan 05 17:34:38 2007 +0000
     6.2 +++ b/xen/arch/x86/mm/shadow/common.c	Fri Jan 05 17:34:39 2007 +0000
     6.3 @@ -3260,7 +3260,7 @@ void shadow_mark_dirty(struct domain *d,
     6.4  
     6.5  int shadow_domctl(struct domain *d, 
     6.6                    xen_domctl_shadow_op_t *sc,
     6.7 -                  XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
     6.8 +                  XEN_GUEST_HANDLE(void) u_domctl)
     6.9  {
    6.10      int rc, preempted = 0;
    6.11  
     7.1 --- a/xen/arch/x86/x86_32/traps.c	Fri Jan 05 17:34:38 2007 +0000
     7.2 +++ b/xen/arch/x86/x86_32/traps.c	Fri Jan 05 17:34:39 2007 +0000
     7.3 @@ -193,7 +193,7 @@ unsigned long do_iret(void)
     7.4  
     7.5      /*
     7.6       * Pop, fix up and restore EFLAGS. We fix up in a local staging area
     7.7 -     * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
     7.8 +     * to avoid firing the BUG_ON(IOPL) check in arch_get_info_guest.
     7.9       */
    7.10      if ( unlikely(__copy_from_user(&eflags, (void __user *)regs->esp, 4)) )
    7.11          goto exit_and_crash;
     8.1 --- a/xen/arch/x86/x86_64/Makefile	Fri Jan 05 17:34:38 2007 +0000
     8.2 +++ b/xen/arch/x86/x86_64/Makefile	Fri Jan 05 17:34:39 2007 +0000
     8.3 @@ -5,6 +5,7 @@ obj-y += traps.o
     8.4  
     8.5  obj-$(CONFIG_COMPAT) += compat.o
     8.6  obj-$(CONFIG_COMPAT) += domain.o
     8.7 +obj-$(CONFIG_COMPAT) += domctl.o
     8.8  obj-$(CONFIG_COMPAT) += physdev.o
     8.9  obj-$(CONFIG_COMPAT) += platform_hypercall.o
    8.10  obj-$(CONFIG_COMPAT) += sysctl.o
    8.11 @@ -12,6 +13,7 @@ obj-$(CONFIG_COMPAT) += sysctl.o
    8.12  ifeq ($(CONFIG_COMPAT),y)
    8.13  # extra dependencies
    8.14  compat.o:	../compat.c
    8.15 +domctl.o:	../domctl.c
    8.16  entry.o:	compat/entry.S
    8.17  mm.o:		compat/mm.c
    8.18  physdev.o:	../physdev.c
     9.1 --- a/xen/arch/x86/x86_64/compat/entry.S	Fri Jan 05 17:34:38 2007 +0000
     9.2 +++ b/xen/arch/x86/x86_64/compat/entry.S	Fri Jan 05 17:34:39 2007 +0000
     9.3 @@ -278,8 +278,6 @@ CFIX14:
     9.4  
     9.5  .section .rodata, "a", @progbits
     9.6  
     9.7 -#define compat_domctl domain_crash_synchronous
     9.8 -
     9.9  ENTRY(compat_hypercall_table)
    9.10          .quad compat_set_trap_table     /*  0 */
    9.11          .quad do_mmu_update
    10.1 --- a/xen/arch/x86/x86_64/compat/traps.c	Fri Jan 05 17:34:38 2007 +0000
    10.2 +++ b/xen/arch/x86/x86_64/compat/traps.c	Fri Jan 05 17:34:39 2007 +0000
    10.3 @@ -49,7 +49,7 @@ unsigned int compat_iret(void)
    10.4  
    10.5      /*
    10.6       * Fix up and restore EFLAGS. We fix up in a local staging area
    10.7 -     * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
    10.8 +     * to avoid firing the BUG_ON(IOPL) check in arch_get_info_guest.
    10.9       */
   10.10      if ( unlikely(__get_user(eflags, (u32 __user *)regs->rsp + 3)) )
   10.11          goto exit_and_crash;
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/xen/arch/x86/x86_64/domctl.c	Fri Jan 05 17:34:39 2007 +0000
    11.3 @@ -0,0 +1,111 @@
    11.4 +/******************************************************************************
    11.5 + * Arch-specific compatibility domctl.c
    11.6 + */
    11.7 +
    11.8 +#include <xen/config.h>
    11.9 +#include <compat/domctl.h>
   11.10 +#include <xen/guest_access.h>
   11.11 +#include <asm/shadow.h>
   11.12 +
   11.13 +DEFINE_XEN_GUEST_HANDLE(compat_domctl_t);
   11.14 +#define xen_domctl                     compat_domctl
   11.15 +#define xen_domctl_t                   compat_domctl_t
   11.16 +#define arch_do_domctl(x, h)           arch_compat_domctl(x, _##h)
   11.17 +
   11.18 +static int compat_shadow_domctl(struct domain *d,
   11.19 +                                compat_domctl_shadow_op_t *csc,
   11.20 +                                XEN_GUEST_HANDLE(void) u_domctl)
   11.21 +{
   11.22 +    xen_domctl_shadow_op_t nsc;
   11.23 +    int rc, mode;
   11.24 +
   11.25 +#define XLAT_domctl_shadow_op_HNDL_dirty_bitmap(_d_, _s_) \
   11.26 +    do \
   11.27 +    { \
   11.28 +        if ( (_s_)->op != XEN_DOMCTL_SHADOW_OP_CLEAN \
   11.29 +             && (_s_)->op != XEN_DOMCTL_SHADOW_OP_PEEK ) \
   11.30 +        { \
   11.31 +            set_xen_guest_handle((_d_)->dirty_bitmap, NULL); \
   11.32 +            mode = -1; \
   11.33 +        } \
   11.34 +        else if ( compat_handle_is_null((_s_)->dirty_bitmap) \
   11.35 +                  || (((_s_)->pages - 1) \
   11.36 +                      & (BITS_PER_LONG - COMPAT_BITS_PER_LONG)) \
   11.37 +                     == BITS_PER_LONG - COMPAT_BITS_PER_LONG ) \
   11.38 +        { \
   11.39 +            XEN_GUEST_HANDLE(void) tmp; \
   11.40 +            guest_from_compat_handle(tmp, (_s_)->dirty_bitmap); \
   11.41 +            (_d_)->dirty_bitmap = guest_handle_cast(tmp, ulong); \
   11.42 +            mode = 0; \
   11.43 +        } \
   11.44 +        else if ( (_s_)->pages > COMPAT_ARG_XLAT_SIZE * 8 ) \
   11.45 +        { \
   11.46 +            printk("Cannot translate compatibility mode XEN_DOMCTL_SHADOW_OP_{CLEAN,PEEK} (0x%lX)\n", \
   11.47 +                   (_s_)->pages); \
   11.48 +            return -E2BIG; \
   11.49 +        } \
   11.50 +        else \
   11.51 +        { \
   11.52 +            set_xen_guest_handle((_d_)->dirty_bitmap, \
   11.53 +                                 (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id)); \
   11.54 +            mode = 1; \
   11.55 +        } \
   11.56 +    } while (0)
   11.57 +    XLAT_domctl_shadow_op(&nsc, csc);
   11.58 +#undef XLAT_domctl_shadow_op_HNDL_dirty_bitmap
   11.59 +    rc = shadow_domctl(d, &nsc, u_domctl);
   11.60 +    if ( rc != __HYPERVISOR_domctl )
   11.61 +    {
   11.62 +        BUG_ON(rc > 0);
   11.63 +#define XLAT_domctl_shadow_op_HNDL_dirty_bitmap(_d_, _s_) \
   11.64 +        do \
   11.65 +        { \
   11.66 +            if ( rc == 0 \
   11.67 +                 && mode > 0 \
   11.68 +                 && copy_to_compat((_d_)->dirty_bitmap, \
   11.69 +                                   (unsigned int *)(_s_)->dirty_bitmap.p, \
   11.70 +                                   ((_s_)->pages + COMPAT_BITS_PER_LONG - 1) / COMPAT_BITS_PER_LONG) ) \
   11.71 +                rc = -EFAULT; \
   11.72 +        } while (0)
   11.73 +        XLAT_domctl_shadow_op(csc, &nsc);
   11.74 +#undef XLAT_domctl_shadow_op_HNDL_dirty_bitmap
   11.75 +    }
   11.76 +    return rc;
   11.77 +}
   11.78 +#define xen_domctl_shadow_op           compat_domctl_shadow_op
   11.79 +#define xen_domctl_shadow_op_t         compat_domctl_shadow_op_t
   11.80 +#define shadow_domctl(d, sc, u)        compat_shadow_domctl(d, sc, u)
   11.81 +
   11.82 +#define xen_domctl_ioport_permission   compat_domctl_ioport_permission
   11.83 +#define xen_domctl_ioport_permission_t compat_domctl_ioport_permission_t
   11.84 +
   11.85 +#define xen_domctl_getpageframeinfo    compat_domctl_getpageframeinfo
   11.86 +#define xen_domctl_getpageframeinfo_t  compat_domctl_getpageframeinfo_t
   11.87 +
   11.88 +#define xen_domctl_getpageframeinfo2   compat_domctl_getpageframeinfo2
   11.89 +#define xen_domctl_getpageframeinfo2_t compat_domctl_getpageframeinfo2_t
   11.90 +
   11.91 +#define xen_domctl_getmemlist          compat_domctl_getmemlist
   11.92 +#define xen_domctl_getmemlist_t        compat_domctl_getmemlist_t
   11.93 +#define xen_pfn_t                      compat_pfn_t
   11.94 +
   11.95 +#define xen_domctl_hypercall_init      compat_domctl_hypercall_init
   11.96 +#define xen_domctl_hypercall_init_t    compat_domctl_hypercall_init_t
   11.97 +
   11.98 +#define COMPAT
   11.99 +#define _XEN_GUEST_HANDLE(t)           XEN_GUEST_HANDLE(t)
  11.100 +#define _long                          int
  11.101 +#define copy_from_xxx_offset           copy_from_compat_offset
  11.102 +#define copy_to_xxx_offset             copy_to_compat_offset
  11.103 +
  11.104 +#include "../domctl.c"
  11.105 +
  11.106 +/*
  11.107 + * Local variables:
  11.108 + * mode: C
  11.109 + * c-set-style: "BSD"
  11.110 + * c-basic-offset: 4
  11.111 + * tab-width: 4
  11.112 + * indent-tabs-mode: nil
  11.113 + * End:
  11.114 + */
    12.1 --- a/xen/common/compat/Makefile	Fri Jan 05 17:34:38 2007 +0000
    12.2 +++ b/xen/common/compat/Makefile	Fri Jan 05 17:34:39 2007 +0000
    12.3 @@ -1,4 +1,5 @@
    12.4  obj-y += domain.o
    12.5 +obj-y += domctl.o
    12.6  obj-y += kernel.o
    12.7  obj-y += memory.o
    12.8  obj-y += multicall.o
    12.9 @@ -6,6 +7,7 @@ obj-y += sysctl.o
   12.10  obj-y += xlat.o
   12.11  
   12.12  # extra dependencies
   12.13 +domctl.o:	../domctl.c
   12.14  kernel.o:	../kernel.c
   12.15  multicall.o:	../multicall.c
   12.16  sysctl.o:	../sysctl.c
    13.1 --- a/xen/common/compat/domain.c	Fri Jan 05 17:34:38 2007 +0000
    13.2 +++ b/xen/common/compat/domain.c	Fri Jan 05 17:34:39 2007 +0000
    13.3 @@ -28,7 +28,6 @@ int compat_vcpu_op(int cmd, int vcpuid, 
    13.4      case VCPUOP_initialise:
    13.5      {
    13.6          struct compat_vcpu_guest_context *cmp_ctxt;
    13.7 -        struct vcpu_guest_context *nat_ctxt;
    13.8  
    13.9          if ( (cmp_ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL )
   13.10          {
   13.11 @@ -43,23 +42,13 @@ int compat_vcpu_op(int cmd, int vcpuid, 
   13.12              break;
   13.13          }
   13.14  
   13.15 -        if ( (nat_ctxt = xmalloc(struct vcpu_guest_context)) == NULL )
   13.16 -        {
   13.17 -            rc = -ENOMEM;
   13.18 -            break;
   13.19 -        }
   13.20 -
   13.21 -        memset(nat_ctxt, 0, sizeof(*nat_ctxt));
   13.22 -        XLAT_vcpu_guest_context(nat_ctxt, cmp_ctxt);
   13.23 -        xfree(cmp_ctxt);
   13.24 -
   13.25          LOCK_BIGLOCK(d);
   13.26          rc = -EEXIST;
   13.27          if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
   13.28 -            rc = boot_vcpu(d, vcpuid, nat_ctxt);
   13.29 +            rc = boot_vcpu(d, vcpuid, cmp_ctxt);
   13.30          UNLOCK_BIGLOCK(d);
   13.31  
   13.32 -        xfree(nat_ctxt);
   13.33 +        xfree(cmp_ctxt);
   13.34          break;
   13.35      }
   13.36  
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/xen/common/compat/domctl.c	Fri Jan 05 17:34:39 2007 +0000
    14.3 @@ -0,0 +1,137 @@
    14.4 +/******************************************************************************
    14.5 + * compat/domctl.c
    14.6 + */
    14.7 +
    14.8 +#include <xen/config.h>
    14.9 +#include <compat/domctl.h>
   14.10 +#include <xen/sched.h>
   14.11 +#include <xen/cpumask.h>
   14.12 +#include <asm/uaccess.h>
   14.13 +
   14.14 +DEFINE_XEN_GUEST_HANDLE(compat_domctl_t);
   14.15 +#define xen_domctl                     compat_domctl
   14.16 +#define xen_domctl_t                   compat_domctl_t
   14.17 +#define do_domctl(h)                   compat_domctl(_##h)
   14.18 +#define arch_do_domctl(x, h)           arch_compat_domctl(x, _##h)
   14.19 +
   14.20 +#define xen_domain_handle_t            compat_domain_handle_t
   14.21 +
   14.22 +#define xen_domctl_vcpucontext         compat_domctl_vcpucontext
   14.23 +#define xen_domctl_vcpucontext_t       compat_domctl_vcpucontext_t
   14.24 +
   14.25 +#define xen_domctl_createdomain        compat_domctl_createdomain
   14.26 +#define xen_domctl_createdomain_t      compat_domctl_createdomain_t
   14.27 +
   14.28 +#define xen_domctl_max_vcpus           compat_domctl_max_vcpus
   14.29 +#define xen_domctl_max_vcpus_t         compat_domctl_max_vcpus_t
   14.30 +
   14.31 +static void cpumask_to_compat_ctl_cpumap(
   14.32 +    struct compat_ctl_cpumap *cmpctl_cpumap, cpumask_t *cpumask)
   14.33 +{
   14.34 +    unsigned int guest_bytes, copy_bytes, i;
   14.35 +    /*static const*/ uint8_t zero = 0;
   14.36 +
   14.37 +    if ( compat_handle_is_null(cmpctl_cpumap->bitmap) )
   14.38 +        return;
   14.39 +
   14.40 +    guest_bytes = (cmpctl_cpumap->nr_cpus + 7) / 8;
   14.41 +    copy_bytes  = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8);
   14.42 +
   14.43 +    copy_to_compat(cmpctl_cpumap->bitmap,
   14.44 +                   (uint8_t *)cpus_addr(*cpumask),
   14.45 +                   copy_bytes);
   14.46 +
   14.47 +    for ( i = copy_bytes; i < guest_bytes; i++ )
   14.48 +        copy_to_compat_offset(cmpctl_cpumap->bitmap, i, &zero, 1);
   14.49 +}
   14.50 +#define cpumask_to_xenctl_cpumap       cpumask_to_compat_ctl_cpumap
   14.51 +
   14.52 +void compat_ctl_cpumap_to_cpumask(
   14.53 +    cpumask_t *cpumask, struct compat_ctl_cpumap *cmpctl_cpumap)
   14.54 +{
   14.55 +    unsigned int guest_bytes, copy_bytes;
   14.56 +
   14.57 +    guest_bytes = (cmpctl_cpumap->nr_cpus + 7) / 8;
   14.58 +    copy_bytes  = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8);
   14.59 +
   14.60 +    cpus_clear(*cpumask);
   14.61 +
   14.62 +    if ( compat_handle_is_null(cmpctl_cpumap->bitmap) )
   14.63 +        return;
   14.64 +
   14.65 +    copy_from_compat((uint8_t *)cpus_addr(*cpumask),
   14.66 +                     cmpctl_cpumap->bitmap,
   14.67 +                     copy_bytes);
   14.68 +}
   14.69 +#define xenctl_cpumap_to_cpumask       compat_ctl_cpumap_to_cpumask
   14.70 +
   14.71 +#define xen_domctl_vcpuaffinity        compat_domctl_vcpuaffinity
   14.72 +#define xen_domctl_vcpuaffinity_t      compat_domctl_vcpuaffinity_t
   14.73 +
   14.74 +static int compat_sched_adjust(struct domain *d,
   14.75 +                               struct compat_domctl_scheduler_op *cop)
   14.76 +{
   14.77 +    struct xen_domctl_scheduler_op nop;
   14.78 +    int ret;
   14.79 +    enum XLAT_domctl_scheduler_op_u u;
   14.80 +
   14.81 +    switch ( cop->sched_id )
   14.82 +    {
   14.83 +    case XEN_SCHEDULER_SEDF:   u = XLAT_domctl_scheduler_op_u_sedf;   break;
   14.84 +    case XEN_SCHEDULER_CREDIT: u = XLAT_domctl_scheduler_op_u_credit; break;
   14.85 +    default: return -EINVAL;
   14.86 +    }
   14.87 +    XLAT_domctl_scheduler_op(&nop, cop);
   14.88 +    ret = sched_adjust(d, &nop);
   14.89 +    XLAT_domctl_scheduler_op(cop, &nop);
   14.90 +
   14.91 +    return ret;
   14.92 +}
   14.93 +#define sched_adjust(d, op)            compat_sched_adjust(d, op)
   14.94 +#define xen_domctl_scheduler_op        compat_domctl_scheduler_op
   14.95 +#define xen_domctl_scheduler_op_t      compat_domctl_scheduler_op_t
   14.96 +
   14.97 +#define xen_domctl_getdomaininfo       compat_domctl_getdomaininfo
   14.98 +#define xen_domctl_getdomaininfo_t     compat_domctl_getdomaininfo_t
   14.99 +#define getdomaininfo(d, i)            compat_getdomaininfo(d, i)
  14.100 +
  14.101 +#define xen_domctl_getvcpuinfo         compat_domctl_getvcpuinfo
  14.102 +#define xen_domctl_getvcpuinfo_t       compat_domctl_getvcpuinfo_t
  14.103 +
  14.104 +#define xen_domctl_max_mem             compat_domctl_max_mem
  14.105 +#define xen_domctl_max_mem_t           compat_domctl_max_mem_t
  14.106 +
  14.107 +#define xen_domctl_setdomainhandle     compat_domctl_setdomainhandle
  14.108 +#define xen_domctl_setdomainhandle_t   compat_domctl_setdomainhandle_t
  14.109 +
  14.110 +#define xen_domctl_setdebugging        compat_domctl_setdebugging
  14.111 +#define xen_domctl_setdebugging_t      compat_domctl_setdebugging_t
  14.112 +
  14.113 +#define xen_domctl_irq_permission      compat_domctl_irq_permission
  14.114 +#define xen_domctl_irq_permission_t    compat_domctl_irq_permission_t
  14.115 +
  14.116 +#define xen_domctl_iomem_permission    compat_domctl_iomem_permission
  14.117 +#define xen_domctl_iomem_permission_t  compat_domctl_iomem_permission_t
  14.118 +
  14.119 +#define xen_domctl_settimeoffset       compat_domctl_settimeoffset
  14.120 +#define xen_domctl_settimeoffset_t     compat_domctl_settimeoffset_t
  14.121 +
  14.122 +#define COMPAT
  14.123 +#define _XEN_GUEST_HANDLE(t)           XEN_GUEST_HANDLE(t)
  14.124 +#define _u_domctl                      u_domctl
  14.125 +//#undef guest_handle_cast
  14.126 +//#define guest_handle_cast              compat_handle_cast
  14.127 +//#define copy_to_xxx_offset             copy_to_compat_offset
  14.128 +typedef int ret_t;
  14.129 +
  14.130 +#include "../domctl.c"
  14.131 +
  14.132 +/*
  14.133 + * Local variables:
  14.134 + * mode: C
  14.135 + * c-set-style: "BSD"
  14.136 + * c-basic-offset: 4
  14.137 + * tab-width: 4
  14.138 + * indent-tabs-mode: nil
  14.139 + * End:
  14.140 + */
    15.1 --- a/xen/common/compat/sysctl.c	Fri Jan 05 17:34:38 2007 +0000
    15.2 +++ b/xen/common/compat/sysctl.c	Fri Jan 05 17:34:39 2007 +0000
    15.3 @@ -40,13 +40,6 @@ static int compat_tb_control(struct comp
    15.4  #define xen_sysctl_sched_id            compat_sysctl_sched_id
    15.5  #define xen_sysctl_sched_id_t          compat_sysctl_sched_id_t
    15.6  
    15.7 -static void compat_getdomaininfo(struct domain *d, struct compat_domctl_getdomaininfo *ci)
    15.8 -{
    15.9 -    struct xen_domctl_getdomaininfo ni;
   15.10 -
   15.11 -    getdomaininfo(d, &ni);
   15.12 -    XLAT_domctl_getdomaininfo(ci, &ni);
   15.13 -}
   15.14  #define xen_sysctl_getdomaininfolist   compat_sysctl_getdomaininfolist
   15.15  #define xen_sysctl_getdomaininfolist_t compat_sysctl_getdomaininfolist_t
   15.16  #define xen_domctl_getdomaininfo       compat_domctl_getdomaininfo
    16.1 --- a/xen/common/domain.c	Fri Jan 05 17:34:38 2007 +0000
    16.2 +++ b/xen/common/domain.c	Fri Jan 05 17:34:39 2007 +0000
    16.3 @@ -26,6 +26,9 @@
    16.4  #include <asm/debugger.h>
    16.5  #include <public/sched.h>
    16.6  #include <public/vcpu.h>
    16.7 +#ifdef CONFIG_COMPAT
    16.8 +#include <compat/domctl.h>
    16.9 +#endif
   16.10  
   16.11  /* Both these structures are protected by the domlist_lock. */
   16.12  DEFINE_RWLOCK(domlist_lock);
   16.13 @@ -451,32 +454,64 @@ void domain_unpause_by_systemcontroller(
   16.14   * the userspace dom0 domain builder.
   16.15   */
   16.16  int set_info_guest(struct domain *d,
   16.17 -                   xen_domctl_vcpucontext_t *vcpucontext)
   16.18 +                   xen_domctl_vcpucontext_u vcpucontext)
   16.19  {
   16.20      int rc = 0;
   16.21 -    struct vcpu_guest_context *c = NULL;
   16.22 -    unsigned long vcpu = vcpucontext->vcpu;
   16.23 +    vcpu_guest_context_u c;
   16.24 +#ifdef CONFIG_COMPAT
   16.25 +    CHECK_FIELD(domctl_vcpucontext, vcpu);
   16.26 +#endif
   16.27 +    unsigned long vcpu = vcpucontext.nat->vcpu;
   16.28      struct vcpu *v;
   16.29  
   16.30      if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
   16.31          return -EINVAL;
   16.32      
   16.33 -    if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
   16.34 +#ifdef CONFIG_COMPAT
   16.35 +    BUILD_BUG_ON(sizeof(struct vcpu_guest_context)
   16.36 +                 < sizeof(struct compat_vcpu_guest_context));
   16.37 +#endif
   16.38 +    if ( (c.nat = xmalloc(struct vcpu_guest_context)) == NULL )
   16.39          return -ENOMEM;
   16.40  
   16.41      domain_pause(d);
   16.42  
   16.43 -    rc = -EFAULT;
   16.44 -    if ( copy_from_guest(c, vcpucontext->ctxt, 1) == 0 )
   16.45 +    if ( !IS_COMPAT(v->domain) )
   16.46 +    {
   16.47 +        if ( !IS_COMPAT(current->domain)
   16.48 +             ? copy_from_guest(c.nat, vcpucontext.nat->ctxt, 1)
   16.49 +#ifndef CONFIG_COMPAT
   16.50 +             : 0 )
   16.51 +#else
   16.52 +             : copy_from_guest(c.nat,
   16.53 +                               compat_handle_cast(vcpucontext.cmp->ctxt,
   16.54 +                                                  void),
   16.55 +                               1) )
   16.56 +#endif
   16.57 +            rc = -EFAULT;
   16.58 +    }
   16.59 +#ifdef CONFIG_COMPAT
   16.60 +    else
   16.61 +    {
   16.62 +        if ( !IS_COMPAT(current->domain)
   16.63 +             ? copy_from_guest(c.cmp,
   16.64 +                               guest_handle_cast(vcpucontext.nat->ctxt, void),
   16.65 +                               1)
   16.66 +             : copy_from_compat(c.cmp, vcpucontext.cmp->ctxt, 1) )
   16.67 +            rc = -EFAULT;
   16.68 +    }
   16.69 +#endif
   16.70 +
   16.71 +    if ( rc == 0 )
   16.72          rc = arch_set_info_guest(v, c);
   16.73  
   16.74      domain_unpause(d);
   16.75  
   16.76 -    xfree(c);
   16.77 +    xfree(c.nat);
   16.78      return rc;
   16.79  }
   16.80  
   16.81 -int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt) 
   16.82 +int boot_vcpu(struct domain *d, int vcpuid, vcpu_guest_context_u ctxt)
   16.83  {
   16.84      struct vcpu *v = d->vcpu[vcpuid];
   16.85  
    17.1 --- a/xen/common/domctl.c	Fri Jan 05 17:34:38 2007 +0000
    17.2 +++ b/xen/common/domctl.c	Fri Jan 05 17:34:39 2007 +0000
    17.3 @@ -18,14 +18,22 @@
    17.4  #include <xen/console.h>
    17.5  #include <xen/iocap.h>
    17.6  #include <xen/guest_access.h>
    17.7 +#ifdef CONFIG_COMPAT
    17.8 +#include <xen/compat.h>
    17.9 +#endif
   17.10  #include <asm/current.h>
   17.11  #include <public/domctl.h>
   17.12  #include <acm/acm_hooks.h>
   17.13  
   17.14 -extern long arch_do_domctl(
   17.15 +#ifndef COMPAT
   17.16 +typedef long ret_t;
   17.17 +#define copy_to_xxx_offset copy_to_guest_offset
   17.18 +#endif
   17.19 +
   17.20 +extern ret_t arch_do_domctl(
   17.21      struct xen_domctl *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
   17.22 -extern void arch_getdomaininfo_ctxt(
   17.23 -    struct vcpu *, struct vcpu_guest_context *);
   17.24 +
   17.25 +#ifndef COMPAT
   17.26  
   17.27  void cpumask_to_xenctl_cpumap(
   17.28      struct xenctl_cpumap *xenctl_cpumap, cpumask_t *cpumask)
   17.29 @@ -65,6 +73,8 @@ void xenctl_cpumap_to_cpumask(
   17.30                      copy_bytes);
   17.31  }
   17.32  
   17.33 +#endif /* COMPAT */
   17.34 +
   17.35  static inline int is_free_domid(domid_t dom)
   17.36  {
   17.37      struct domain *d;
   17.38 @@ -169,9 +179,9 @@ static unsigned int default_vcpu0_locati
   17.39      return cpu;
   17.40  }
   17.41  
   17.42 -long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
   17.43 +ret_t do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
   17.44  {
   17.45 -    long ret = 0;
   17.46 +    ret_t ret = 0;
   17.47      struct xen_domctl curop, *op = &curop;
   17.48      void *ssid = NULL; /* save security ptr between pre and post/fail hooks */
   17.49      static DEFINE_SPINLOCK(domctl_lock);
   17.50 @@ -283,11 +293,36 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   17.51          if ( (d = domain_create(dom, domcr_flags)) == NULL )
   17.52              break;
   17.53  
   17.54 +        ret = 0;
   17.55 +        switch ( (op->u.createdomain.flags >> XEN_DOMCTL_CDF_WORDSIZE_SHIFT)
   17.56 +                 & XEN_DOMCTL_CDF_WORDSIZE_MASK )
   17.57 +        {
   17.58 +        case 0:
   17.59 +            if ( !IS_COMPAT(current->domain) )
   17.60 +                op->u.createdomain.flags |= BITS_PER_LONG
   17.61 +                                            << XEN_DOMCTL_CDF_WORDSIZE_SHIFT;
   17.62 +#ifdef CONFIG_COMPAT
   17.63 +            else
   17.64 +            {
   17.65 +                op->u.createdomain.flags |= COMPAT_BITS_PER_LONG
   17.66 +                                            << XEN_DOMCTL_CDF_WORDSIZE_SHIFT;
   17.67 +        case COMPAT_BITS_PER_LONG:
   17.68 +                ret = switch_compat(d);
   17.69 +            }
   17.70 +#endif
   17.71 +            break;
   17.72 +        case BITS_PER_LONG:
   17.73 +            break;
   17.74 +        default:
   17.75 +            ret = -EINVAL;
   17.76 +            break;
   17.77 +        }
   17.78 +        if ( ret )
   17.79 +            break;
   17.80 +
   17.81          memcpy(d->handle, op->u.createdomain.handle,
   17.82                 sizeof(xen_domain_handle_t));
   17.83  
   17.84 -        ret = 0;
   17.85 -
   17.86          op->domain = d->domain_id;
   17.87          if ( copy_to_guest(u_domctl, op, 1) )
   17.88              ret = -EFAULT;
   17.89 @@ -446,7 +481,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   17.90  
   17.91      case XEN_DOMCTL_getvcpucontext:
   17.92      { 
   17.93 -        struct vcpu_guest_context *c;
   17.94 +        vcpu_guest_context_u       c;
   17.95          struct domain             *d;
   17.96          struct vcpu               *v;
   17.97  
   17.98 @@ -466,23 +501,48 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
   17.99          if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
  17.100              goto getvcpucontext_out;
  17.101  
  17.102 +#ifdef CONFIG_COMPAT
  17.103 +        BUILD_BUG_ON(sizeof(struct vcpu_guest_context)
  17.104 +                     < sizeof(struct compat_vcpu_guest_context));
  17.105 +#endif
  17.106          ret = -ENOMEM;
  17.107 -        if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
  17.108 +        if ( (c.nat = xmalloc(struct vcpu_guest_context)) == NULL )
  17.109              goto getvcpucontext_out;
  17.110  
  17.111          if ( v != current )
  17.112              vcpu_pause(v);
  17.113  
  17.114 -        arch_getdomaininfo_ctxt(v,c);
  17.115 +        arch_get_info_guest(v, c);
  17.116          ret = 0;
  17.117  
  17.118          if ( v != current )
  17.119              vcpu_unpause(v);
  17.120  
  17.121 -        if ( copy_to_guest(op->u.vcpucontext.ctxt, c, 1) )
  17.122 -            ret = -EFAULT;
  17.123 +        if ( !IS_COMPAT(v->domain) )
  17.124 +        {
  17.125 +#ifndef COMPAT
  17.126 +            if ( copy_to_guest(op->u.vcpucontext.ctxt, c.nat, 1) )
  17.127 +#else
  17.128 +            if ( copy_to_guest(compat_handle_cast(op->u.vcpucontext.ctxt,
  17.129 +                                                  void),
  17.130 +                               c.nat, 1) )
  17.131 +#endif
  17.132 +                ret = -EFAULT;
  17.133 +        }
  17.134 +#ifdef CONFIG_COMPAT
  17.135 +        else
  17.136 +        {
  17.137 +#ifndef COMPAT
  17.138 +            if ( copy_to_guest(guest_handle_cast(op->u.vcpucontext.ctxt, void),
  17.139 +                               c.cmp, 1) )
  17.140 +#else
  17.141 +            if ( copy_to_compat(op->u.vcpucontext.ctxt, c.cmp, 1) )
  17.142 +#endif
  17.143 +                ret = -EFAULT;
  17.144 +        }
  17.145 +#endif
  17.146  
  17.147 -        xfree(c);
  17.148 +        xfree(c.nat);
  17.149  
  17.150          if ( copy_to_guest(u_domctl, op, 1) )
  17.151              ret = -EFAULT;
  17.152 @@ -646,6 +706,16 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
  17.153      }
  17.154      break;
  17.155  
  17.156 +#ifdef CONFIG_COMPAT
  17.157 +    case XEN_DOMCTL_set_compat:
  17.158 +        ret = switch_compat(find_domain_by_id(op->domain));
  17.159 +        break;
  17.160 +
  17.161 +    case XEN_DOMCTL_set_native:
  17.162 +        ret = switch_native(find_domain_by_id(op->domain));
  17.163 +        break;
  17.164 +#endif
  17.165 +
  17.166      default:
  17.167          ret = arch_do_domctl(op, u_domctl);
  17.168          break;
    18.1 --- a/xen/common/schedule.c	Fri Jan 05 17:34:38 2007 +0000
    18.2 +++ b/xen/common/schedule.c	Fri Jan 05 17:34:39 2007 +0000
    18.3 @@ -33,8 +33,6 @@
    18.4  #include <xen/multicall.h>
    18.5  #include <public/sched.h>
    18.6  
    18.7 -extern void arch_getdomaininfo_ctxt(struct vcpu *,
    18.8 -                                    struct vcpu_guest_context *);
    18.9  /* opt_sched: scheduler - default to credit */
   18.10  static char opt_sched[10] = "credit";
   18.11  string_param("sched", opt_sched);
    19.1 --- a/xen/include/asm-x86/shadow.h	Fri Jan 05 17:34:38 2007 +0000
    19.2 +++ b/xen/include/asm-x86/shadow.h	Fri Jan 05 17:34:39 2007 +0000
    19.3 @@ -192,7 +192,7 @@ int shadow_enable(struct domain *d, u32 
    19.4   * manipulate the log-dirty bitmap. */
    19.5  int shadow_domctl(struct domain *d, 
    19.6                    xen_domctl_shadow_op_t *sc,
    19.7 -                  XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
    19.8 +                  XEN_GUEST_HANDLE(void) u_domctl);
    19.9  
   19.10  /* Call when destroying a domain */
   19.11  void shadow_teardown(struct domain *d);
    20.1 --- a/xen/include/public/domctl.h	Fri Jan 05 17:34:38 2007 +0000
    20.2 +++ b/xen/include/public/domctl.h	Fri Jan 05 17:34:39 2007 +0000
    20.3 @@ -53,6 +53,8 @@ struct xen_domctl_createdomain {
    20.4   /* Is this an HVM guest (as opposed to a PV guest)? */
    20.5  #define _XEN_DOMCTL_CDF_hvm_guest 0
    20.6  #define XEN_DOMCTL_CDF_hvm_guest  (1U<<_XEN_DOMCTL_CDF_hvm_guest)
    20.7 +#define XEN_DOMCTL_CDF_WORDSIZE_MASK 255
    20.8 +#define XEN_DOMCTL_CDF_WORDSIZE_SHIFT 24
    20.9      uint32_t flags;
   20.10  };
   20.11  typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
   20.12 @@ -392,6 +394,9 @@ struct xen_domctl_real_mode_area {
   20.13  typedef struct xen_domctl_real_mode_area xen_domctl_real_mode_area_t;
   20.14  DEFINE_XEN_GUEST_HANDLE(xen_domctl_real_mode_area_t);
   20.15  
   20.16 +#define XEN_DOMCTL_set_compat        42
   20.17 +#define XEN_DOMCTL_set_native        43
   20.18 +
   20.19  struct xen_domctl {
   20.20      uint32_t cmd;
   20.21      uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
    21.1 --- a/xen/include/xen/compat.h	Fri Jan 05 17:34:38 2007 +0000
    21.2 +++ b/xen/include/xen/compat.h	Fri Jan 05 17:34:39 2007 +0000
    21.3 @@ -166,6 +166,9 @@ void xlat_start_info(struct start_info *
    21.4  struct vcpu_runstate_info;
    21.5  void xlat_vcpu_runstate_info(struct vcpu_runstate_info *);
    21.6  
    21.7 +int switch_compat(struct domain *);
    21.8 +int switch_native(struct domain *);
    21.9 +
   21.10  #define BITS_PER_GUEST_LONG(d) (!IS_COMPAT(d) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG)
   21.11  
   21.12  #else
    22.1 --- a/xen/include/xen/domain.h	Fri Jan 05 17:34:38 2007 +0000
    22.2 +++ b/xen/include/xen/domain.h	Fri Jan 05 17:34:39 2007 +0000
    22.3 @@ -2,10 +2,15 @@
    22.4  #ifndef __XEN_DOMAIN_H__
    22.5  #define __XEN_DOMAIN_H__
    22.6  
    22.7 +typedef union {
    22.8 +    struct vcpu_guest_context *nat;
    22.9 +    struct compat_vcpu_guest_context *cmp;
   22.10 +} vcpu_guest_context_u __attribute__((__transparent_union__));
   22.11 +
   22.12  struct vcpu *alloc_vcpu(
   22.13      struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
   22.14  int boot_vcpu(
   22.15 -    struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt);
   22.16 +    struct domain *d, int vcpuid, vcpu_guest_context_u ctxt);
   22.17  struct vcpu *alloc_idle_vcpu(unsigned int cpu_id);
   22.18  
   22.19  struct domain *alloc_domain(domid_t domid);
   22.20 @@ -14,6 +19,9 @@ void free_domain(struct domain *d);
   22.21  struct xen_domctl_getdomaininfo;
   22.22  void getdomaininfo(
   22.23      struct domain *d, struct xen_domctl_getdomaininfo *info);
   22.24 +struct compat_domctl_getdomaininfo;
   22.25 +void compat_getdomaininfo(
   22.26 +    struct domain *d, struct compat_domctl_getdomaininfo *info);
   22.27  
   22.28  /*
   22.29   * Arch-specifics.
   22.30 @@ -37,7 +45,8 @@ int arch_domain_create(struct domain *d)
   22.31  
   22.32  void arch_domain_destroy(struct domain *d);
   22.33  
   22.34 -int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c);
   22.35 +int arch_set_info_guest(struct vcpu *, vcpu_guest_context_u);
   22.36 +void arch_get_info_guest(struct vcpu *, vcpu_guest_context_u);
   22.37  
   22.38  void domain_relinquish_resources(struct domain *d);
   22.39  
    23.1 --- a/xen/include/xen/sched.h	Fri Jan 05 17:34:38 2007 +0000
    23.2 +++ b/xen/include/xen/sched.h	Fri Jan 05 17:34:39 2007 +0000
    23.3 @@ -275,7 +275,13 @@ int construct_dom0(
    23.4      unsigned long image_start, unsigned long image_len, 
    23.5      unsigned long initrd_start, unsigned long initrd_len,
    23.6      char *cmdline);
    23.7 -int set_info_guest(struct domain *d, xen_domctl_vcpucontext_t *);
    23.8 +
    23.9 +typedef union {
   23.10 +    struct xen_domctl_vcpucontext *nat;
   23.11 +    struct compat_domctl_vcpucontext *cmp;
   23.12 +} xen_domctl_vcpucontext_u __attribute__((__transparent_union__));
   23.13 +
   23.14 +int set_info_guest(struct domain *d, xen_domctl_vcpucontext_u);
   23.15  
   23.16  struct domain *find_domain_by_id(domid_t dom);
   23.17  void domain_destroy(struct domain *d);
    24.1 --- a/xen/include/xlat.lst	Fri Jan 05 17:34:38 2007 +0000
    24.2 +++ b/xen/include/xlat.lst	Fri Jan 05 17:34:39 2007 +0000
    24.3 @@ -11,7 +11,9 @@
    24.4  !	vcpu_guest_context		arch-x86/xen.h
    24.5  ?	acm_getdecision			acm_ops.h
    24.6  !	ctl_cpumap			domctl.h
    24.7 -!	domctl_getdomaininfo		domctl.h
    24.8 +!	domctl_scheduler_op		domctl.h
    24.9 +!	domctl_shadow_op		domctl.h
   24.10 +!	domctl_shadow_op_stats		domctl.h
   24.11  ?	evtchn_alloc_unbound		event_channel.h
   24.12  ?	evtchn_bind_interdomain		event_channel.h
   24.13  ?	evtchn_bind_ipi			event_channel.h