diff options
-rw-r--r-- | .rootkeys | 1 | ||||
-rw-r--r-- | xen/arch/x86/Rules.mk | 2 | ||||
-rw-r--r-- | xen/arch/x86/boot/x86_64.S | 23 | ||||
-rw-r--r-- | xen/arch/x86/irq.c | 10 | ||||
-rw-r--r-- | xen/arch/x86/smpboot.c | 17 | ||||
-rw-r--r-- | xen/arch/x86/traps.c | 31 | ||||
-rw-r--r-- | xen/arch/x86/x86_32/traps.c | 24 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/entry.S | 154 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/traps.c | 30 | ||||
-rw-r--r-- | xen/include/asm-x86/config.h | 10 | ||||
-rw-r--r-- | xen/include/asm-x86/desc.h | 14 | ||||
-rw-r--r-- | xen/include/asm-x86/irq.h | 78 | ||||
-rw-r--r-- | xen/include/asm-x86/pda.h | 63 | ||||
-rw-r--r-- | xen/include/asm-x86/smp.h | 5 | ||||
-rw-r--r-- | xen/include/asm-x86/x86_32/asm_defns.h | 47 | ||||
-rw-r--r-- | xen/include/asm-x86/x86_64/asm_defns.h | 89 | ||||
-rw-r--r-- | xen/include/asm-x86/x86_64/current.h | 21 |
17 files changed, 397 insertions, 222 deletions
@@ -1020,7 +1020,6 @@ 41a61536MFhNalgbVmYGXAhQsPTZNw xen/include/asm-x86/multicall.h 3ddb79c3xjYnrv5t3VqYlR4tNEOl4Q xen/include/asm-x86/page.h 3ddb79c3ysKUbxZuwKBRK3WXU2TlEg xen/include/asm-x86/pci.h -404f1bb41Yl-5ZjIWnG66HDCj6OIWA xen/include/asm-x86/pda.h 4022a73diKn2Ax4-R4gzk59lm1YdDg xen/include/asm-x86/pdb.h 3ddb79c2QF5-pZGzuX4QukPCDAl59A xen/include/asm-x86/processor.h 40cf1596bim9F9DNdV75klgRSZ6Y2A xen/include/asm-x86/regs.h diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk index c3e1c2aea1..1eda23b416 100644 --- a/xen/arch/x86/Rules.mk +++ b/xen/arch/x86/Rules.mk @@ -5,7 +5,7 @@ CC := gcc LD := ld CFLAGS := -nostdinc -fno-builtin -fno-common -fno-strict-aliasing -CFLAGS += -iwithprefix include -Wall -Werror -pipe +CFLAGS += -iwithprefix include -Wall -Werror -Wno-format -pipe CFLAGS += -I$(BASEDIR)/include -Wno-pointer-arith -Wredundant-decls ifeq ($(optimize),y) diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index f1bc4ece46..d867340480 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -52,16 +52,16 @@ __start: /* Set up a few descriptors: on entry only CS is guaranteed good. */ lgdt %cs:0x1001f0 - mov $(__HYPERVISOR_DS),%ecx + mov $(__HYPERVISOR_DS32),%ecx mov %ecx,%ds mov %ecx,%es - /* Check for Multiboot bootloader */ cmp $(SECONDARY_CPU_FLAG),%ebx - je skip_multiboot_check + je skip_boot_checks + + /* Check for Multiboot bootloader */ cmp $0x2BADB002,%eax jne not_multiboot -skip_multiboot_check: /* Save the Multiboot info structure for later use. */ mov %ebx,0x1001e0 @@ -75,7 +75,8 @@ skip_multiboot_check: cpuid bt $29,%edx # Long mode feature? jnc bad_cpu - +skip_boot_checks: + /* Set up FPU. */ fninit @@ -123,6 +124,13 @@ skip_multiboot_check: ret __high_start: + mov $(__HYPERVISOR_DS64),%ecx + mov %ecx,%ds + mov %ecx,%es + mov %ecx,%fs + mov %ecx,%gs + mov %ecx,%ss + lidt idt_descr(%rip) cmp $(SECONDARY_CPU_FLAG),%ebx @@ -203,7 +211,7 @@ SYMBOL_NAME(idt): .quad SYMBOL_NAME(idt_table) ENTRY(stack_start) - .quad SYMBOL_NAME(cpu0_stack) + 8100 + .quad SYMBOL_NAME(cpu0_stack) + 8000 high_start: .quad __high_start @@ -241,9 +249,8 @@ ENTRY(cpu0_stack) # Initial stack is 8kB ENTRY(stext) ENTRY(_stext) -.globl switch_to, ret_from_intr, do_iopl +.globl switch_to, do_iopl switch_to: -ret_from_intr: do_iopl: .globl copy_from_user, copy_to_user, copy_user_generic, new_thread copy_from_user: diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 81b8e37d31..210c52b8af 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -87,13 +87,9 @@ void enable_irq(unsigned int irq) spin_unlock_irqrestore(&desc->lock, flags); } -asmlinkage void do_IRQ(struct xen_regs regs) +asmlinkage void do_IRQ(struct xen_regs *regs) { -#if defined(__i386__) - unsigned int irq = regs.entry_vector; -#else - unsigned int irq = 0; /* XXX */ -#endif + unsigned int irq = regs->entry_vector; irq_desc_t *desc = &irq_desc[irq]; struct irqaction *action; @@ -127,7 +123,7 @@ asmlinkage void do_IRQ(struct xen_regs regs) desc->status &= ~IRQ_PENDING; irq_enter(smp_processor_id(), irq); spin_unlock_irq(&desc->lock); - action->handler(irq, action->dev_id, ®s); + action->handler(irq, action->dev_id, regs); spin_lock_irq(&desc->lock); irq_exit(smp_processor_id(), irq); } diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 7a98fd8ae5..f7c7e3d137 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -409,7 +409,7 @@ void __init start_secondary(void) * At this point, boot CPU has fully initialised the IDT. It is * now safe to make ourselves a private copy. */ - idt_tables[cpu] = xmalloc_array(struct desc_struct, IDT_ENTRIES); + idt_tables[cpu] = xmalloc_array(idt_entry_t, IDT_ENTRIES); memcpy(idt_tables[cpu], idt_table, IDT_ENTRIES*8); *(unsigned short *)(&idt_load[0]) = (IDT_ENTRIES*8)-1; *(unsigned long *)(&idt_load[2]) = (unsigned long)idt_tables[cpu]; @@ -650,7 +650,8 @@ static void __init do_boot_cpu (int apicid) struct exec_domain *ed; unsigned long boot_error = 0; int timeout, cpu; - unsigned long start_eip, stack; + unsigned long start_eip; + void *stack; cpu = ++cpucount; @@ -673,11 +674,15 @@ static void __init do_boot_cpu (int apicid) /* So we see what's up. */ printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); - stack = __pa(alloc_xenheap_pages(1)); - stack_start.esp = stack + STACK_SIZE - STACK_RESERVED; + stack = (void *)alloc_xenheap_pages(1); +#if defined(__i386__) + stack_start.esp = __pa(stack) + STACK_SIZE - STACK_RESERVED; +#elif defined(__x86_64__) + stack_start.esp = (unsigned long)stack + STACK_SIZE - STACK_RESERVED; +#endif /* Debug build: detect stack overflow by setting up a guard page. */ - memguard_guard_range(__va(stack), PAGE_SIZE); + memguard_guard_range(stack, PAGE_SIZE); /* * This grunge runs the startup process for @@ -739,7 +744,7 @@ static void __init do_boot_cpu (int apicid) printk("CPU%d has booted.\n", cpu); } else { boot_error= 1; - if (*((volatile unsigned long *)phys_to_virt(start_eip)) + if (*((volatile unsigned int *)phys_to_virt(start_eip)) == 0xA5A5A5A5) /* trampoline started but...? */ printk("Stuck ??\n"); diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 773f6be78e..e70c56a6e2 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -116,7 +116,7 @@ asmlinkage void fatal_trap(int trapnr, struct xen_regs *regs) if ( trapnr == TRAP_page_fault ) { __asm__ __volatile__ ("mov %%cr2,%0" : "=r" (cr2) : ); - printk("Faulting linear address might be %08lx\n", cr2); + printk("Faulting linear address might be %0lx %lx\n", cr2, cr2); } printk("************************************\n"); @@ -165,7 +165,7 @@ static inline int do_trap(int trapnr, char *str, if ( likely((fixup = search_exception_table(regs->eip)) != 0) ) { - DPRINTK("Trap %d: %08lx -> %08lx\n", trapnr, regs->eip, fixup); + DPRINTK("Trap %d: %p -> %p\n", trapnr, regs->eip, fixup); regs->eip = fixup; return 0; } @@ -322,7 +322,7 @@ asmlinkage int do_page_fault(struct xen_regs *regs) { perfc_incrc(copy_user_faults); if ( !ed->mm.shadow_mode ) - DPRINTK("Page fault: %08lx -> %08lx\n", regs->eip, fixup); + DPRINTK("Page fault: %p -> %p\n", regs->eip, fixup); regs->eip = fixup; return 0; } @@ -334,12 +334,12 @@ asmlinkage int do_page_fault(struct xen_regs *regs) { unsigned long page; page = l2_pgentry_val(idle_pg_table[addr >> L2_PAGETABLE_SHIFT]); - printk("*pde = %08lx\n", page); + printk("*pde = %p\n", page); if ( page & _PAGE_PRESENT ) { page &= PAGE_MASK; page = ((unsigned long *) __va(page))[(addr&0x3ff000)>>PAGE_SHIFT]; - printk(" *pte = %08lx\n", page); + printk(" *pte = %p\n", page); } #ifdef MEMORY_GUARD if ( !(regs->error_code & 1) ) @@ -351,7 +351,7 @@ asmlinkage int do_page_fault(struct xen_regs *regs) show_registers(regs); panic("CPU%d FATAL PAGE FAULT\n" "[error_code=%04x]\n" - "Faulting linear address might be %08lx\n", + "Faulting linear address might be %p\n", smp_processor_id(), regs->error_code, addr); return 0; } @@ -555,7 +555,7 @@ asmlinkage int do_general_protection(struct xen_regs *regs) if ( likely((fixup = search_exception_table(regs->eip)) != 0) ) { - DPRINTK("GPF (%04x): %08lx -> %08lx\n", + DPRINTK("GPF (%04x): %p -> %p\n", regs->error_code, regs->eip, fixup); regs->eip = fixup; return 0; @@ -705,16 +705,6 @@ void set_task_gate(unsigned int n, unsigned int sel) idt_table[n].b = 0x8500; } -#define _set_seg_desc(gate_addr,type,dpl,base,limit) {\ - *((gate_addr)+1) = ((base) & 0xff000000) | \ - (((base) & 0x00ff0000)>>16) | \ - ((limit) & 0xf0000) | \ - ((dpl)<<13) | \ - (0x00408000) | \ - ((type)<<8); \ - *(gate_addr) = (((base) & 0x0000ffff)<<16) | \ - ((limit) & 0x0ffff); } - void set_tss_desc(unsigned int n, void *addr) { _set_tssldt_desc( @@ -729,7 +719,6 @@ void __init trap_init(void) extern void doublefault_init(void); doublefault_init(); -#ifdef __i386__ /* * Note that interrupt gates are always used, rather than trap gates. We * must have interrupts disabled until DS/ES/FS/GS are saved because the @@ -760,8 +749,10 @@ void __init trap_init(void) set_intr_gate(TRAP_simd_error,&simd_coprocessor_error); set_intr_gate(TRAP_deferred_nmi,&nmi); - /* Only ring 1 can access Xen services. */ - _set_gate(idt_table+HYPERCALL_VECTOR,14,1,&hypercall); +#if defined(__i386__) + _set_gate(idt_table+HYPERCALL_VECTOR, 14, 1, &hypercall); +#elif defined(__x86_64__) + _set_gate(idt_table+HYPERCALL_VECTOR, 14, 3, &hypercall); #endif /* CPU0 uses the master IDT. */ diff --git a/xen/arch/x86/x86_32/traps.c b/xen/arch/x86/x86_32/traps.c index edb63a67fb..8526068db4 100644 --- a/xen/arch/x86/x86_32/traps.c +++ b/xen/arch/x86/x86_32/traps.c @@ -23,15 +23,15 @@ void show_guest_stack(void) int i; execution_context_t *ec = get_execution_context(); unsigned long *stack = (unsigned long *)ec->esp; - printk("Guest EIP is %lx\n",ec->eip); + printk("Guest EIP is %lx\n ",ec->eip); for ( i = 0; i < kstack_depth_to_print; i++ ) { if ( ((long)stack & (STACK_SIZE-1)) == 0 ) break; if ( i && ((i % 8) == 0) ) - printk("\n "); - printk("%08lx ", *stack++); + printk("\n "); + printk("%p ", *stack++); } printk("\n"); @@ -42,7 +42,7 @@ void show_trace(unsigned long *esp) unsigned long *stack, addr; int i; - printk("Call Trace from ESP=%p: ", esp); + printk("Call Trace from ESP=%p:\n ", esp); stack = esp; i = 0; while (((long) stack & (STACK_SIZE-1)) != 0) { @@ -50,7 +50,7 @@ void show_trace(unsigned long *esp) if (kernel_text_address(addr)) { if (i && ((i % 6) == 0)) printk("\n "); - printk("[<%08lx>] ", addr); + printk("[<%p>] ", addr); i++; } } @@ -62,7 +62,7 @@ void show_stack(unsigned long *esp) unsigned long *stack; int i; - printk("Stack trace from ESP=%p:\n", esp); + printk("Stack trace from ESP=%p:\n ", esp); stack = esp; for ( i = 0; i < kstack_depth_to_print; i++ ) @@ -70,11 +70,11 @@ void show_stack(unsigned long *esp) if ( ((long)stack & (STACK_SIZE-1)) == 0 ) break; if ( i && ((i % 8) == 0) ) - printk("\n "); + printk("\n "); if ( kernel_text_address(*stack) ) - printk("[%08lx] ", *stack++); + printk("[%p] ", *stack++); else - printk("%08lx ", *stack++); + printk("%p ", *stack++); } printk("\n"); @@ -105,11 +105,11 @@ void show_registers(struct xen_regs *regs) gs = __HYPERVISOR_DS; } - printk("CPU: %d\nEIP: %04lx:[<%08lx>] \nEFLAGS: %08lx\n", + printk("CPU: %d\nEIP: %04lx:[<%p>] \nEFLAGS: %p\n", smp_processor_id(), 0xffff & regs->cs, regs->eip, regs->eflags); - printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", + printk("eax: %p ebx: %p ecx: %p edx: %p\n", regs->eax, regs->ebx, regs->ecx, regs->edx); - printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", + printk("esi: %p edi: %p ebp: %p esp: %p\n", regs->esi, regs->edi, regs->ebp, esp); printk("ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n", ds, es, fs, gs, ss); diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index e69de29bb2..11f97202dd 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -0,0 +1,154 @@ +/* + * Hypercall and fault low-level handling routines. + * + * Copyright (c) 2005, K A Fraser + */ + +#include <xen/config.h> +#include <xen/errno.h> +#include <xen/softirq.h> +#include <asm/asm_defns.h> +#include <asm/apicdef.h> +#include <public/xen.h> + +ENTRY(hypercall) + iret + +ENTRY(ret_from_intr) +restore_all_xen: + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbp + popq %rbx + popq %r11 + popq %r10 + popq %r9 + popq %r8 + popq %rax + popq %rcx + popq %rdx + popq %rsi + popq %rdi + addq $8,%rsp + iret + +error_code: + SAVE_ALL + movq %rsp,%rdi + movl XREGS_entry_vector(%rsp),%eax + leaq SYMBOL_NAME(exception_table)(%rip),%rdx + callq *(%rdx,%rax,8) + jmp restore_all_xen + +ENTRY(divide_error) + pushq $0 + movl $TRAP_divide_error,4(%rsp) + jmp error_code + +ENTRY(coprocessor_error) + pushq $0 + movl $TRAP_copro_error,4(%rsp) + jmp error_code + +ENTRY(simd_coprocessor_error) + pushq $0 + movl $TRAP_simd_error,4(%rsp) + jmp error_code + +ENTRY(device_not_available) + pushq $0 + movl $TRAP_no_device,4(%rsp) + jmp error_code + +ENTRY(debug) + pushq $0 + movl $TRAP_debug,4(%rsp) + jmp error_code + +ENTRY(int3) + pushq $0 + movl $TRAP_int3,4(%rsp) + jmp error_code + +ENTRY(overflow) + pushq $0 + movl $TRAP_overflow,4(%rsp) + jmp error_code + +ENTRY(bounds) + pushq $0 + movl $TRAP_bounds,4(%rsp) + jmp error_code + +ENTRY(invalid_op) + pushq $0 + movl $TRAP_invalid_op,4(%rsp) + jmp error_code + +ENTRY(coprocessor_segment_overrun) + pushq $0 + movl $TRAP_copro_seg,4(%rsp) + jmp error_code + +ENTRY(invalid_TSS) + movl $TRAP_invalid_tss,4(%rsp) + jmp error_code + +ENTRY(segment_not_present) + movl $TRAP_no_segment,4(%rsp) + jmp error_code + +ENTRY(stack_segment) + movl $TRAP_stack_error,4(%rsp) + jmp error_code + +ENTRY(general_protection) + movl $TRAP_gp_fault,4(%rsp) + jmp error_code + +ENTRY(alignment_check) + movl $TRAP_alignment_check,4(%rsp) + jmp error_code + +ENTRY(page_fault) + movl $TRAP_page_fault,4(%rsp) + jmp error_code + +ENTRY(machine_check) + pushq $0 + movl $TRAP_machine_check,4(%rsp) + jmp error_code + +ENTRY(spurious_interrupt_bug) + pushq $0 + movl $TRAP_spurious_int,4(%rsp) + jmp error_code + +ENTRY(nmi) + iret + +.data + +ENTRY(exception_table) + .quad SYMBOL_NAME(do_divide_error) + .quad SYMBOL_NAME(do_debug) + .quad 0 # nmi + .quad SYMBOL_NAME(do_int3) + .quad SYMBOL_NAME(do_overflow) + .quad SYMBOL_NAME(do_bounds) + .quad SYMBOL_NAME(do_invalid_op) + .quad SYMBOL_NAME(math_state_restore) + .quad 0 # double fault + .quad SYMBOL_NAME(do_coprocessor_segment_overrun) + .quad SYMBOL_NAME(do_invalid_TSS) + .quad SYMBOL_NAME(do_segment_not_present) + .quad SYMBOL_NAME(do_stack_segment) + .quad SYMBOL_NAME(do_general_protection) + .quad SYMBOL_NAME(do_page_fault) + .quad SYMBOL_NAME(do_spurious_interrupt_bug) + .quad SYMBOL_NAME(do_coprocessor_error) + .quad SYMBOL_NAME(do_alignment_check) + .quad SYMBOL_NAME(do_machine_check) + .quad SYMBOL_NAME(do_simd_coprocessor_error) diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index f4e7f2626b..c1ed33a03d 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -23,15 +23,15 @@ void show_guest_stack(void) int i; execution_context_t *ec = get_execution_context(); unsigned long *stack = (unsigned long *)ec->rsp; - printk("Guest RIP is %lx\n", ec->rip); + printk("Guest RIP is %lx\n ", ec->rip); for ( i = 0; i < kstack_depth_to_print; i++ ) { if ( ((long)stack & (STACK_SIZE-1)) == 0 ) break; if ( i && ((i % 8) == 0) ) - printk("\n "); - printk("%08lx ", *stack++); + printk("\n "); + printk("%p ", *stack++); } printk("\n"); @@ -42,7 +42,7 @@ void show_trace(unsigned long *rsp) unsigned long *stack, addr; int i; - printk("Call Trace from RSP=%p: ", rsp); + printk("Call Trace from RSP=%p:\n ", rsp); stack = rsp; i = 0; while (((long) stack & (STACK_SIZE-1)) != 0) { @@ -50,7 +50,7 @@ void show_trace(unsigned long *rsp) if (kernel_text_address(addr)) { if (i && ((i % 6) == 0)) printk("\n "); - printk("[<%08lx>] ", addr); + printk("[<%p>] ", addr); i++; } } @@ -62,7 +62,7 @@ void show_stack(unsigned long *rsp) unsigned long *stack; int i; - printk("Stack trace from RSP=%p:\n", rsp); + printk("Stack trace from RSP=%p:\n ", rsp); stack = rsp; for ( i = 0; i < kstack_depth_to_print; i++ ) @@ -70,11 +70,11 @@ void show_stack(unsigned long *rsp) if ( ((long)stack & (STACK_SIZE-1)) == 0 ) break; if ( i && ((i % 8) == 0) ) - printk("\n "); + printk("\n "); if ( kernel_text_address(*stack) ) - printk("[%08lx] ", *stack++); + printk("[%p] ", *stack++); else - printk("%08lx ", *stack++); + printk("%p ", *stack++); } printk("\n"); @@ -83,15 +83,15 @@ void show_stack(unsigned long *rsp) void show_registers(struct xen_regs *regs) { - printk("CPU: %d\nEIP: %04lx:[<%08lx>] \nEFLAGS: %08lx\n", + printk("CPU: %d\nEIP: %04lx:[<%p>] \nEFLAGS: %p\n", smp_processor_id(), 0xffff & regs->cs, regs->rip, regs->eflags); - printk("rax: %08lx rbx: %08lx rcx: %08lx rdx: %08lx\n", + printk("rax: %p rbx: %p rcx: %p rdx: %p\n", regs->rax, regs->rbx, regs->rcx, regs->rdx); - printk("rsi: %08lx rdi: %08lx rbp: %08lx rsp: %08lx ss: %04x\n", - regs->rsi, regs->rdi, regs->rbp, regs->rsp, regs->ss); - printk("r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", + printk("rsi: %p rdi: %p rbp: %p rsp: %p\n", + regs->rsi, regs->rdi, regs->rbp, regs->rsp); + printk("r8: %p r9: %p r10: %p r11: %p\n", regs->r8, regs->r9, regs->r10, regs->r11); - printk("r12: %08lx r13: %08lx r14: %08lx r15: %08lx\n", + printk("r12: %p r13: %p r14: %p r15: %p\n", regs->r12, regs->r13, regs->r14, regs->r15); show_stack((unsigned long *)regs->rsp); diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index 1d45339f05..959b25d1b0 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -61,7 +61,6 @@ #define NR_CPUS 16 /* Linkage for x86 */ -#define asmlinkage __attribute__((regparm(0))) #define __ALIGN .align 16,0x90 #define __ALIGN_STR ".align 16,0x90" #define SYMBOL_NAME_STR(X) #X @@ -97,6 +96,8 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn)); #if defined(__x86_64__) +#define asmlinkage + #define XENHEAP_DEFAULT_MB (16) #define PML4_ENTRY_BITS 39 @@ -175,7 +176,10 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn)); #define __HYPERVISOR_CS64 0x0810 #define __HYPERVISOR_CS32 0x0808 -#define __HYPERVISOR_DS 0x0818 +#define __HYPERVISOR_CS __HYPERVISOR_CS64 +#define __HYPERVISOR_DS64 0x0000 +#define __HYPERVISOR_DS32 0x0818 +#define __HYPERVISOR_DS __HYPERVISOR_DS64 /* For generic assembly code: use macros to define operation/operand sizes. */ #define __OS "q" /* Operation Suffix */ @@ -183,6 +187,8 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn)); #elif defined(__i386__) +#define asmlinkage __attribute__((regparm(0))) + #define XENHEAP_DEFAULT_MB (12) #define DIRECTMAP_PHYS_END (12*1024*1024) diff --git a/xen/include/asm-x86/desc.h b/xen/include/asm-x86/desc.h index ee8c7faa3b..846f2256e5 100644 --- a/xen/include/asm-x86/desc.h +++ b/xen/include/asm-x86/desc.h @@ -50,7 +50,19 @@ typedef struct { u64 a, b; } idt_entry_t; -#define _set_gate(gate_addr,type,dpl,addr) ((void)0) +#define _set_gate(gate_addr,type,dpl,addr) \ +do { \ + (gate_addr)->a = \ + (((unsigned long)(addr) & 0xFFFF0000UL) << 32) | \ + ((unsigned long)(dpl) << 45) | \ + ((unsigned long)(type) << 40) | \ + ((unsigned long)(addr) & 0xFFFFUL) | \ + ((unsigned long)__HYPERVISOR_CS64 << 16) | \ + (1UL << 47); \ + (gate_addr)->b = \ + ((unsigned long)(addr) >> 32); \ +} while (0) + #define _set_tssldt_desc(n,addr,limit,type) ((void)0) #elif defined(__i386__) diff --git a/xen/include/asm-x86/irq.h b/xen/include/asm-x86/irq.h index 1f428a29e0..bc7ecfa317 100644 --- a/xen/include/asm-x86/irq.h +++ b/xen/include/asm-x86/irq.h @@ -15,11 +15,11 @@ extern void enable_irq(unsigned int); * IDT vectors usable for external interrupt sources start * at 0x20: */ -#define FIRST_EXTERNAL_VECTOR 0x30 +#define FIRST_EXTERNAL_VECTOR 0x30 #define NR_IRQS (256 - FIRST_EXTERNAL_VECTOR) -#define HYPERCALL_VECTOR 0x82 +#define HYPERCALL_VECTOR 0x82 /* * Vectors 0x30-0x3f are used for ISA interrupts. @@ -28,30 +28,30 @@ extern void enable_irq(unsigned int); /* * Special IRQ vectors used by the SMP architecture, 0xf0-0xff */ -#define SPURIOUS_APIC_VECTOR 0xff -#define ERROR_APIC_VECTOR 0xfe -#define INVALIDATE_TLB_VECTOR 0xfd -#define EVENT_CHECK_VECTOR 0xfc -#define CALL_FUNCTION_VECTOR 0xfb -#define KDB_VECTOR 0xfa +#define SPURIOUS_APIC_VECTOR 0xff +#define ERROR_APIC_VECTOR 0xfe +#define INVALIDATE_TLB_VECTOR 0xfd +#define EVENT_CHECK_VECTOR 0xfc +#define CALL_FUNCTION_VECTOR 0xfb +#define KDB_VECTOR 0xfa /* * Local APIC timer IRQ vector is on a different priority level, * to work around the 'lost local interrupt if more than 2 IRQ * sources per level' errata. */ -#define LOCAL_TIMER_VECTOR 0xef +#define LOCAL_TIMER_VECTOR 0xef /* * First APIC vector available to drivers: (vectors 0x40-0xee) * we start at 0x41 to spread out vectors evenly between priority * levels. (0x82 is the hypercall vector) */ -#define FIRST_DEVICE_VECTOR 0x41 -#define FIRST_SYSTEM_VECTOR 0xef +#define FIRST_DEVICE_VECTOR 0x41 +#define FIRST_SYSTEM_VECTOR 0xef extern int irq_vector[NR_IRQS]; -#define IO_APIC_VECTOR(irq) irq_vector[irq] +#define IO_APIC_VECTOR(irq) irq_vector[irq] /* * Various low-level irq details needed by irq.c, process.c, @@ -84,63 +84,13 @@ extern char _stext, _etext; #define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs)) -#define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v) -#define XBUILD_SMP_INTERRUPT(x,v)\ -asmlinkage void x(void); \ -asmlinkage void call_##x(void); \ -__asm__( \ -"\n"__ALIGN_STR"\n" \ -SYMBOL_NAME_STR(x) ":\n\t" \ - "push"__OS" $"#v"<<16\n\t" \ - SAVE_ALL(a) \ - SYMBOL_NAME_STR(call_##x)":\n\t" \ - "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ - "jmp ret_from_intr\n"); - -#define BUILD_SMP_TIMER_INTERRUPT(x,v) XBUILD_SMP_TIMER_INTERRUPT(x,v) -#define XBUILD_SMP_TIMER_INTERRUPT(x,v) \ -asmlinkage void x(struct xen_regs * regs); \ -asmlinkage void call_##x(void); \ -__asm__( \ -"\n"__ALIGN_STR"\n" \ -SYMBOL_NAME_STR(x) ":\n\t" \ - "push"__OS" $"#v"<<16\n\t" \ - SAVE_ALL(a) \ - "mov %"__OP"sp,%"__OP"ax\n\t" \ - "push %"__OP"ax\n\t" \ - SYMBOL_NAME_STR(call_##x)":\n\t" \ - "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ - "add $4,%"__OP"sp\n\t" \ - "jmp ret_from_intr\n"); - -#define BUILD_COMMON_IRQ() \ -asmlinkage void call_do_IRQ(void); \ -__asm__( \ - "\n" __ALIGN_STR"\n" \ - "common_interrupt:\n\t" \ - SAVE_ALL(a) \ - SYMBOL_NAME_STR(call_do_IRQ)":\n\t" \ - "call " SYMBOL_NAME_STR(do_IRQ) "\n\t" \ - "jmp ret_from_intr\n"); - -#define IRQ_NAME2(nr) nr##_interrupt(void) -#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) - -#define BUILD_IRQ(nr) \ -asmlinkage void IRQ_NAME(nr); \ -__asm__( \ -"\n"__ALIGN_STR"\n" \ -SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ - "push"__OS" $"#nr"<<16\n\t" \ - "jmp common_interrupt"); - #include <xen/irq.h> static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { #if defined(CONFIG_X86_IO_APIC) - if (IO_APIC_IRQ(i)) - send_IPI_self(IO_APIC_VECTOR(i)); + if (IO_APIC_IRQ(i)) + send_IPI_self(IO_APIC_VECTOR(i)); #endif } diff --git a/xen/include/asm-x86/pda.h b/xen/include/asm-x86/pda.h deleted file mode 100644 index 42fa8be9b0..0000000000 --- a/xen/include/asm-x86/pda.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef X86_64_PDA_H -#define X86_64_PDA_H - -#include <xen/cache.h> - -/* Per processor datastructure. %gs points to it while the kernel runs */ -/* To use a new field with the *_pda macros it needs to be added to tools/offset.c */ -struct x8664_pda { - unsigned long kernelstack; /* TOS for current process */ - unsigned long oldrsp; /* user rsp for system call */ - unsigned long irqrsp; /* Old rsp for interrupts. */ - struct exec_domain *pcurrent; /* Current process */ - int irqcount; /* Irq nesting counter. Starts with -1 */ - int cpunumber; /* Logical CPU number */ - char *irqstackptr; /* top of irqstack */ - unsigned long volatile *level4_pgt; -} __cacheline_aligned; - -#define PDA_STACKOFFSET (5*8) - -#define IRQSTACK_ORDER 2 -#define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) - -extern struct x8664_pda cpu_pda[]; - -/* - * There is no fast way to get the base address of the PDA, all the accesses - * have to mention %fs/%gs. So it needs to be done this Torvaldian way. - */ -#define sizeof_field(type,field) (sizeof(((type *)0)->field)) -#define typeof_field(type,field) typeof(((type *)0)->field) - -extern void __bad_pda_field(void); -/* Don't use offsetof because it requires too much infrastructure */ -#define pda_offset(field) ((unsigned long)&((struct x8664_pda *)0)->field) - -#define pda_to_op(op,field,val) do { \ - switch (sizeof_field(struct x8664_pda, field)) { \ - case 2: asm volatile(op "w %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break; \ - case 4: asm volatile(op "l %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break; \ - case 8: asm volatile(op "q %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break; \ - default: __bad_pda_field(); \ - } \ - } while (0) - - -#define pda_from_op(op,field) ({ \ - typedef typeof_field(struct x8664_pda, field) T__; T__ ret__; \ - switch (sizeof_field(struct x8664_pda, field)) { \ - case 2: asm volatile(op "w %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break; \ - case 4: asm volatile(op "l %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break; \ - case 8: asm volatile(op "q %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break; \ - default: __bad_pda_field(); \ - } \ - ret__; }) - - -#define read_pda(field) pda_from_op("mov",field) -#define write_pda(field,val) pda_to_op("mov",field,val) -#define add_pda(field,val) pda_to_op("add",field,val) -#define sub_pda(field,val) pda_to_op("sub",field,val) - -#endif diff --git a/xen/include/asm-x86/smp.h b/xen/include/asm-x86/smp.h index b4d79087c5..e1e9443035 100644 --- a/xen/include/asm-x86/smp.h +++ b/xen/include/asm-x86/smp.h @@ -61,12 +61,7 @@ extern void smp_store_cpu_info(int id); /* Store per CPU info (like the initial * so this is correct in the x86 case. */ -#if defined(__i386__) #define smp_processor_id() (current->processor) -#elif defined(__x86_64__) -#include <asm/pda.h> -#define smp_processor_id() read_pda(cpunumber) -#endif static __inline int hard_smp_processor_id(void) { diff --git a/xen/include/asm-x86/x86_32/asm_defns.h b/xen/include/asm-x86/x86_32/asm_defns.h index e11ea34964..08932f2610 100644 --- a/xen/include/asm-x86/x86_32/asm_defns.h +++ b/xen/include/asm-x86/x86_32/asm_defns.h @@ -78,4 +78,51 @@ #endif +#define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v) +#define XBUILD_SMP_INTERRUPT(x,v)\ +asmlinkage void x(void); \ +__asm__( \ + "\n"__ALIGN_STR"\n" \ + SYMBOL_NAME_STR(x) ":\n\t" \ + "pushl $"#v"<<16\n\t" \ + SAVE_ALL(a) \ + "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ + "jmp ret_from_intr\n"); + +#define BUILD_SMP_TIMER_INTERRUPT(x,v) XBUILD_SMP_TIMER_INTERRUPT(x,v) +#define XBUILD_SMP_TIMER_INTERRUPT(x,v) \ +asmlinkage void x(struct xen_regs * regs); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(x) ":\n\t" \ + "pushl $"#v"<<16\n\t" \ + SAVE_ALL(a) \ + "movl %esp,%eax\n\t" \ + "pushl %eax\n\t" \ + "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \ + "addl $4,%esp\n\t" \ + "jmp ret_from_intr\n"); + +#define BUILD_COMMON_IRQ() \ +__asm__( \ + "\n" __ALIGN_STR"\n" \ + "common_interrupt:\n\t" \ + SAVE_ALL(a) \ + "movl %esp,%eax\n\t" \ + "pushl %eax\n\t" \ + "call " SYMBOL_NAME_STR(do_IRQ) "\n\t" \ + "addl $4,%esp\n\t" \ + "jmp ret_from_intr\n"); + +#define IRQ_NAME2(nr) nr##_interrupt(void) +#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) + +#define BUILD_IRQ(nr) \ +asmlinkage void IRQ_NAME(nr); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ + "pushl $"#nr"<<16\n\t" \ + "jmp common_interrupt"); + #endif /* __X86_32_ASM_DEFNS_H__ */ diff --git a/xen/include/asm-x86/x86_64/asm_defns.h b/xen/include/asm-x86/x86_64/asm_defns.h index fa0b978304..fc1c387aa0 100644 --- a/xen/include/asm-x86/x86_64/asm_defns.h +++ b/xen/include/asm-x86/x86_64/asm_defns.h @@ -1,6 +1,93 @@ #ifndef __X86_64_ASM_DEFNS_H__ #define __X86_64_ASM_DEFNS_H__ -#define SAVE_ALL(_r) "" +/* Maybe auto-generate the following two cases (quoted vs. unquoted). */ +#ifndef __ASSEMBLY__ + +#define SAVE_ALL \ + "cld;" \ + "pushq %rdi;" \ + "pushq %rsi;" \ + "pushq %rdx;" \ + "pushq %rcx;" \ + "pushq %rax;" \ + "pushq %r8;" \ + "pushq %r9;" \ + "pushq %r10;" \ + "pushq %r11;" \ + "pushq %rbx;" \ + "pushq %rbp;" \ + "pushq %r12;" \ + "pushq %r13;" \ + "pushq %r14;" \ + "pushq %r15;" + +#else + +#define SAVE_ALL \ + cld; \ + pushq %rdi; \ + pushq %rsi; \ + pushq %rdx; \ + pushq %rcx; \ + pushq %rax; \ + pushq %r8; \ + pushq %r9; \ + pushq %r10; \ + pushq %r11; \ + pushq %rbx; \ + pushq %rbp; \ + pushq %r12; \ + pushq %r13; \ + pushq %r14; \ + pushq %r15; + +#endif + +#define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v) +#define XBUILD_SMP_INTERRUPT(x,v)\ +asmlinkage void x(void); \ +__asm__( \ + "\n"__ALIGN_STR"\n" \ + SYMBOL_NAME_STR(x) ":\n\t" \ + "pushq $0\n\t" \ + "movl $"#v",4(%rsp)\n\t" \ + SAVE_ALL \ + "callq "SYMBOL_NAME_STR(smp_##x)"\n\t" \ + "jmp ret_from_intr\n"); + +#define BUILD_SMP_TIMER_INTERRUPT(x,v) XBUILD_SMP_TIMER_INTERRUPT(x,v) +#define XBUILD_SMP_TIMER_INTERRUPT(x,v) \ +asmlinkage void x(struct xen_regs * regs); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(x) ":\n\t" \ + "pushq $0\n\t" \ + "movl $"#v",4(%rsp)\n\t" \ + SAVE_ALL \ + "movq %rsp,%rdi\n\t" \ + "callq "SYMBOL_NAME_STR(smp_##x)"\n\t" \ + "jmp ret_from_intr\n"); + +#define BUILD_COMMON_IRQ() \ +__asm__( \ + "\n" __ALIGN_STR"\n" \ + "common_interrupt:\n\t" \ + SAVE_ALL \ + "movq %rsp,%rdi\n\t" \ + "callq " SYMBOL_NAME_STR(do_IRQ) "\n\t" \ + "jmp ret_from_intr\n"); + +#define IRQ_NAME2(nr) nr##_interrupt(void) +#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) + +#define BUILD_IRQ(nr) \ +asmlinkage void IRQ_NAME(nr); \ +__asm__( \ +"\n"__ALIGN_STR"\n" \ +SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \ + "pushq $0\n\t" \ + "movl $"#nr",4(%rsp)\n\t" \ + "jmp common_interrupt"); #endif /* __X86_64_ASM_DEFNS_H__ */ diff --git a/xen/include/asm-x86/x86_64/current.h b/xen/include/asm-x86/x86_64/current.h index 576e19c112..7d8904a607 100644 --- a/xen/include/asm-x86/x86_64/current.h +++ b/xen/include/asm-x86/x86_64/current.h @@ -1,18 +1,16 @@ #ifndef _X86_64_CURRENT_H #define _X86_64_CURRENT_H -#if !defined(__ASSEMBLY__) struct domain; -#include <asm/pda.h> - #define STACK_RESERVED \ - (sizeof(execution_context_t)) + (sizeof(execution_context_t) + sizeof(struct domain *)) static inline struct exec_domain *get_current(void) { struct exec_domain *ed; - ed = read_pda(pcurrent); + __asm__ ( "orq %%rsp,%0; andq $~7,%0; movq (%0),%0" + : "=r" (ed) : "0" (STACK_SIZE-8) ); return ed; } @@ -20,7 +18,8 @@ static inline struct exec_domain *get_current(void) static inline void set_current(struct exec_domain *ed) { - write_pda(pcurrent, ed); + __asm__ ( "orq %%rsp,%0; andq $~7,%0; movq %1,(%0)" + : : "r" (STACK_SIZE-8), "r" (ed) ); } static inline execution_context_t *get_execution_context(void) @@ -47,14 +46,4 @@ static inline unsigned long get_stack_top(void) #define schedule_tail(_d) ((_d)->thread.schedule_tail)(_d) -#else - -#ifndef ASM_OFFSET_H -#include <asm/offset.h> -#endif - -#define GET_CURRENT(reg) movq %gs:(pda_pcurrent),reg - -#endif - #endif /* !(_X86_64_CURRENT_H) */ |