[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Introduce _DOMF_compat and infrastructure as well as several conditionals
# HG changeset patch # User Emmanuel Ackaouy <ack@xxxxxxxxxxxxx> # Date 1168018320 0 # Node ID 7c5eea5feebd78eb314a87338e8632ce206d6634 # Parent c75883680f28f9815a683b18402c50c0ab2438b4 Introduce _DOMF_compat and infrastructure as well as several conditionals dealing with operations that need to distinguish between native and compatibility mode guests. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx> --- config/x86_64.mk | 1 tools/libxc/xc_linux_build.c | 2 xen/arch/x86/boot/x86_64.S | 27 +++++- xen/arch/x86/domain.c | 138 +++++++++++++++++++++++-------- xen/arch/x86/domain_build.c | 97 ++++++++++++++++++--- xen/arch/x86/mm.c | 4 xen/arch/x86/setup.c | 3 xen/arch/x86/traps.c | 13 ++ xen/arch/x86/x86_32/mm.c | 12 +- xen/arch/x86/x86_32/traps.c | 4 xen/arch/x86/x86_64/asm-offsets.c | 8 + xen/arch/x86/x86_64/mm.c | 12 +- xen/arch/x86/x86_64/traps.c | 2 xen/common/Makefile | 1 xen/common/elf.c | 2 xen/common/elf32.c | 19 ++++ xen/include/asm-x86/config.h | 15 ++- xen/include/asm-x86/desc.h | 90 ++++++++++++++------ xen/include/asm-x86/ldt.h | 3 xen/include/asm-x86/mm.h | 2 xen/include/asm-x86/regs.h | 3 xen/include/asm-x86/x86_32/regs.h | 2 xen/include/asm-x86/x86_64/regs.h | 7 + xen/include/public/arch-x86/xen-x86_64.h | 5 - xen/include/public/arch-x86/xen.h | 10 ++ xen/include/xen/elf.h | 9 ++ xen/include/xen/sched.h | 10 ++ 27 files changed, 394 insertions(+), 107 deletions(-) diff -r c75883680f28 -r 7c5eea5feebd config/x86_64.mk --- a/config/x86_64.mk Fri Jan 05 17:24:55 2007 +0000 +++ b/config/x86_64.mk Fri Jan 05 17:32:00 2007 +0000 @@ -2,6 +2,7 @@ CONFIG_X86_64 := y CONFIG_X86_64 := y CONFIG_X86_$(XEN_OS) := y +CONFIG_COMPAT := y CONFIG_HVM := y CONFIG_MIGRATE := y CONFIG_XCUTILS := y diff -r c75883680f28 -r 7c5eea5feebd tools/libxc/xc_linux_build.c --- a/tools/libxc/xc_linux_build.c Fri Jan 05 17:24:55 2007 +0000 +++ b/tools/libxc/xc_linux_build.c Fri Jan 05 17:32:00 2007 +0000 @@ -595,6 +595,7 @@ static int compat_check(int xc_handle, s return 0; } +#ifndef __x86_64__//temp if (strstr(xen_caps, "xen-3.0-x86_32p")) { if (dsi->pae_kernel == PAEKERN_bimodal) { dsi->pae_kernel = PAEKERN_extended_cr3; @@ -612,6 +613,7 @@ static int compat_check(int xc_handle, s return 0; } } +#endif return 1; } diff -r c75883680f28 -r 7c5eea5feebd xen/arch/x86/boot/x86_64.S --- a/xen/arch/x86/boot/x86_64.S Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/arch/x86/boot/x86_64.S Fri Jan 05 17:32:00 2007 +0000 @@ -224,14 +224,33 @@ high_start: .align PAGE_SIZE, 0 ENTRY(gdt_table) .quad 0x0000000000000000 /* unused */ - .quad 0x00cf9a000000ffff /* 0xe008 ring 0 code, compatibility */ - .quad 0x00af9a000000ffff /* 0xe010 ring 0 code, 64-bit mode */ - .quad 0x00cf92000000ffff /* 0xe018 ring 0 data */ + .quad 0x00af9a000000ffff /* 0xe008 ring 0 code, 64-bit mode */ + .quad 0x00cf92000000ffff /* 0xe010 ring 0 data */ + .quad 0x0000000000000000 /* reserved */ .quad 0x00cffa000000ffff /* 0xe023 ring 3 code, compatibility */ .quad 0x00cff2000000ffff /* 0xe02b ring 3 data */ .quad 0x00affa000000ffff /* 0xe033 ring 3 code, 64-bit mode */ - .quad 0x0000000000000000 /* unused */ + .quad 0x00cf9a000000ffff /* 0xe038 ring 0 code, compatibility */ + .org gdt_table - FIRST_RESERVED_GDT_BYTE + __TSS(0) * 8 .fill 4*NR_CPUS,8,0 /* space for TSS and LDT per CPU */ + +#ifdef CONFIG_COMPAT + .align PAGE_SIZE, 0 +/* NB. Even rings != 0 get access to the full 4Gb, as only the */ +/* (compatibility) machine->physical mapping table lives there. */ +ENTRY(compat_gdt_table) + .quad 0x0000000000000000 /* unused */ + .quad 0x00af9a000000ffff /* 0xe008 ring 0 code, 64-bit mode */ + .quad 0x00cf92000000ffff /* 0xe010 ring 0 data */ + .quad 0x00cfba000000ffff /* 0xe019 ring 1 code, compatibility */ + .quad 0x00cfb2000000ffff /* 0xe021 ring 1 data */ + .quad 0x00cffa000000ffff /* 0xe02b ring 3 code, compatibility */ + .quad 0x00cff2000000ffff /* 0xe033 ring 3 data */ + .quad 0x00cf9a000000ffff /* 0xe038 ring 0 code, compatibility */ + .org compat_gdt_table - FIRST_RESERVED_GDT_BYTE + __TSS(0) * 8 + .fill 4*NR_CPUS,8,0 /* space for TSS and LDT per CPU */ +# undef LIMIT +#endif /* Initial PML4 -- level-4 page table. */ .align PAGE_SIZE, 0 diff -r c75883680f28 -r 7c5eea5feebd xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/arch/x86/domain.c Fri Jan 05 17:32:00 2007 +0000 @@ -283,17 +283,18 @@ int arch_set_info_guest( if ( !is_hvm_vcpu(v) ) { - fixup_guest_stack_selector(c->user_regs.ss); - fixup_guest_stack_selector(c->kernel_ss); - fixup_guest_code_selector(c->user_regs.cs); - -#ifdef __i386__ - fixup_guest_code_selector(c->event_callback_cs); - fixup_guest_code_selector(c->failsafe_callback_cs); -#endif + 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(c->trap_ctxt[i].cs); + fixup_guest_code_selector(d, c->trap_ctxt[i].cs); /* LDT safety checks. */ if ( ((c->ldt_base & (PAGE_SIZE-1)) != 0) || @@ -489,27 +490,30 @@ static void load_segments(struct vcpu *n all_segs_okay &= loadsegment(gs, nctxt->user_regs.gs); } - /* This can only be non-zero if selector is NULL. */ - if ( nctxt->fs_base ) - wrmsr(MSR_FS_BASE, - nctxt->fs_base, - nctxt->fs_base>>32); - - /* Most kernels have non-zero GS base, so don't bother testing. */ - /* (This is also a serialising instruction, avoiding AMD erratum #88.) */ - wrmsr(MSR_SHADOW_GS_BASE, - nctxt->gs_base_kernel, - nctxt->gs_base_kernel>>32); - - /* This can only be non-zero if selector is NULL. */ - if ( nctxt->gs_base_user ) - wrmsr(MSR_GS_BASE, - nctxt->gs_base_user, - nctxt->gs_base_user>>32); - - /* If in kernel mode then switch the GS bases around. */ - if ( n->arch.flags & TF_kernel_mode ) - __asm__ __volatile__ ( "swapgs" ); + if ( !IS_COMPAT(n->domain) ) + { + /* This can only be non-zero if selector is NULL. */ + if ( nctxt->fs_base ) + wrmsr(MSR_FS_BASE, + nctxt->fs_base, + nctxt->fs_base>>32); + + /* Most kernels have non-zero GS base, so don't bother testing. */ + /* (This is also a serialising instruction, avoiding AMD erratum #88.) */ + wrmsr(MSR_SHADOW_GS_BASE, + nctxt->gs_base_kernel, + nctxt->gs_base_kernel>>32); + + /* This can only be non-zero if selector is NULL. */ + if ( nctxt->gs_base_user ) + wrmsr(MSR_GS_BASE, + nctxt->gs_base_user, + nctxt->gs_base_user>>32); + + /* If in kernel mode then switch the GS bases around. */ + if ( (n->arch.flags & TF_kernel_mode) ) + __asm__ __volatile__ ( "swapgs" ); + } if ( unlikely(!all_segs_okay) ) { @@ -519,6 +523,55 @@ static void load_segments(struct vcpu *n (unsigned long *)regs->rsp : (unsigned long *)nctxt->kernel_sp; unsigned long cs_and_mask, rflags; + + if ( IS_COMPAT(n->domain) ) + { + unsigned int *esp = ring_1(regs) ? + (unsigned int *)regs->rsp : + (unsigned int *)nctxt->kernel_sp; + unsigned int cs_and_mask, eflags; + int ret = 0; + + /* CS longword also contains full evtchn_upcall_mask. */ + cs_and_mask = (unsigned short)regs->cs | + ((unsigned int)n->vcpu_info->evtchn_upcall_mask << 16); + /* Fold upcall mask into RFLAGS.IF. */ + eflags = regs->_eflags & ~X86_EFLAGS_IF; + eflags |= !n->vcpu_info->evtchn_upcall_mask << 9; + + if ( !ring_1(regs) ) + { + ret = put_user(regs->ss, esp-1); + ret |= put_user(regs->_esp, esp-2); + esp -= 2; + } + + if ( ret | + put_user(eflags, esp-1) | + put_user(cs_and_mask, esp-2) | + put_user(regs->_eip, esp-3) | + put_user(nctxt->user_regs.gs, esp-4) | + put_user(nctxt->user_regs.fs, esp-5) | + put_user(nctxt->user_regs.es, esp-6) | + put_user(nctxt->user_regs.ds, esp-7) ) + { + gdprintk(XENLOG_ERR, "Error while creating compat " + "failsafe callback frame.\n"); + domain_crash(n->domain); + } + + if ( test_bit(_VGCF_failsafe_disables_events, + &n->arch.guest_context.flags) ) + n->vcpu_info->evtchn_upcall_mask = 1; + + regs->entry_vector = TRAP_syscall; + regs->_eflags &= 0xFFFCBEFFUL; + regs->ss = FLAT_COMPAT_KERNEL_SS; + regs->_esp = (unsigned long)(esp-7); + regs->cs = FLAT_COMPAT_KERNEL_CS; + regs->_eip = nctxt->failsafe_callback_eip; + return; + } if ( !(n->arch.flags & TF_kernel_mode) ) toggle_guest_mode(n); @@ -581,7 +634,7 @@ static void save_segments(struct vcpu *v if ( regs->es ) dirty_segment_mask |= DIRTY_ES; - if ( regs->fs ) + if ( regs->fs || IS_COMPAT(v->domain) ) { dirty_segment_mask |= DIRTY_FS; ctxt->fs_base = 0; /* != 0 selector kills fs_base */ @@ -591,7 +644,7 @@ static void save_segments(struct vcpu *v dirty_segment_mask |= DIRTY_FS_BASE; } - if ( regs->gs ) + if ( regs->gs || IS_COMPAT(v->domain) ) { dirty_segment_mask |= DIRTY_GS; ctxt->gs_base_user = 0; /* != 0 selector kills gs_base_user */ @@ -725,6 +778,23 @@ void context_switch(struct vcpu *prev, s else { __context_switch(); + +#ifdef CONFIG_COMPAT + if ( is_idle_vcpu(prev) + || IS_COMPAT(prev->domain) != IS_COMPAT(next->domain) ) + { + uint32_t efer_lo, efer_hi; + + local_flush_tlb_one(GDT_VIRT_START(next) + FIRST_RESERVED_GDT_BYTE); + + rdmsr(MSR_EFER, efer_lo, efer_hi); + if ( !IS_COMPAT(next->domain) == !(efer_lo & EFER_SCE) ) + { + efer_lo ^= EFER_SCE; + wrmsr(MSR_EFER, efer_lo, efer_hi); + } + } +#endif /* Re-enable interrupts before restoring state which may fault. */ local_irq_enable(); @@ -938,6 +1008,10 @@ void domain_relinquish_resources(struct put_page(mfn_to_page(pfn)); else put_page_and_type(mfn_to_page(pfn)); +#ifdef __x86_64__ + if ( pfn == pagetable_get_pfn(v->arch.guest_table_user) ) + v->arch.guest_table_user = pagetable_null(); +#endif v->arch.guest_table = pagetable_null(); } diff -r c75883680f28 -r 7c5eea5feebd xen/arch/x86/domain_build.c --- a/xen/arch/x86/domain_build.c Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/arch/x86/domain_build.c Fri Jan 05 17:32:00 2007 +0000 @@ -319,10 +319,38 @@ int construct_dom0(struct domain *d, nr_pages = compute_dom0_nr_pages(); - if ( (rc = parseelfimage(&dsi)) != 0 ) - return rc; - - xen_pae = (CONFIG_PAGING_LEVELS == 3); + rc = parseelfimage(&dsi); +#ifdef CONFIG_COMPAT + if ( rc == -ENOSYS + && (rc = parseelf32image(&dsi)) == 0 ) + { + l1_pgentry_t gdt_l1e; + + set_bit(_DOMF_compat, &d->domain_flags); + + if ( nr_pages != (unsigned int)nr_pages ) + nr_pages = UINT_MAX; + + /* + * Map compatibility Xen segments into every VCPU's GDT. See + * arch_domain_create() for further comments. + */ + gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), + PAGE_HYPERVISOR); + for ( i = 0; i < MAX_VIRT_CPUS; i++ ) + d->arch.mm_perdomain_pt[((i << GDT_LDT_VCPU_SHIFT) + + FIRST_RESERVED_GDT_PAGE)] = gdt_l1e; + local_flush_tlb_one(GDT_LDT_VIRT_START + FIRST_RESERVED_GDT_BYTE); + } +#endif + if ( rc != 0) + { + if ( rc == -ENOSYS ) + printk("DOM0 image is not a Xen-compatible Elf image.\n"); + return rc; + } + + xen_pae = (CONFIG_PAGING_LEVELS == 3) || IS_COMPAT(d); if (dsi.pae_kernel == PAEKERN_bimodal) dom0_pae = xen_pae; else @@ -338,7 +366,13 @@ int construct_dom0(struct domain *d, dsi.pae_kernel == PAEKERN_bimodal) ) set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist); - if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL ) +#ifdef CONFIG_COMPAT + if ( IS_COMPAT(d) ) + p = xen_elf32note_string(&dsi, XEN_ELFNOTE_FEATURES); + else +#endif + p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES); + if ( p != NULL ) { parse_features(p, dom0_features_supported, @@ -590,6 +624,12 @@ int construct_dom0(struct domain *d, return -EINVAL; } + if ( IS_COMPAT(d) ) + { + v->arch.guest_context.failsafe_callback_cs = FLAT_COMPAT_KERNEL_CS; + v->arch.guest_context.event_callback_cs = FLAT_COMPAT_KERNEL_CS; + } + /* WARNING: The new domain must have its 'processor' field filled in! */ maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l4_page_table; l4start = l4tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; @@ -599,6 +639,8 @@ int construct_dom0(struct domain *d, l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] = l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); v->arch.guest_table = pagetable_from_paddr(__pa(l4start)); + if ( IS_COMPAT(d) ) + v->arch.guest_table_user = v->arch.guest_table; l4tab += l4_table_offset(dsi.v_start); mfn = alloc_spfn; @@ -711,10 +753,20 @@ int construct_dom0(struct domain *d, write_ptbase(v); /* Copy the OS image and free temporary buffer. */ - (void)loadelfimage(&dsi); - - hypercall_page = - xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); +#ifdef CONFIG_COMPAT + if ( IS_COMPAT(d) ) + { + (void)loadelf32image(&dsi); + hypercall_page = + xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); + } + else +#endif + { + (void)loadelfimage(&dsi); + hypercall_page = + xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); + } if ( hypercall_page_defined ) { if ( (hypercall_page < dsi.v_start) || (hypercall_page >= v_end) ) @@ -747,7 +799,7 @@ int construct_dom0(struct domain *d, si->mfn_list = vphysmap_start; sprintf(si->magic, "xen-%i.%i-x86_%d%s", xen_major_version(), xen_minor_version(), - BITS_PER_LONG, xen_pae ? "p" : ""); + !IS_COMPAT(d) ? BITS_PER_LONG : 32, xen_pae ? "p" : ""); /* Write the phys->machine and machine->phys table entries. */ for ( pfn = 0; pfn < d->tot_pages; pfn++ ) @@ -819,9 +871,11 @@ int construct_dom0(struct domain *d, * [EAX,EBX,ECX,EDX,EDI,EBP are zero] */ regs = &v->arch.guest_context.user_regs; - regs->ds = regs->es = regs->fs = regs->gs = FLAT_KERNEL_DS; - regs->ss = FLAT_KERNEL_SS; - regs->cs = FLAT_KERNEL_CS; + regs->ds = regs->es = regs->fs = regs->gs = !IS_COMPAT(d) + ? FLAT_KERNEL_DS + : FLAT_COMPAT_KERNEL_DS; + regs->ss = !IS_COMPAT(d) ? FLAT_KERNEL_SS : FLAT_COMPAT_KERNEL_SS; + regs->cs = !IS_COMPAT(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS; regs->eip = dsi.v_kernentry; regs->esp = vstack_end; regs->esi = vstartinfo_start; @@ -906,12 +960,27 @@ int elf_sanity_check(const Elf_Ehdr *ehd (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) || (ehdr->e_type != ET_EXEC) ) { - printk("DOM0 image is not a Xen-compatible Elf image.\n"); return 0; } return 1; } + +#ifdef CONFIG_COMPAT +int elf32_sanity_check(const Elf32_Ehdr *ehdr) +{ + if ( !IS_ELF(*ehdr) || + (ehdr->e_ident[EI_CLASS] != ELFCLASS32) || + (ehdr->e_machine != EM_386) || + (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) || + (ehdr->e_type != ET_EXEC) ) + { + return 0; + } + + return 1; +} +#endif /* * Local variables: diff -r c75883680f28 -r 7c5eea5feebd xen/arch/x86/mm.c --- a/xen/arch/x86/mm.c Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/arch/x86/mm.c Fri Jan 05 17:32:00 2007 +0000 @@ -433,7 +433,7 @@ static int alloc_segdesc_page(struct pag descs = map_domain_page(page_to_mfn(page)); for ( i = 0; i < 512; i++ ) - if ( unlikely(!check_descriptor(&descs[i])) ) + if ( unlikely(!check_descriptor(page_get_owner(page), &descs[i])) ) goto fail; unmap_domain_page(descs); @@ -2835,7 +2835,7 @@ long do_update_descriptor(u64 pa, u64 de mfn = gmfn_to_mfn(dom, gmfn); if ( (((unsigned int)pa % sizeof(struct desc_struct)) != 0) || !mfn_valid(mfn) || - !check_descriptor(&d) ) + !check_descriptor(dom, &d) ) { UNLOCK_BIGLOCK(dom); return -EINVAL; diff -r c75883680f28 -r 7c5eea5feebd xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/arch/x86/setup.c Fri Jan 05 17:32:00 2007 +0000 @@ -791,6 +791,9 @@ void arch_get_xen_caps(xen_capabilities_ #elif defined(CONFIG_X86_64) p += sprintf(p, "xen-%d.%d-x86_64 ", major, minor); +#ifdef CONFIG_COMPAT + p += sprintf(p, "xen-%d.%d-x86_32p ", major, minor); +#endif if ( hvm_enabled ) { p += sprintf(p, "hvm-%d.%d-x86_32 ", major, minor); diff -r c75883680f28 -r 7c5eea5feebd xen/arch/x86/traps.c --- a/xen/arch/x86/traps.c Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/arch/x86/traps.c Fri Jan 05 17:32:00 2007 +0000 @@ -382,7 +382,7 @@ static int do_guest_trap( if ( TI_GET_IF(ti) ) tb->flags |= TBF_INTERRUPT; - if ( unlikely(null_trap_bounce(tb)) ) + if ( unlikely(null_trap_bounce(v, tb)) ) gdprintk(XENLOG_WARNING, "Unhandled %s fault/trap [#%d] in " "domain %d on VCPU %d [ec=%04x]\n", trapstr(trapnr), trapnr, v->domain->domain_id, v->vcpu_id, @@ -673,7 +673,7 @@ void propagate_page_fault(unsigned long tb->eip = ti->address; if ( TI_GET_IF(ti) ) tb->flags |= TBF_INTERRUPT; - if ( unlikely(null_trap_bounce(tb)) ) + if ( unlikely(null_trap_bounce(v, tb)) ) { printk("Unhandled page fault in domain %d on VCPU %d (ec=%04X)\n", v->domain->domain_id, v->vcpu_id, error_code); @@ -1785,6 +1785,13 @@ void set_tss_desc(unsigned int n, void * (unsigned long)addr, offsetof(struct tss_struct, __cacheline_filler) - 1, 9); +#ifdef CONFIG_COMPAT + _set_tssldt_desc( + compat_gdt_table + __TSS(n) - FIRST_RESERVED_GDT_ENTRY, + (unsigned long)addr, + offsetof(struct tss_struct, __cacheline_filler) - 1, + 11); +#endif } void __init trap_init(void) @@ -1859,7 +1866,7 @@ long do_set_trap_table(XEN_GUEST_HANDLE( if ( cur.address == 0 ) break; - fixup_guest_code_selector(cur.cs); + fixup_guest_code_selector(current->domain, cur.cs); memcpy(&dst[cur.vector], &cur, sizeof(cur)); diff -r c75883680f28 -r 7c5eea5feebd xen/arch/x86/x86_32/mm.c --- a/xen/arch/x86/x86_32/mm.c Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/arch/x86/x86_32/mm.c Fri Jan 05 17:32:00 2007 +0000 @@ -230,7 +230,7 @@ long do_stack_switch(unsigned long ss, u int nr = smp_processor_id(); struct tss_struct *t = &init_tss[nr]; - fixup_guest_stack_selector(ss); + fixup_guest_stack_selector(current->domain, ss); current->arch.guest_context.kernel_ss = ss; current->arch.guest_context.kernel_sp = esp; @@ -241,7 +241,7 @@ long do_stack_switch(unsigned long ss, u } /* Returns TRUE if given descriptor is valid for GDT or LDT. */ -int check_descriptor(struct desc_struct *d) +int check_descriptor(const struct domain *dom, struct desc_struct *d) { unsigned long base, limit; u32 a = d->a, b = d->b; @@ -261,8 +261,8 @@ int check_descriptor(struct desc_struct * gates (consider a call gate pointing at another kernel descriptor with * DPL 0 -- this would get the OS ring-0 privileges). */ - if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL << 13) ) - d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL << 13); + if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL(dom) << 13) ) + d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL(dom) << 13); if ( !(b & _SEGMENT_S) ) { @@ -284,8 +284,8 @@ int check_descriptor(struct desc_struct /* Validate and fix up the target code selector. */ cs = a >> 16; - fixup_guest_code_selector(cs); - if ( !guest_gate_selector_okay(cs) ) + fixup_guest_code_selector(dom, cs); + if ( !guest_gate_selector_okay(dom, cs) ) goto bad; a = d->a = (d->a & 0xffffU) | (cs << 16); diff -r c75883680f28 -r 7c5eea5feebd xen/arch/x86/x86_32/traps.c --- a/xen/arch/x86/x86_32/traps.c Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/arch/x86/x86_32/traps.c Fri Jan 05 17:32:00 2007 +0000 @@ -296,7 +296,7 @@ void init_int80_direct_trap(struct vcpu * switch to the Xen stack and we need to swap back to the guest * kernel stack before passing control to the system call entry point. */ - if ( TI_GET_IF(ti) || !guest_gate_selector_okay(ti->cs) || + if ( TI_GET_IF(ti) || !guest_gate_selector_okay(v->domain, ti->cs) || supervisor_mode_kernel ) { v->arch.int80_desc.a = v->arch.int80_desc.b = 0; @@ -326,7 +326,7 @@ static long register_guest_callback(stru long ret = 0; struct vcpu *v = current; - fixup_guest_code_selector(reg->address.cs); + fixup_guest_code_selector(v->domain, reg->address.cs); switch ( reg->type ) { diff -r c75883680f28 -r 7c5eea5feebd xen/arch/x86/x86_64/asm-offsets.c --- a/xen/arch/x86/x86_64/asm-offsets.c Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/arch/x86/x86_64/asm-offsets.c Fri Jan 05 17:32:00 2007 +0000 @@ -58,12 +58,16 @@ void __dummy__(void) OFFSET(VCPU_thread_flags, struct vcpu, arch.flags); OFFSET(VCPU_event_addr, struct vcpu, arch.guest_context.event_callback_eip); + OFFSET(VCPU_event_sel, struct vcpu, + arch.guest_context.event_callback_cs); OFFSET(VCPU_failsafe_addr, struct vcpu, arch.guest_context.failsafe_callback_eip); + OFFSET(VCPU_failsafe_sel, struct vcpu, + arch.guest_context.failsafe_callback_cs); OFFSET(VCPU_syscall_addr, struct vcpu, arch.guest_context.syscall_callback_eip); - OFFSET(VCPU_kernel_sp, struct vcpu, - arch.guest_context.kernel_sp); + OFFSET(VCPU_kernel_sp, struct vcpu, arch.guest_context.kernel_sp); + OFFSET(VCPU_kernel_ss, struct vcpu, arch.guest_context.kernel_ss); OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags); OFFSET(VCPU_arch_guest_fpu_ctxt, struct vcpu, arch.guest_context.fpu_ctxt); OFFSET(VCPU_flags, struct vcpu, vcpu_flags); diff -r c75883680f28 -r 7c5eea5feebd xen/arch/x86/x86_64/mm.c --- a/xen/arch/x86/x86_64/mm.c Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/arch/x86/x86_64/mm.c Fri Jan 05 17:32:00 2007 +0000 @@ -231,7 +231,7 @@ long subarch_memory_op(int op, XEN_GUEST long do_stack_switch(unsigned long ss, unsigned long esp) { - fixup_guest_stack_selector(ss); + fixup_guest_stack_selector(current->domain, ss); current->arch.guest_context.kernel_ss = ss; current->arch.guest_context.kernel_sp = esp; return 0; @@ -291,7 +291,7 @@ long do_set_segment_base(unsigned int wh /* Returns TRUE if given descriptor is valid for GDT or LDT. */ -int check_descriptor(struct desc_struct *d) +int check_descriptor(const struct domain *dom, struct desc_struct *d) { u32 a = d->a, b = d->b; u16 cs; @@ -301,8 +301,8 @@ int check_descriptor(struct desc_struct goto good; /* Check and fix up the DPL. */ - if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL << 13) ) - d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL << 13); + if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL(dom) << 13) ) + d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL(dom) << 13); /* All code and data segments are okay. No base/limit checking. */ if ( (b & _SEGMENT_S) ) @@ -318,8 +318,8 @@ int check_descriptor(struct desc_struct /* Validate and fix up the target code selector. */ cs = a >> 16; - fixup_guest_code_selector(cs); - if ( !guest_gate_selector_okay(cs) ) + fixup_guest_code_selector(dom, cs); + if ( !guest_gate_selector_okay(dom, cs) ) goto bad; a = d->a = (d->a & 0xffffU) | (cs << 16); diff -r c75883680f28 -r 7c5eea5feebd xen/arch/x86/x86_64/traps.c --- a/xen/arch/x86/x86_64/traps.c Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/arch/x86/x86_64/traps.c Fri Jan 05 17:32:00 2007 +0000 @@ -178,6 +178,8 @@ asmlinkage void do_double_fault(struct c void toggle_guest_mode(struct vcpu *v) { + if ( IS_COMPAT(v->domain) ) + return; v->arch.flags ^= TF_kernel_mode; __asm__ __volatile__ ( "swapgs" ); update_cr3(v); diff -r c75883680f28 -r 7c5eea5feebd xen/common/Makefile --- a/xen/common/Makefile Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/common/Makefile Fri Jan 05 17:32:00 2007 +0000 @@ -3,6 +3,7 @@ obj-y += domctl.o obj-y += domctl.o obj-y += domain.o obj-y += elf.o +obj-$(CONFIG_COMPAT) += elf32.o obj-y += event_channel.o obj-y += grant_table.o obj-y += kernel.o diff -r c75883680f28 -r 7c5eea5feebd xen/common/elf.c --- a/xen/common/elf.c Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/common/elf.c Fri Jan 05 17:32:00 2007 +0000 @@ -203,7 +203,7 @@ int parseelfimage(struct domain_setup_in int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined; if ( !elf_sanity_check(ehdr) ) - return -EINVAL; + return -ENOSYS; if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len ) { diff -r c75883680f28 -r 7c5eea5feebd xen/common/elf32.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/common/elf32.c Fri Jan 05 17:32:00 2007 +0000 @@ -0,0 +1,19 @@ +/****************************************************************************** + * elf32.c + * + * Stub to support 32-bit ELF images on 64-bit platforms. + */ + +#include <xen/config.h> +#undef ELFSIZE +#define ELFSIZE 32 +#include <xen/types.h> +#include <xen/elf.h> + +#define xen_elfnote_string xen_elf32note_string +#define xen_elfnote_numeric xen_elf32note_numeric +#define parseelfimage parseelf32image +#define loadelfimage loadelf32image +#define elf_sanity_check elf32_sanity_check + +#include "elf.c" diff -r c75883680f28 -r 7c5eea5feebd xen/include/asm-x86/config.h --- a/xen/include/asm-x86/config.h Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/include/asm-x86/config.h Fri Jan 05 17:32:00 2007 +0000 @@ -87,6 +87,7 @@ #if defined(__x86_64__) #define CONFIG_X86_64 1 +#define CONFIG_COMPAT 1 #define asmlinkage @@ -181,13 +182,21 @@ #define DIRECTMAP_VIRT_START (PML4_ADDR(262)) #define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + PML4_ENTRY_BYTES*2) +#define __HYPERVISOR_COMPAT_VIRT_START 0xF5800000 +#define HYPERVISOR_COMPAT_VIRT_START \ + mk_unsigned_long(__HYPERVISOR_COMPAT_VIRT_START) +#define MACH2PHYS_COMPAT_VIRT_START HYPERVISOR_COMPAT_VIRT_START +#define MACH2PHYS_COMPAT_VIRT_END 0xFFE00000 +#define MACH2PHYS_COMPAT_NR_ENTRIES \ + ((MACH2PHYS_COMPAT_VIRT_END-MACH2PHYS_COMPAT_VIRT_START)>>2) + #define PGT_base_page_table PGT_l4_page_table -#define __HYPERVISOR_CS64 0xe010 -#define __HYPERVISOR_CS32 0xe008 +#define __HYPERVISOR_CS64 0xe008 +#define __HYPERVISOR_CS32 0xe038 #define __HYPERVISOR_CS __HYPERVISOR_CS64 #define __HYPERVISOR_DS64 0x0000 -#define __HYPERVISOR_DS32 0xe018 +#define __HYPERVISOR_DS32 0xe010 #define __HYPERVISOR_DS __HYPERVISOR_DS64 /* For generic assembly code: use macros to define operation/operand sizes. */ diff -r c75883680f28 -r 7c5eea5feebd xen/include/asm-x86/desc.h --- a/xen/include/asm-x86/desc.h Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/include/asm-x86/desc.h Fri Jan 05 17:32:00 2007 +0000 @@ -18,31 +18,76 @@ #define LDT_ENTRY_SIZE 8 +#if defined(__x86_64__) + +#define FLAT_COMPAT_RING1_CS 0xe019 /* GDT index 259 */ +#define FLAT_COMPAT_RING1_DS 0xe021 /* GDT index 260 */ +#define FLAT_COMPAT_RING1_SS 0xe021 /* GDT index 260 */ +#define FLAT_COMPAT_RING3_CS 0xe02b /* GDT index 261 */ +#define FLAT_COMPAT_RING3_DS 0xe033 /* GDT index 262 */ +#define FLAT_COMPAT_RING3_SS 0xe033 /* GDT index 262 */ + +#define FLAT_COMPAT_KERNEL_DS FLAT_COMPAT_RING1_DS +#define FLAT_COMPAT_KERNEL_CS FLAT_COMPAT_RING1_CS +#define FLAT_COMPAT_KERNEL_SS FLAT_COMPAT_RING1_SS +#define FLAT_COMPAT_USER_DS FLAT_COMPAT_RING3_DS +#define FLAT_COMPAT_USER_CS FLAT_COMPAT_RING3_CS +#define FLAT_COMPAT_USER_SS FLAT_COMPAT_RING3_SS + +#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) +#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 2) + +#define __TSS(n) (((n)<<2) + __FIRST_TSS_ENTRY) +#define __LDT(n) (((n)<<2) + __FIRST_LDT_ENTRY) + +#elif defined(__i386__) + +#define FLAT_COMPAT_KERNEL_CS FLAT_KERNEL_CS +#define FLAT_COMPAT_KERNEL_DS FLAT_KERNEL_DS +#define FLAT_COMPAT_KERNEL_SS FLAT_KERNEL_SS +#define FLAT_COMPAT_USER_CS FLAT_USER_CS +#define FLAT_COMPAT_USER_DS FLAT_USER_DS +#define FLAT_COMPAT_USER_SS FLAT_USER_SS + +#define __DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY + +#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) +#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 1) + +#define __TSS(n) (((n)<<1) + __FIRST_TSS_ENTRY) +#define __LDT(n) (((n)<<1) + __FIRST_LDT_ENTRY) + +#endif + +#ifndef __ASSEMBLY__ + #define load_TR(n) __asm__ __volatile__ ("ltr %%ax" : : "a" (__TSS(n)<<3) ) #if defined(__x86_64__) -#define GUEST_KERNEL_RPL 3 -#elif defined(__i386__) -#define GUEST_KERNEL_RPL 1 +#define GUEST_KERNEL_RPL(d) (!IS_COMPAT(d) ? 3 : 1) +#elif defined(__i386__) +#define GUEST_KERNEL_RPL(d) ((void)(d), 1) #endif /* Fix up the RPL of a guest segment selector. */ -#define __fixup_guest_selector(sel) \ - ((sel) = (((sel) & 3) >= GUEST_KERNEL_RPL) ? (sel) : \ - (((sel) & ~3) | GUEST_KERNEL_RPL)) +#define __fixup_guest_selector(d, sel) \ +({ \ + uint16_t _rpl = GUEST_KERNEL_RPL(d); \ + (sel) = (((sel) & 3) >= _rpl) ? (sel) : (((sel) & ~3) | _rpl); \ +}) /* Stack selectors don't need fixing up if the kernel runs in ring 0. */ #ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL -#define fixup_guest_stack_selector(ss) ((void)0) +#define fixup_guest_stack_selector(d, ss) ((void)0) #else -#define fixup_guest_stack_selector(ss) __fixup_guest_selector(ss) +#define fixup_guest_stack_selector(d, ss) __fixup_guest_selector(d, ss) #endif /* * Code selectors are always fixed up. It allows the Xen exit stub to detect * return to guest context, even when the guest kernel runs in ring 0. */ -#define fixup_guest_code_selector(cs) __fixup_guest_selector(cs) +#define fixup_guest_code_selector(d, cs) __fixup_guest_selector(d, cs) /* * We need this function because enforcing the correct guest kernel RPL is @@ -57,10 +102,14 @@ * DPL < CPL then they'll be cleared automatically. If SS RPL or DPL differs * from CS RPL then we'll #GP. */ -#define guest_gate_selector_okay(sel) \ +#define guest_gate_selector_okay(d, sel) \ ((((sel)>>3) < FIRST_RESERVED_GDT_ENTRY) || /* Guest seg? */ \ - ((sel) == FLAT_KERNEL_CS) || /* Xen default seg? */ \ + ((sel) == (!IS_COMPAT(d) ? \ + FLAT_KERNEL_CS : /* Xen default seg? */ \ + FLAT_COMPAT_KERNEL_CS)) || /* Xen default compat seg? */ \ ((sel) & 4)) /* LDT seg? */ + +#endif /* __ASSEMBLY__ */ /* These are bitmasks for the high 32 bits of a descriptor table entry. */ #define _SEGMENT_TYPE (15<< 8) @@ -80,12 +129,6 @@ struct desc_struct { }; #if defined(__x86_64__) - -#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) -#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 2) - -#define __TSS(n) (((n)<<2) + __FIRST_TSS_ENTRY) -#define __LDT(n) (((n)<<2) + __FIRST_LDT_ENTRY) typedef struct { u64 a, b; @@ -118,14 +161,6 @@ do { #elif defined(__i386__) -#define __DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY - -#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) -#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 1) - -#define __TSS(n) (((n)<<1) + __FIRST_TSS_ENTRY) -#define __LDT(n) (((n)<<1) + __FIRST_LDT_ENTRY) - typedef struct desc_struct idt_entry_t; #define _set_gate(gate_addr,type,dpl,addr) \ @@ -155,6 +190,11 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\ #endif extern struct desc_struct gdt_table[]; +#ifdef CONFIG_COMPAT +extern struct desc_struct compat_gdt_table[]; +#else +# define compat_gdt_table gdt_table +#endif struct Xgt_desc_struct { unsigned short size; diff -r c75883680f28 -r 7c5eea5feebd xen/include/asm-x86/ldt.h --- a/xen/include/asm-x86/ldt.h Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/include/asm-x86/ldt.h Fri Jan 05 17:32:00 2007 +0000 @@ -17,7 +17,8 @@ static inline void load_LDT(struct vcpu else { cpu = smp_processor_id(); - desc = gdt_table + __LDT(cpu) - FIRST_RESERVED_GDT_ENTRY; + desc = (!IS_COMPAT(v->domain) ? gdt_table : compat_gdt_table) + + __LDT(cpu) - FIRST_RESERVED_GDT_ENTRY; _set_tssldt_desc(desc, LDT_VIRT_START(v), ents*8-1, 2); __asm__ __volatile__ ( "lldt %%ax" : : "a" (__LDT(cpu)<<3) ); } diff -r c75883680f28 -r 7c5eea5feebd xen/include/asm-x86/mm.h --- a/xen/include/asm-x86/mm.h Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/include/asm-x86/mm.h Fri Jan 05 17:32:00 2007 +0000 @@ -244,7 +244,7 @@ pae_copy_root(struct vcpu *v, l3_pgentry pae_copy_root(struct vcpu *v, l3_pgentry_t *l3tab); #endif /* CONFIG_PAGING_LEVELS == 3 */ -int check_descriptor(struct desc_struct *d); +int check_descriptor(const struct domain *, struct desc_struct *d); /* * The MPT (machine->physical mapping table) is an array of word-sized diff -r c75883680f28 -r 7c5eea5feebd xen/include/asm-x86/regs.h --- a/xen/include/asm-x86/regs.h Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/include/asm-x86/regs.h Fri Jan 05 17:32:00 2007 +0000 @@ -38,7 +38,8 @@ enum EFLAGS { ASSERT(diff < STACK_SIZE); \ /* If a guest frame, it must be have guest privs (unless HVM guest). */ \ /* We permit CS==0 which can come from an uninitialised trap entry. */ \ - ASSERT((diff != 0) || vm86_mode(r) || ((r->cs&3) >= GUEST_KERNEL_RPL) || \ + ASSERT((diff != 0) || vm86_mode(r) || \ + ((r->cs&3) >= GUEST_KERNEL_RPL(current->domain)) || \ (r->cs == 0) || is_hvm_vcpu(current)); \ /* If not a guest frame, it must be a hypervisor frame. */ \ ASSERT((diff == 0) || (!vm86_mode(r) && (r->cs == __HYPERVISOR_CS))); \ diff -r c75883680f28 -r 7c5eea5feebd xen/include/asm-x86/x86_32/regs.h --- a/xen/include/asm-x86/x86_32/regs.h Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/include/asm-x86/x86_32/regs.h Fri Jan 05 17:32:00 2007 +0000 @@ -17,7 +17,7 @@ ((dpl) >= (vm86_mode(r) ? 3 : ((r)->cs & 3))) /* Check for null trap callback handler: Is the selector null (0-3)? */ -#define null_trap_bounce(tb) (((tb)->cs & ~3) == 0) +#define null_trap_bounce(v, tb) (((tb)->cs & ~3) == 0) /* Number of bytes of on-stack execution state to be context-switched. */ #define CTXT_SWITCH_STACK_BYTES (sizeof(struct cpu_user_regs)) diff -r c75883680f28 -r 7c5eea5feebd xen/include/asm-x86/x86_64/regs.h --- a/xen/include/asm-x86/x86_64/regs.h Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/include/asm-x86/x86_64/regs.h Fri Jan 05 17:32:00 2007 +0000 @@ -11,13 +11,16 @@ #define ring_3(r) (((r)->cs & 3) == 3) #define guest_kernel_mode(v, r) \ - (ring_3(r) && ((v)->arch.flags & TF_kernel_mode)) + (!IS_COMPAT((v)->domain) ? \ + ring_3(r) && ((v)->arch.flags & TF_kernel_mode) : \ + ring_1(r)) #define permit_softint(dpl, v, r) \ ((dpl) >= (guest_kernel_mode(v, r) ? 1 : 3)) /* Check for null trap callback handler: Is the EIP null? */ -#define null_trap_bounce(tb) ((tb)->eip == 0) +#define null_trap_bounce(v, tb) \ + (!IS_COMPAT((v)->domain) ? (tb)->eip == 0 : ((tb)->cs & ~3) == 0) /* Number of bytes of on-stack execution state to be context-switched. */ /* NB. Segment registers and bases are not saved/restored on x86/64 stack. */ diff -r c75883680f28 -r 7c5eea5feebd xen/include/public/arch-x86/xen-x86_64.h --- a/xen/include/public/arch-x86/xen-x86_64.h Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/include/public/arch-x86/xen-x86_64.h Fri Jan 05 17:32:00 2007 +0000 @@ -141,7 +141,10 @@ struct iret_context { #ifdef __GNUC__ /* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ -#define __DECL_REG(name) union { uint64_t r ## name, e ## name; } +#define __DECL_REG(name) union { \ + uint64_t r ## name, e ## name; \ + uint32_t _e ## name; \ +} #else /* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */ #define __DECL_REG(name) uint64_t r ## name diff -r c75883680f28 -r 7c5eea5feebd xen/include/public/arch-x86/xen.h --- a/xen/include/public/arch-x86/xen.h Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/include/public/arch-x86/xen.h Fri Jan 05 17:32:00 2007 +0000 @@ -141,7 +141,17 @@ struct vcpu_guest_context { #else unsigned long event_callback_eip; unsigned long failsafe_callback_eip; +#ifdef __XEN__ + union { + unsigned long syscall_callback_eip; + struct { + unsigned int event_callback_cs; /* compat CS of event cb */ + unsigned int failsafe_callback_cs; /* compat CS of failsafe cb */ + }; + }; +#else unsigned long syscall_callback_eip; +#endif #endif unsigned long vm_assist; /* VMASST_TYPE_* bitmap */ #ifdef __x86_64__ diff -r c75883680f28 -r 7c5eea5feebd xen/include/xen/elf.h --- a/xen/include/xen/elf.h Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/include/xen/elf.h Fri Jan 05 17:32:00 2007 +0000 @@ -525,6 +525,15 @@ extern unsigned long long xen_elfnote_nu int type, int *defined); extern const char *xen_elfnote_string(struct domain_setup_info *dsi, int type); +#ifdef CONFIG_COMPAT +extern int elf32_sanity_check(const Elf32_Ehdr *ehdr); +extern int loadelf32image(struct domain_setup_info *); +extern int parseelf32image(struct domain_setup_info *); +extern unsigned long long xen_elf32note_numeric(struct domain_setup_info *, + int type, int *defined); +extern const char *xen_elf32note_string(struct domain_setup_info *, int type); +#endif + #ifdef Elf_Ehdr extern int elf_sanity_check(const Elf_Ehdr *ehdr); #endif diff -r c75883680f28 -r 7c5eea5feebd xen/include/xen/sched.h --- a/xen/include/xen/sched.h Fri Jan 05 17:24:55 2007 +0000 +++ b/xen/include/xen/sched.h Fri Jan 05 17:32:00 2007 +0000 @@ -422,6 +422,9 @@ extern struct domain *domain_list; /* Domain is paused by the hypervisor? */ #define _DOMF_paused 5 #define DOMF_paused (1UL<<_DOMF_paused) + /* Domain is a compatibility one? */ +#define _DOMF_compat 6 +#define DOMF_compat (1UL<<_DOMF_compat) static inline int vcpu_runnable(struct vcpu *v) { @@ -458,6 +461,13 @@ static inline void vcpu_unblock(struct v #define IS_PRIV(_d) ((_d)->is_privileged) +#ifdef CONFIG_COMPAT +#define IS_COMPAT(_d) \ + (test_bit(_DOMF_compat, &(_d)->domain_flags)) +#else +#define IS_COMPAT(_d) 0 +#endif + #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist)) #define is_hvm_domain(d) ((d)->is_hvm) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |