direct-io.hg

changeset 3797:7561a06348cf

bitkeeper revision 1.1185 (420cf3c8-bMMcsnH1kMVRwy5AQ-ecg)

Various mini-os and Xen fixes. The M2P table is now definitely
accessible (read-only) from guest context.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Fri Feb 11 18:04:56 2005 +0000 (2005-02-11)
parents 50e6fb796ba1
children b5a5aa93e24f
files extras/mini-os/h/lib.h extras/mini-os/h/mm.h extras/mini-os/h/os.h extras/mini-os/h/types.h extras/mini-os/kernel.c extras/mini-os/lib/printf.c extras/mini-os/mm.c extras/mini-os/traps.c extras/mini-os/x86_64.S xen/arch/x86/domain.c xen/arch/x86/x86_32/domain_build.c xen/arch/x86/x86_32/mm.c xen/arch/x86/x86_64/domain_build.c xen/arch/x86/x86_64/entry.S xen/arch/x86/x86_64/mm.c xen/include/asm-x86/x86_64/page.h
line diff
     1.1 --- a/extras/mini-os/h/lib.h	Fri Feb 11 16:42:22 2005 +0000
     1.2 +++ b/extras/mini-os/h/lib.h	Fri Feb 11 18:04:56 2005 +0000
     1.3 @@ -55,22 +55,7 @@
     1.4  #ifndef _LIB_H_
     1.5  #define _LIB_H_
     1.6  
     1.7 -
     1.8 -/* variadic function support */
     1.9 -typedef char *va_list;
    1.10 -#define __va_size(type) \
    1.11 -        (((sizeof(type) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
    1.12 -#ifdef __GNUC__
    1.13 -#define va_start(ap, last) \
    1.14 -        ((ap) = (va_list)__builtin_next_arg(last))
    1.15 -#else
    1.16 -#define va_start(ap, last) \
    1.17 -        ((ap) = (va_list)&(last) + __va_size(last))
    1.18 -#endif
    1.19 -#define va_arg(ap, type) \
    1.20 -        (*(type *)((ap) += __va_size(type), (ap) - __va_size(type)))
    1.21 -#define va_end(ap)
    1.22 -
    1.23 +#include <stdarg.h>
    1.24  
    1.25  /* printing */
    1.26  #define printk  printf
     2.1 --- a/extras/mini-os/h/mm.h	Fri Feb 11 16:42:22 2005 +0000
     2.2 +++ b/extras/mini-os/h/mm.h	Fri Feb 11 18:04:56 2005 +0000
     2.3 @@ -1,20 +1,8 @@
     2.4  /* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
     2.5 - ****************************************************************************
     2.6 - * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
     2.7 - ****************************************************************************
     2.8   *
     2.9 - *        File: mm.h
    2.10 - *      Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
    2.11 - *     Changes: 
    2.12 - *              
    2.13 - *        Date: Aug 2003
    2.14 - * 
    2.15 - * Environment: 
    2.16 - * Description: 
    2.17 + * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
    2.18 + * Copyright (c) 2005, Keir A Fraser
    2.19   *
    2.20 - ****************************************************************************
    2.21 - * $Id: h-insert.h,v 1.4 2002/11/08 16:03:55 rn Exp $
    2.22 - ****************************************************************************
    2.23   * Permission is hereby granted, free of charge, to any person obtaining a copy
    2.24   * of this software and associated documentation files (the "Software"), to
    2.25   * deal in the Software without restriction, including without limitation the
    2.26 @@ -37,6 +25,48 @@
    2.27  #ifndef _MM_H_
    2.28  #define _MM_H_
    2.29  
    2.30 +#ifdef __x86_64__
    2.31 +
    2.32 +#define L1_PAGETABLE_SHIFT      12
    2.33 +#define L2_PAGETABLE_SHIFT      21
    2.34 +#define L3_PAGETABLE_SHIFT      30
    2.35 +#define L4_PAGETABLE_SHIFT      39
    2.36 +
    2.37 +#define L1_PAGETABLE_ENTRIES    512
    2.38 +#define L2_PAGETABLE_ENTRIES    512
    2.39 +#define L3_PAGETABLE_ENTRIES    512
    2.40 +#define L4_PAGETABLE_ENTRIES    512
    2.41 +
    2.42 +/* These are page-table limitations. Current CPUs support only 40-bit phys. */
    2.43 +#define PADDR_BITS              52
    2.44 +#define VADDR_BITS              48
    2.45 +#define PADDR_MASK              ((1UL << PADDR_BITS)-1)
    2.46 +#define VADDR_MASK              ((1UL << VADDR_BITS)-1)
    2.47 +
    2.48 +#define pte_to_mfn(_pte) (((_pte) & (PADDR_MASK&PAGE_MASK)) >> PAGE_SHIFT)
    2.49 +
    2.50 +/* Given a virtual address, get an entry offset into a page table. */
    2.51 +#define l1_table_offset(_a) \
    2.52 +  (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
    2.53 +#define l2_table_offset(_a) \
    2.54 +  (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
    2.55 +#define l3_table_offset(_a) \
    2.56 +  (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
    2.57 +#define l4_table_offset(_a) \
    2.58 +  (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
    2.59 +#endif
    2.60 +
    2.61 +#define _PAGE_PRESENT  0x001UL
    2.62 +#define _PAGE_RW       0x002UL
    2.63 +#define _PAGE_USER     0x004UL
    2.64 +#define _PAGE_PWT      0x008UL
    2.65 +#define _PAGE_PCD      0x010UL
    2.66 +#define _PAGE_ACCESSED 0x020UL
    2.67 +#define _PAGE_DIRTY    0x040UL
    2.68 +#define _PAGE_PAT      0x080UL
    2.69 +#define _PAGE_PSE      0x080UL
    2.70 +#define _PAGE_GLOBAL   0x100UL
    2.71 +
    2.72  #define PAGE_SHIFT      12
    2.73  #define PAGE_SIZE       (1UL << PAGE_SHIFT)
    2.74  #define PAGE_MASK       (~(PAGE_SIZE-1))
    2.75 @@ -72,6 +102,8 @@ static __inline__ unsigned long machine_
    2.76  
    2.77  #define to_phys(x)                 ((unsigned long)(x)-VIRT_START)
    2.78  #define to_virt(x)                 ((void *)((unsigned long)(x)+VIRT_START))
    2.79 +#define __va to_virt
    2.80 +#define __pa to_phys
    2.81  
    2.82  void init_mm(void);
    2.83  unsigned long alloc_pages(int order);
     3.1 --- a/extras/mini-os/h/os.h	Fri Feb 11 16:42:22 2005 +0000
     3.2 +++ b/extras/mini-os/h/os.h	Fri Feb 11 18:04:56 2005 +0000
     3.3 @@ -29,6 +29,28 @@
     3.4  #define __KERNEL_DS  FLAT_KERNEL_DS
     3.5  #define __KERNEL_SS  FLAT_KERNEL_SS
     3.6  
     3.7 +#define TRAP_divide_error      0
     3.8 +#define TRAP_debug             1
     3.9 +#define TRAP_nmi               2
    3.10 +#define TRAP_int3              3
    3.11 +#define TRAP_overflow          4
    3.12 +#define TRAP_bounds            5
    3.13 +#define TRAP_invalid_op        6
    3.14 +#define TRAP_no_device         7
    3.15 +#define TRAP_double_fault      8
    3.16 +#define TRAP_copro_seg         9
    3.17 +#define TRAP_invalid_tss      10
    3.18 +#define TRAP_no_segment       11
    3.19 +#define TRAP_stack_error      12
    3.20 +#define TRAP_gp_fault         13
    3.21 +#define TRAP_page_fault       14
    3.22 +#define TRAP_spurious_int     15
    3.23 +#define TRAP_copro_error      16
    3.24 +#define TRAP_alignment_check  17
    3.25 +#define TRAP_machine_check    18
    3.26 +#define TRAP_simd_error       19
    3.27 +#define TRAP_deferred_nmi     31
    3.28 +
    3.29  /* Everything below this point is not included by assembler (.S) files. */
    3.30  #ifndef __ASSEMBLY__
    3.31  
     4.1 --- a/extras/mini-os/h/types.h	Fri Feb 11 16:42:22 2005 +0000
     4.2 +++ b/extras/mini-os/h/types.h	Fri Feb 11 18:04:56 2005 +0000
     4.3 @@ -26,8 +26,13 @@ typedef signed short        s16;
     4.4  typedef unsigned short      u16;
     4.5  typedef signed int          s32;
     4.6  typedef unsigned int        u32;
     4.7 +#ifdef __i386__
     4.8  typedef signed long long    s64;
     4.9  typedef unsigned long long  u64;
    4.10 +#elif defined(__x86_64__)
    4.11 +typedef signed long         s64;
    4.12 +typedef unsigned long       u64;
    4.13 +#endif
    4.14  
    4.15  typedef unsigned int        size_t;
    4.16  
    4.17 @@ -35,7 +40,13 @@ typedef unsigned int        size_t;
    4.18  typedef unsigned char       u_char;
    4.19  typedef unsigned int        u_int;
    4.20  typedef unsigned long       u_long;
    4.21 +#ifdef __i386__
    4.22  typedef long long           quad_t;
    4.23  typedef unsigned long long  u_quad_t;
    4.24  typedef unsigned int        uintptr_t;
    4.25 +#elif defined(__x86_64__)
    4.26 +typedef long                quad_t;
    4.27 +typedef unsigned long       u_quad_t;
    4.28 +typedef unsigned long       uintptr_t;
    4.29 +#endif
    4.30  #endif /* _TYPES_H_ */
     5.1 --- a/extras/mini-os/kernel.c	Fri Feb 11 16:42:22 2005 +0000
     5.2 +++ b/extras/mini-os/kernel.c	Fri Feb 11 18:04:56 2005 +0000
     5.3 @@ -65,7 +65,7 @@ extern char shared_info[PAGE_SIZE];
     5.4  static shared_info_t *map_shared_info(unsigned long pa)
     5.5  {
     5.6      if ( HYPERVISOR_update_va_mapping(
     5.7 -        (unsigned long)shared_info, pa | 3, UVMF_INVLPG) )
     5.8 +        (unsigned long)shared_info, pa | 7, UVMF_INVLPG) )
     5.9      {
    5.10          printk("Failed to map shared_info!!\n");
    5.11          *(int*)0=0;
     6.1 --- a/extras/mini-os/lib/printf.c	Fri Feb 11 16:42:22 2005 +0000
     6.2 +++ b/extras/mini-os/lib/printf.c	Fri Feb 11 18:04:56 2005 +0000
     6.3 @@ -341,7 +341,9 @@ reswitch:	switch (ch = (u_char)*fmt++) {
     6.4  		case 'p':
     6.5  			ul = (uintptr_t)va_arg(ap, void *);
     6.6  			base = 16;
     6.7 -			sharpflag = (width == 0);
     6.8 +			sharpflag = 0;
     6.9 +            padc  = '0';
    6.10 +            width = sizeof(uintptr_t)*2;
    6.11  			goto nosign;
    6.12  		case 'q':
    6.13  			qflag = 1;
     7.1 --- a/extras/mini-os/mm.c	Fri Feb 11 16:42:22 2005 +0000
     7.2 +++ b/extras/mini-os/mm.c	Fri Feb 11 18:04:56 2005 +0000
     7.3 @@ -84,6 +84,7 @@ void init_mm(void)
     7.4       */
     7.5  
     7.6      max_free_pfn = PFN_DOWN(to_phys(pgd));
     7.7 +#ifdef __i386__
     7.8      {
     7.9          unsigned long *pgd = (unsigned long *)start_info.pt_base;
    7.10          unsigned long  pte;
    7.11 @@ -110,6 +111,7 @@ void init_mm(void)
    7.12             (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
    7.13             (u_long)to_virt(PFN_PHYS(max_free_pfn)), PFN_PHYS(max_free_pfn));
    7.14      init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_free_pfn));   
    7.15 +#endif
    7.16  
    7.17  
    7.18      /* Now initialise the physical->machine mapping table. */
     8.1 --- a/extras/mini-os/traps.c	Fri Feb 11 16:42:22 2005 +0000
     8.2 +++ b/extras/mini-os/traps.c	Fri Feb 11 18:04:56 2005 +0000
     8.3 @@ -15,7 +15,6 @@ void overflow(void);
     8.4  void bounds(void);
     8.5  void invalid_op(void);
     8.6  void device_not_available(void);
     8.7 -void double_fault(void);
     8.8  void coprocessor_segment_overrun(void);
     8.9  void invalid_TSS(void);
    8.10  void segment_not_present(void);
    8.11 @@ -33,111 +32,134 @@ extern void do_exit(void);
    8.12  
    8.13  void dump_regs(struct pt_regs *regs)
    8.14  {
    8.15 -    int in_kernel = 1;
    8.16      unsigned long esp;
    8.17      unsigned short ss;
    8.18  
    8.19 +#ifdef __x86_64__
    8.20 +    esp = regs->rsp;
    8.21 +    ss  = regs->ss;
    8.22 +#else
    8.23      esp = (unsigned long) (&regs->esp);
    8.24      ss = __KERNEL_DS;
    8.25      if (regs->cs & 2) {
    8.26 -        in_kernel = 0;
    8.27          esp = regs->esp;
    8.28          ss = regs->ss & 0xffff;
    8.29      }
    8.30 -    printf("EIP:    %04x:[<%p>]\n",
    8.31 -           0xffff & regs->cs , regs->eip);
    8.32 +#endif
    8.33 +    printf("EIP:    %04x:[<%p>] %08x\n",
    8.34 +           0xffff & regs->cs , regs->eip, regs->error_code);
    8.35      printf("EFLAGS: %p\n",regs->eflags);
    8.36      printf("eax: %p   ebx: %p   ecx: %p   edx: %p\n",
    8.37             regs->eax, regs->ebx, regs->ecx, regs->edx);
    8.38      printf("esi: %p   edi: %p   ebp: %p   esp: %p\n",
    8.39             regs->esi, regs->edi, regs->ebp, esp);
    8.40 +#ifdef __x86_64__
    8.41 +    printf("r8 : %p   r9 : %p   r10: %p   r11: %p\n",
    8.42 +           regs->r8,  regs->r9,  regs->r10, regs->r11);
    8.43 +    printf("r12: %p   r13: %p   r14: %p   r15: %p\n",
    8.44 +           regs->r12, regs->r13, regs->r14, regs->r15);
    8.45 +#endif
    8.46      printf("ds: %04x   es: %04x   ss: %04x\n",
    8.47             regs->ds & 0xffff, regs->es & 0xffff, ss);
    8.48 -    printf("\n");
    8.49  }	
    8.50  
    8.51  
    8.52  static __inline__ void dump_code(unsigned long eip)
    8.53  {
    8.54 -    unsigned *ptr = (unsigned *)eip;
    8.55 +    unsigned char *ptr = (unsigned char *)eip;
    8.56      int x;
    8.57      
    8.58 -    printk("Bytes at eip:\n");
    8.59 -    for (x = -4; x < 5; x++)
    8.60 -        printf("%p", ptr[x]);
    8.61 +    printk("Bytes at eip: ");
    8.62 +    for ( x = -4; x < 5; x++ )
    8.63 +        printf("%02x ", ptr[x]);
    8.64 +    printk("\n");
    8.65  }
    8.66  
    8.67 -
    8.68 -/*
    8.69 - * C handlers here have their parameter-list constructed by the
    8.70 - * assembler stubs above. Each one gets a pointer to a list
    8.71 - * of register values (to be restored at end of exception).
    8.72 - * Some will also receive an error code -- this is the code that
    8.73 - * was generated by the processor for the underlying real exception. 
    8.74 - * 
    8.75 - * Note that the page-fault exception is special. It also receives
    8.76 - * the faulting linear address. Normally this would be found in
    8.77 - * register CR2, but that is not accessible in a virtualised OS.
    8.78 - */
    8.79 -
    8.80  static void __inline__ do_trap(int trapnr, char *str,
    8.81 -                               struct pt_regs * regs, long error_code)
    8.82 +                               struct pt_regs * regs)
    8.83  {
    8.84 -    printk("FATAL:  Unhandled Trap (see mini-os:traps.c)");
    8.85 -    printf("%d %s", trapnr, str);
    8.86 +    printk("FATAL:  Unhandled Trap %d (%s)\n", trapnr, str);
    8.87      dump_regs(regs);
    8.88      dump_code(regs->eip);
    8.89 -
    8.90      do_exit();
    8.91  }
    8.92  
    8.93  #define DO_ERROR(trapnr, str, name) \
    8.94 -void do_##name(struct pt_regs * regs, long error_code) \
    8.95 +void do_##name(struct pt_regs * regs) \
    8.96  { \
    8.97 -	do_trap(trapnr, str, regs, error_code); \
    8.98 +	do_trap(trapnr, str, regs); \
    8.99  }
   8.100  
   8.101  #define DO_ERROR_INFO(trapnr, str, name, sicode, siaddr) \
   8.102 -void do_##name(struct pt_regs * regs, long error_code) \
   8.103 +void do_##name(struct pt_regs * regs) \
   8.104  { \
   8.105 -	do_trap(trapnr, str, regs, error_code); \
   8.106 +	do_trap(trapnr, str, regs); \
   8.107  }
   8.108  
   8.109  DO_ERROR_INFO( 0, "divide error", divide_error, FPE_INTDIV, regs->eip)
   8.110 -    DO_ERROR( 3, "int3", int3)
   8.111 -    DO_ERROR( 4, "overflow", overflow)
   8.112 -    DO_ERROR( 5, "bounds", bounds)
   8.113 -    DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
   8.114 -    DO_ERROR( 7, "device not available", device_not_available)
   8.115 -    DO_ERROR( 8, "double fault", double_fault)
   8.116 -    DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
   8.117 -    DO_ERROR(10, "invalid TSS", invalid_TSS)
   8.118 -    DO_ERROR(11, "segment not present", segment_not_present)
   8.119 -    DO_ERROR(12, "stack segment", stack_segment)
   8.120 -    DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
   8.121 -    DO_ERROR(18, "machine check", machine_check)
   8.122 +DO_ERROR( 3, "int3", int3)
   8.123 +DO_ERROR( 4, "overflow", overflow)
   8.124 +DO_ERROR( 5, "bounds", bounds)
   8.125 +DO_ERROR_INFO( 6, "invalid operand", invalid_op, ILL_ILLOPN, regs->eip)
   8.126 +DO_ERROR( 7, "device not available", device_not_available)
   8.127 +DO_ERROR( 9, "coprocessor segment overrun", coprocessor_segment_overrun)
   8.128 +DO_ERROR(10, "invalid TSS", invalid_TSS)
   8.129 +DO_ERROR(11, "segment not present", segment_not_present)
   8.130 +DO_ERROR(12, "stack segment", stack_segment)
   8.131 +DO_ERROR_INFO(17, "alignment check", alignment_check, BUS_ADRALN, 0)
   8.132 +DO_ERROR(18, "machine check", machine_check)
   8.133  
   8.134 -    void do_page_fault(struct pt_regs *regs, long error_code,
   8.135 -                       unsigned long address)
   8.136 +extern unsigned long virt_cr2;
   8.137 +void do_page_fault(struct pt_regs *regs)
   8.138  {
   8.139 -    printk("Page fault\n");
   8.140 -    printk("Address: 0x%p", address);
   8.141 -    printk("Error Code: 0x%p", error_code);
   8.142 -    printk("eip: \t 0x%p", regs->eip);
   8.143 +    unsigned long addr = virt_cr2;
   8.144 +    printk("Page fault at linear address %p\n", addr);
   8.145 +    dump_regs(regs);
   8.146 +    dump_code(regs->eip);
   8.147 +#ifdef __x86_64__
   8.148 +    {
   8.149 +        unsigned long *tab = (unsigned long *)start_info.pt_base;
   8.150 +        unsigned long page;
   8.151 +    
   8.152 +        printk("Pagetable walk from %p:\n", tab);
   8.153 +        
   8.154 +        page = tab[l4_table_offset(addr)];
   8.155 +        tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
   8.156 +        printk(" L4 = %p (%p)\n", page, tab);
   8.157 +        if ( !(page & _PAGE_PRESENT) )
   8.158 +            goto out;
   8.159 +
   8.160 +        page = tab[l3_table_offset(addr)];
   8.161 +        tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
   8.162 +        printk("  L3 = %p (%p)\n", page, tab);
   8.163 +        if ( !(page & _PAGE_PRESENT) )
   8.164 +            goto out;
   8.165 +        
   8.166 +        page = tab[l2_table_offset(addr)];
   8.167 +        tab = __va(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
   8.168 +        printk("   L2 = %p (%p) %s\n", page, tab,
   8.169 +               (page & _PAGE_PSE) ? "(2MB)" : "");
   8.170 +        if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) )
   8.171 +            goto out;
   8.172 +        
   8.173 +        page = tab[l1_table_offset(addr)];
   8.174 +        printk("    L1 = %p\n", page);
   8.175 +    }
   8.176 +#endif
   8.177 + out:
   8.178      do_exit();
   8.179  }
   8.180  
   8.181 -void do_general_protection(struct pt_regs * regs, long error_code)
   8.182 +void do_general_protection(struct pt_regs *regs)
   8.183  {
   8.184      printk("GPF\n");
   8.185 -    printk("Error Code: 0x%p", error_code);
   8.186      dump_regs(regs);
   8.187      dump_code(regs->eip);
   8.188      do_exit();
   8.189  }
   8.190  
   8.191  
   8.192 -void do_debug(struct pt_regs * regs, long error_code)
   8.193 +void do_debug(struct pt_regs * regs)
   8.194  {
   8.195      printk("Debug exception\n");
   8.196  #define TF_MASK 0x100
   8.197 @@ -146,9 +168,7 @@ void do_debug(struct pt_regs * regs, lon
   8.198      do_exit();
   8.199  }
   8.200  
   8.201 -
   8.202 -
   8.203 -void do_coprocessor_error(struct pt_regs * regs, long error_code)
   8.204 +void do_coprocessor_error(struct pt_regs * regs)
   8.205  {
   8.206      printk("Copro error\n");
   8.207      dump_regs(regs);
   8.208 @@ -161,14 +181,12 @@ void simd_math_error(void *eip)
   8.209      printk("SIMD error\n");
   8.210  }
   8.211  
   8.212 -void do_simd_coprocessor_error(struct pt_regs * regs,
   8.213 -                               long error_code)
   8.214 +void do_simd_coprocessor_error(struct pt_regs * regs)
   8.215  {
   8.216      printk("SIMD copro error\n");
   8.217  }
   8.218  
   8.219 -void do_spurious_interrupt_bug(struct pt_regs * regs,
   8.220 -                               long error_code)
   8.221 +void do_spurious_interrupt_bug(struct pt_regs * regs)
   8.222  {
   8.223  }
   8.224  
   8.225 @@ -189,7 +207,6 @@ static trap_info_t trap_table[] = {
   8.226      {  5, 3, __KERNEL_CS, _P (unsigned long)bounds                      },
   8.227      {  6, 0, __KERNEL_CS, _P (unsigned long)invalid_op                  },
   8.228      {  7, 0, __KERNEL_CS, _P (unsigned long)device_not_available        },
   8.229 -    {  8, 0, __KERNEL_CS, _P (unsigned long)double_fault                },
   8.230      {  9, 0, __KERNEL_CS, _P (unsigned long)coprocessor_segment_overrun },
   8.231      { 10, 0, __KERNEL_CS, _P (unsigned long)invalid_TSS                 },
   8.232      { 11, 0, __KERNEL_CS, _P (unsigned long)segment_not_present         },
     9.1 --- a/extras/mini-os/x86_64.S	Fri Feb 11 16:42:22 2005 +0000
     9.2 +++ b/extras/mini-os/x86_64.S	Fri Feb 11 18:04:56 2005 +0000
     9.3 @@ -6,7 +6,42 @@
     9.4  
     9.5  #define ENTRY(X) .globl X ; X :
     9.6  .globl _start, shared_info
     9.7 -                        
     9.8 +
     9.9 +#define SAVE_ALL \
    9.10 +        cld; \
    9.11 +        pushq %rdi; \
    9.12 +        pushq %rsi; \
    9.13 +        pushq %rdx; \
    9.14 +        pushq %rcx; \
    9.15 +        pushq %rax; \
    9.16 +        pushq %r8; \
    9.17 +        pushq %r9; \
    9.18 +        pushq %r10; \
    9.19 +        pushq %r11; \
    9.20 +        pushq %rbx; \
    9.21 +        pushq %rbp; \
    9.22 +        pushq %r12; \
    9.23 +        pushq %r13; \
    9.24 +        pushq %r14; \
    9.25 +        pushq %r15;
    9.26 +
    9.27 +#define RESTORE_ALL \
    9.28 +        popq  %r15; \
    9.29 +        popq  %r14; \
    9.30 +        popq  %r13; \
    9.31 +        popq  %r12; \
    9.32 +        popq  %rbp; \
    9.33 +        popq  %rbx; \
    9.34 +        popq  %r11; \
    9.35 +        popq  %r10; \
    9.36 +        popq  %r9; \
    9.37 +        popq  %r8; \
    9.38 +        popq  %rax; \
    9.39 +        popq  %rcx; \
    9.40 +        popq  %rdx; \
    9.41 +        popq  %rsi; \
    9.42 +        popq  %rdi
    9.43 +
    9.44  _start:
    9.45          cld
    9.46          movq stack_start(%rip),%rsp
    9.47 @@ -23,56 +58,165 @@ shared_info:
    9.48          .org 0x2000
    9.49  
    9.50  ENTRY(hypervisor_callback)
    9.51 +        popq  %rcx
    9.52 +        popq  %r11
    9.53 +        iretq
    9.54  
    9.55  ENTRY(failsafe_callback)
    9.56 -      iret
    9.57 -                
    9.58 +        popq  %rcx
    9.59 +        popq  %r11
    9.60 +        iretq
    9.61 +
    9.62 +error_code:
    9.63 +        SAVE_ALL
    9.64 +        movq  %rsp,%rdi
    9.65 +        movl  15*8+4(%rsp),%eax
    9.66 +        leaq  exception_table(%rip),%rdx
    9.67 +        callq *(%rdx,%rax,8)
    9.68 +        RESTORE_ALL
    9.69 +        addq  $8,%rsp
    9.70 +        iretq
    9.71 +                        
    9.72  ENTRY(divide_error)
    9.73 +        popq  %rcx
    9.74 +        popq  %r11
    9.75  	pushq $0
    9.76 -
    9.77 +        movl  $TRAP_divide_error,4(%rsp)
    9.78 +        jmp   error_code
    9.79 +        
    9.80  ENTRY(coprocessor_error)
    9.81 +        popq  %rcx
    9.82 +        popq  %r11
    9.83  	pushq $0
    9.84 +        movl  $TRAP_copro_error,4(%rsp)
    9.85 +        jmp   error_code
    9.86  
    9.87  ENTRY(simd_coprocessor_error)
    9.88 +        popq  %rcx
    9.89 +        popq  %r11
    9.90  	pushq $0
    9.91 +        movl  $TRAP_simd_error,4(%rsp)
    9.92 +        jmp   error_code
    9.93  
    9.94  ENTRY(device_not_available)
    9.95 -        iret
    9.96 +        popq  %rcx
    9.97 +        popq  %r11
    9.98 +        movl  $TRAP_no_device,4(%rsp)
    9.99 +        jmp   error_code
   9.100  
   9.101  ENTRY(debug)
   9.102 +        popq  %rcx
   9.103 +        popq  %r11
   9.104  	pushq $0
   9.105 +        movl  $TRAP_debug,4(%rsp)
   9.106 +        jmp   error_code
   9.107  
   9.108  ENTRY(int3)
   9.109 +        popq  %rcx
   9.110 +        popq  %r11
   9.111  	pushq $0
   9.112 +        movl  $TRAP_int3,4(%rsp)
   9.113 +        jmp   error_code
   9.114  
   9.115  ENTRY(overflow)
   9.116 +        popq  %rcx
   9.117 +        popq  %r11
   9.118  	pushq $0
   9.119 +        movl  $TRAP_overflow,4(%rsp)
   9.120 +        jmp   error_code
   9.121  
   9.122  ENTRY(bounds)
   9.123 +        popq  %rcx
   9.124 +        popq  %r11
   9.125  	pushq $0
   9.126 +        movl  $TRAP_bounds,4(%rsp)
   9.127 +        jmp   error_code
   9.128  
   9.129  ENTRY(invalid_op)
   9.130 +        popq  %rcx
   9.131 +        popq  %r11
   9.132  	pushq $0
   9.133 +        movl  $TRAP_invalid_op,4(%rsp)
   9.134 +        jmp   error_code
   9.135  
   9.136  ENTRY(coprocessor_segment_overrun)
   9.137 +        popq  %rcx
   9.138 +        popq  %r11
   9.139  	pushq $0
   9.140 -
   9.141 -ENTRY(double_fault)
   9.142 +        movl  $TRAP_copro_seg,4(%rsp)
   9.143 +        jmp   error_code
   9.144  
   9.145  ENTRY(invalid_TSS)
   9.146 +        popq  %rcx
   9.147 +        popq  %r11
   9.148 +        movl  $TRAP_invalid_tss,4(%rsp)
   9.149 +        jmp   error_code
   9.150  
   9.151  ENTRY(segment_not_present)
   9.152 +        popq  %rcx
   9.153 +        popq  %r11
   9.154 +        movl  $TRAP_no_segment,4(%rsp)
   9.155 +        jmp   error_code
   9.156  
   9.157  ENTRY(stack_segment)
   9.158 +        popq  %rcx
   9.159 +        popq  %r11
   9.160 +        movl  $TRAP_stack_error,4(%rsp)
   9.161 +        jmp   error_code
   9.162  
   9.163  ENTRY(general_protection)
   9.164 +        popq  %rcx
   9.165 +        popq  %r11
   9.166 +        movl  $TRAP_gp_fault,4(%rsp)
   9.167 +        jmp   error_code
   9.168  
   9.169  ENTRY(alignment_check)
   9.170 -
   9.171 -ENTRY(page_fault)
   9.172 +        popq  %rcx
   9.173 +        popq  %r11
   9.174 +        movl  $TRAP_alignment_check,4(%rsp)
   9.175 +        jmp   error_code
   9.176  
   9.177 +ENTRY(virt_cr2)
   9.178 +        .quad 0
   9.179 +ENTRY(page_fault)
   9.180 +        popq  %rcx
   9.181 +        popq  %r11
   9.182 +        popq  virt_cr2(%rip)
   9.183 +        movl  $TRAP_page_fault,4(%rsp)
   9.184 +        jmp   error_code
   9.185 +        
   9.186  ENTRY(machine_check)
   9.187 +        popq  %rcx
   9.188 +        popq  %r11
   9.189  	pushq $0
   9.190 +        movl  $TRAP_machine_check,4(%rsp)
   9.191 +        jmp   error_code
   9.192  
   9.193  ENTRY(spurious_interrupt_bug)
   9.194 +        popq  %rcx
   9.195 +        popq  %r11
   9.196  	pushq $0
   9.197 +        movl  $TRAP_spurious_int,4(%rsp)
   9.198 +        jmp   error_code
   9.199 +
   9.200 +ENTRY(exception_table)
   9.201 +        .quad do_divide_error
   9.202 +        .quad do_debug
   9.203 +        .quad 0 # nmi
   9.204 +        .quad do_int3
   9.205 +        .quad do_overflow
   9.206 +        .quad do_bounds
   9.207 +        .quad do_invalid_op
   9.208 +        .quad 0
   9.209 +        .quad 0
   9.210 +        .quad do_coprocessor_segment_overrun
   9.211 +        .quad do_invalid_TSS
   9.212 +        .quad do_segment_not_present
   9.213 +        .quad do_stack_segment
   9.214 +        .quad do_general_protection
   9.215 +        .quad do_page_fault
   9.216 +        .quad do_spurious_interrupt_bug
   9.217 +        .quad do_coprocessor_error
   9.218 +        .quad do_alignment_check
   9.219 +        .quad do_machine_check
   9.220 +        .quad do_simd_coprocessor_error
    10.1 --- a/xen/arch/x86/domain.c	Fri Feb 11 16:42:22 2005 +0000
    10.2 +++ b/xen/arch/x86/domain.c	Fri Feb 11 18:04:56 2005 +0000
    10.3 @@ -85,109 +85,79 @@ void startup_cpu_idle_loop(void)
    10.4  
    10.5  static long no_idt[2];
    10.6  static int reboot_mode;
    10.7 -int reboot_thru_bios = 0;
    10.8 -
    10.9 -#ifdef CONFIG_SMP
   10.10 -int reboot_smp = 0;
   10.11 -static int reboot_cpu = -1;
   10.12 -/* shamelessly grabbed from lib/vsprintf.c for readability */
   10.13 -#define is_digit(c)	((c) >= '0' && (c) <= '9')
   10.14 -#endif
   10.15 -
   10.16  
   10.17  static inline void kb_wait(void)
   10.18  {
   10.19      int i;
   10.20  
   10.21 -    for (i=0; i<0x10000; i++)
   10.22 -        if ((inb_p(0x64) & 0x02) == 0)
   10.23 +    for ( i = 0; i < 0x10000; i++ )
   10.24 +        if ( (inb_p(0x64) & 0x02) == 0 )
   10.25              break;
   10.26  }
   10.27  
   10.28 -
   10.29  void machine_restart(char * __unused)
   10.30  {
   10.31 -#ifdef CONFIG_SMP
   10.32 -    int cpuid;
   10.33 -#endif
   10.34 +    int i;
   10.35  	
   10.36      if ( opt_noreboot )
   10.37      {
   10.38          printk("Reboot disabled on cmdline: require manual reset\n");
   10.39 -        for ( ; ; ) __asm__ __volatile__ ("hlt");
   10.40 +        for ( ; ; )
   10.41 +            safe_halt();
   10.42      }
   10.43  
   10.44 -#ifdef CONFIG_SMP
   10.45 -    cpuid = GET_APIC_ID(apic_read(APIC_ID));
   10.46 -
   10.47 -    /* KAF: Need interrupts enabled for safe IPI. */
   10.48      __sti();
   10.49  
   10.50 -    if (reboot_smp) {
   10.51 -
   10.52 -        /* check to see if reboot_cpu is valid 
   10.53 -           if its not, default to the BSP */
   10.54 -        if ((reboot_cpu == -1) ||  
   10.55 -            (reboot_cpu > (NR_CPUS -1))  || 
   10.56 -            !(phys_cpu_present_map & (1<<cpuid))) 
   10.57 -            reboot_cpu = boot_cpu_physical_apicid;
   10.58 -
   10.59 -        reboot_smp = 0;  /* use this as a flag to only go through this once*/
   10.60 -        /* re-run this function on the other CPUs
   10.61 -           it will fall though this section since we have 
   10.62 -           cleared reboot_smp, and do the reboot if it is the
   10.63 -           correct CPU, otherwise it halts. */
   10.64 -        if (reboot_cpu != cpuid)
   10.65 -            smp_call_function((void *)machine_restart , NULL, 1, 0);
   10.66 +    /* Ensure we are the boot CPU. */
   10.67 +    if ( GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_physical_apicid )
   10.68 +    {
   10.69 +        smp_call_function((void *)machine_restart, NULL, 1, 0);
   10.70 +        for ( ; ; )
   10.71 +            safe_halt();
   10.72      }
   10.73  
   10.74 -    /* if reboot_cpu is still -1, then we want a tradional reboot, 
   10.75 -       and if we are not running on the reboot_cpu,, halt */
   10.76 -    if ((reboot_cpu != -1) && (cpuid != reboot_cpu)) {
   10.77 -        for (;;)
   10.78 -            __asm__ __volatile__ ("hlt");
   10.79 -    }
   10.80      /*
   10.81       * Stop all CPUs and turn off local APICs and the IO-APIC, so
   10.82       * other OSs see a clean IRQ state.
   10.83       */
   10.84      smp_send_stop();
   10.85      disable_IO_APIC();
   10.86 -#endif
   10.87 +
   10.88  #ifdef CONFIG_VMX
   10.89      stop_vmx();
   10.90  #endif
   10.91  
   10.92 -    if(!reboot_thru_bios) {
   10.93 -        /* rebooting needs to touch the page at absolute addr 0 */
   10.94 -        *((unsigned short *)__va(0x472)) = reboot_mode;
   10.95 -        for (;;) {
   10.96 -            int i;
   10.97 -            for (i=0; i<100; i++) {
   10.98 -                kb_wait();
   10.99 -                udelay(50);
  10.100 -                outb(0xfe,0x64);         /* pulse reset low */
  10.101 -                udelay(50);
  10.102 -            }
  10.103 -            /* That didn't work - force a triple fault.. */
  10.104 -            __asm__ __volatile__("lidt %0": "=m" (no_idt));
  10.105 -            __asm__ __volatile__("int3");
  10.106 +    /* Rebooting needs to touch the page at absolute address 0. */
  10.107 +    *((unsigned short *)__va(0x472)) = reboot_mode;
  10.108 +
  10.109 +    for ( ; ; )
  10.110 +    {
  10.111 +        /* Pulse the keyboard reset line. */
  10.112 +        for ( i = 0; i < 100; i++ )
  10.113 +        {
  10.114 +            kb_wait();
  10.115 +            udelay(50);
  10.116 +            outb(0xfe,0x64); /* pulse reset low */
  10.117 +            udelay(50);
  10.118          }
  10.119 +
  10.120 +        /* That didn't work - force a triple fault.. */
  10.121 +        __asm__ __volatile__("lidt %0": "=m" (no_idt));
  10.122 +        __asm__ __volatile__("int3");
  10.123      }
  10.124 -
  10.125 -    panic("Need to reinclude BIOS reboot code\n");
  10.126  }
  10.127  
  10.128  
  10.129  void __attribute__((noreturn)) __machine_halt(void *unused)
  10.130  {
  10.131      for ( ; ; )
  10.132 -        __asm__ __volatile__ ( "cli; hlt" );
  10.133 +        safe_halt();
  10.134  }
  10.135  
  10.136  void machine_halt(void)
  10.137  {
  10.138 -    smp_call_function(__machine_halt, NULL, 1, 1);
  10.139 +    watchdog_on = 0;
  10.140 +    smp_call_function(__machine_halt, NULL, 1, 0);
  10.141      __machine_halt(NULL);
  10.142  }
  10.143  
    11.1 --- a/xen/arch/x86/x86_32/domain_build.c	Fri Feb 11 16:42:22 2005 +0000
    11.2 +++ b/xen/arch/x86/x86_32/domain_build.c	Fri Feb 11 18:04:56 2005 +0000
    11.3 @@ -24,7 +24,7 @@
    11.4  
    11.5  /* No ring-3 access in initial page tables. */
    11.6  #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
    11.7 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    11.8 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
    11.9  
   11.10  #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   11.11  #define round_pgdown(_p)  ((_p)&PAGE_MASK)
    12.1 --- a/xen/arch/x86/x86_32/mm.c	Fri Feb 11 16:42:22 2005 +0000
    12.2 +++ b/xen/arch/x86/x86_32/mm.c	Fri Feb 11 18:04:56 2005 +0000
    12.3 @@ -29,6 +29,7 @@
    12.4  #include <asm/domain_page.h>
    12.5  
    12.6  /* Map physical byte range (@p, @p+@s) at virt address @v in pagetable @pt. */
    12.7 +#define __PTE_MASK (~(_PAGE_GLOBAL|_PAGE_DIRTY|_PAGE_PCD|_PAGE_PWT))
    12.8  int map_pages(
    12.9      root_pgentry_t *pt,
   12.10      unsigned long v,
   12.11 @@ -62,7 +63,7 @@ int map_pages(
   12.12              {
   12.13                  newpg = (void *)alloc_xenheap_page();
   12.14                  clear_page(newpg);
   12.15 -                *pl2e = mk_l2_pgentry(__pa(newpg) | __PAGE_HYPERVISOR);
   12.16 +                *pl2e = mk_l2_pgentry(__pa(newpg) | (flags & __PTE_MASK));
   12.17              }
   12.18              pl1e = l2_pgentry_to_l1(*pl2e) + l1_table_offset(v);
   12.19              if ( (l1_pgentry_val(*pl1e) & _PAGE_PRESENT) )
    13.1 --- a/xen/arch/x86/x86_64/domain_build.c	Fri Feb 11 16:42:22 2005 +0000
    13.2 +++ b/xen/arch/x86/x86_64/domain_build.c	Fri Feb 11 18:04:56 2005 +0000
    13.3 @@ -23,9 +23,9 @@
    13.4  
    13.5  /* Allow ring-3 access in long mode as guest cannot use ring 1. */
    13.6  #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
    13.7 -#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    13.8 -#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    13.9 -#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
   13.10 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
   13.11 +#define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
   13.12 +#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
   13.13  
   13.14  #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
   13.15  #define round_pgdown(_p)  ((_p)&PAGE_MASK)
    14.1 --- a/xen/arch/x86/x86_64/entry.S	Fri Feb 11 16:42:22 2005 +0000
    14.2 +++ b/xen/arch/x86/x86_64/entry.S	Fri Feb 11 18:04:56 2005 +0000
    14.3 @@ -298,7 +298,7 @@ exception_with_ints_disabled:
    14.4          testb $3,XREGS_cs(%rsp)         # interrupts disabled outside Xen?
    14.5          jnz   1b                        # it really does happen!
    14.6                                          #  (e.g., DOM0 X server)
    14.7 -        movq  XREGS_rip(%rsp),%rdi
    14.8 +        movq  %rsp,%rdi
    14.9          call  search_pre_exception_table
   14.10          testq %rax,%rax                 # no fixup code for faulting EIP?
   14.11          jz    FATAL_exception_with_ints_disabled
    15.1 --- a/xen/arch/x86/x86_64/mm.c	Fri Feb 11 16:42:22 2005 +0000
    15.2 +++ b/xen/arch/x86/x86_64/mm.c	Fri Feb 11 18:04:56 2005 +0000
    15.3 @@ -37,6 +37,7 @@ void *safe_page_alloc(void)
    15.4  }
    15.5  
    15.6  /* Map physical byte range (@p, @p+@s) at virt address @v in pagetable @pt. */
    15.7 +#define __PTE_MASK (~(_PAGE_GLOBAL|_PAGE_DIRTY|_PAGE_PCD|_PAGE_PWT))
    15.8  int map_pages(
    15.9      root_pgentry_t *pt,
   15.10      unsigned long v,
   15.11 @@ -57,7 +58,7 @@ int map_pages(
   15.12          {
   15.13              newpg = safe_page_alloc();
   15.14              clear_page(newpg);
   15.15 -            *pl4e = mk_l4_pgentry(__pa(newpg) | __PAGE_HYPERVISOR);
   15.16 +            *pl4e = mk_l4_pgentry(__pa(newpg) | (flags & __PTE_MASK));
   15.17          }
   15.18  
   15.19          pl3e = l4_pgentry_to_l3(*pl4e) + l3_table_offset(v);
   15.20 @@ -65,7 +66,7 @@ int map_pages(
   15.21          {
   15.22              newpg = safe_page_alloc();
   15.23              clear_page(newpg);
   15.24 -            *pl3e = mk_l3_pgentry(__pa(newpg) | __PAGE_HYPERVISOR);
   15.25 +            *pl3e = mk_l3_pgentry(__pa(newpg) | (flags & __PTE_MASK));
   15.26          }
   15.27  
   15.28          pl2e = l3_pgentry_to_l2(*pl3e) + l2_table_offset(v);
   15.29 @@ -88,7 +89,7 @@ int map_pages(
   15.30              {
   15.31                  newpg = safe_page_alloc();
   15.32                  clear_page(newpg);
   15.33 -                *pl2e = mk_l2_pgentry(__pa(newpg) | __PAGE_HYPERVISOR);
   15.34 +                *pl2e = mk_l2_pgentry(__pa(newpg) | (flags & __PTE_MASK));
   15.35              }
   15.36              pl1e = l2_pgentry_to_l1(*pl2e) + l1_table_offset(v);
   15.37              if ( (l1_pgentry_val(*pl1e) & _PAGE_PRESENT) )
    16.1 --- a/xen/include/asm-x86/x86_64/page.h	Fri Feb 11 16:42:22 2005 +0000
    16.2 +++ b/xen/include/asm-x86/x86_64/page.h	Fri Feb 11 18:04:56 2005 +0000
    16.3 @@ -55,10 +55,10 @@ typedef l4_pgentry_t root_pgentry_t;
    16.4  #define root_pgentry_to_phys(_x) (l4_pgentry_to_phys(_x))
    16.5  
    16.6  /* Turn a typed table entry into a page index. */
    16.7 -#define l1_pgentry_to_pfn(_x)   (l1_pgentry_val(_x) >> PAGE_SHIFT) 
    16.8 -#define l2_pgentry_to_pfn(_x)   (l2_pgentry_val(_x) >> PAGE_SHIFT)
    16.9 -#define l3_pgentry_to_pfn(_x)   (l3_pgentry_val(_x) >> PAGE_SHIFT)
   16.10 -#define l4_pgentry_to_pfn(_x)   (l4_pgentry_val(_x) >> PAGE_SHIFT)
   16.11 +#define l1_pgentry_to_pfn(_x)   (l1_pgentry_to_phys(_x) >> PAGE_SHIFT) 
   16.12 +#define l2_pgentry_to_pfn(_x)   (l2_pgentry_to_phys(_x) >> PAGE_SHIFT)
   16.13 +#define l3_pgentry_to_pfn(_x)   (l3_pgentry_to_phys(_x) >> PAGE_SHIFT)
   16.14 +#define l4_pgentry_to_pfn(_x)   (l4_pgentry_to_phys(_x) >> PAGE_SHIFT)
   16.15  #define root_pgentry_to_pfn(_x) (l4_pgentry_to_pfn(_x))
   16.16  
   16.17  /* Pagetable walking. */