From cb674a9f230d1a8903f2e01d021f4f28e626feaa Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sat, 11 Dec 2004 11:42:58 +0000 Subject: [PATCH 1/7] bitkeeper revision 1.1159.187.61 (41badd42WPbpyTHpQn9bVGYapDfdOQ) Type decl cleanups from Charles Coffing. --- tools/libxc/xc.h | 17 +++++++++-------- tools/libxc/xc_linux_save.c | 7 ++++--- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/tools/libxc/xc.h b/tools/libxc/xc.h index 18665e9178..30ac7c5c99 100644 --- a/tools/libxc/xc.h +++ b/tools/libxc/xc.h @@ -9,14 +9,15 @@ #ifndef __XC_H__ #define __XC_H__ -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned long u32; -typedef unsigned long long u64; -typedef signed char s8; -typedef signed short s16; -typedef signed long s32; -typedef signed long long s64; +#include +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; #include #include diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c index 9ff85a241b..6d877c84f0 100644 --- a/tools/libxc/xc_linux_save.c +++ b/tools/libxc/xc_linux_save.c @@ -6,6 +6,7 @@ * Copyright (c) 2003, K A Fraser. */ +#include #include #include "xc_private.h" #include @@ -245,7 +246,7 @@ static int print_stats( int xc_handle, u32 domid, if ( print ) printf("delta %lldms, dom0 %d%%, target %d%%, sent %dMb/s, " - "dirtied %dMb/s %ld pages\n", + "dirtied %dMb/s %" PRId32 " pages\n", wall_delta, (int)((d0_cpu_delta*100)/wall_delta), (int)((d1_cpu_delta*100)/wall_delta), @@ -307,8 +308,8 @@ static int analysis_phase( int xc_handle, u32 domid, DOM0_SHADOW_CONTROL_OP_PEEK, NULL, 0, &stats); - printf("now= %lld faults= %ld dirty= %ld dirty_net= %ld " - "dirty_block= %ld\n", + printf("now= %lld faults= %" PRId32 " dirty= %" PRId32 + " dirty_net= %" PRId32 " dirty_block= %" PRId32"\n", ((now-start)+500)/1000, stats.fault_count, stats.dirty_count, stats.dirty_net_count, stats.dirty_block_count); From ce966235a0f426c6ee9c4548a0f67b7d63c56235 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sat, 11 Dec 2004 14:40:31 +0000 Subject: [PATCH 2/7] bitkeeper revision 1.1159.187.62 (41bb06dfBOXZ2Y0I-fSinx_R6pcANQ) Fix PCI cardbus. --- xen/common/physdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xen/common/physdev.c b/xen/common/physdev.c index 728a8fe07f..a2559e5223 100644 --- a/xen/common/physdev.c +++ b/xen/common/physdev.c @@ -742,7 +742,8 @@ void physdev_init_dom0(struct domain *p) * * In Linux2.6 we set pcibios_scan_all_fns(). */ - if ( dev->hdr_type != PCI_HEADER_TYPE_NORMAL ) + if ( (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) && + (dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) ) continue; pdev = xmalloc(sizeof(phys_dev_t)); pdev->dev = dev; From 2607eac3a51a032af447ad175751dd35379c37ad Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sun, 12 Dec 2004 17:02:07 +0000 Subject: [PATCH 3/7] bitkeeper revision 1.1159.187.63 (41bc798fur1rDv8Orxkp3jwAHWFutA) Linux 2.6 fix for 3DNOW. --- linux-2.6.9-xen-sparse/arch/xen/i386/kernel/traps.c | 1 - 1 file changed, 1 deletion(-) diff --git a/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/traps.c b/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/traps.c index 7c00926053..c24f6d52e0 100644 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/traps.c +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/kernel/traps.c @@ -1056,7 +1056,6 @@ void __init trap_init(void) * default LDT is a single-entry callgate to lcall7 for iBCS * and a callgate to lcall27 for Solaris/x86 binaries */ - clear_page(&default_ldt[0]); set_call_gate(&default_ldt[0],lcall7); set_call_gate(&default_ldt[4],lcall27); make_lowmem_page_readonly(&default_ldt[0]); From 3876b13db7efbf2de19cbdd05a7083f9fc907578 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 14 Dec 2004 10:51:30 +0000 Subject: [PATCH 4/7] bitkeeper revision 1.1159.187.64 (41bec5b2hEqxDdXD0_RNHHR7utG6gA) schedule_tail is now an indirect function call in x86 architecture. --- .rootkeys | 2 +- xen/arch/x86/boot/x86_64.S | 3 +- xen/arch/x86/domain.c | 82 +++++++++++++-------------- xen/arch/x86/setup.c | 2 + xen/arch/x86/smpboot.c | 4 -- xen/arch/x86/x86_32/entry.S | 4 -- xen/common/domain.c | 27 ++++----- xen/include/asm-x86/processor.h | 8 +-- xen/include/asm-x86/system.h | 7 --- xen/include/asm-x86/x86_32/current.h | 11 ++-- xen/include/asm-x86/x86_64/current.h | 11 ++-- xen/include/{asm-x86 => xen}/domain.h | 12 +++- xen/include/xen/sched.h | 5 +- 13 files changed, 78 insertions(+), 100 deletions(-) rename xen/include/{asm-x86 => xen}/domain.h (69%) diff --git a/.rootkeys b/.rootkeys index 87bb718abb..b8615ff886 100644 --- a/.rootkeys +++ b/.rootkeys @@ -792,7 +792,6 @@ 3ddb79c3r9-31dIsewPV3P3i8HALsQ xen/include/asm-x86/delay.h 3ddb79c34BFiXjBJ_cCKB0aCsV1IDw xen/include/asm-x86/desc.h 40715b2dTokMLYGSuD58BnxOqyWVew xen/include/asm-x86/div64.h -40f2b4a2hC3HtChu-ArD8LyojxWMjg xen/include/asm-x86/domain.h 3e20b82fl1jmQiKdLy7fxMcutfpjWA xen/include/asm-x86/domain_page.h 3ddb79c3NU8Zy40OTrq3D-i30Y3t4A xen/include/asm-x86/fixmap.h 3e2d29944GI24gf7vOP_7x8EyuqxeA xen/include/asm-x86/flushtlb.h @@ -855,6 +854,7 @@ 3eb165e0eawr3R-p2ZQtSdLWtLRN_A xen/include/xen/console.h 3ddb79c1V44RD26YqCUm-kqIupM37A xen/include/xen/ctype.h 3ddb79c05DdHQ0UxX_jKsXdR4QlMCA xen/include/xen/delay.h +40f2b4a2hC3HtChu-ArD8LyojxWMjg xen/include/xen/domain.h 3ddb79c2O729EttZTYu1c8LcsUO_GQ xen/include/xen/elf.h 3ddb79c0HIghfBF8zFUdmXhOU8i6hA xen/include/xen/errno.h 3ddb79c1W0lQca8gRV7sN6j3iY4Luw xen/include/xen/event.h diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 98289c7ab6..b16cde8762 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -270,9 +270,8 @@ copy_user_generic: memcmp: idt_tables: new_thread: -.globl switch_to, continue_nonidle_task, __get_user_1, paging_init, trap_init +.globl switch_to, __get_user_1, paging_init, trap_init switch_to: -continue_nonidle_task: __get_user_1: paging_init: trap_init: diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 4a01d86351..1881afa3fd 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -48,35 +48,16 @@ #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) #define round_pgdown(_p) ((_p)&PAGE_MASK) -int hlt_counter; - -void disable_hlt(void) -{ - hlt_counter++; -} - -void enable_hlt(void) -{ - hlt_counter--; -} - -/* - * We use this if we don't have any better - * idle routine.. - */ static void default_idle(void) { - if ( hlt_counter == 0 ) - { - __cli(); - if ( !softirq_pending(smp_processor_id()) ) - safe_halt(); - else - __sti(); - } + __cli(); + if ( !softirq_pending(smp_processor_id()) ) + safe_halt(); + else + __sti(); } -void continue_cpu_idle_loop(void) +static void idle_loop(void) { int cpu = smp_processor_id(); for ( ; ; ) @@ -102,7 +83,7 @@ void startup_cpu_idle_loop(void) smp_mb(); init_idle(); - continue_cpu_idle_loop(); + idle_loop(); } static long no_idt[2]; @@ -216,20 +197,43 @@ void free_perdomain_pt(struct domain *d) free_xenheap_page((unsigned long)d->mm.perdomain_pt); } +static void continue_idle_task(struct domain *d) +{ + reset_stack_and_jump(idle_loop); +} + +static void continue_nonidle_task(struct domain *d) +{ + reset_stack_and_jump(ret_from_intr); +} + void arch_do_createdomain(struct domain *d) { - d->shared_info = (void *)alloc_xenheap_page(); - memset(d->shared_info, 0, PAGE_SIZE); - d->shared_info->arch.mfn_to_pfn_start = - virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT; - SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d); - machine_to_phys_mapping[virt_to_phys(d->shared_info) >> - PAGE_SHIFT] = INVALID_P2M_ENTRY; +#ifdef ARCH_HAS_FAST_TRAP + SET_DEFAULT_FAST_TRAP(&d->thread); +#endif - d->mm.perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page(); - memset(d->mm.perdomain_pt, 0, PAGE_SIZE); - machine_to_phys_mapping[virt_to_phys(d->mm.perdomain_pt) >> - PAGE_SHIFT] = INVALID_P2M_ENTRY; + if ( d->id == IDLE_DOMAIN_ID ) + { + d->thread.schedule_tail = continue_idle_task; + } + else + { + d->thread.schedule_tail = continue_nonidle_task; + + d->shared_info = (void *)alloc_xenheap_page(); + memset(d->shared_info, 0, PAGE_SIZE); + d->shared_info->arch.mfn_to_pfn_start = + virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT; + SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d); + machine_to_phys_mapping[virt_to_phys(d->shared_info) >> + PAGE_SHIFT] = INVALID_P2M_ENTRY; + + d->mm.perdomain_pt = (l1_pgentry_t *)alloc_xenheap_page(); + memset(d->mm.perdomain_pt, 0, PAGE_SIZE); + machine_to_phys_mapping[virt_to_phys(d->mm.perdomain_pt) >> + PAGE_SHIFT] = INVALID_P2M_ENTRY; + } } int arch_final_setup_guestos(struct domain *d, full_execution_context_t *c) @@ -263,7 +267,6 @@ int arch_final_setup_guestos(struct domain *d, full_execution_context_t *c) sizeof(d->thread.traps)); #ifdef ARCH_HAS_FAST_TRAP - SET_DEFAULT_FAST_TRAP(&d->thread); if ( (rc = (int)set_fast_trap(d, c->fast_trap_idx)) != 0 ) return rc; #endif @@ -328,9 +331,6 @@ void new_thread(struct domain *d, __save_flags(ec->eflags); ec->eflags |= X86_EFLAGS_IF; - - /* No fast trap at start of day. */ - SET_DEFAULT_FAST_TRAP(&d->thread); } diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index cf6f7980e1..d2109f4fb8 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -328,6 +328,8 @@ void __init start_of_day(void) sort_exception_tables(); + arch_do_createdomain(current); + /* Tell the PCI layer not to allocate too close to the RAM area.. */ low_mem_size = ((max_page << PAGE_SHIFT) + 0xfffff) & ~0xfffff; if ( low_mem_size > pci_mem_start ) pci_mem_start = low_mem_size; diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 05d49a27d0..991b5c577a 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -662,10 +662,6 @@ static void __init do_boot_cpu (int apicid) map_cpu_to_boot_apicid(cpu, apicid); -#if defined(__i386__) - SET_DEFAULT_FAST_TRAP(&idle->thread); -#endif - idle_task[cpu] = idle; /* start_eip had better be page-aligned! */ diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S index c85d84c649..a3ed040538 100644 --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -65,10 +65,6 @@ andl $~3,reg; \ movl (reg),reg; -ENTRY(continue_nonidle_task) - GET_CURRENT(%ebx) - jmp test_all_events - ALIGN restore_all_guest: testb $TF_failsafe_return,DOMAIN_thread_flags(%ebx) diff --git a/xen/common/domain.c b/xen/common/domain.c index d4a97d307a..ed18817cec 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -47,20 +47,21 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) /* Per-domain PCI-device list. */ spin_lock_init(&d->pcidev_lock); INIT_LIST_HEAD(&d->pcidev_list); + + if ( (d->id != IDLE_DOMAIN_ID) && + ((init_event_channels(d) != 0) || (grant_table_create(d) != 0)) ) + { + destroy_event_channels(d); + free_domain_struct(d); + return NULL; + } + + arch_do_createdomain(d); + + sched_add_domain(d); if ( d->id != IDLE_DOMAIN_ID ) { - if ( (init_event_channels(d) != 0) || (grant_table_create(d) != 0) ) - { - destroy_event_channels(d); - free_domain_struct(d); - return NULL; - } - - arch_do_createdomain(d); - - sched_add_domain(d); - write_lock(&domlist_lock); pd = &domain_list; /* NB. domain_list maintained in order of dom_id. */ for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_list ) @@ -72,10 +73,6 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) domain_hash[DOMAIN_HASH(dom_id)] = d; write_unlock(&domlist_lock); } - else - { - sched_add_domain(d); - } return d; } diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index c5ccb59fa3..6d3cf3036a 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -399,6 +399,8 @@ struct thread_struct { /* general user-visible register state */ execution_context_t user_ctxt; + void (*schedule_tail) (struct domain *); + /* * Return vectors pushed to us by guest OS. * The stack frame for events is exactly that of an x86 hardware interrupt. @@ -456,14 +458,10 @@ extern struct desc_struct *idt_tables[]; long set_fast_trap(struct domain *p, int idx); -#define INIT_THREAD { fast_trap_idx: 0x20 } - -#elif defined(__x86_64__) +#endif #define INIT_THREAD { 0 } -#endif /* __x86_64__ */ - extern int gpf_emulate_4gb(struct xen_regs *regs); struct mm_struct { diff --git a/xen/include/asm-x86/system.h b/xen/include/asm-x86/system.h index e2c961e360..18854edc3f 100644 --- a/xen/include/asm-x86/system.h +++ b/xen/include/asm-x86/system.h @@ -271,13 +271,6 @@ static inline int local_irq_is_enabled(void) return !!(flags & (1<<9)); /* EFLAGS_IF */ } -/* - * disable hlt during certain critical i/o operations - */ -#define HAVE_DISABLE_HLT -void disable_hlt(void); -void enable_hlt(void); - #define BROKEN_ACPI_Sx 0x0001 #define BROKEN_INIT_AFTER_S1 0x0002 diff --git a/xen/include/asm-x86/x86_32/current.h b/xen/include/asm-x86/x86_32/current.h index 3450cd02cc..2c76a133aa 100644 --- a/xen/include/asm-x86/x86_32/current.h +++ b/xen/include/asm-x86/x86_32/current.h @@ -45,14 +45,11 @@ static inline unsigned long get_stack_top(void) return p; } -#define schedule_tail(_p) \ +#define reset_stack_and_jump(__fn) \ __asm__ __volatile__ ( \ - "andl %%esp,%0; addl %2,%0; movl %0,%%esp; jmp *%1" \ - : : "r" (~(STACK_SIZE-1)), \ - "r" (unlikely(is_idle_task((_p))) ? \ - continue_cpu_idle_loop : \ - continue_nonidle_task), \ - "i" (STACK_SIZE-STACK_RESERVED) ) + "movl %0,%%esp; jmp "STR(__fn) \ + : : "r" (get_execution_context()) ) +#define schedule_tail(_d) ((_d)->thread.schedule_tail)(_d) #endif /* _X86_CURRENT_H */ diff --git a/xen/include/asm-x86/x86_64/current.h b/xen/include/asm-x86/x86_64/current.h index 2f3a6e5665..2ee550643b 100644 --- a/xen/include/asm-x86/x86_64/current.h +++ b/xen/include/asm-x86/x86_64/current.h @@ -40,15 +40,12 @@ static inline unsigned long get_stack_top(void) return p; } -#define schedule_tail(_p) \ +#define reset_stack_and_jump(__fn) \ __asm__ __volatile__ ( \ - "andq %%rsp,%0; addq %2,%0; movq %0,%%rsp; jmp *%1" \ - : : "r" (~(STACK_SIZE-1)), \ - "r" (unlikely(is_idle_task((_p))) ? \ - continue_cpu_idle_loop : \ - continue_nonidle_task), \ - "i" (STACK_SIZE-STACK_RESERVED) ) + "movq %0,%%rsp; jmp "STR(__fn) \ + : : "r" (get_execution_context()) ) +#define schedule_tail(_d) ((_d)->thread.schedule_tail)(_d) #else diff --git a/xen/include/asm-x86/domain.h b/xen/include/xen/domain.h similarity index 69% rename from xen/include/asm-x86/domain.h rename to xen/include/xen/domain.h index 7dde4efa6d..5ff5ed62ad 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/xen/domain.h @@ -1,6 +1,12 @@ -#ifndef __ASM_X86_DOMAIN_H__ -#define __ASM_X86_DOMAIN_H__ +#ifndef __XEN_DOMAIN_H__ +#define __XEN_DOMAIN_H__ + + + +/* + * Arch-specifics. + */ extern void arch_do_createdomain(struct domain *d); @@ -11,4 +17,4 @@ extern void free_perdomain_pt(struct domain *d); extern void domain_relinquish_memory(struct domain *d); -#endif /* __ASM_X86_DOMAIN_H__ */ +#endif /* __XEN_DOMAIN_H__ */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index c8781f0440..d7e6f0be26 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -214,9 +214,6 @@ void domain_init(void); int idle_cpu(int cpu); /* Is CPU 'cpu' idle right now? */ void startup_cpu_idle_loop(void); -void continue_cpu_idle_loop(void); - -void continue_nonidle_task(void); unsigned long hypercall_create_continuation( unsigned int op, unsigned int nr_args, ...); @@ -295,6 +292,6 @@ static inline void domain_unpause_by_systemcontroller(struct domain *d) #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist)) #include -#include +#include #endif /* __SCHED_H__ */ From b3b32340da8438117ccb8001bfea56427a39f1ab Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 14 Dec 2004 14:45:51 +0000 Subject: [PATCH 5/7] bitkeeper revision 1.1159.187.65 (41befc9fe8LSbgOityRpN_xjEaT_mw) Copyright updates --- xen/include/public/arch-x86_32.h | 2 ++ xen/include/public/arch-x86_64.h | 2 ++ xen/include/public/trace.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/xen/include/public/arch-x86_32.h b/xen/include/public/arch-x86_32.h index dee8b783ef..b7210fc1b5 100644 --- a/xen/include/public/arch-x86_32.h +++ b/xen/include/public/arch-x86_32.h @@ -2,6 +2,8 @@ * arch-x86_32.h * * Guest OS interface to x86 32-bit Xen. + * + * Copyright (c) 2004, K A Fraser */ #ifndef __XEN_PUBLIC_ARCH_X86_32_H__ diff --git a/xen/include/public/arch-x86_64.h b/xen/include/public/arch-x86_64.h index 856b5070a8..2144b0d63b 100644 --- a/xen/include/public/arch-x86_64.h +++ b/xen/include/public/arch-x86_64.h @@ -2,6 +2,8 @@ * arch-x86_64.h * * Guest OS interface to x86 64-bit Xen. + * + * Copyright (c) 2004, K A Fraser */ #ifndef __XEN_PUBLIC_ARCH_X86_64_H__ diff --git a/xen/include/public/trace.h b/xen/include/public/trace.h index 5e7904d52a..e4ee78b975 100644 --- a/xen/include/public/trace.h +++ b/xen/include/public/trace.h @@ -1,5 +1,7 @@ /****************************************************************************** * trace.h + * + * Mark Williamson, (C) 2004 Intel Research Cambridge */ #ifndef __XEN_PUBLIC_TRACE_H__ From c155842b30d55e66e7ff21281daf99685e910a7c Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 14 Dec 2004 16:38:48 +0000 Subject: [PATCH 6/7] bitkeeper revision 1.1159.187.66 (41bf1718JfLUlcF63YjP4sfqtgAPWA) Some more x86/64 progress... --- .rootkeys | 4 + xen/arch/x86/boot/x86_64.S | 19 +- xen/arch/x86/domain.c | 9 +- xen/arch/x86/traps.c | 6 + xen/arch/x86/x86_32/entry.S | 2 +- xen/arch/x86/x86_64/asm-offsets.c | 71 ++++ xen/arch/x86/x86_64/mm.c | 455 +++++++++++++++++++++++++ xen/arch/x86/x86_64/xen.lds | 5 + xen/include/asm-x86/asm_defns.h | 18 + xen/include/asm-x86/irq.h | 2 +- xen/include/asm-x86/multicall.h | 10 +- xen/include/asm-x86/processor.h | 10 +- xen/include/asm-x86/uaccess.h | 26 ++ xen/include/asm-x86/x86_32/asm_defns.h | 13 +- xen/include/asm-x86/x86_32/uaccess.h | 21 -- xen/include/asm-x86/x86_64/asm_defns.h | 6 + xen/include/asm-x86/x86_64/uaccess.h | 24 +- 17 files changed, 626 insertions(+), 75 deletions(-) create mode 100644 xen/arch/x86/x86_64/asm-offsets.c create mode 100644 xen/arch/x86/x86_64/mm.c create mode 100644 xen/include/asm-x86/asm_defns.h create mode 100644 xen/include/asm-x86/x86_64/asm_defns.h diff --git a/.rootkeys b/.rootkeys index b8615ff886..2d0c24586c 100644 --- a/.rootkeys +++ b/.rootkeys @@ -693,7 +693,9 @@ 40f92331jfOlE7MfKwpdkEb1CEf23g xen/arch/x86/x86_32/seg_fixup.c 3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/x86_32/usercopy.c 3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/x86_32/xen.lds +41bf1717Ty3hwN3E9swdu8QfnvGqww xen/arch/x86/x86_64/asm-offsets.c 40e96d3aLDI-nViMuYneD7VKYlZrVg xen/arch/x86/x86_64/entry.S +41bf1717XhPz_dNT5OKSjgmbFuWBuA xen/arch/x86/x86_64/mm.c 40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/x86/x86_64/usercopy.c 40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds 3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile @@ -781,6 +783,7 @@ 40715b2dWe0tDhx9LkLXzTQkvD49RA xen/include/asm-x86/acpi.h 3ddb79c3l4IiQtf6MS2jIzcd-hJS8g xen/include/asm-x86/apic.h 3ddb79c3QJYWr8LLGdonLbWmNb9pQQ xen/include/asm-x86/apicdef.h +41bf17171g_hhz2k4B-fN9LQlODDjQ xen/include/asm-x86/asm_defns.h 3ddb79c3OiG9eTsi9Dy3F_OkuRAzKA xen/include/asm-x86/atomic.h 3ddb79c3rM-Ote0Xn6Ytg8Y6YqAG-A xen/include/asm-x86/bitops.h 3ddb79c3KhTI0F_Iw_hRL9QEyOVK-g xen/include/asm-x86/cache.h @@ -827,6 +830,7 @@ 3ddb79c3mbqEM7QQr3zVq7NiBNhouA xen/include/asm-x86/x86_32/regs.h 3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/x86_32/string.h 3ddb79c3M2n1ROZH6xk3HbyN4CPDqg xen/include/asm-x86/x86_32/uaccess.h +41bf1717bML6GxpclTWJabiaO5W5vg xen/include/asm-x86/x86_64/asm_defns.h 404f1b9ceJeGVaPNIENm2FkK0AgEOQ xen/include/asm-x86/x86_64/current.h 404f1b9fl6AQ_a-T1TDK3fuwTPXmHw xen/include/asm-x86/x86_64/desc.h 404f1badfXZJZ2sU8sh9PS2EZvd19Q xen/include/asm-x86/x86_64/ldt.h diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index b16cde8762..a8253a4ce1 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -257,29 +257,22 @@ copy_to_user: set_intr_gate: die: machine_to_phys_mapping: -.globl copy_from_user, show_registers, __set_fixmap, do_iopl, check_descriptor +.globl copy_from_user, show_registers, do_iopl copy_from_user: show_registers: -__set_fixmap: do_iopl: -check_descriptor: -.globl set_gdt, idt_table, copy_user_generic, memcmp, idt_tables, new_thread -set_gdt: +.globl idt_table, copy_user_generic, memcmp, idt_tables, new_thread idt_table: copy_user_generic: memcmp: idt_tables: new_thread: -.globl switch_to, __get_user_1, paging_init, trap_init +.globl switch_to, __get_user_1, __get_user_4, __get_user_8, trap_init switch_to: __get_user_1: -paging_init: -trap_init: -.globl __get_user_8, zap_low_mappings, set_debugreg,synchronise_pagetables +__get_user_4: __get_user_8: -zap_low_mappings: +trap_init: +.globl set_debugreg set_debugreg: -synchronise_pagetables: -.globl destroy_gdt -destroy_gdt: diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 1881afa3fd..964062cb89 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -427,6 +427,8 @@ long do_iopl(domid_t domain, unsigned int new_io_pl) return 0; } +#endif + unsigned long hypercall_create_continuation( unsigned int op, unsigned int nr_args, ...) { @@ -448,11 +450,15 @@ unsigned long hypercall_create_continuation( else { ec = get_execution_context(); +#if defined(__i386__) ec->eax = op; ec->eip -= 2; /* re-execute 'int 0x82' */ for ( i = 0, preg = &ec->ebx; i < nr_args; i++, preg++ ) *preg = va_arg(args, unsigned long); +#else + preg = NULL; /* XXX x86/64 */ +#endif } va_end(args); @@ -460,9 +466,6 @@ unsigned long hypercall_create_continuation( return op; } -#endif - - static void relinquish_list(struct domain *d, struct list_head *list) { struct list_head *ent; diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 842de24582..6837a143d3 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -981,4 +981,10 @@ unsigned long do_get_debugreg(int reg) return current->thread.debugreg[reg]; } +#else + +asmlinkage void fatal_trap(int trapnr, struct xen_regs *regs) +{ +} + #endif /* __i386__ */ diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S index a3ed040538..d3df231fbb 100644 --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include #define GET_CURRENT(reg) \ diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c new file mode 100644 index 0000000000..2e6c3b396e --- /dev/null +++ b/xen/arch/x86/x86_64/asm-offsets.c @@ -0,0 +1,71 @@ +/* + * Generate definitions needed by assembly language modules. + * This code generates raw asm output which is post-processed + * to extract and format the required data. + */ + +#include + +#define DEFINE(_sym, _val) \ + __asm__ __volatile__ ( "\n->" #_sym " %0 " #_val : : "i" (_val) ) +#define BLANK() \ + __asm__ __volatile__ ( "\n->" : : ) +#define OFFSET(_sym, _str, _mem) \ + DEFINE(_sym, offsetof(_str, _mem)); + +void __dummy__(void) +{ + OFFSET(XREGS_r15, struct xen_regs, r15); + OFFSET(XREGS_r14, struct xen_regs, r14); + OFFSET(XREGS_r13, struct xen_regs, r13); + OFFSET(XREGS_r12, struct xen_regs, r12); + OFFSET(XREGS_rbp, struct xen_regs, rbp); + OFFSET(XREGS_rbx, struct xen_regs, rbx); + OFFSET(XREGS_r11, struct xen_regs, r11); + OFFSET(XREGS_r10, struct xen_regs, r10); + OFFSET(XREGS_r9, struct xen_regs, r9); + OFFSET(XREGS_r8, struct xen_regs, r8); + OFFSET(XREGS_rax, struct xen_regs, rax); + OFFSET(XREGS_rcx, struct xen_regs, rcx); + OFFSET(XREGS_rdx, struct xen_regs, rdx); + OFFSET(XREGS_rsi, struct xen_regs, rsi); + OFFSET(XREGS_rdi, struct xen_regs, rdi); + OFFSET(XREGS_orig_rax, struct xen_regs, orig_rax); + OFFSET(XREGS_rip, struct xen_regs, rip); + OFFSET(XREGS_cs, struct xen_regs, cs); + OFFSET(XREGS_eflags, struct xen_regs, eflags); + OFFSET(XREGS_rsp, struct xen_regs, rsp); + OFFSET(XREGS_ss, struct xen_regs, ss); + BLANK(); + + OFFSET(DOMAIN_processor, struct domain, processor); + OFFSET(DOMAIN_shared_info, struct domain, shared_info); + OFFSET(DOMAIN_event_sel, struct domain, thread.event_selector); + OFFSET(DOMAIN_event_addr, struct domain, thread.event_address); + OFFSET(DOMAIN_failsafe_sel, struct domain, thread.failsafe_selector); + OFFSET(DOMAIN_failsafe_addr, struct domain, thread.failsafe_address); + OFFSET(DOMAIN_trap_bounce, struct domain, thread.trap_bounce); + OFFSET(DOMAIN_thread_flags, struct domain, thread.flags); + BLANK(); + + OFFSET(SHINFO_upcall_pending, shared_info_t, + vcpu_data[0].evtchn_upcall_pending); + OFFSET(SHINFO_upcall_mask, shared_info_t, + vcpu_data[0].evtchn_upcall_mask); + BLANK(); + + OFFSET(TRAPBOUNCE_error_code, struct trap_bounce, error_code); + OFFSET(TRAPBOUNCE_cr2, struct trap_bounce, cr2); + OFFSET(TRAPBOUNCE_flags, struct trap_bounce, flags); + OFFSET(TRAPBOUNCE_cs, struct trap_bounce, cs); + OFFSET(TRAPBOUNCE_eip, struct trap_bounce, eip); + BLANK(); + + OFFSET(MULTICALL_op, multicall_entry_t, op); + OFFSET(MULTICALL_arg0, multicall_entry_t, args[0]); + OFFSET(MULTICALL_arg1, multicall_entry_t, args[1]); + OFFSET(MULTICALL_arg2, multicall_entry_t, args[2]); + OFFSET(MULTICALL_arg3, multicall_entry_t, args[3]); + OFFSET(MULTICALL_arg4, multicall_entry_t, args[4]); + OFFSET(MULTICALL_result, multicall_entry_t, args[5]); +} diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c new file mode 100644 index 0000000000..c7bcb17805 --- /dev/null +++ b/xen/arch/x86/x86_64/mm.c @@ -0,0 +1,455 @@ +/****************************************************************************** + * arch/x86/x86_64/mm.c + * + * Modifications to Linux original are copyright (c) 2004, K A Fraser + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static inline void set_pte_phys(unsigned long vaddr, + l1_pgentry_t entry) +{ + l4_pgentry_t *l4ent; + l3_pgentry_t *l3ent; + l2_pgentry_t *l2ent; + l1_pgentry_t *l1ent; + + l4ent = &idle_pg_table[l4_table_offset(vaddr)]; + l3ent = l4_pgentry_to_l3(*l4ent) + l3_table_offset(vaddr); + l2ent = l3_pgentry_to_l2(*l3ent) + l2_table_offset(vaddr); + l1ent = l2_pgentry_to_l1(*l2ent) + l1_table_offset(vaddr); + *l1ent = entry; + + /* It's enough to flush this one mapping. */ + __flush_tlb_one(vaddr); +} + + +void __set_fixmap(enum fixed_addresses idx, + l1_pgentry_t entry) +{ + unsigned long address = fix_to_virt(idx); + + if ( likely(idx < __end_of_fixed_addresses) ) + set_pte_phys(address, entry); + else + printk("Invalid __set_fixmap\n"); +} + + +void __init paging_init(void) +{ + void *ioremap_pt; + int i; + + /* Create page table for ioremap(). */ + ioremap_pt = (void *)alloc_xenheap_page(); + clear_page(ioremap_pt); + idle_pg_table[IOREMAP_VIRT_START >> L2_PAGETABLE_SHIFT] = + mk_l2_pgentry(__pa(ioremap_pt) | __PAGE_HYPERVISOR); + + /* Create read-only mapping of MPT for guest-OS use. */ + idle_pg_table[RO_MPT_VIRT_START >> L2_PAGETABLE_SHIFT] = + mk_l2_pgentry(l2_pgentry_val( + idle_pg_table[RDWR_MPT_VIRT_START >> L2_PAGETABLE_SHIFT]) & + ~_PAGE_RW); + + /* Set up mapping cache for domain pages. */ + mapcache = (unsigned long *)alloc_xenheap_page(); + clear_page(mapcache); + idle_pg_table[MAPCACHE_VIRT_START >> L2_PAGETABLE_SHIFT] = + mk_l2_pgentry(__pa(mapcache) | __PAGE_HYPERVISOR); + + /* Set up linear page table mapping. */ + idle_pg_table[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] = + mk_l2_pgentry(__pa(idle_pg_table) | __PAGE_HYPERVISOR); + +} + +void __init zap_low_mappings(void) +{ + idle_pg_table[0] = 0; +} + + +/* + * Allows shooting down of borrowed page-table use on specific CPUs. + * Specifically, we borrow page tables when running the idle domain. + */ +static void __synchronise_pagetables(void *mask) +{ + struct domain *d = current; + if ( ((unsigned long)mask & (1<processor)) && is_idle_task(d) ) + write_ptbase(&d->mm); +} +void synchronise_pagetables(unsigned long cpu_mask) +{ + __synchronise_pagetables((void *)cpu_mask); + smp_call_function(__synchronise_pagetables, (void *)cpu_mask, 1, 1); +} + +long do_stack_switch(unsigned long ss, unsigned long esp) +{ + int nr = smp_processor_id(); + struct tss_struct *t = &init_tss[nr]; + + /* We need to do this check as we load and use SS on guest's behalf. */ + if ( (ss & 3) == 0 ) + return -EPERM; + + current->thread.guestos_ss = ss; + current->thread.guestos_sp = esp; + t->ss1 = ss; + t->esp1 = esp; + + return 0; +} + + +/* Returns TRUE if given descriptor is valid for GDT or LDT. */ +int check_descriptor(unsigned long *d) +{ + unsigned long base, limit, a = d[0], b = d[1]; + + /* A not-present descriptor will always fault, so is safe. */ + if ( !(b & _SEGMENT_P) ) + goto good; + + /* + * We don't allow a DPL of zero. There is no legitimate reason for + * specifying DPL==0, and it gets rather dangerous if we also accept call + * gates (consider a call gate pointing at another guestos descriptor with + * DPL 0 -- this would get the OS ring-0 privileges). + */ + if ( (b & _SEGMENT_DPL) == 0 ) + goto bad; + + if ( !(b & _SEGMENT_S) ) + { + /* + * System segment: + * 1. Don't allow interrupt or trap gates as they belong in the IDT. + * 2. Don't allow TSS descriptors or task gates as we don't + * virtualise x86 tasks. + * 3. Don't allow LDT descriptors because they're unnecessary and + * I'm uneasy about allowing an LDT page to contain LDT + * descriptors. In any case, Xen automatically creates the + * required descriptor when reloading the LDT register. + * 4. We allow call gates but they must not jump to a private segment. + */ + + /* Disallow everything but call gates. */ + if ( (b & _SEGMENT_TYPE) != 0xc00 ) + goto bad; + + /* Can't allow far jump to a Xen-private segment. */ + if ( !VALID_CODESEL(a>>16) ) + goto bad; + + /* Reserved bits must be zero. */ + if ( (b & 0xe0) != 0 ) + goto bad; + + /* No base/limit check is needed for a call gate. */ + goto good; + } + + /* Check that base is at least a page away from Xen-private area. */ + base = (b&(0xff<<24)) | ((b&0xff)<<16) | (a>>16); + if ( base >= (PAGE_OFFSET - PAGE_SIZE) ) + goto bad; + + /* Check and truncate the limit if necessary. */ + limit = (b&0xf0000) | (a&0xffff); + limit++; /* We add one because limit is inclusive. */ + if ( (b & _SEGMENT_G) ) + limit <<= 12; + + if ( (b & (_SEGMENT_CODE | _SEGMENT_EC)) == _SEGMENT_EC ) + { + /* + * Grows-down limit check. + * NB. limit == 0xFFFFF provides no access (if G=1). + * limit == 0x00000 provides 4GB-4kB access (if G=1). + */ + if ( (base + limit) > base ) + { + limit = -(base & PAGE_MASK); + goto truncate; + } + } + else + { + /* + * Grows-up limit check. + * NB. limit == 0xFFFFF provides 4GB access (if G=1). + * limit == 0x00000 provides 4kB access (if G=1). + */ + if ( ((base + limit) <= base) || + ((base + limit) > PAGE_OFFSET) ) + { + limit = PAGE_OFFSET - base; + truncate: + if ( !(b & _SEGMENT_G) ) + goto bad; /* too dangerous; too hard to work out... */ + limit = (limit >> 12) - 1; + d[0] &= ~0x0ffff; d[0] |= limit & 0x0ffff; + d[1] &= ~0xf0000; d[1] |= limit & 0xf0000; + } + } + + good: + return 1; + bad: + return 0; +} + + +void destroy_gdt(struct domain *d) +{ + int i; + unsigned long pfn; + + for ( i = 0; i < 16; i++ ) + { + if ( (pfn = l1_pgentry_to_pagenr(d->mm.perdomain_pt[i])) != 0 ) + put_page_and_type(&frame_table[pfn]); + d->mm.perdomain_pt[i] = mk_l1_pgentry(0); + } +} + + +long set_gdt(struct domain *d, + unsigned long *frames, + unsigned int entries) +{ + /* NB. There are 512 8-byte entries per GDT page. */ + int i = 0, nr_pages = (entries + 511) / 512; + struct desc_struct *vgdt; + unsigned long pfn; + + /* Check the first page in the new GDT. */ + if ( (pfn = frames[0]) >= max_page ) + goto fail; + + /* The first page is special because Xen owns a range of entries in it. */ + if ( !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) ) + { + /* GDT checks failed: try zapping the Xen reserved entries. */ + if ( !get_page_and_type(&frame_table[pfn], d, PGT_writable_page) ) + goto fail; + vgdt = map_domain_mem(pfn << PAGE_SHIFT); + memset(vgdt + FIRST_RESERVED_GDT_ENTRY, 0, + NR_RESERVED_GDT_ENTRIES*8); + unmap_domain_mem(vgdt); + put_page_and_type(&frame_table[pfn]); + + /* Okay, we zapped the entries. Now try the GDT checks again. */ + if ( !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) ) + goto fail; + } + + /* Check the remaining pages in the new GDT. */ + for ( i = 1; i < nr_pages; i++ ) + if ( ((pfn = frames[i]) >= max_page) || + !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) ) + goto fail; + + /* Copy reserved GDT entries to the new GDT. */ + vgdt = map_domain_mem(frames[0] << PAGE_SHIFT); + memcpy(vgdt + FIRST_RESERVED_GDT_ENTRY, + gdt_table + FIRST_RESERVED_GDT_ENTRY, + NR_RESERVED_GDT_ENTRIES*8); + unmap_domain_mem(vgdt); + + /* Tear down the old GDT. */ + destroy_gdt(d); + + /* Install the new GDT. */ + for ( i = 0; i < nr_pages; i++ ) + d->mm.perdomain_pt[i] = + mk_l1_pgentry((frames[i] << PAGE_SHIFT) | __PAGE_HYPERVISOR); + + SET_GDT_ADDRESS(d, GDT_VIRT_START); + SET_GDT_ENTRIES(d, entries); + + return 0; + + fail: + while ( i-- > 0 ) + put_page_and_type(&frame_table[frames[i]]); + return -EINVAL; +} + + +long do_set_gdt(unsigned long *frame_list, unsigned int entries) +{ + int nr_pages = (entries + 511) / 512; + unsigned long frames[16]; + long ret; + + if ( (entries <= LAST_RESERVED_GDT_ENTRY) || (entries > 8192) ) + return -EINVAL; + + if ( copy_from_user(frames, frame_list, nr_pages * sizeof(unsigned long)) ) + return -EFAULT; + + if ( (ret = set_gdt(current, frames, entries)) == 0 ) + { + local_flush_tlb(); + __asm__ __volatile__ ("lgdt %0" : "=m" (*current->mm.gdt)); + } + + return ret; +} + + +long do_update_descriptor( + unsigned long pa, unsigned long word1, unsigned long word2) +{ + unsigned long *gdt_pent, pfn = pa >> PAGE_SHIFT, d[2]; + struct pfn_info *page; + long ret = -EINVAL; + + d[0] = word1; + d[1] = word2; + + if ( (pa & 7) || (pfn >= max_page) || !check_descriptor(d) ) + return -EINVAL; + + page = &frame_table[pfn]; + if ( unlikely(!get_page(page, current)) ) + return -EINVAL; + + /* Check if the given frame is in use in an unsafe context. */ + switch ( page->u.inuse.type_info & PGT_type_mask ) + { + case PGT_gdt_page: + /* Disallow updates of Xen-reserved descriptors in the current GDT. */ + if ( (l1_pgentry_to_pagenr(current->mm.perdomain_pt[0]) == pfn) && + (((pa&(PAGE_SIZE-1))>>3) >= FIRST_RESERVED_GDT_ENTRY) && + (((pa&(PAGE_SIZE-1))>>3) <= LAST_RESERVED_GDT_ENTRY) ) + goto out; + if ( unlikely(!get_page_type(page, PGT_gdt_page)) ) + goto out; + break; + case PGT_ldt_page: + if ( unlikely(!get_page_type(page, PGT_ldt_page)) ) + goto out; + break; + default: + if ( unlikely(!get_page_type(page, PGT_writable_page)) ) + goto out; + break; + } + + /* All is good so make the update. */ + gdt_pent = map_domain_mem(pa); + memcpy(gdt_pent, d, 8); + unmap_domain_mem(gdt_pent); + + put_page_type(page); + + ret = 0; /* success */ + + out: + put_page(page); + return ret; +} + +#ifdef MEMORY_GUARD + +void *memguard_init(void *heap_start) +{ + l1_pgentry_t *l1; + int i, j; + + /* Round the allocation pointer up to a page boundary. */ + heap_start = (void *)(((unsigned long)heap_start + (PAGE_SIZE-1)) & + PAGE_MASK); + + /* Memory guarding is incompatible with super pages. */ + for ( i = 0; i < (xenheap_phys_end >> L2_PAGETABLE_SHIFT); i++ ) + { + l1 = (l1_pgentry_t *)heap_start; + heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE); + for ( j = 0; j < ENTRIES_PER_L1_PAGETABLE; j++ ) + l1[j] = mk_l1_pgentry((i << L2_PAGETABLE_SHIFT) | + (j << L1_PAGETABLE_SHIFT) | + __PAGE_HYPERVISOR); + idle_pg_table[i] = idle_pg_table[i + l2_table_offset(PAGE_OFFSET)] = + mk_l2_pgentry(virt_to_phys(l1) | __PAGE_HYPERVISOR); + } + + return heap_start; +} + +static void __memguard_change_range(void *p, unsigned long l, int guard) +{ + l1_pgentry_t *l1; + l2_pgentry_t *l2; + unsigned long _p = (unsigned long)p; + unsigned long _l = (unsigned long)l; + + /* Ensure we are dealing with a page-aligned whole number of pages. */ + ASSERT((_p&PAGE_MASK) != 0); + ASSERT((_l&PAGE_MASK) != 0); + ASSERT((_p&~PAGE_MASK) == 0); + ASSERT((_l&~PAGE_MASK) == 0); + + while ( _l != 0 ) + { + l2 = &idle_pg_table[l2_table_offset(_p)]; + l1 = l2_pgentry_to_l1(*l2) + l1_table_offset(_p); + if ( guard ) + *l1 = mk_l1_pgentry(l1_pgentry_val(*l1) & ~_PAGE_PRESENT); + else + *l1 = mk_l1_pgentry(l1_pgentry_val(*l1) | _PAGE_PRESENT); + _p += PAGE_SIZE; + _l -= PAGE_SIZE; + } +} + +void memguard_guard_range(void *p, unsigned long l) +{ + __memguard_change_range(p, l, 1); + local_flush_tlb(); +} + +void memguard_unguard_range(void *p, unsigned long l) +{ + __memguard_change_range(p, l, 0); +} + +int memguard_is_guarded(void *p) +{ + l1_pgentry_t *l1; + l2_pgentry_t *l2; + unsigned long _p = (unsigned long)p; + l2 = &idle_pg_table[l2_table_offset(_p)]; + l1 = l2_pgentry_to_l1(*l2) + l1_table_offset(_p); + return !(l1_pgentry_val(*l1) & _PAGE_PRESENT); +} + +#endif diff --git a/xen/arch/x86/x86_64/xen.lds b/xen/arch/x86/x86_64/xen.lds index 4763fdf55a..8a6b3a27ac 100644 --- a/xen/arch/x86/x86_64/xen.lds +++ b/xen/arch/x86/x86_64/xen.lds @@ -28,6 +28,11 @@ SECTIONS __ex_table : { *(__ex_table) } :text __stop___ex_table = .; + . = ALIGN(16); /* Pre-exception table */ + __start___pre_ex_table = .; + __pre_ex_table : { *(__pre_ex_table) } :text + __stop___pre_ex_table = .; + __start___ksymtab = .; /* Kernel symbol table */ __ksymtab : { *(__ksymtab) } :text __stop___ksymtab = .; diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h new file mode 100644 index 0000000000..0fb3e44727 --- /dev/null +++ b/xen/include/asm-x86/asm_defns.h @@ -0,0 +1,18 @@ + +#ifndef __X86_ASM_DEFNS_H__ +#define __X86_ASM_DEFNS_H__ + +/* NB. Auto-generated from arch/.../asm-offsets.c */ +#include +#include + +#define __STR(x) #x +#define STR(x) __STR(x) + +#ifdef __x86_64__ +#include +#else +#include +#endif + +#endif /* __X86_ASM_DEFNS_H__ */ diff --git a/xen/include/asm-x86/irq.h b/xen/include/asm-x86/irq.h index b07fef7809..2779282659 100644 --- a/xen/include/asm-x86/irq.h +++ b/xen/include/asm-x86/irq.h @@ -5,7 +5,7 @@ #include #include -#include +#include extern void disable_irq(unsigned int); extern void disable_irq_nosync(unsigned int); diff --git a/xen/include/asm-x86/multicall.h b/xen/include/asm-x86/multicall.h index e1a7770354..d03ac9ffb1 100644 --- a/xen/include/asm-x86/multicall.h +++ b/xen/include/asm-x86/multicall.h @@ -5,7 +5,13 @@ #ifndef __ASM_X86_MULTICALL_H__ #define __ASM_X86_MULTICALL_H__ -#include +#include + +#ifdef __x86_64__ + +#define do_multicall_call(_call) BUG() + +#else #define do_multicall_call(_call) \ do { \ @@ -23,4 +29,6 @@ : : "b" (_call) : "eax", "ecx", "edx" ); \ } while ( 0 ) +#endif + #endif /* __ASM_X86_MULTICALL_H__ */ diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index 6d3cf3036a..ae5b13b7d1 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -254,18 +254,18 @@ static inline unsigned int cpuid_edx(unsigned int op) }) #define write_cr0(x) \ - __asm__("mov"__OS" %0,%%cr0": :"r" (x)); + __asm__("mov"__OS" %0,%%cr0": :"r" ((unsigned long)x)); #define read_cr4() ({ \ - unsigned int __dummy; \ + unsigned long __dummy; \ __asm__( \ - "movl %%cr4,%0\n\t" \ + "mov"__OS" %%cr4,%0\n\t" \ :"=r" (__dummy)); \ __dummy; \ }) #define write_cr4(x) \ - __asm__("movl %0,%%cr4": :"r" (x)); + __asm__("mov"__OS" %0,%%cr4": :"r" ((unsigned long)x)); /* * Save the cr4 feature set we're using (ie @@ -290,7 +290,7 @@ static inline void clear_in_cr4 (unsigned long mask) mmu_cr4_features &= ~mask; __asm__("mov"__OS" %%cr4,%%"__OP"ax\n\t" "and"__OS" %0,%%"__OP"ax\n\t" - "movl"__OS" %%"__OP"ax,%%cr4\n" + "mov"__OS" %%"__OP"ax,%%cr4\n" : : "irg" (~mask) :"ax"); } diff --git a/xen/include/asm-x86/uaccess.h b/xen/include/asm-x86/uaccess.h index 52a8b25c56..46c02ecef4 100644 --- a/xen/include/asm-x86/uaccess.h +++ b/xen/include/asm-x86/uaccess.h @@ -1,6 +1,32 @@ +#ifndef __X86_UACCESS_H__ +#define __X86_UACCESS_H__ + #ifdef __x86_64__ #include #else #include #endif + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +extern unsigned long search_exception_table(unsigned long); +extern void sort_exception_tables(void); + +#endif /* __X86_UACCESS_H__ */ diff --git a/xen/include/asm-x86/x86_32/asm_defns.h b/xen/include/asm-x86/x86_32/asm_defns.h index 8231bb2dec..e11ea34964 100644 --- a/xen/include/asm-x86/x86_32/asm_defns.h +++ b/xen/include/asm-x86/x86_32/asm_defns.h @@ -1,12 +1,5 @@ -#ifndef __ASM_DEFNS_H__ -#define __ASM_DEFNS_H__ - -/* NB. Auto-generated from arch/.../asm-offsets.c */ -#include -#include - -#define __STR(x) #x -#define STR(x) __STR(x) +#ifndef __X86_32_ASM_DEFNS_H__ +#define __X86_32_ASM_DEFNS_H__ /* Maybe auto-generate the following two cases (quoted vs. unquoted). */ #ifndef __ASSEMBLY__ @@ -85,4 +78,4 @@ #endif -#endif /* __ASM_DEFNS_H__ */ +#endif /* __X86_32_ASM_DEFNS_H__ */ diff --git a/xen/include/asm-x86/x86_32/uaccess.h b/xen/include/asm-x86/x86_32/uaccess.h index 650492d59e..b202a1a12b 100644 --- a/xen/include/asm-x86/x86_32/uaccess.h +++ b/xen/include/asm-x86/x86_32/uaccess.h @@ -69,27 +69,6 @@ extern struct movsl_mask { #define array_access_ok(type,addr,count,size) \ (likely(count < (~0UL/size)) && access_ok(type,addr,count*size)) -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - -extern unsigned long search_exception_table(unsigned long); -extern void sort_exception_tables(void); - /** * get_user: - Get a simple variable from user space. * @x: Variable to store result. diff --git a/xen/include/asm-x86/x86_64/asm_defns.h b/xen/include/asm-x86/x86_64/asm_defns.h new file mode 100644 index 0000000000..fa0b978304 --- /dev/null +++ b/xen/include/asm-x86/x86_64/asm_defns.h @@ -0,0 +1,6 @@ +#ifndef __X86_64_ASM_DEFNS_H__ +#define __X86_64_ASM_DEFNS_H__ + +#define SAVE_ALL(_r) "" + +#endif /* __X86_64_ASM_DEFNS_H__ */ diff --git a/xen/include/asm-x86/x86_64/uaccess.h b/xen/include/asm-x86/x86_64/uaccess.h index be49ff870b..f965c87d32 100644 --- a/xen/include/asm-x86/x86_64/uaccess.h +++ b/xen/include/asm-x86/x86_64/uaccess.h @@ -35,31 +35,15 @@ #define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0) +#define array_access_ok(type,addr,count,size) \ + (likely(sizeof(count) <= 4) /* disallow 64-bit counts */ && \ + access_ok(type,addr,count*size)) + extern inline int verify_area(int type, const void __user * addr, unsigned long size) { return access_ok(type,addr,size) ? 0 : -EFAULT; } - -/* - * The exception table consists of pairs of addresses: the first is the - * address of an instruction that is allowed to fault, and the second is - * the address at which the program should continue. No registers are - * modified, so it is entirely up to the continuation code to figure out - * what to do. - * - * All the routines below use bits of fixup code that are out of line - * with the main instruction path. This means when everything is well, - * we don't even have to jump over them. Further, they do not intrude - * on our cache or tlb entries. - */ - -struct exception_table_entry -{ - unsigned long insn, fixup; -}; - - /* * These are the main single-value transfer routines. They automatically * use the right size if we just have the right pointer type. From b0567edaaadc96995eaf9353a4c5879179b42294 Mon Sep 17 00:00:00 2001 From: "cl349@arcadians.cl.cam.ac.uk" Date: Tue, 14 Dec 2004 17:07:36 +0000 Subject: [PATCH 7/7] bitkeeper revision 1.1159.204.1 (41bf1dd8Z_SVQLEm3wU35arFIdsQEQ) Bump version numbers. --- xen/Makefile | 4 ++-- xen/include/public/dom0_ops.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/xen/Makefile b/xen/Makefile index d08706d669..c1e60c5043 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -1,9 +1,9 @@ # This is the correct place to edit the build version. # All other places this is stored (eg. compile.h) should be autogenerated. -export XEN_VERSION = 2 +export XEN_VERSION = 3 export XEN_SUBVERSION = 0 -export XEN_EXTRAVERSION = "" +export XEN_EXTRAVERSION = "-devel" export BASEDIR := $(shell pwd) diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index 9673c88678..e2a3786f95 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -19,7 +19,7 @@ * This makes sure that old versions of dom0 tools will stop working in a * well-defined way (rather than crashing the machine, for instance). */ -#define DOM0_INTERFACE_VERSION 0xAAAA001A +#define DOM0_INTERFACE_VERSION 0xAAAA1001 /************************************************************************/