[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Enable compatibility mode operation for HYPERVISOR_domctl. Also add logic
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |