# HG changeset patch
# User Emmanuel Ackaouy <ack@xxxxxxxxxxxxx>
# Date 1168018479 0
# Node ID 5442b2458e1b2d07e6ae06ebbbc1071c8fd544cb
# Parent d80684d19ef4abff8658d762be4303fe2cfe01d0
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@xxxxxxxxxx>
---
xen/arch/ia64/xen/domain.c | 20 ++--
xen/arch/powerpc/domain.c | 4
xen/arch/powerpc/domctl.c | 6 -
xen/arch/x86/domain.c | 171 +++++++++++++++++++++++++++++++------
xen/arch/x86/domctl.c | 107 ++++++++++++++++-------
xen/arch/x86/mm/shadow/common.c | 2
xen/arch/x86/x86_32/traps.c | 2
xen/arch/x86/x86_64/Makefile | 2
xen/arch/x86/x86_64/compat/entry.S | 2
xen/arch/x86/x86_64/compat/traps.c | 2
xen/arch/x86/x86_64/domctl.c | 111 ++++++++++++++++++++++++
xen/common/compat/Makefile | 2
xen/common/compat/domain.c | 15 ---
xen/common/compat/domctl.c | 137 +++++++++++++++++++++++++++++
xen/common/compat/sysctl.c | 7 -
xen/common/domain.c | 51 +++++++++--
xen/common/domctl.c | 98 ++++++++++++++++++---
xen/common/schedule.c | 2
xen/include/asm-x86/shadow.h | 2
xen/include/public/domctl.h | 5 +
xen/include/xen/compat.h | 3
xen/include/xen/domain.h | 13 ++
xen/include/xen/sched.h | 8 +
xen/include/xlat.lst | 4
24 files changed, 648 insertions(+), 128 deletions(-)
diff -r d80684d19ef4 -r 5442b2458e1b xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/arch/ia64/xen/domain.c Fri Jan 05 17:34:39 2007 +0000
@@ -522,14 +522,14 @@ void arch_domain_destroy(struct domain *
deallocate_rid_range(d);
}
-void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c)
+void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
{
int i;
- struct vcpu_extra_regs *er = &c->extra_regs;
-
- c->user_regs = *vcpu_regs (v);
- c->privregs_pfn = get_gpfn_from_mfn(virt_to_maddr(v->arch.privregs) >>
- PAGE_SHIFT);
+ struct vcpu_extra_regs *er = &c.nat->extra_regs;
+
+ c.nat->user_regs = *vcpu_regs(v);
+ c.nat->privregs_pfn = get_gpfn_from_mfn(virt_to_maddr(v->arch.privregs)
>>
+ PAGE_SHIFT);
/* Fill extra regs. */
for (i = 0; i < 8; i++) {
@@ -549,12 +549,12 @@ void arch_getdomaininfo_ctxt(struct vcpu
er->iva = v->arch.iva;
}
-int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c)
+int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
{
struct pt_regs *regs = vcpu_regs (v);
struct domain *d = v->domain;
- *regs = c->user_regs;
+ *regs = c.nat->user_regs;
if (!d->arch.is_vti) {
/* domain runs at PL2/3 */
@@ -562,9 +562,9 @@ int arch_set_info_guest(struct vcpu *v,
regs->ar_rsc |= (2 << 2); /* force PL2/3 */
}
- if (c->flags & VGCF_EXTRA_REGS) {
+ if (c.nat->flags & VGCF_EXTRA_REGS) {
int i;
- struct vcpu_extra_regs *er = &c->extra_regs;
+ struct vcpu_extra_regs *er = &c.nat->extra_regs;
for (i = 0; i < 8; i++) {
vcpu_set_itr(v, i, er->itrs[i].pte,
diff -r d80684d19ef4 -r 5442b2458e1b xen/arch/powerpc/domain.c
--- a/xen/arch/powerpc/domain.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/arch/powerpc/domain.c Fri Jan 05 17:34:39 2007 +0000
@@ -150,9 +150,9 @@ void vcpu_destroy(struct vcpu *v)
{
}
-int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_t *c)
+int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c)
{
- memcpy(&v->arch.ctxt, &c->user_regs, sizeof(c->user_regs));
+ memcpy(&v->arch.ctxt, &c.nat->user_regs, sizeof(c.nat->user_regs));
printk("Domain[%d].%d: initializing\n",
v->domain->domain_id, v->vcpu_id);
diff -r d80684d19ef4 -r 5442b2458e1b xen/arch/powerpc/domctl.c
--- a/xen/arch/powerpc/domctl.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/arch/powerpc/domctl.c Fri Jan 05 17:34:39 2007 +0000
@@ -22,6 +22,7 @@
#include <xen/types.h>
#include <xen/lib.h>
#include <xen/sched.h>
+#include <xen/domain.h>
#include <xen/guest_access.h>
#include <xen/shadow.h>
#include <public/xen.h>
@@ -29,10 +30,9 @@
#include <public/sysctl.h>
#include <asm/processor.h>
-void arch_getdomaininfo_ctxt(struct vcpu *, vcpu_guest_context_t *);
-void arch_getdomaininfo_ctxt(struct vcpu *v, vcpu_guest_context_t *c)
+void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
{
- memcpy(&c->user_regs, &v->arch.ctxt, sizeof(struct cpu_user_regs));
+ memcpy(&c.nat->user_regs, &v->arch.ctxt, sizeof(struct cpu_user_regs));
/* XXX fill in rest of vcpu_guest_context_t */
}
diff -r d80684d19ef4 -r 5442b2458e1b xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/arch/x86/domain.c Fri Jan 05 17:34:39 2007 +0000
@@ -16,6 +16,7 @@
#include <xen/lib.h>
#include <xen/errno.h>
#include <xen/sched.h>
+#include <xen/domain.h>
#include <xen/smp.h>
#include <xen/delay.h>
#include <xen/softirq.h>
@@ -250,6 +251,69 @@ static void release_compat_l4(struct vcp
v->arch.guest_table_user = pagetable_null();
}
+static inline int may_switch_mode(struct domain *d)
+{
+ return 1; /* XXX */
+}
+
+int switch_native(struct domain *d)
+{
+ l1_pgentry_t gdt_l1e;
+ unsigned int vcpuid;
+
+ if ( !d )
+ return -EINVAL;
+ if ( !may_switch_mode(d) )
+ return -EACCES;
+ if ( !IS_COMPAT(d) )
+ return 0;
+
+ clear_bit(_DOMF_compat, &d->domain_flags);
+ release_arg_xlat_area(d);
+
+ /* switch gdt */
+ gdt_l1e = l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR);
+ for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ )
+ {
+ d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
+ FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
+ if (d->vcpu[vcpuid])
+ release_compat_l4(d->vcpu[vcpuid]);
+ }
+
+ return 0;
+}
+
+int switch_compat(struct domain *d)
+{
+ l1_pgentry_t gdt_l1e;
+ unsigned int vcpuid;
+
+ if ( !d )
+ return -EINVAL;
+ if ( compat_disabled )
+ return -ENOSYS;
+ if ( !may_switch_mode(d) )
+ return -EACCES;
+ if ( IS_COMPAT(d) )
+ return 0;
+
+ set_bit(_DOMF_compat, &d->domain_flags);
+
+ /* switch gdt */
+ gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR);
+ for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ )
+ {
+ d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) +
+ FIRST_RESERVED_GDT_PAGE)] = gdt_l1e;
+ if (d->vcpu[vcpuid]
+ && setup_compat_l4(d->vcpu[vcpuid]) != 0)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
#else
#define release_arg_xlat_area(d) ((void)0)
#define setup_compat_l4(v) 0
@@ -416,43 +480,80 @@ void arch_domain_destroy(struct domain *
/* This is called by arch_final_setup_guest and do_boot_vcpu */
int arch_set_info_guest(
- struct vcpu *v, struct vcpu_guest_context *c)
+ struct vcpu *v, vcpu_guest_context_u c)
{
struct domain *d = v->domain;
+#ifdef CONFIG_COMPAT
+#define c(fld) (!IS_COMPAT(d) ? (c.nat->fld) : (c.cmp->fld))
+#else
+#define c(fld) (c.nat->fld)
+#endif
unsigned long cr3_pfn = INVALID_MFN;
+ unsigned long flags = c(flags);
int i, rc;
if ( !is_hvm_vcpu(v) )
{
- fixup_guest_stack_selector(d, c->user_regs.ss);
- fixup_guest_stack_selector(d, c->kernel_ss);
- fixup_guest_code_selector(d, c->user_regs.cs);
-
- if ( CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d) )
- {
- fixup_guest_code_selector(d, c->event_callback_cs);
- fixup_guest_code_selector(d, c->failsafe_callback_cs);
- }
-
- for ( i = 0; i < 256; i++ )
- fixup_guest_code_selector(d, c->trap_ctxt[i].cs);
-
- /* LDT safety checks. */
- if ( ((c->ldt_base & (PAGE_SIZE-1)) != 0) ||
- (c->ldt_ents > 8192) ||
- !array_access_ok(c->ldt_base, c->ldt_ents, LDT_ENTRY_SIZE) )
- return -EINVAL;
+ if ( !IS_COMPAT(d) )
+ {
+ fixup_guest_stack_selector(d, c.nat->user_regs.ss);
+ fixup_guest_stack_selector(d, c.nat->kernel_ss);
+ fixup_guest_code_selector(d, c.nat->user_regs.cs);
+#ifdef __i386__
+ fixup_guest_code_selector(d, c.nat->event_callback_cs);
+ fixup_guest_code_selector(d, c.nat->failsafe_callback_cs);
+#endif
+
+ for ( i = 0; i < 256; i++ )
+ fixup_guest_code_selector(d, c.nat->trap_ctxt[i].cs);
+
+ /* LDT safety checks. */
+ if ( ((c.nat->ldt_base & (PAGE_SIZE-1)) != 0) ||
+ (c.nat->ldt_ents > 8192) ||
+ !array_access_ok(c.nat->ldt_base,
+ c.nat->ldt_ents,
+ LDT_ENTRY_SIZE) )
+ return -EINVAL;
+ }
+#ifdef CONFIG_COMPAT
+ else
+ {
+ fixup_guest_stack_selector(d, c.cmp->user_regs.ss);
+ fixup_guest_stack_selector(d, c.cmp->kernel_ss);
+ fixup_guest_code_selector(d, c.cmp->user_regs.cs);
+ fixup_guest_code_selector(d, c.cmp->event_callback_cs);
+ fixup_guest_code_selector(d, c.cmp->failsafe_callback_cs);
+
+ for ( i = 0; i < 256; i++ )
+ fixup_guest_code_selector(d, c.cmp->trap_ctxt[i].cs);
+
+ /* LDT safety checks. */
+ if ( ((c.cmp->ldt_base & (PAGE_SIZE-1)) != 0) ||
+ (c.cmp->ldt_ents > 8192) ||
+ !compat_array_access_ok(c.cmp->ldt_base,
+ c.cmp->ldt_ents,
+ LDT_ENTRY_SIZE) )
+ return -EINVAL;
+ }
+#endif
}
clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
- if ( c->flags & VGCF_i387_valid )
+ if ( flags & VGCF_I387_VALID )
set_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
v->arch.flags &= ~TF_kernel_mode;
- if ( (c->flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ )
+ if ( (flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ )
v->arch.flags |= TF_kernel_mode;
- memcpy(&v->arch.guest_context, c, sizeof(*c));
+ if ( !IS_COMPAT(v->domain) )
+ memcpy(&v->arch.guest_context, c.nat, sizeof(*c.nat));
+#ifdef CONFIG_COMPAT
+ else
+ {
+ XLAT_vcpu_guest_context(&v->arch.guest_context, c.cmp);
+ }
+#endif
/* Only CR0.TS is modifiable by guest or admin. */
v->arch.guest_context.ctrlreg[0] &= X86_CR0_TS;
@@ -480,19 +581,34 @@ int arch_set_info_guest(
memset(v->arch.guest_context.debugreg, 0,
sizeof(v->arch.guest_context.debugreg));
for ( i = 0; i < 8; i++ )
- (void)set_debugreg(v, i, c->debugreg[i]);
+ (void)set_debugreg(v, i, c(debugreg[i]));
if ( v->vcpu_id == 0 )
- d->vm_assist = c->vm_assist;
+ d->vm_assist = c(vm_assist);
if ( !is_hvm_vcpu(v) )
{
- if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 )
+ if ( !IS_COMPAT(d) )
+ rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents);
+#ifdef CONFIG_COMPAT
+ else
+ {
+ unsigned long gdt_frames[ARRAY_SIZE(c.cmp->gdt_frames)];
+ unsigned int i, n = (c.cmp->gdt_ents + 511) / 512;
+
+ if ( n > ARRAY_SIZE(c.cmp->gdt_frames) )
+ return -EINVAL;
+ for ( i = 0; i < n; ++i )
+ gdt_frames[i] = c.cmp->gdt_frames[i];
+ rc = (int)set_gdt(v, gdt_frames, c.cmp->gdt_ents);
+ }
+#endif
+ if ( rc != 0 )
return rc;
if ( !IS_COMPAT(d) )
{
- cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c->ctrlreg[3]));
+ cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3]));
if ( shadow_mode_refcounts(d)
? !get_page(mfn_to_page(cr3_pfn), d)
@@ -510,7 +626,7 @@ int arch_set_info_guest(
{
l4_pgentry_t *l4tab;
- cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c->ctrlreg[3]));
+ cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3]));
if ( shadow_mode_refcounts(d)
? !get_page(mfn_to_page(cr3_pfn), d)
@@ -539,6 +655,7 @@ int arch_set_info_guest(
update_cr3(v);
return 0;
+#undef c
}
long
diff -r d80684d19ef4 -r 5442b2458e1b xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/arch/x86/domctl.c Fri Jan 05 17:34:39 2007 +0000
@@ -11,6 +11,7 @@
#include <xen/guest_access.h>
#include <public/domctl.h>
#include <xen/sched.h>
+#include <xen/domain.h>
#include <xen/event.h>
#include <xen/domain_page.h>
#include <asm/msr.h>
@@ -23,12 +24,21 @@
#include <asm/hvm/support.h>
#include <asm/processor.h>
#include <public/hvm/e820.h>
-
-long arch_do_domctl(
+#ifdef CONFIG_COMPAT
+#include <compat/xen.h>
+#endif
+
+#ifndef COMPAT
+#define _long long
+#define copy_from_xxx_offset copy_from_guest_offset
+#define copy_to_xxx_offset copy_to_guest_offset
+#endif
+
+_long arch_do_domctl(
struct xen_domctl *domctl,
XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
{
- long ret = 0;
+ _long ret = 0;
switch ( domctl->cmd )
{
@@ -40,7 +50,9 @@ long arch_do_domctl(
d = find_domain_by_id(domctl->domain);
if ( d != NULL )
{
- ret = shadow_domctl(d, &domctl->u.shadow_op, u_domctl);
+ ret = shadow_domctl(d,
+ &domctl->u.shadow_op,
+ guest_handle_cast(u_domctl, void));
put_domain(d);
copy_to_guest(u_domctl, domctl, 1);
}
@@ -123,12 +135,12 @@ long arch_do_domctl(
case XEN_DOMCTL_getpageframeinfo2:
{
-#define GPF2_BATCH (PAGE_SIZE / sizeof(long))
+#define GPF2_BATCH (PAGE_SIZE / sizeof(_long))
int n,j;
int num = domctl->u.getpageframeinfo2.num;
domid_t dom = domctl->domain;
struct domain *d;
- unsigned long *l_arr;
+ unsigned _long *l_arr;
ret = -ESRCH;
if ( unlikely((d = find_domain_by_id(dom)) == NULL) )
@@ -148,9 +160,9 @@ long arch_do_domctl(
{
int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n);
- if ( copy_from_guest_offset(l_arr,
- domctl->u.getpageframeinfo2.array,
- n, k) )
+ if ( copy_from_xxx_offset(l_arr,
+ domctl->u.getpageframeinfo2.array,
+ n, k) )
{
ret = -EINVAL;
break;
@@ -159,13 +171,13 @@ long arch_do_domctl(
for ( j = 0; j < k; j++ )
{
struct page_info *page;
- unsigned long mfn = l_arr[j];
+ unsigned _long mfn = l_arr[j];
page = mfn_to_page(mfn);
if ( likely(mfn_valid(mfn) && get_page(page, d)) )
{
- unsigned long type = 0;
+ unsigned _long type = 0;
switch( page->u.inuse.type_info & PGT_type_mask )
{
@@ -193,8 +205,8 @@ long arch_do_domctl(
}
- if ( copy_to_guest_offset(domctl->u.getpageframeinfo2.array,
- n, l_arr, k) )
+ if ( copy_to_xxx_offset(domctl->u.getpageframeinfo2.array,
+ n, l_arr, k) )
{
ret = -EINVAL;
break;
@@ -214,7 +226,7 @@ long arch_do_domctl(
int i;
struct domain *d = find_domain_by_id(domctl->domain);
unsigned long max_pfns = domctl->u.getmemlist.max_pfns;
- unsigned long mfn;
+ xen_pfn_t mfn;
struct list_head *list_ent;
ret = -EINVAL;
@@ -229,8 +241,8 @@ long arch_do_domctl(
{
mfn = page_to_mfn(list_entry(
list_ent, struct page_info, list));
- if ( copy_to_guest_offset(domctl->u.getmemlist.buffer,
- i, &mfn, 1) )
+ if ( copy_to_xxx_offset(domctl->u.getmemlist.buffer,
+ i, &mfn, 1) )
{
ret = -EFAULT;
break;
@@ -289,37 +301,68 @@ long arch_do_domctl(
return ret;
}
-void arch_getdomaininfo_ctxt(
- struct vcpu *v, struct vcpu_guest_context *c)
+#ifndef COMPAT
+void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
{
- memcpy(c, &v->arch.guest_context, sizeof(*c));
+#ifdef CONFIG_COMPAT
+#define c(fld) (!IS_COMPAT(v->domain) ? (c.nat->fld) : (c.cmp->fld))
+#else
+#define c(fld) (c.nat->fld)
+#endif
+ unsigned long flags;
+
+ if ( !IS_COMPAT(v->domain) )
+ memcpy(c.nat, &v->arch.guest_context, sizeof(*c.nat));
+#ifdef CONFIG_COMPAT
+ else
+ {
+ XLAT_vcpu_guest_context(c.cmp, &v->arch.guest_context);
+ }
+#endif
if ( is_hvm_vcpu(v) )
{
- hvm_store_cpu_guest_regs(v, &c->user_regs, c->ctrlreg);
+ if ( !IS_COMPAT(v->domain) )
+ hvm_store_cpu_guest_regs(v, &c.nat->user_regs, c.nat->ctrlreg);
+#ifdef CONFIG_COMPAT
+ else
+ {
+ struct cpu_user_regs user_regs;
+ typeof(c.nat->ctrlreg) ctrlreg;
+ unsigned i;
+
+ hvm_store_cpu_guest_regs(v, &user_regs, ctrlreg);
+ XLAT_cpu_user_regs(&c.cmp->user_regs, &user_regs);
+ for ( i = 0; i < ARRAY_SIZE(c.cmp->ctrlreg); ++i )
+ c.cmp->ctrlreg[i] = ctrlreg[i];
+ }
+#endif
}
else
{
/* IOPL privileges are virtualised: merge back into returned eflags. */
- BUG_ON((c->user_regs.eflags & EF_IOPL) != 0);
- c->user_regs.eflags |= v->arch.iopl << 12;
- }
-
- c->flags = 0;
+ BUG_ON((c(user_regs.eflags) & EF_IOPL) != 0);
+ c(user_regs.eflags |= v->arch.iopl << 12);
+ }
+
+ flags = 0;
if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) )
- c->flags |= VGCF_i387_valid;
+ flags |= VGCF_i387_valid;
if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) )
- c->flags |= VGCF_in_kernel;
+ flags |= VGCF_in_kernel;
+ c(flags = flags);
if ( !IS_COMPAT(v->domain) )
- c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
+ c.nat->ctrlreg[3] =
xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
#ifdef CONFIG_COMPAT
else
- c->ctrlreg[3] =
compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
-#endif
-
- c->vm_assist = v->domain->vm_assist;
+ c.cmp->ctrlreg[3] =
compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
+#endif
+
+ c(vm_assist = v->domain->vm_assist);
+#undef c
}
+#endif
/*
* Local variables:
diff -r d80684d19ef4 -r 5442b2458e1b xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/arch/x86/mm/shadow/common.c Fri Jan 05 17:34:39 2007 +0000
@@ -3260,7 +3260,7 @@ void shadow_mark_dirty(struct domain *d,
int shadow_domctl(struct domain *d,
xen_domctl_shadow_op_t *sc,
- XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
+ XEN_GUEST_HANDLE(void) u_domctl)
{
int rc, preempted = 0;
diff -r d80684d19ef4 -r 5442b2458e1b xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/arch/x86/x86_32/traps.c Fri Jan 05 17:34:39 2007 +0000
@@ -193,7 +193,7 @@ unsigned long do_iret(void)
/*
* Pop, fix up and restore EFLAGS. We fix up in a local staging area
- * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
+ * to avoid firing the BUG_ON(IOPL) check in arch_get_info_guest.
*/
if ( unlikely(__copy_from_user(&eflags, (void __user *)regs->esp, 4)) )
goto exit_and_crash;
diff -r d80684d19ef4 -r 5442b2458e1b xen/arch/x86/x86_64/Makefile
--- a/xen/arch/x86/x86_64/Makefile Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/arch/x86/x86_64/Makefile Fri Jan 05 17:34:39 2007 +0000
@@ -5,6 +5,7 @@ obj-y += traps.o
obj-$(CONFIG_COMPAT) += compat.o
obj-$(CONFIG_COMPAT) += domain.o
+obj-$(CONFIG_COMPAT) += domctl.o
obj-$(CONFIG_COMPAT) += physdev.o
obj-$(CONFIG_COMPAT) += platform_hypercall.o
obj-$(CONFIG_COMPAT) += sysctl.o
@@ -12,6 +13,7 @@ ifeq ($(CONFIG_COMPAT),y)
ifeq ($(CONFIG_COMPAT),y)
# extra dependencies
compat.o: ../compat.c
+domctl.o: ../domctl.c
entry.o: compat/entry.S
mm.o: compat/mm.c
physdev.o: ../physdev.c
diff -r d80684d19ef4 -r 5442b2458e1b xen/arch/x86/x86_64/compat/entry.S
--- a/xen/arch/x86/x86_64/compat/entry.S Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/arch/x86/x86_64/compat/entry.S Fri Jan 05 17:34:39 2007 +0000
@@ -278,8 +278,6 @@ CFIX14:
.section .rodata, "a", @progbits
-#define compat_domctl domain_crash_synchronous
-
ENTRY(compat_hypercall_table)
.quad compat_set_trap_table /* 0 */
.quad do_mmu_update
diff -r d80684d19ef4 -r 5442b2458e1b xen/arch/x86/x86_64/compat/traps.c
--- a/xen/arch/x86/x86_64/compat/traps.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/arch/x86/x86_64/compat/traps.c Fri Jan 05 17:34:39 2007 +0000
@@ -49,7 +49,7 @@ unsigned int compat_iret(void)
/*
* Fix up and restore EFLAGS. We fix up in a local staging area
- * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
+ * to avoid firing the BUG_ON(IOPL) check in arch_get_info_guest.
*/
if ( unlikely(__get_user(eflags, (u32 __user *)regs->rsp + 3)) )
goto exit_and_crash;
diff -r d80684d19ef4 -r 5442b2458e1b xen/arch/x86/x86_64/domctl.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/arch/x86/x86_64/domctl.c Fri Jan 05 17:34:39 2007 +0000
@@ -0,0 +1,111 @@
+/******************************************************************************
+ * Arch-specific compatibility domctl.c
+ */
+
+#include <xen/config.h>
+#include <compat/domctl.h>
+#include <xen/guest_access.h>
+#include <asm/shadow.h>
+
+DEFINE_XEN_GUEST_HANDLE(compat_domctl_t);
+#define xen_domctl compat_domctl
+#define xen_domctl_t compat_domctl_t
+#define arch_do_domctl(x, h) arch_compat_domctl(x, _##h)
+
+static int compat_shadow_domctl(struct domain *d,
+ compat_domctl_shadow_op_t *csc,
+ XEN_GUEST_HANDLE(void) u_domctl)
+{
+ xen_domctl_shadow_op_t nsc;
+ int rc, mode;
+
+#define XLAT_domctl_shadow_op_HNDL_dirty_bitmap(_d_, _s_) \
+ do \
+ { \
+ if ( (_s_)->op != XEN_DOMCTL_SHADOW_OP_CLEAN \
+ && (_s_)->op != XEN_DOMCTL_SHADOW_OP_PEEK ) \
+ { \
+ set_xen_guest_handle((_d_)->dirty_bitmap, NULL); \
+ mode = -1; \
+ } \
+ else if ( compat_handle_is_null((_s_)->dirty_bitmap) \
+ || (((_s_)->pages - 1) \
+ & (BITS_PER_LONG - COMPAT_BITS_PER_LONG)) \
+ == BITS_PER_LONG - COMPAT_BITS_PER_LONG ) \
+ { \
+ XEN_GUEST_HANDLE(void) tmp; \
+ guest_from_compat_handle(tmp, (_s_)->dirty_bitmap); \
+ (_d_)->dirty_bitmap = guest_handle_cast(tmp, ulong); \
+ mode = 0; \
+ } \
+ else if ( (_s_)->pages > COMPAT_ARG_XLAT_SIZE * 8 ) \
+ { \
+ printk("Cannot translate compatibility mode
XEN_DOMCTL_SHADOW_OP_{CLEAN,PEEK} (0x%lX)\n", \
+ (_s_)->pages); \
+ return -E2BIG; \
+ } \
+ else \
+ { \
+ set_xen_guest_handle((_d_)->dirty_bitmap, \
+ (void
*)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id)); \
+ mode = 1; \
+ } \
+ } while (0)
+ XLAT_domctl_shadow_op(&nsc, csc);
+#undef XLAT_domctl_shadow_op_HNDL_dirty_bitmap
+ rc = shadow_domctl(d, &nsc, u_domctl);
+ if ( rc != __HYPERVISOR_domctl )
+ {
+ BUG_ON(rc > 0);
+#define XLAT_domctl_shadow_op_HNDL_dirty_bitmap(_d_, _s_) \
+ do \
+ { \
+ if ( rc == 0 \
+ && mode > 0 \
+ && copy_to_compat((_d_)->dirty_bitmap, \
+ (unsigned int *)(_s_)->dirty_bitmap.p, \
+ ((_s_)->pages + COMPAT_BITS_PER_LONG - 1) /
COMPAT_BITS_PER_LONG) ) \
+ rc = -EFAULT; \
+ } while (0)
+ XLAT_domctl_shadow_op(csc, &nsc);
+#undef XLAT_domctl_shadow_op_HNDL_dirty_bitmap
+ }
+ return rc;
+}
+#define xen_domctl_shadow_op compat_domctl_shadow_op
+#define xen_domctl_shadow_op_t compat_domctl_shadow_op_t
+#define shadow_domctl(d, sc, u) compat_shadow_domctl(d, sc, u)
+
+#define xen_domctl_ioport_permission compat_domctl_ioport_permission
+#define xen_domctl_ioport_permission_t compat_domctl_ioport_permission_t
+
+#define xen_domctl_getpageframeinfo compat_domctl_getpageframeinfo
+#define xen_domctl_getpageframeinfo_t compat_domctl_getpageframeinfo_t
+
+#define xen_domctl_getpageframeinfo2 compat_domctl_getpageframeinfo2
+#define xen_domctl_getpageframeinfo2_t compat_domctl_getpageframeinfo2_t
+
+#define xen_domctl_getmemlist compat_domctl_getmemlist
+#define xen_domctl_getmemlist_t compat_domctl_getmemlist_t
+#define xen_pfn_t compat_pfn_t
+
+#define xen_domctl_hypercall_init compat_domctl_hypercall_init
+#define xen_domctl_hypercall_init_t compat_domctl_hypercall_init_t
+
+#define COMPAT
+#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t)
+#define _long int
+#define copy_from_xxx_offset copy_from_compat_offset
+#define copy_to_xxx_offset copy_to_compat_offset
+
+#include "../domctl.c"
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r d80684d19ef4 -r 5442b2458e1b xen/common/compat/Makefile
--- a/xen/common/compat/Makefile Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/common/compat/Makefile Fri Jan 05 17:34:39 2007 +0000
@@ -1,4 +1,5 @@ obj-y += domain.o
obj-y += domain.o
+obj-y += domctl.o
obj-y += kernel.o
obj-y += memory.o
obj-y += multicall.o
@@ -6,6 +7,7 @@ obj-y += xlat.o
obj-y += xlat.o
# extra dependencies
+domctl.o: ../domctl.c
kernel.o: ../kernel.c
multicall.o: ../multicall.c
sysctl.o: ../sysctl.c
diff -r d80684d19ef4 -r 5442b2458e1b xen/common/compat/domain.c
--- a/xen/common/compat/domain.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/common/compat/domain.c Fri Jan 05 17:34:39 2007 +0000
@@ -28,7 +28,6 @@ int compat_vcpu_op(int cmd, int vcpuid,
case VCPUOP_initialise:
{
struct compat_vcpu_guest_context *cmp_ctxt;
- struct vcpu_guest_context *nat_ctxt;
if ( (cmp_ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL )
{
@@ -43,23 +42,13 @@ int compat_vcpu_op(int cmd, int vcpuid,
break;
}
- if ( (nat_ctxt = xmalloc(struct vcpu_guest_context)) == NULL )
- {
- rc = -ENOMEM;
- break;
- }
-
- memset(nat_ctxt, 0, sizeof(*nat_ctxt));
- XLAT_vcpu_guest_context(nat_ctxt, cmp_ctxt);
- xfree(cmp_ctxt);
-
LOCK_BIGLOCK(d);
rc = -EEXIST;
if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
- rc = boot_vcpu(d, vcpuid, nat_ctxt);
+ rc = boot_vcpu(d, vcpuid, cmp_ctxt);
UNLOCK_BIGLOCK(d);
- xfree(nat_ctxt);
+ xfree(cmp_ctxt);
break;
}
diff -r d80684d19ef4 -r 5442b2458e1b xen/common/compat/domctl.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/common/compat/domctl.c Fri Jan 05 17:34:39 2007 +0000
@@ -0,0 +1,137 @@
+/******************************************************************************
+ * compat/domctl.c
+ */
+
+#include <xen/config.h>
+#include <compat/domctl.h>
+#include <xen/sched.h>
+#include <xen/cpumask.h>
+#include <asm/uaccess.h>
+
+DEFINE_XEN_GUEST_HANDLE(compat_domctl_t);
+#define xen_domctl compat_domctl
+#define xen_domctl_t compat_domctl_t
+#define do_domctl(h) compat_domctl(_##h)
+#define arch_do_domctl(x, h) arch_compat_domctl(x, _##h)
+
+#define xen_domain_handle_t compat_domain_handle_t
+
+#define xen_domctl_vcpucontext compat_domctl_vcpucontext
+#define xen_domctl_vcpucontext_t compat_domctl_vcpucontext_t
+
+#define xen_domctl_createdomain compat_domctl_createdomain
+#define xen_domctl_createdomain_t compat_domctl_createdomain_t
+
+#define xen_domctl_max_vcpus compat_domctl_max_vcpus
+#define xen_domctl_max_vcpus_t compat_domctl_max_vcpus_t
+
+static void cpumask_to_compat_ctl_cpumap(
+ struct compat_ctl_cpumap *cmpctl_cpumap, cpumask_t *cpumask)
+{
+ unsigned int guest_bytes, copy_bytes, i;
+ /*static const*/ uint8_t zero = 0;
+
+ if ( compat_handle_is_null(cmpctl_cpumap->bitmap) )
+ return;
+
+ guest_bytes = (cmpctl_cpumap->nr_cpus + 7) / 8;
+ copy_bytes = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8);
+
+ copy_to_compat(cmpctl_cpumap->bitmap,
+ (uint8_t *)cpus_addr(*cpumask),
+ copy_bytes);
+
+ for ( i = copy_bytes; i < guest_bytes; i++ )
+ copy_to_compat_offset(cmpctl_cpumap->bitmap, i, &zero, 1);
+}
+#define cpumask_to_xenctl_cpumap cpumask_to_compat_ctl_cpumap
+
+void compat_ctl_cpumap_to_cpumask(
+ cpumask_t *cpumask, struct compat_ctl_cpumap *cmpctl_cpumap)
+{
+ unsigned int guest_bytes, copy_bytes;
+
+ guest_bytes = (cmpctl_cpumap->nr_cpus + 7) / 8;
+ copy_bytes = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8);
+
+ cpus_clear(*cpumask);
+
+ if ( compat_handle_is_null(cmpctl_cpumap->bitmap) )
+ return;
+
+ copy_from_compat((uint8_t *)cpus_addr(*cpumask),
+ cmpctl_cpumap->bitmap,
+ copy_bytes);
+}
+#define xenctl_cpumap_to_cpumask compat_ctl_cpumap_to_cpumask
+
+#define xen_domctl_vcpuaffinity compat_domctl_vcpuaffinity
+#define xen_domctl_vcpuaffinity_t compat_domctl_vcpuaffinity_t
+
+static int compat_sched_adjust(struct domain *d,
+ struct compat_domctl_scheduler_op *cop)
+{
+ struct xen_domctl_scheduler_op nop;
+ int ret;
+ enum XLAT_domctl_scheduler_op_u u;
+
+ switch ( cop->sched_id )
+ {
+ case XEN_SCHEDULER_SEDF: u = XLAT_domctl_scheduler_op_u_sedf; break;
+ case XEN_SCHEDULER_CREDIT: u = XLAT_domctl_scheduler_op_u_credit; break;
+ default: return -EINVAL;
+ }
+ XLAT_domctl_scheduler_op(&nop, cop);
+ ret = sched_adjust(d, &nop);
+ XLAT_domctl_scheduler_op(cop, &nop);
+
+ return ret;
+}
+#define sched_adjust(d, op) compat_sched_adjust(d, op)
+#define xen_domctl_scheduler_op compat_domctl_scheduler_op
+#define xen_domctl_scheduler_op_t compat_domctl_scheduler_op_t
+
+#define xen_domctl_getdomaininfo compat_domctl_getdomaininfo
+#define xen_domctl_getdomaininfo_t compat_domctl_getdomaininfo_t
+#define getdomaininfo(d, i) compat_getdomaininfo(d, i)
+
+#define xen_domctl_getvcpuinfo compat_domctl_getvcpuinfo
+#define xen_domctl_getvcpuinfo_t compat_domctl_getvcpuinfo_t
+
+#define xen_domctl_max_mem compat_domctl_max_mem
+#define xen_domctl_max_mem_t compat_domctl_max_mem_t
+
+#define xen_domctl_setdomainhandle compat_domctl_setdomainhandle
+#define xen_domctl_setdomainhandle_t compat_domctl_setdomainhandle_t
+
+#define xen_domctl_setdebugging compat_domctl_setdebugging
+#define xen_domctl_setdebugging_t compat_domctl_setdebugging_t
+
+#define xen_domctl_irq_permission compat_domctl_irq_permission
+#define xen_domctl_irq_permission_t compat_domctl_irq_permission_t
+
+#define xen_domctl_iomem_permission compat_domctl_iomem_permission
+#define xen_domctl_iomem_permission_t compat_domctl_iomem_permission_t
+
+#define xen_domctl_settimeoffset compat_domctl_settimeoffset
+#define xen_domctl_settimeoffset_t compat_domctl_settimeoffset_t
+
+#define COMPAT
+#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t)
+#define _u_domctl u_domctl
+//#undef guest_handle_cast
+//#define guest_handle_cast compat_handle_cast
+//#define copy_to_xxx_offset copy_to_compat_offset
+typedef int ret_t;
+
+#include "../domctl.c"
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r d80684d19ef4 -r 5442b2458e1b xen/common/compat/sysctl.c
--- a/xen/common/compat/sysctl.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/common/compat/sysctl.c Fri Jan 05 17:34:39 2007 +0000
@@ -40,13 +40,6 @@ static int compat_tb_control(struct comp
#define xen_sysctl_sched_id compat_sysctl_sched_id
#define xen_sysctl_sched_id_t compat_sysctl_sched_id_t
-static void compat_getdomaininfo(struct domain *d, struct
compat_domctl_getdomaininfo *ci)
-{
- struct xen_domctl_getdomaininfo ni;
-
- getdomaininfo(d, &ni);
- XLAT_domctl_getdomaininfo(ci, &ni);
-}
#define xen_sysctl_getdomaininfolist compat_sysctl_getdomaininfolist
#define xen_sysctl_getdomaininfolist_t compat_sysctl_getdomaininfolist_t
#define xen_domctl_getdomaininfo compat_domctl_getdomaininfo
diff -r d80684d19ef4 -r 5442b2458e1b xen/common/domain.c
--- a/xen/common/domain.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/common/domain.c Fri Jan 05 17:34:39 2007 +0000
@@ -26,6 +26,9 @@
#include <asm/debugger.h>
#include <public/sched.h>
#include <public/vcpu.h>
+#ifdef CONFIG_COMPAT
+#include <compat/domctl.h>
+#endif
/* Both these structures are protected by the domlist_lock. */
DEFINE_RWLOCK(domlist_lock);
@@ -451,32 +454,64 @@ void domain_unpause_by_systemcontroller(
* the userspace dom0 domain builder.
*/
int set_info_guest(struct domain *d,
- xen_domctl_vcpucontext_t *vcpucontext)
+ xen_domctl_vcpucontext_u vcpucontext)
{
int rc = 0;
- struct vcpu_guest_context *c = NULL;
- unsigned long vcpu = vcpucontext->vcpu;
+ vcpu_guest_context_u c;
+#ifdef CONFIG_COMPAT
+ CHECK_FIELD(domctl_vcpucontext, vcpu);
+#endif
+ unsigned long vcpu = vcpucontext.nat->vcpu;
struct vcpu *v;
if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) )
return -EINVAL;
- if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
+#ifdef CONFIG_COMPAT
+ BUILD_BUG_ON(sizeof(struct vcpu_guest_context)
+ < sizeof(struct compat_vcpu_guest_context));
+#endif
+ if ( (c.nat = xmalloc(struct vcpu_guest_context)) == NULL )
return -ENOMEM;
domain_pause(d);
- rc = -EFAULT;
- if ( copy_from_guest(c, vcpucontext->ctxt, 1) == 0 )
+ if ( !IS_COMPAT(v->domain) )
+ {
+ if ( !IS_COMPAT(current->domain)
+ ? copy_from_guest(c.nat, vcpucontext.nat->ctxt, 1)
+#ifndef CONFIG_COMPAT
+ : 0 )
+#else
+ : copy_from_guest(c.nat,
+ compat_handle_cast(vcpucontext.cmp->ctxt,
+ void),
+ 1) )
+#endif
+ rc = -EFAULT;
+ }
+#ifdef CONFIG_COMPAT
+ else
+ {
+ if ( !IS_COMPAT(current->domain)
+ ? copy_from_guest(c.cmp,
+ guest_handle_cast(vcpucontext.nat->ctxt, void),
+ 1)
+ : copy_from_compat(c.cmp, vcpucontext.cmp->ctxt, 1) )
+ rc = -EFAULT;
+ }
+#endif
+
+ if ( rc == 0 )
rc = arch_set_info_guest(v, c);
domain_unpause(d);
- xfree(c);
+ xfree(c.nat);
return rc;
}
-int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt)
+int boot_vcpu(struct domain *d, int vcpuid, vcpu_guest_context_u ctxt)
{
struct vcpu *v = d->vcpu[vcpuid];
diff -r d80684d19ef4 -r 5442b2458e1b xen/common/domctl.c
--- a/xen/common/domctl.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/common/domctl.c Fri Jan 05 17:34:39 2007 +0000
@@ -18,14 +18,22 @@
#include <xen/console.h>
#include <xen/iocap.h>
#include <xen/guest_access.h>
+#ifdef CONFIG_COMPAT
+#include <xen/compat.h>
+#endif
#include <asm/current.h>
#include <public/domctl.h>
#include <acm/acm_hooks.h>
-extern long arch_do_domctl(
+#ifndef COMPAT
+typedef long ret_t;
+#define copy_to_xxx_offset copy_to_guest_offset
+#endif
+
+extern ret_t arch_do_domctl(
struct xen_domctl *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
-extern void arch_getdomaininfo_ctxt(
- struct vcpu *, struct vcpu_guest_context *);
+
+#ifndef COMPAT
void cpumask_to_xenctl_cpumap(
struct xenctl_cpumap *xenctl_cpumap, cpumask_t *cpumask)
@@ -64,6 +72,8 @@ void xenctl_cpumap_to_cpumask(
xenctl_cpumap->bitmap,
copy_bytes);
}
+
+#endif /* COMPAT */
static inline int is_free_domid(domid_t dom)
{
@@ -169,9 +179,9 @@ static unsigned int default_vcpu0_locati
return cpu;
}
-long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
+ret_t do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
{
- long ret = 0;
+ ret_t ret = 0;
struct xen_domctl curop, *op = &curop;
void *ssid = NULL; /* save security ptr between pre and post/fail hooks */
static DEFINE_SPINLOCK(domctl_lock);
@@ -283,10 +293,35 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( (d = domain_create(dom, domcr_flags)) == NULL )
break;
+ ret = 0;
+ switch ( (op->u.createdomain.flags >> XEN_DOMCTL_CDF_WORDSIZE_SHIFT)
+ & XEN_DOMCTL_CDF_WORDSIZE_MASK )
+ {
+ case 0:
+ if ( !IS_COMPAT(current->domain) )
+ op->u.createdomain.flags |= BITS_PER_LONG
+ << XEN_DOMCTL_CDF_WORDSIZE_SHIFT;
+#ifdef CONFIG_COMPAT
+ else
+ {
+ op->u.createdomain.flags |= COMPAT_BITS_PER_LONG
+ << XEN_DOMCTL_CDF_WORDSIZE_SHIFT;
+ case COMPAT_BITS_PER_LONG:
+ ret = switch_compat(d);
+ }
+#endif
+ break;
+ case BITS_PER_LONG:
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ if ( ret )
+ break;
+
memcpy(d->handle, op->u.createdomain.handle,
sizeof(xen_domain_handle_t));
-
- ret = 0;
op->domain = d->domain_id;
if ( copy_to_guest(u_domctl, op, 1) )
@@ -446,7 +481,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
case XEN_DOMCTL_getvcpucontext:
{
- struct vcpu_guest_context *c;
+ vcpu_guest_context_u c;
struct domain *d;
struct vcpu *v;
@@ -466,23 +501,48 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
goto getvcpucontext_out;
+#ifdef CONFIG_COMPAT
+ BUILD_BUG_ON(sizeof(struct vcpu_guest_context)
+ < sizeof(struct compat_vcpu_guest_context));
+#endif
ret = -ENOMEM;
- if ( (c = xmalloc(struct vcpu_guest_context)) == NULL )
+ if ( (c.nat = xmalloc(struct vcpu_guest_context)) == NULL )
goto getvcpucontext_out;
if ( v != current )
vcpu_pause(v);
- arch_getdomaininfo_ctxt(v,c);
+ arch_get_info_guest(v, c);
ret = 0;
if ( v != current )
vcpu_unpause(v);
- if ( copy_to_guest(op->u.vcpucontext.ctxt, c, 1) )
- ret = -EFAULT;
-
- xfree(c);
+ if ( !IS_COMPAT(v->domain) )
+ {
+#ifndef COMPAT
+ if ( copy_to_guest(op->u.vcpucontext.ctxt, c.nat, 1) )
+#else
+ if ( copy_to_guest(compat_handle_cast(op->u.vcpucontext.ctxt,
+ void),
+ c.nat, 1) )
+#endif
+ ret = -EFAULT;
+ }
+#ifdef CONFIG_COMPAT
+ else
+ {
+#ifndef COMPAT
+ if ( copy_to_guest(guest_handle_cast(op->u.vcpucontext.ctxt, void),
+ c.cmp, 1) )
+#else
+ if ( copy_to_compat(op->u.vcpucontext.ctxt, c.cmp, 1) )
+#endif
+ ret = -EFAULT;
+ }
+#endif
+
+ xfree(c.nat);
if ( copy_to_guest(u_domctl, op, 1) )
ret = -EFAULT;
@@ -645,6 +705,16 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
}
}
break;
+
+#ifdef CONFIG_COMPAT
+ case XEN_DOMCTL_set_compat:
+ ret = switch_compat(find_domain_by_id(op->domain));
+ break;
+
+ case XEN_DOMCTL_set_native:
+ ret = switch_native(find_domain_by_id(op->domain));
+ break;
+#endif
default:
ret = arch_do_domctl(op, u_domctl);
diff -r d80684d19ef4 -r 5442b2458e1b xen/common/schedule.c
--- a/xen/common/schedule.c Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/common/schedule.c Fri Jan 05 17:34:39 2007 +0000
@@ -33,8 +33,6 @@
#include <xen/multicall.h>
#include <public/sched.h>
-extern void arch_getdomaininfo_ctxt(struct vcpu *,
- struct vcpu_guest_context *);
/* opt_sched: scheduler - default to credit */
static char opt_sched[10] = "credit";
string_param("sched", opt_sched);
diff -r d80684d19ef4 -r 5442b2458e1b xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/include/asm-x86/shadow.h Fri Jan 05 17:34:39 2007 +0000
@@ -192,7 +192,7 @@ int shadow_enable(struct domain *d, u32
* manipulate the log-dirty bitmap. */
int shadow_domctl(struct domain *d,
xen_domctl_shadow_op_t *sc,
- XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
+ XEN_GUEST_HANDLE(void) u_domctl);
/* Call when destroying a domain */
void shadow_teardown(struct domain *d);
diff -r d80684d19ef4 -r 5442b2458e1b xen/include/public/domctl.h
--- a/xen/include/public/domctl.h Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/include/public/domctl.h Fri Jan 05 17:34:39 2007 +0000
@@ -53,6 +53,8 @@ struct xen_domctl_createdomain {
/* Is this an HVM guest (as opposed to a PV guest)? */
#define _XEN_DOMCTL_CDF_hvm_guest 0
#define XEN_DOMCTL_CDF_hvm_guest (1U<<_XEN_DOMCTL_CDF_hvm_guest)
+#define XEN_DOMCTL_CDF_WORDSIZE_MASK 255
+#define XEN_DOMCTL_CDF_WORDSIZE_SHIFT 24
uint32_t flags;
};
typedef struct xen_domctl_createdomain xen_domctl_createdomain_t;
@@ -392,6 +394,9 @@ typedef struct xen_domctl_real_mode_area
typedef struct xen_domctl_real_mode_area xen_domctl_real_mode_area_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_real_mode_area_t);
+#define XEN_DOMCTL_set_compat 42
+#define XEN_DOMCTL_set_native 43
+
struct xen_domctl {
uint32_t cmd;
uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
diff -r d80684d19ef4 -r 5442b2458e1b xen/include/xen/compat.h
--- a/xen/include/xen/compat.h Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/include/xen/compat.h Fri Jan 05 17:34:39 2007 +0000
@@ -166,6 +166,9 @@ struct vcpu_runstate_info;
struct vcpu_runstate_info;
void xlat_vcpu_runstate_info(struct vcpu_runstate_info *);
+int switch_compat(struct domain *);
+int switch_native(struct domain *);
+
#define BITS_PER_GUEST_LONG(d) (!IS_COMPAT(d) ? BITS_PER_LONG :
COMPAT_BITS_PER_LONG)
#else
diff -r d80684d19ef4 -r 5442b2458e1b xen/include/xen/domain.h
--- a/xen/include/xen/domain.h Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/include/xen/domain.h Fri Jan 05 17:34:39 2007 +0000
@@ -2,10 +2,15 @@
#ifndef __XEN_DOMAIN_H__
#define __XEN_DOMAIN_H__
+typedef union {
+ struct vcpu_guest_context *nat;
+ struct compat_vcpu_guest_context *cmp;
+} vcpu_guest_context_u __attribute__((__transparent_union__));
+
struct vcpu *alloc_vcpu(
struct domain *d, unsigned int vcpu_id, unsigned int cpu_id);
int boot_vcpu(
- struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt);
+ struct domain *d, int vcpuid, vcpu_guest_context_u ctxt);
struct vcpu *alloc_idle_vcpu(unsigned int cpu_id);
struct domain *alloc_domain(domid_t domid);
@@ -14,6 +19,9 @@ struct xen_domctl_getdomaininfo;
struct xen_domctl_getdomaininfo;
void getdomaininfo(
struct domain *d, struct xen_domctl_getdomaininfo *info);
+struct compat_domctl_getdomaininfo;
+void compat_getdomaininfo(
+ struct domain *d, struct compat_domctl_getdomaininfo *info);
/*
* Arch-specifics.
@@ -37,7 +45,8 @@ int arch_domain_create(struct domain *d)
void arch_domain_destroy(struct domain *d);
-int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c);
+int arch_set_info_guest(struct vcpu *, vcpu_guest_context_u);
+void arch_get_info_guest(struct vcpu *, vcpu_guest_context_u);
void domain_relinquish_resources(struct domain *d);
diff -r d80684d19ef4 -r 5442b2458e1b xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/include/xen/sched.h Fri Jan 05 17:34:39 2007 +0000
@@ -275,7 +275,13 @@ int construct_dom0(
unsigned long image_start, unsigned long image_len,
unsigned long initrd_start, unsigned long initrd_len,
char *cmdline);
-int set_info_guest(struct domain *d, xen_domctl_vcpucontext_t *);
+
+typedef union {
+ struct xen_domctl_vcpucontext *nat;
+ struct compat_domctl_vcpucontext *cmp;
+} xen_domctl_vcpucontext_u __attribute__((__transparent_union__));
+
+int set_info_guest(struct domain *d, xen_domctl_vcpucontext_u);
struct domain *find_domain_by_id(domid_t dom);
void domain_destroy(struct domain *d);
diff -r d80684d19ef4 -r 5442b2458e1b xen/include/xlat.lst
--- a/xen/include/xlat.lst Fri Jan 05 17:34:38 2007 +0000
+++ b/xen/include/xlat.lst Fri Jan 05 17:34:39 2007 +0000
@@ -11,7 +11,9 @@
! vcpu_guest_context arch-x86/xen.h
? acm_getdecision acm_ops.h
! ctl_cpumap domctl.h
-! domctl_getdomaininfo domctl.h
+! domctl_scheduler_op domctl.h
+! domctl_shadow_op domctl.h
+! domctl_shadow_op_stats domctl.h
? evtchn_alloc_unbound event_channel.h
? evtchn_bind_interdomain event_channel.h
? evtchn_bind_ipi event_channel.h
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|