aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extras/mini-os/h/lib.h17
-rw-r--r--extras/mini-os/h/mm.h60
-rw-r--r--extras/mini-os/h/os.h22
-rw-r--r--extras/mini-os/h/types.h11
-rw-r--r--extras/mini-os/kernel.c2
-rw-r--r--extras/mini-os/lib/printf.c4
-rw-r--r--extras/mini-os/mm.c2
-rw-r--r--extras/mini-os/traps.c139
-rw-r--r--extras/mini-os/x86_64.S160
-rw-r--r--xen/arch/x86/domain.c92
-rw-r--r--xen/arch/x86/x86_32/domain_build.c2
-rw-r--r--xen/arch/x86/x86_32/mm.c3
-rw-r--r--xen/arch/x86/x86_64/domain_build.c6
-rw-r--r--xen/arch/x86/x86_64/entry.S2
-rw-r--r--xen/arch/x86/x86_64/mm.c7
-rw-r--r--xen/include/asm-x86/x86_64/page.h8
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) (&regs->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. */