diff options
-rw-r--r-- | extras/mini-os/h/lib.h | 17 | ||||
-rw-r--r-- | extras/mini-os/h/mm.h | 60 | ||||
-rw-r--r-- | extras/mini-os/h/os.h | 22 | ||||
-rw-r--r-- | extras/mini-os/h/types.h | 11 | ||||
-rw-r--r-- | extras/mini-os/kernel.c | 2 | ||||
-rw-r--r-- | extras/mini-os/lib/printf.c | 4 | ||||
-rw-r--r-- | extras/mini-os/mm.c | 2 | ||||
-rw-r--r-- | extras/mini-os/traps.c | 139 | ||||
-rw-r--r-- | extras/mini-os/x86_64.S | 160 | ||||
-rw-r--r-- | xen/arch/x86/domain.c | 92 | ||||
-rw-r--r-- | xen/arch/x86/x86_32/domain_build.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/x86_32/mm.c | 3 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/domain_build.c | 6 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/entry.S | 2 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/mm.c | 7 | ||||
-rw-r--r-- | xen/include/asm-x86/x86_64/page.h | 8 |
16 files changed, 362 insertions, 175 deletions
diff --git a/extras/mini-os/h/lib.h b/extras/mini-os/h/lib.h index d9996a2f85..0b405ee006 100644 --- a/extras/mini-os/h/lib.h +++ b/extras/mini-os/h/lib.h @@ -55,22 +55,7 @@ #ifndef _LIB_H_ #define _LIB_H_ - -/* variadic function support */ -typedef char *va_list; -#define __va_size(type) \ - (((sizeof(type) + sizeof(int) - 1) / sizeof(int)) * sizeof(int)) -#ifdef __GNUC__ -#define va_start(ap, last) \ - ((ap) = (va_list)__builtin_next_arg(last)) -#else -#define va_start(ap, last) \ - ((ap) = (va_list)&(last) + __va_size(last)) -#endif -#define va_arg(ap, type) \ - (*(type *)((ap) += __va_size(type), (ap) - __va_size(type))) -#define va_end(ap) - +#include <stdarg.h> /* printing */ #define printk printf diff --git a/extras/mini-os/h/mm.h b/extras/mini-os/h/mm.h index 5c6224db28..c5f6ad4788 100644 --- a/extras/mini-os/h/mm.h +++ b/extras/mini-os/h/mm.h @@ -1,20 +1,8 @@ /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- - **************************************************************************** - * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge - **************************************************************************** * - * File: mm.h - * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk) - * Changes: - * - * Date: Aug 2003 - * - * Environment: - * Description: + * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge + * Copyright (c) 2005, Keir A Fraser * - **************************************************************************** - * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $ - **************************************************************************** * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the @@ -37,6 +25,48 @@ #ifndef _MM_H_ #define _MM_H_ +#ifdef __x86_64__ + +#define L1_PAGETABLE_SHIFT 12 +#define L2_PAGETABLE_SHIFT 21 +#define L3_PAGETABLE_SHIFT 30 +#define L4_PAGETABLE_SHIFT 39 + +#define L1_PAGETABLE_ENTRIES 512 +#define L2_PAGETABLE_ENTRIES 512 +#define L3_PAGETABLE_ENTRIES 512 +#define L4_PAGETABLE_ENTRIES 512 + +/* These are page-table limitations. Current CPUs support only 40-bit phys. */ +#define PADDR_BITS 52 +#define VADDR_BITS 48 +#define PADDR_MASK ((1UL << PADDR_BITS)-1) +#define VADDR_MASK ((1UL << VADDR_BITS)-1) + +#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> PAGE_SHIFT) + +/* Given a virtual address, get an entry offset into a page table. */ +#define l1_table_offset(_a) \ + (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1)) +#define l2_table_offset(_a) \ + (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1)) +#define l3_table_offset(_a) \ + (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1)) +#define l4_table_offset(_a) \ + (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1)) +#endif + +#define _PAGE_PRESENT 0x001UL +#define _PAGE_RW 0x002UL +#define _PAGE_USER 0x004UL +#define _PAGE_PWT 0x008UL +#define _PAGE_PCD 0x010UL +#define _PAGE_ACCESSED 0x020UL +#define _PAGE_DIRTY 0x040UL +#define _PAGE_PAT 0x080UL +#define _PAGE_PSE 0x080UL +#define _PAGE_GLOBAL 0x100UL + #define PAGE_SHIFT 12 #define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) @@ -72,6 +102,8 @@ static __inline__ unsigned long machine_to_phys(unsigned long machine) #define to_phys(x) ((unsigned long)(x)-VIRT_START) #define to_virt(x) ((void *)((unsigned long)(x)+VIRT_START)) +#define __va to_virt +#define __pa to_phys void init_mm(void); unsigned long alloc_pages(int order); diff --git a/extras/mini-os/h/os.h b/extras/mini-os/h/os.h index 6a0447ca39..434dd992f6 100644 --- a/extras/mini-os/h/os.h +++ b/extras/mini-os/h/os.h @@ -29,6 +29,28 @@ #define __KERNEL_DS FLAT_KERNEL_DS #define __KERNEL_SS FLAT_KERNEL_SS +#define TRAP_divide_error 0 +#define TRAP_debug 1 +#define TRAP_nmi 2 +#define TRAP_int3 3 +#define TRAP_overflow 4 +#define TRAP_bounds 5 +#define TRAP_invalid_op 6 +#define TRAP_no_device 7 +#define TRAP_double_fault 8 +#define TRAP_copro_seg 9 +#define TRAP_invalid_tss 10 +#define TRAP_no_segment 11 +#define TRAP_stack_error 12 +#define TRAP_gp_fault 13 +#define TRAP_page_fault 14 +#define TRAP_spurious_int 15 +#define TRAP_copro_error 16 +#define TRAP_alignment_check 17 +#define TRAP_machine_check 18 +#define TRAP_simd_error 19 +#define TRAP_deferred_nmi 31 + /* Everything below this point is not included by assembler (.S) files. */ #ifndef __ASSEMBLY__ diff --git a/extras/mini-os/h/types.h b/extras/mini-os/h/types.h index 85ede91c13..7bf103ab9c 100644 --- a/extras/mini-os/h/types.h +++ b/extras/mini-os/h/types.h @@ -26,8 +26,13 @@ typedef signed short s16; typedef unsigned short u16; typedef signed int s32; typedef unsigned int u32; +#ifdef __i386__ typedef signed long long s64; typedef unsigned long long u64; +#elif defined(__x86_64__) +typedef signed long s64; +typedef unsigned long u64; +#endif typedef unsigned int size_t; @@ -35,7 +40,13 @@ typedef unsigned int size_t; typedef unsigned char u_char; typedef unsigned int u_int; typedef unsigned long u_long; +#ifdef __i386__ typedef long long quad_t; typedef unsigned long long u_quad_t; typedef unsigned int uintptr_t; +#elif defined(__x86_64__) +typedef long quad_t; +typedef unsigned long u_quad_t; +typedef unsigned long uintptr_t; +#endif #endif /* _TYPES_H_ */ diff --git a/extras/mini-os/kernel.c b/extras/mini-os/kernel.c index a794145e68..b6f89b8bbb 100644 --- a/extras/mini-os/kernel.c +++ b/extras/mini-os/kernel.c @@ -65,7 +65,7 @@ extern char shared_info[PAGE_SIZE]; static shared_info_t *map_shared_info(unsigned long pa) { if ( HYPERVISOR_update_va_mapping( - (unsigned long)shared_info, pa | 3, UVMF_INVLPG) ) + (unsigned long)shared_info, pa | 7, UVMF_INVLPG) ) { printk("Failed to map shared_info!!\n"); *(int*)0=0; diff --git a/extras/mini-os/lib/printf.c b/extras/mini-os/lib/printf.c index f6232c4044..a08bb20e6c 100644 --- a/extras/mini-os/lib/printf.c +++ b/extras/mini-os/lib/printf.c @@ -341,7 +341,9 @@ reswitch: switch (ch = (u_char)*fmt++) { case 'p': ul = (uintptr_t)va_arg(ap, void *); base = 16; - sharpflag = (width == 0); + sharpflag = 0; + padc = '0'; + width = sizeof(uintptr_t)*2; goto nosign; case 'q': qflag = 1; diff --git a/extras/mini-os/mm.c b/extras/mini-os/mm.c index 2bc87a5165..40a80e2ccb 100644 --- a/extras/mini-os/mm.c +++ b/extras/mini-os/mm.c @@ -84,6 +84,7 @@ void init_mm(void) */ max_free_pfn = PFN_DOWN(to_phys(pgd)); +#ifdef __i386__ { unsigned long *pgd = (unsigned long *)start_info.pt_base; unsigned long pte; @@ -110,6 +111,7 @@ void init_mm(void) (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), (u_long)to_virt(PFN_PHYS(max_free_pfn)), PFN_PHYS(max_free_pfn)); init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_free_pfn)); +#endif /* Now initialise the physical->machine mapping table. */ diff --git a/extras/mini-os/traps.c b/extras/mini-os/traps.c index 858c54d3f2..7000128230 100644 --- a/extras/mini-os/traps.c +++ b/extras/mini-os/traps.c @@ -15,7 +15,6 @@ void overflow(void); void bounds(void); void invalid_op(void); void device_not_available(void); -void double_fault(void); void coprocessor_segment_overrun(void); void invalid_TSS(void); void segment_not_present(void); @@ -33,111 +32,134 @@ extern void do_exit(void); void dump_regs(struct pt_regs *regs) { - int in_kernel = 1; unsigned long esp; unsigned short ss; +#ifdef __x86_64__ + esp = regs->rsp; + ss = regs->ss; +#else esp = (unsigned long) (®s->esp); ss = __KERNEL_DS; if (regs->cs & 2) { - in_kernel = 0; esp = regs->esp; ss = regs->ss & 0xffff; } - printf("EIP: %04x:[<%p>]\n", - 0xffff & regs->cs , regs->eip); +#endif + printf("EIP: %04x:[<%p>] %08x\n", + 0xffff & regs->cs , regs->eip, regs->error_code); printf("EFLAGS: %p\n",regs->eflags); printf("eax: %p ebx: %p ecx: %p edx: %p\n", regs->eax, regs->ebx, regs->ecx, regs->edx); printf("esi: %p edi: %p ebp: %p esp: %p\n", regs->esi, regs->edi, regs->ebp, esp); +#ifdef __x86_64__ + printf("r8 : %p r9 : %p r10: %p r11: %p\n", + regs->r8, regs->r9, regs->r10, regs->r11); + printf("r12: %p r13: %p r14: %p r15: %p\n", + regs->r12, regs->r13, regs->r14, regs->r15); +#endif printf("ds: %04x es: %04x ss: %04x\n", regs->ds & 0xffff, regs->es & 0xffff, ss); - printf("\n"); } static __inline__ void dump_code(unsigned long eip) { - unsigned *ptr = (unsigned *)eip; + unsigned char *ptr = (unsigned char *)eip; int x; - printk("Bytes at eip:\n"); - for (x = -4; x < 5; x++) - printf("%p", ptr[x]); + printk("Bytes at eip: "); + for ( x = -4; x < 5; x++ ) + printf("%02x ", ptr[x]); + printk("\n"); } - -/* - * C handlers here have their parameter-list constructed by the - * assembler stubs above. Each one gets a pointer to a list - * of register values (to be restored at end of exception). - * Some will also receive an error code -- this is the code that - * was generated by the processor for the underlying real exception. - * - * Note that the page-fault exception is special. It also receives - * the faulting linear address. Normally this would be found in - * register CR2, but that is not accessible in a virtualised OS. - */ - static void __inline__ do_trap(int trapnr, char *str, - struct pt_regs * regs, long error_code) + struct pt_regs * regs) { - printk("FATAL: Unhandled Trap (see mini-os:traps.c)"); - printf("%d %s", trapnr, str); + printk("FATAL: Unhandled Trap %d (%s)\n", trapnr, str); dump_regs(regs); dump_code(regs->eip); - do_exit(); } #define DO_ERROR(trapnr, str, name) \ -void do_##name(struct pt_regs * regs, long error_code) \ +void do_##name(struct pt_regs * regs) \ { \ - do_trap(trapnr, str, regs, error_code); \ + do_trap(trapnr, str, regs); \ } #define DO_ERROR_INFO(trapnr, str, name, sicode, siaddr) \ -void do_##name(struct pt_regs * regs, long error_code) \ +void do_##name(struct pt_regs * regs) \ { \ - do_trap(trapnr, str, regs, error_code); \ + do_trap(trapnr, str, regs); \ } DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip) - DO_ERROR( 3, "int3", int3) - DO_ERROR( 4, "overflow", overflow) - DO_ERROR( 5, "bounds", bounds) - DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip) - DO_ERROR( 7, "device not available", device_not_available) - DO_ERROR( 8, "double fault", double_fault) - DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun) - DO_ERROR(10, "invalid TSS", invalid_TSS) - DO_ERROR(11, "segment not present", segment_not_present) - DO_ERROR(12, "stack segment", stack_segment) - DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0) - DO_ERROR(18, "machine check", machine_check) - - void do_page_fault(struct pt_regs *regs, long error_code, - unsigned long address) +DO_ERROR( 3, "int3", int3) +DO_ERROR( 4, "overflow", overflow) +DO_ERROR( 5, "bounds", bounds) +DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip) +DO_ERROR( 7, "device not available", device_not_available) +DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun) +DO_ERROR(10, "invalid TSS", invalid_TSS) +DO_ERROR(11, "segment not present", segment_not_present) +DO_ERROR(12, "stack segment", stack_segment) +DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0) +DO_ERROR(18, "machine check", machine_check) + +extern unsigned long virt_cr2; +void do_page_fault(struct pt_regs *regs) { - printk("Page fault\n"); - printk("Address: 0x%p", address); - printk("Error Code: 0x%p", error_code); - printk("eip: \t 0x%p", regs->eip); + unsigned long addr = virt_cr2; + printk("Page fault at linear address %p\n", addr); + dump_regs(regs); + dump_code(regs->eip); +#ifdef __x86_64__ + { + unsigned long *tab = (unsigned long *)start_info.pt_base; + unsigned long page; + + printk("Pagetable walk from %p:\n", tab); + + page = tab[l4_table_offset(addr)]; + tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT); + printk(" L4 = %p (%p)\n", page, tab); + if ( !(page & _PAGE_PRESENT) ) + goto out; + + page = tab[l3_table_offset(addr)]; + tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT); + printk(" L3 = %p (%p)\n", page, tab); + if ( !(page & _PAGE_PRESENT) ) + goto out; + + page = tab[l2_table_offset(addr)]; + tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT); + printk(" L2 = %p (%p) %s\n", page, tab, + (page & _PAGE_PSE) ? "(2MB)" : ""); + if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) ) + goto out; + + page = tab[l1_table_offset(addr)]; + printk(" L1 = %p\n", page); + } +#endif + out: do_exit(); } -void do_general_protection(struct pt_regs * regs, long error_code) +void do_general_protection(struct pt_regs *regs) { printk("GPF\n"); - printk("Error Code: 0x%p", error_code); dump_regs(regs); dump_code(regs->eip); do_exit(); } -void do_debug(struct pt_regs * regs, long error_code) +void do_debug(struct pt_regs * regs) { printk("Debug exception\n"); #define TF_MASK 0x100 @@ -146,9 +168,7 @@ void do_debug(struct pt_regs * regs, long error_code) do_exit(); } - - -void do_coprocessor_error(struct pt_regs * regs, long error_code) +void do_coprocessor_error(struct pt_regs * regs) { printk("Copro error\n"); dump_regs(regs); @@ -161,14 +181,12 @@ void simd_math_error(void *eip) printk("SIMD error\n"); } -void do_simd_coprocessor_error(struct pt_regs * regs, - long error_code) +void do_simd_coprocessor_error(struct pt_regs * regs) { printk("SIMD copro error\n"); } -void do_spurious_interrupt_bug(struct pt_regs * regs, - long error_code) +void do_spurious_interrupt_bug(struct pt_regs * regs) { } @@ -189,7 +207,6 @@ static trap_info_t trap_table[] = { { 5, 3, __KERNEL_CS, _P (unsigned long)bounds }, { 6, 0, __KERNEL_CS, _P (unsigned long)invalid_op }, { 7, 0, __KERNEL_CS, _P (unsigned long)device_not_available }, - { 8, 0, __KERNEL_CS, _P (unsigned long)double_fault }, { 9, 0, __KERNEL_CS, _P (unsigned long)coprocessor_segment_overrun }, { 10, 0, __KERNEL_CS, _P (unsigned long)invalid_TSS }, { 11, 0, __KERNEL_CS, _P (unsigned long)segment_not_present }, diff --git a/extras/mini-os/x86_64.S b/extras/mini-os/x86_64.S index 4a4708ddd5..0f37d596f7 100644 --- a/extras/mini-os/x86_64.S +++ b/extras/mini-os/x86_64.S @@ -6,7 +6,42 @@ #define ENTRY(X) .globl X ; X : .globl _start, shared_info - + +#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; + +#define RESTORE_ALL \ + 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 + _start: cld movq stack_start(%rip),%rsp @@ -23,56 +58,165 @@ shared_info: .org 0x2000 ENTRY(hypervisor_callback) + popq %rcx + popq %r11 + iretq ENTRY(failsafe_callback) - iret - + popq %rcx + popq %r11 + iretq + +error_code: + SAVE_ALL + movq %rsp,%rdi + movl 15*8+4(%rsp),%eax + leaq exception_table(%rip),%rdx + callq *(%rdx,%rax,8) + RESTORE_ALL + addq $8,%rsp + iretq + ENTRY(divide_error) + popq %rcx + popq %r11 pushq $0 - + movl $TRAP_divide_error,4(%rsp) + jmp error_code + ENTRY(coprocessor_error) + popq %rcx + popq %r11 pushq $0 + movl $TRAP_copro_error,4(%rsp) + jmp error_code ENTRY(simd_coprocessor_error) + popq %rcx + popq %r11 pushq $0 + movl $TRAP_simd_error,4(%rsp) + jmp error_code ENTRY(device_not_available) - iret + popq %rcx + popq %r11 + movl $TRAP_no_device,4(%rsp) + jmp error_code ENTRY(debug) + popq %rcx + popq %r11 pushq $0 + movl $TRAP_debug,4(%rsp) + jmp error_code ENTRY(int3) + popq %rcx + popq %r11 pushq $0 + movl $TRAP_int3,4(%rsp) + jmp error_code ENTRY(overflow) + popq %rcx + popq %r11 pushq $0 + movl $TRAP_overflow,4(%rsp) + jmp error_code ENTRY(bounds) + popq %rcx + popq %r11 pushq $0 + movl $TRAP_bounds,4(%rsp) + jmp error_code ENTRY(invalid_op) + popq %rcx + popq %r11 pushq $0 + movl $TRAP_invalid_op,4(%rsp) + jmp error_code ENTRY(coprocessor_segment_overrun) + popq %rcx + popq %r11 pushq $0 - -ENTRY(double_fault) + movl $TRAP_copro_seg,4(%rsp) + jmp error_code ENTRY(invalid_TSS) + popq %rcx + popq %r11 + movl $TRAP_invalid_tss,4(%rsp) + jmp error_code ENTRY(segment_not_present) + popq %rcx + popq %r11 + movl $TRAP_no_segment,4(%rsp) + jmp error_code ENTRY(stack_segment) + popq %rcx + popq %r11 + movl $TRAP_stack_error,4(%rsp) + jmp error_code ENTRY(general_protection) + popq %rcx + popq %r11 + movl $TRAP_gp_fault,4(%rsp) + jmp error_code ENTRY(alignment_check) + popq %rcx + popq %r11 + movl $TRAP_alignment_check,4(%rsp) + jmp error_code +ENTRY(virt_cr2) + .quad 0 ENTRY(page_fault) - + popq %rcx + popq %r11 + popq virt_cr2(%rip) + movl $TRAP_page_fault,4(%rsp) + jmp error_code + ENTRY(machine_check) + popq %rcx + popq %r11 pushq $0 + movl $TRAP_machine_check,4(%rsp) + jmp error_code ENTRY(spurious_interrupt_bug) + popq %rcx + popq %r11 pushq $0 + movl $TRAP_spurious_int,4(%rsp) + jmp error_code + +ENTRY(exception_table) + .quad do_divide_error + .quad do_debug + .quad 0 # nmi + .quad do_int3 + .quad do_overflow + .quad do_bounds + .quad do_invalid_op + .quad 0 + .quad 0 + .quad do_coprocessor_segment_overrun + .quad do_invalid_TSS + .quad do_segment_not_present + .quad do_stack_segment + .quad do_general_protection + .quad do_page_fault + .quad do_spurious_interrupt_bug + .quad do_coprocessor_error + .quad do_alignment_check + .quad do_machine_check + .quad do_simd_coprocessor_error diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 2ff1455820..a4ccdf21bc 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -85,109 +85,79 @@ void startup_cpu_idle_loop(void) static long no_idt[2]; static int reboot_mode; -int reboot_thru_bios = 0; - -#ifdef CONFIG_SMP -int reboot_smp = 0; -static int reboot_cpu = -1; -/* shamelessly grabbed from lib/vsprintf.c for readability */ -#define is_digit(c) ((c) >= '0' && (c) <= '9') -#endif - static inline void kb_wait(void) { int i; - for (i=0; i<0x10000; i++) - if ((inb_p(0x64) & 0x02) == 0) + for ( i = 0; i < 0x10000; i++ ) + if ( (inb_p(0x64) & 0x02) == 0 ) break; } - void machine_restart(char * __unused) { -#ifdef CONFIG_SMP - int cpuid; -#endif + int i; if ( opt_noreboot ) { printk("Reboot disabled on cmdline: require manual reset\n"); - for ( ; ; ) __asm__ __volatile__ ("hlt"); + for ( ; ; ) + safe_halt(); } -#ifdef CONFIG_SMP - cpuid = GET_APIC_ID(apic_read(APIC_ID)); - - /* KAF: Need interrupts enabled for safe IPI. */ __sti(); - if (reboot_smp) { - - /* check to see if reboot_cpu is valid - if its not, default to the BSP */ - if ((reboot_cpu == -1) || - (reboot_cpu > (NR_CPUS -1)) || - !(phys_cpu_present_map & (1<<cpuid))) - reboot_cpu = boot_cpu_physical_apicid; - - reboot_smp = 0; /* use this as a flag to only go through this once*/ - /* re-run this function on the other CPUs - it will fall though this section since we have - cleared reboot_smp, and do the reboot if it is the - correct CPU, otherwise it halts. */ - if (reboot_cpu != cpuid) - smp_call_function((void *)machine_restart , NULL, 1, 0); + /* Ensure we are the boot CPU. */ + if ( GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_physical_apicid ) + { + smp_call_function((void *)machine_restart, NULL, 1, 0); + for ( ; ; ) + safe_halt(); } - /* if reboot_cpu is still -1, then we want a tradional reboot, - and if we are not running on the reboot_cpu,, halt */ - if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) { - for (;;) - __asm__ __volatile__ ("hlt"); - } /* * Stop all CPUs and turn off local APICs and the IO-APIC, so * other OSs see a clean IRQ state. */ smp_send_stop(); disable_IO_APIC(); -#endif + #ifdef CONFIG_VMX stop_vmx(); #endif - if(!reboot_thru_bios) { - /* rebooting needs to touch the page at absolute addr 0 */ - *((unsigned short *)__va(0x472)) = reboot_mode; - for (;;) { - int i; - for (i=0; i<100; i++) { - kb_wait(); - udelay(50); - outb(0xfe,0x64); /* pulse reset low */ - udelay(50); - } - /* That didn't work - force a triple fault.. */ - __asm__ __volatile__("lidt %0": "=m" (no_idt)); - __asm__ __volatile__("int3"); + /* Rebooting needs to touch the page at absolute address 0. */ + *((unsigned short *)__va(0x472)) = reboot_mode; + + for ( ; ; ) + { + /* Pulse the keyboard reset line. */ + for ( i = 0; i < 100; i++ ) + { + kb_wait(); + udelay(50); + outb(0xfe,0x64); /* pulse reset low */ + udelay(50); } - } - panic("Need to reinclude BIOS reboot code\n"); + /* That didn't work - force a triple fault.. */ + __asm__ __volatile__("lidt %0": "=m" (no_idt)); + __asm__ __volatile__("int3"); + } } void __attribute__((noreturn)) __machine_halt(void *unused) { for ( ; ; ) - __asm__ __volatile__ ( "cli; hlt" ); + safe_halt(); } void machine_halt(void) { - smp_call_function(__machine_halt, NULL, 1, 1); + watchdog_on = 0; + smp_call_function(__machine_halt, NULL, 1, 0); __machine_halt(NULL); } diff --git a/xen/arch/x86/x86_32/domain_build.c b/xen/arch/x86/x86_32/domain_build.c index 2c11f71668..38abb1d3b7 100644 --- a/xen/arch/x86/x86_32/domain_build.c +++ b/xen/arch/x86/x86_32/domain_build.c @@ -24,7 +24,7 @@ /* No ring-3 access in initial page tables. */ #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) #define round_pgdown(_p) ((_p)&PAGE_MASK) diff --git a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c index 7fc6323a93..788e7c1241 100644 --- a/xen/arch/x86/x86_32/mm.c +++ b/xen/arch/x86/x86_32/mm.c @@ -29,6 +29,7 @@ #include <asm/domain_page.h> /* Map physical byte range (@p, @p+@s) at virt address @v in pagetable @pt. */ +#define __PTE_MASK (~(_PAGE_GLOBAL|_PAGE_DIRTY|_PAGE_PCD|_PAGE_PWT)) int map_pages( root_pgentry_t *pt, unsigned long v, @@ -62,7 +63,7 @@ int map_pages( { newpg = (void *)alloc_xenheap_page(); clear_page(newpg); - *pl2e = mk_l2_pgentry(__pa(newpg) | __PAGE_HYPERVISOR); + *pl2e = mk_l2_pgentry(__pa(newpg) | (flags & __PTE_MASK)); } pl1e = l2_pgentry_to_l1(*pl2e) + l1_table_offset(v); if ( (l1_pgentry_val(*pl1e) & _PAGE_PRESENT) ) diff --git a/xen/arch/x86/x86_64/domain_build.c b/xen/arch/x86/x86_64/domain_build.c index bd82b4ef7c..7f39c1694c 100644 --- a/xen/arch/x86/x86_64/domain_build.c +++ b/xen/arch/x86/x86_64/domain_build.c @@ -23,9 +23,9 @@ /* Allow ring-3 access in long mode as guest cannot use ring 1. */ #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) -#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) -#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) +#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) +#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) #define round_pgdown(_p) ((_p)&PAGE_MASK) diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index 03301855ec..feb7ec342b 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -298,7 +298,7 @@ exception_with_ints_disabled: testb $3,XREGS_cs(%rsp) # interrupts disabled outside Xen? jnz 1b # it really does happen! # (e.g., DOM0 X server) - movq XREGS_rip(%rsp),%rdi + movq %rsp,%rdi call search_pre_exception_table testq %rax,%rax # no fixup code for faulting EIP? jz FATAL_exception_with_ints_disabled diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 5bced9a509..dacf6ae55d 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -37,6 +37,7 @@ void *safe_page_alloc(void) } /* Map physical byte range (@p, @p+@s) at virt address @v in pagetable @pt. */ +#define __PTE_MASK (~(_PAGE_GLOBAL|_PAGE_DIRTY|_PAGE_PCD|_PAGE_PWT)) int map_pages( root_pgentry_t *pt, unsigned long v, @@ -57,7 +58,7 @@ int map_pages( { newpg = safe_page_alloc(); clear_page(newpg); - *pl4e = mk_l4_pgentry(__pa(newpg) | __PAGE_HYPERVISOR); + *pl4e = mk_l4_pgentry(__pa(newpg) | (flags & __PTE_MASK)); } pl3e = l4_pgentry_to_l3(*pl4e) + l3_table_offset(v); @@ -65,7 +66,7 @@ int map_pages( { newpg = safe_page_alloc(); clear_page(newpg); - *pl3e = mk_l3_pgentry(__pa(newpg) | __PAGE_HYPERVISOR); + *pl3e = mk_l3_pgentry(__pa(newpg) | (flags & __PTE_MASK)); } pl2e = l3_pgentry_to_l2(*pl3e) + l2_table_offset(v); @@ -88,7 +89,7 @@ int map_pages( { newpg = safe_page_alloc(); clear_page(newpg); - *pl2e = mk_l2_pgentry(__pa(newpg) | __PAGE_HYPERVISOR); + *pl2e = mk_l2_pgentry(__pa(newpg) | (flags & __PTE_MASK)); } pl1e = l2_pgentry_to_l1(*pl2e) + l1_table_offset(v); if ( (l1_pgentry_val(*pl1e) & _PAGE_PRESENT) ) diff --git a/xen/include/asm-x86/x86_64/page.h b/xen/include/asm-x86/x86_64/page.h index 350fec4b3b..9c8a62663a 100644 --- a/xen/include/asm-x86/x86_64/page.h +++ b/xen/include/asm-x86/x86_64/page.h @@ -55,10 +55,10 @@ typedef l4_pgentry_t root_pgentry_t; #define root_pgentry_to_phys(_x) (l4_pgentry_to_phys(_x)) /* Turn a typed table entry into a page index. */ -#define l1_pgentry_to_pfn(_x) (l1_pgentry_val(_x) >> PAGE_SHIFT) -#define l2_pgentry_to_pfn(_x) (l2_pgentry_val(_x) >> PAGE_SHIFT) -#define l3_pgentry_to_pfn(_x) (l3_pgentry_val(_x) >> PAGE_SHIFT) -#define l4_pgentry_to_pfn(_x) (l4_pgentry_val(_x) >> PAGE_SHIFT) +#define l1_pgentry_to_pfn(_x) (l1_pgentry_to_phys(_x) >> PAGE_SHIFT) +#define l2_pgentry_to_pfn(_x) (l2_pgentry_to_phys(_x) >> PAGE_SHIFT) +#define l3_pgentry_to_pfn(_x) (l3_pgentry_to_phys(_x) >> PAGE_SHIFT) +#define l4_pgentry_to_pfn(_x) (l4_pgentry_to_phys(_x) >> PAGE_SHIFT) #define root_pgentry_to_pfn(_x) (l4_pgentry_to_pfn(_x)) /* Pagetable walking. */ |