debuggers.hg
changeset 3314:12cf2ba64202
bitkeeper revision 1.1159.187.66 (41bf1718JfLUlcF63YjP4sfqtgAPWA)
Some more x86/64 progress...
Some more x86/64 progress...
line diff
1.1 --- a/.rootkeys Tue Dec 14 14:45:51 2004 +0000 1.2 +++ b/.rootkeys Tue Dec 14 16:38:48 2004 +0000 1.3 @@ -693,7 +693,9 @@ 3ddb79bcHwuCQDjBICDTSis52hWguw xen/arch/ 1.4 40f92331jfOlE7MfKwpdkEb1CEf23g xen/arch/x86/x86_32/seg_fixup.c 1.5 3ddb79bc4nTpGQOe6_-MbyZzkhlhFQ xen/arch/x86/x86_32/usercopy.c 1.6 3ddb79bcOMCu9-5mKpjIh5d0qqBDPg xen/arch/x86/x86_32/xen.lds 1.7 +41bf1717Ty3hwN3E9swdu8QfnvGqww xen/arch/x86/x86_64/asm-offsets.c 1.8 40e96d3aLDI-nViMuYneD7VKYlZrVg xen/arch/x86/x86_64/entry.S 1.9 +41bf1717XhPz_dNT5OKSjgmbFuWBuA xen/arch/x86/x86_64/mm.c 1.10 40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/x86/x86_64/usercopy.c 1.11 40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds 1.12 3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile 1.13 @@ -781,6 +783,7 @@ 40715b2d1yZkqyAt0kgx2xEwsatuuA xen/inclu 1.14 40715b2dWe0tDhx9LkLXzTQkvD49RA xen/include/asm-x86/acpi.h 1.15 3ddb79c3l4IiQtf6MS2jIzcd-hJS8g xen/include/asm-x86/apic.h 1.16 3ddb79c3QJYWr8LLGdonLbWmNb9pQQ xen/include/asm-x86/apicdef.h 1.17 +41bf17171g_hhz2k4B-fN9LQlODDjQ xen/include/asm-x86/asm_defns.h 1.18 3ddb79c3OiG9eTsi9Dy3F_OkuRAzKA xen/include/asm-x86/atomic.h 1.19 3ddb79c3rM-Ote0Xn6Ytg8Y6YqAG-A xen/include/asm-x86/bitops.h 1.20 3ddb79c3KhTI0F_Iw_hRL9QEyOVK-g xen/include/asm-x86/cache.h 1.21 @@ -827,6 +830,7 @@ 3ddb79c2ADvRmdexd9y3AYK9_NTx-Q xen/inclu 1.22 3ddb79c3mbqEM7QQr3zVq7NiBNhouA xen/include/asm-x86/x86_32/regs.h 1.23 3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/x86_32/string.h 1.24 3ddb79c3M2n1ROZH6xk3HbyN4CPDqg xen/include/asm-x86/x86_32/uaccess.h 1.25 +41bf1717bML6GxpclTWJabiaO5W5vg xen/include/asm-x86/x86_64/asm_defns.h 1.26 404f1b9ceJeGVaPNIENm2FkK0AgEOQ xen/include/asm-x86/x86_64/current.h 1.27 404f1b9fl6AQ_a-T1TDK3fuwTPXmHw xen/include/asm-x86/x86_64/desc.h 1.28 404f1badfXZJZ2sU8sh9PS2EZvd19Q xen/include/asm-x86/x86_64/ldt.h
2.1 --- a/xen/arch/x86/boot/x86_64.S Tue Dec 14 14:45:51 2004 +0000 2.2 +++ b/xen/arch/x86/boot/x86_64.S Tue Dec 14 16:38:48 2004 +0000 2.3 @@ -257,29 +257,22 @@ copy_to_user: 2.4 set_intr_gate: 2.5 die: 2.6 machine_to_phys_mapping: 2.7 -.globl copy_from_user, show_registers, __set_fixmap, do_iopl, check_descriptor 2.8 +.globl copy_from_user, show_registers, do_iopl 2.9 copy_from_user: 2.10 show_registers: 2.11 -__set_fixmap: 2.12 do_iopl: 2.13 -check_descriptor: 2.14 -.globl set_gdt, idt_table, copy_user_generic, memcmp, idt_tables, new_thread 2.15 -set_gdt: 2.16 +.globl idt_table, copy_user_generic, memcmp, idt_tables, new_thread 2.17 idt_table: 2.18 copy_user_generic: 2.19 memcmp: 2.20 idt_tables: 2.21 new_thread: 2.22 -.globl switch_to, __get_user_1, paging_init, trap_init 2.23 +.globl switch_to, __get_user_1, __get_user_4, __get_user_8, trap_init 2.24 switch_to: 2.25 __get_user_1: 2.26 -paging_init: 2.27 -trap_init: 2.28 -.globl __get_user_8, zap_low_mappings, set_debugreg,synchronise_pagetables 2.29 +__get_user_4: 2.30 __get_user_8: 2.31 -zap_low_mappings: 2.32 +trap_init: 2.33 +.globl set_debugreg 2.34 set_debugreg: 2.35 -synchronise_pagetables: 2.36 -.globl destroy_gdt 2.37 -destroy_gdt: 2.38
3.1 --- a/xen/arch/x86/domain.c Tue Dec 14 14:45:51 2004 +0000 3.2 +++ b/xen/arch/x86/domain.c Tue Dec 14 16:38:48 2004 +0000 3.3 @@ -427,6 +427,8 @@ long do_iopl(domid_t domain, unsigned in 3.4 return 0; 3.5 } 3.6 3.7 +#endif 3.8 + 3.9 unsigned long hypercall_create_continuation( 3.10 unsigned int op, unsigned int nr_args, ...) 3.11 { 3.12 @@ -448,11 +450,15 @@ unsigned long hypercall_create_continuat 3.13 else 3.14 { 3.15 ec = get_execution_context(); 3.16 +#if defined(__i386__) 3.17 ec->eax = op; 3.18 ec->eip -= 2; /* re-execute 'int 0x82' */ 3.19 3.20 for ( i = 0, preg = &ec->ebx; i < nr_args; i++, preg++ ) 3.21 *preg = va_arg(args, unsigned long); 3.22 +#else 3.23 + preg = NULL; /* XXX x86/64 */ 3.24 +#endif 3.25 } 3.26 3.27 va_end(args); 3.28 @@ -460,9 +466,6 @@ unsigned long hypercall_create_continuat 3.29 return op; 3.30 } 3.31 3.32 -#endif 3.33 - 3.34 - 3.35 static void relinquish_list(struct domain *d, struct list_head *list) 3.36 { 3.37 struct list_head *ent;
4.1 --- a/xen/arch/x86/traps.c Tue Dec 14 14:45:51 2004 +0000 4.2 +++ b/xen/arch/x86/traps.c Tue Dec 14 16:38:48 2004 +0000 4.3 @@ -981,4 +981,10 @@ unsigned long do_get_debugreg(int reg) 4.4 return current->thread.debugreg[reg]; 4.5 } 4.6 4.7 +#else 4.8 + 4.9 +asmlinkage void fatal_trap(int trapnr, struct xen_regs *regs) 4.10 +{ 4.11 +} 4.12 + 4.13 #endif /* __i386__ */
5.1 --- a/xen/arch/x86/x86_32/entry.S Tue Dec 14 14:45:51 2004 +0000 5.2 +++ b/xen/arch/x86/x86_32/entry.S Tue Dec 14 16:38:48 2004 +0000 5.3 @@ -56,7 +56,7 @@ 5.4 #include <xen/config.h> 5.5 #include <xen/errno.h> 5.6 #include <xen/softirq.h> 5.7 -#include <asm/x86_32/asm_defns.h> 5.8 +#include <asm/asm_defns.h> 5.9 #include <public/xen.h> 5.10 5.11 #define GET_CURRENT(reg) \
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/xen/arch/x86/x86_64/asm-offsets.c Tue Dec 14 16:38:48 2004 +0000 6.3 @@ -0,0 +1,71 @@ 6.4 +/* 6.5 + * Generate definitions needed by assembly language modules. 6.6 + * This code generates raw asm output which is post-processed 6.7 + * to extract and format the required data. 6.8 + */ 6.9 + 6.10 +#include <xen/sched.h> 6.11 + 6.12 +#define DEFINE(_sym, _val) \ 6.13 + __asm__ __volatile__ ( "\n->" #_sym " %0 " #_val : : "i" (_val) ) 6.14 +#define BLANK() \ 6.15 + __asm__ __volatile__ ( "\n->" : : ) 6.16 +#define OFFSET(_sym, _str, _mem) \ 6.17 + DEFINE(_sym, offsetof(_str, _mem)); 6.18 + 6.19 +void __dummy__(void) 6.20 +{ 6.21 + OFFSET(XREGS_r15, struct xen_regs, r15); 6.22 + OFFSET(XREGS_r14, struct xen_regs, r14); 6.23 + OFFSET(XREGS_r13, struct xen_regs, r13); 6.24 + OFFSET(XREGS_r12, struct xen_regs, r12); 6.25 + OFFSET(XREGS_rbp, struct xen_regs, rbp); 6.26 + OFFSET(XREGS_rbx, struct xen_regs, rbx); 6.27 + OFFSET(XREGS_r11, struct xen_regs, r11); 6.28 + OFFSET(XREGS_r10, struct xen_regs, r10); 6.29 + OFFSET(XREGS_r9, struct xen_regs, r9); 6.30 + OFFSET(XREGS_r8, struct xen_regs, r8); 6.31 + OFFSET(XREGS_rax, struct xen_regs, rax); 6.32 + OFFSET(XREGS_rcx, struct xen_regs, rcx); 6.33 + OFFSET(XREGS_rdx, struct xen_regs, rdx); 6.34 + OFFSET(XREGS_rsi, struct xen_regs, rsi); 6.35 + OFFSET(XREGS_rdi, struct xen_regs, rdi); 6.36 + OFFSET(XREGS_orig_rax, struct xen_regs, orig_rax); 6.37 + OFFSET(XREGS_rip, struct xen_regs, rip); 6.38 + OFFSET(XREGS_cs, struct xen_regs, cs); 6.39 + OFFSET(XREGS_eflags, struct xen_regs, eflags); 6.40 + OFFSET(XREGS_rsp, struct xen_regs, rsp); 6.41 + OFFSET(XREGS_ss, struct xen_regs, ss); 6.42 + BLANK(); 6.43 + 6.44 + OFFSET(DOMAIN_processor, struct domain, processor); 6.45 + OFFSET(DOMAIN_shared_info, struct domain, shared_info); 6.46 + OFFSET(DOMAIN_event_sel, struct domain, thread.event_selector); 6.47 + OFFSET(DOMAIN_event_addr, struct domain, thread.event_address); 6.48 + OFFSET(DOMAIN_failsafe_sel, struct domain, thread.failsafe_selector); 6.49 + OFFSET(DOMAIN_failsafe_addr, struct domain, thread.failsafe_address); 6.50 + OFFSET(DOMAIN_trap_bounce, struct domain, thread.trap_bounce); 6.51 + OFFSET(DOMAIN_thread_flags, struct domain, thread.flags); 6.52 + BLANK(); 6.53 + 6.54 + OFFSET(SHINFO_upcall_pending, shared_info_t, 6.55 + vcpu_data[0].evtchn_upcall_pending); 6.56 + OFFSET(SHINFO_upcall_mask, shared_info_t, 6.57 + vcpu_data[0].evtchn_upcall_mask); 6.58 + BLANK(); 6.59 + 6.60 + OFFSET(TRAPBOUNCE_error_code, struct trap_bounce, error_code); 6.61 + OFFSET(TRAPBOUNCE_cr2, struct trap_bounce, cr2); 6.62 + OFFSET(TRAPBOUNCE_flags, struct trap_bounce, flags); 6.63 + OFFSET(TRAPBOUNCE_cs, struct trap_bounce, cs); 6.64 + OFFSET(TRAPBOUNCE_eip, struct trap_bounce, eip); 6.65 + BLANK(); 6.66 + 6.67 + OFFSET(MULTICALL_op, multicall_entry_t, op); 6.68 + OFFSET(MULTICALL_arg0, multicall_entry_t, args[0]); 6.69 + OFFSET(MULTICALL_arg1, multicall_entry_t, args[1]); 6.70 + OFFSET(MULTICALL_arg2, multicall_entry_t, args[2]); 6.71 + OFFSET(MULTICALL_arg3, multicall_entry_t, args[3]); 6.72 + OFFSET(MULTICALL_arg4, multicall_entry_t, args[4]); 6.73 + OFFSET(MULTICALL_result, multicall_entry_t, args[5]); 6.74 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/xen/arch/x86/x86_64/mm.c Tue Dec 14 16:38:48 2004 +0000 7.3 @@ -0,0 +1,455 @@ 7.4 +/****************************************************************************** 7.5 + * arch/x86/x86_64/mm.c 7.6 + * 7.7 + * Modifications to Linux original are copyright (c) 2004, K A Fraser 7.8 + * 7.9 + * This program is free software; you can redistribute it and/or modify 7.10 + * it under the terms of the GNU General Public License as published by 7.11 + * the Free Software Foundation; either version 2 of the License, or 7.12 + * (at your option) any later version. 7.13 + * 7.14 + * This program is distributed in the hope that it will be useful, 7.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 7.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 7.17 + * GNU General Public License for more details. 7.18 + * 7.19 + * You should have received a copy of the GNU General Public License 7.20 + * along with this program; if not, write to the Free Software 7.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 7.22 + */ 7.23 + 7.24 +#include <xen/config.h> 7.25 +#include <xen/lib.h> 7.26 +#include <xen/init.h> 7.27 +#include <xen/mm.h> 7.28 +#include <asm/page.h> 7.29 +#include <asm/flushtlb.h> 7.30 +#include <asm/fixmap.h> 7.31 +#include <asm/domain_page.h> 7.32 + 7.33 +static inline void set_pte_phys(unsigned long vaddr, 7.34 + l1_pgentry_t entry) 7.35 +{ 7.36 + l4_pgentry_t *l4ent; 7.37 + l3_pgentry_t *l3ent; 7.38 + l2_pgentry_t *l2ent; 7.39 + l1_pgentry_t *l1ent; 7.40 + 7.41 + l4ent = &idle_pg_table[l4_table_offset(vaddr)]; 7.42 + l3ent = l4_pgentry_to_l3(*l4ent) + l3_table_offset(vaddr); 7.43 + l2ent = l3_pgentry_to_l2(*l3ent) + l2_table_offset(vaddr); 7.44 + l1ent = l2_pgentry_to_l1(*l2ent) + l1_table_offset(vaddr); 7.45 + *l1ent = entry; 7.46 + 7.47 + /* It's enough to flush this one mapping. */ 7.48 + __flush_tlb_one(vaddr); 7.49 +} 7.50 + 7.51 + 7.52 +void __set_fixmap(enum fixed_addresses idx, 7.53 + l1_pgentry_t entry) 7.54 +{ 7.55 + unsigned long address = fix_to_virt(idx); 7.56 + 7.57 + if ( likely(idx < __end_of_fixed_addresses) ) 7.58 + set_pte_phys(address, entry); 7.59 + else 7.60 + printk("Invalid __set_fixmap\n"); 7.61 +} 7.62 + 7.63 + 7.64 +void __init paging_init(void) 7.65 +{ 7.66 + void *ioremap_pt; 7.67 + int i; 7.68 + 7.69 + /* Create page table for ioremap(). */ 7.70 + ioremap_pt = (void *)alloc_xenheap_page(); 7.71 + clear_page(ioremap_pt); 7.72 + idle_pg_table[IOREMAP_VIRT_START >> L2_PAGETABLE_SHIFT] = 7.73 + mk_l2_pgentry(__pa(ioremap_pt) | __PAGE_HYPERVISOR); 7.74 + 7.75 + /* Create read-only mapping of MPT for guest-OS use. */ 7.76 + idle_pg_table[RO_MPT_VIRT_START >> L2_PAGETABLE_SHIFT] = 7.77 + mk_l2_pgentry(l2_pgentry_val( 7.78 + idle_pg_table[RDWR_MPT_VIRT_START >> L2_PAGETABLE_SHIFT]) & 7.79 + ~_PAGE_RW); 7.80 + 7.81 + /* Set up mapping cache for domain pages. */ 7.82 + mapcache = (unsigned long *)alloc_xenheap_page(); 7.83 + clear_page(mapcache); 7.84 + idle_pg_table[MAPCACHE_VIRT_START >> L2_PAGETABLE_SHIFT] = 7.85 + mk_l2_pgentry(__pa(mapcache) | __PAGE_HYPERVISOR); 7.86 + 7.87 + /* Set up linear page table mapping. */ 7.88 + idle_pg_table[LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT] = 7.89 + mk_l2_pgentry(__pa(idle_pg_table) | __PAGE_HYPERVISOR); 7.90 + 7.91 +} 7.92 + 7.93 +void __init zap_low_mappings(void) 7.94 +{ 7.95 + idle_pg_table[0] = 0; 7.96 +} 7.97 + 7.98 + 7.99 +/* 7.100 + * Allows shooting down of borrowed page-table use on specific CPUs. 7.101 + * Specifically, we borrow page tables when running the idle domain. 7.102 + */ 7.103 +static void __synchronise_pagetables(void *mask) 7.104 +{ 7.105 + struct domain *d = current; 7.106 + if ( ((unsigned long)mask & (1<<d->processor)) && is_idle_task(d) ) 7.107 + write_ptbase(&d->mm); 7.108 +} 7.109 +void synchronise_pagetables(unsigned long cpu_mask) 7.110 +{ 7.111 + __synchronise_pagetables((void *)cpu_mask); 7.112 + smp_call_function(__synchronise_pagetables, (void *)cpu_mask, 1, 1); 7.113 +} 7.114 + 7.115 +long do_stack_switch(unsigned long ss, unsigned long esp) 7.116 +{ 7.117 + int nr = smp_processor_id(); 7.118 + struct tss_struct *t = &init_tss[nr]; 7.119 + 7.120 + /* We need to do this check as we load and use SS on guest's behalf. */ 7.121 + if ( (ss & 3) == 0 ) 7.122 + return -EPERM; 7.123 + 7.124 + current->thread.guestos_ss = ss; 7.125 + current->thread.guestos_sp = esp; 7.126 + t->ss1 = ss; 7.127 + t->esp1 = esp; 7.128 + 7.129 + return 0; 7.130 +} 7.131 + 7.132 + 7.133 +/* Returns TRUE if given descriptor is valid for GDT or LDT. */ 7.134 +int check_descriptor(unsigned long *d) 7.135 +{ 7.136 + unsigned long base, limit, a = d[0], b = d[1]; 7.137 + 7.138 + /* A not-present descriptor will always fault, so is safe. */ 7.139 + if ( !(b & _SEGMENT_P) ) 7.140 + goto good; 7.141 + 7.142 + /* 7.143 + * We don't allow a DPL of zero. There is no legitimate reason for 7.144 + * specifying DPL==0, and it gets rather dangerous if we also accept call 7.145 + * gates (consider a call gate pointing at another guestos descriptor with 7.146 + * DPL 0 -- this would get the OS ring-0 privileges). 7.147 + */ 7.148 + if ( (b & _SEGMENT_DPL) == 0 ) 7.149 + goto bad; 7.150 + 7.151 + if ( !(b & _SEGMENT_S) ) 7.152 + { 7.153 + /* 7.154 + * System segment: 7.155 + * 1. Don't allow interrupt or trap gates as they belong in the IDT. 7.156 + * 2. Don't allow TSS descriptors or task gates as we don't 7.157 + * virtualise x86 tasks. 7.158 + * 3. Don't allow LDT descriptors because they're unnecessary and 7.159 + * I'm uneasy about allowing an LDT page to contain LDT 7.160 + * descriptors. In any case, Xen automatically creates the 7.161 + * required descriptor when reloading the LDT register. 7.162 + * 4. We allow call gates but they must not jump to a private segment. 7.163 + */ 7.164 + 7.165 + /* Disallow everything but call gates. */ 7.166 + if ( (b & _SEGMENT_TYPE) != 0xc00 ) 7.167 + goto bad; 7.168 + 7.169 + /* Can't allow far jump to a Xen-private segment. */ 7.170 + if ( !VALID_CODESEL(a>>16) ) 7.171 + goto bad; 7.172 + 7.173 + /* Reserved bits must be zero. */ 7.174 + if ( (b & 0xe0) != 0 ) 7.175 + goto bad; 7.176 + 7.177 + /* No base/limit check is needed for a call gate. */ 7.178 + goto good; 7.179 + } 7.180 + 7.181 + /* Check that base is at least a page away from Xen-private area. */ 7.182 + base = (b&(0xff<<24)) | ((b&0xff)<<16) | (a>>16); 7.183 + if ( base >= (PAGE_OFFSET - PAGE_SIZE) ) 7.184 + goto bad; 7.185 + 7.186 + /* Check and truncate the limit if necessary. */ 7.187 + limit = (b&0xf0000) | (a&0xffff); 7.188 + limit++; /* We add one because limit is inclusive. */ 7.189 + if ( (b & _SEGMENT_G) ) 7.190 + limit <<= 12; 7.191 + 7.192 + if ( (b & (_SEGMENT_CODE | _SEGMENT_EC)) == _SEGMENT_EC ) 7.193 + { 7.194 + /* 7.195 + * Grows-down limit check. 7.196 + * NB. limit == 0xFFFFF provides no access (if G=1). 7.197 + * limit == 0x00000 provides 4GB-4kB access (if G=1). 7.198 + */ 7.199 + if ( (base + limit) > base ) 7.200 + { 7.201 + limit = -(base & PAGE_MASK); 7.202 + goto truncate; 7.203 + } 7.204 + } 7.205 + else 7.206 + { 7.207 + /* 7.208 + * Grows-up limit check. 7.209 + * NB. limit == 0xFFFFF provides 4GB access (if G=1). 7.210 + * limit == 0x00000 provides 4kB access (if G=1). 7.211 + */ 7.212 + if ( ((base + limit) <= base) || 7.213 + ((base + limit) > PAGE_OFFSET) ) 7.214 + { 7.215 + limit = PAGE_OFFSET - base; 7.216 + truncate: 7.217 + if ( !(b & _SEGMENT_G) ) 7.218 + goto bad; /* too dangerous; too hard to work out... */ 7.219 + limit = (limit >> 12) - 1; 7.220 + d[0] &= ~0x0ffff; d[0] |= limit & 0x0ffff; 7.221 + d[1] &= ~0xf0000; d[1] |= limit & 0xf0000; 7.222 + } 7.223 + } 7.224 + 7.225 + good: 7.226 + return 1; 7.227 + bad: 7.228 + return 0; 7.229 +} 7.230 + 7.231 + 7.232 +void destroy_gdt(struct domain *d) 7.233 +{ 7.234 + int i; 7.235 + unsigned long pfn; 7.236 + 7.237 + for ( i = 0; i < 16; i++ ) 7.238 + { 7.239 + if ( (pfn = l1_pgentry_to_pagenr(d->mm.perdomain_pt[i])) != 0 ) 7.240 + put_page_and_type(&frame_table[pfn]); 7.241 + d->mm.perdomain_pt[i] = mk_l1_pgentry(0); 7.242 + } 7.243 +} 7.244 + 7.245 + 7.246 +long set_gdt(struct domain *d, 7.247 + unsigned long *frames, 7.248 + unsigned int entries) 7.249 +{ 7.250 + /* NB. There are 512 8-byte entries per GDT page. */ 7.251 + int i = 0, nr_pages = (entries + 511) / 512; 7.252 + struct desc_struct *vgdt; 7.253 + unsigned long pfn; 7.254 + 7.255 + /* Check the first page in the new GDT. */ 7.256 + if ( (pfn = frames[0]) >= max_page ) 7.257 + goto fail; 7.258 + 7.259 + /* The first page is special because Xen owns a range of entries in it. */ 7.260 + if ( !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) ) 7.261 + { 7.262 + /* GDT checks failed: try zapping the Xen reserved entries. */ 7.263 + if ( !get_page_and_type(&frame_table[pfn], d, PGT_writable_page) ) 7.264 + goto fail; 7.265 + vgdt = map_domain_mem(pfn << PAGE_SHIFT); 7.266 + memset(vgdt + FIRST_RESERVED_GDT_ENTRY, 0, 7.267 + NR_RESERVED_GDT_ENTRIES*8); 7.268 + unmap_domain_mem(vgdt); 7.269 + put_page_and_type(&frame_table[pfn]); 7.270 + 7.271 + /* Okay, we zapped the entries. Now try the GDT checks again. */ 7.272 + if ( !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) ) 7.273 + goto fail; 7.274 + } 7.275 + 7.276 + /* Check the remaining pages in the new GDT. */ 7.277 + for ( i = 1; i < nr_pages; i++ ) 7.278 + if ( ((pfn = frames[i]) >= max_page) || 7.279 + !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) ) 7.280 + goto fail; 7.281 + 7.282 + /* Copy reserved GDT entries to the new GDT. */ 7.283 + vgdt = map_domain_mem(frames[0] << PAGE_SHIFT); 7.284 + memcpy(vgdt + FIRST_RESERVED_GDT_ENTRY, 7.285 + gdt_table + FIRST_RESERVED_GDT_ENTRY, 7.286 + NR_RESERVED_GDT_ENTRIES*8); 7.287 + unmap_domain_mem(vgdt); 7.288 + 7.289 + /* Tear down the old GDT. */ 7.290 + destroy_gdt(d); 7.291 + 7.292 + /* Install the new GDT. */ 7.293 + for ( i = 0; i < nr_pages; i++ ) 7.294 + d->mm.perdomain_pt[i] = 7.295 + mk_l1_pgentry((frames[i] << PAGE_SHIFT) | __PAGE_HYPERVISOR); 7.296 + 7.297 + SET_GDT_ADDRESS(d, GDT_VIRT_START); 7.298 + SET_GDT_ENTRIES(d, entries); 7.299 + 7.300 + return 0; 7.301 + 7.302 + fail: 7.303 + while ( i-- > 0 ) 7.304 + put_page_and_type(&frame_table[frames[i]]); 7.305 + return -EINVAL; 7.306 +} 7.307 + 7.308 + 7.309 +long do_set_gdt(unsigned long *frame_list, unsigned int entries) 7.310 +{ 7.311 + int nr_pages = (entries + 511) / 512; 7.312 + unsigned long frames[16]; 7.313 + long ret; 7.314 + 7.315 + if ( (entries <= LAST_RESERVED_GDT_ENTRY) || (entries > 8192) ) 7.316 + return -EINVAL; 7.317 + 7.318 + if ( copy_from_user(frames, frame_list, nr_pages * sizeof(unsigned long)) ) 7.319 + return -EFAULT; 7.320 + 7.321 + if ( (ret = set_gdt(current, frames, entries)) == 0 ) 7.322 + { 7.323 + local_flush_tlb(); 7.324 + __asm__ __volatile__ ("lgdt %0" : "=m" (*current->mm.gdt)); 7.325 + } 7.326 + 7.327 + return ret; 7.328 +} 7.329 + 7.330 + 7.331 +long do_update_descriptor( 7.332 + unsigned long pa, unsigned long word1, unsigned long word2) 7.333 +{ 7.334 + unsigned long *gdt_pent, pfn = pa >> PAGE_SHIFT, d[2]; 7.335 + struct pfn_info *page; 7.336 + long ret = -EINVAL; 7.337 + 7.338 + d[0] = word1; 7.339 + d[1] = word2; 7.340 + 7.341 + if ( (pa & 7) || (pfn >= max_page) || !check_descriptor(d) ) 7.342 + return -EINVAL; 7.343 + 7.344 + page = &frame_table[pfn]; 7.345 + if ( unlikely(!get_page(page, current)) ) 7.346 + return -EINVAL; 7.347 + 7.348 + /* Check if the given frame is in use in an unsafe context. */ 7.349 + switch ( page->u.inuse.type_info & PGT_type_mask ) 7.350 + { 7.351 + case PGT_gdt_page: 7.352 + /* Disallow updates of Xen-reserved descriptors in the current GDT. */ 7.353 + if ( (l1_pgentry_to_pagenr(current->mm.perdomain_pt[0]) == pfn) && 7.354 + (((pa&(PAGE_SIZE-1))>>3) >= FIRST_RESERVED_GDT_ENTRY) && 7.355 + (((pa&(PAGE_SIZE-1))>>3) <= LAST_RESERVED_GDT_ENTRY) ) 7.356 + goto out; 7.357 + if ( unlikely(!get_page_type(page, PGT_gdt_page)) ) 7.358 + goto out; 7.359 + break; 7.360 + case PGT_ldt_page: 7.361 + if ( unlikely(!get_page_type(page, PGT_ldt_page)) ) 7.362 + goto out; 7.363 + break; 7.364 + default: 7.365 + if ( unlikely(!get_page_type(page, PGT_writable_page)) ) 7.366 + goto out; 7.367 + break; 7.368 + } 7.369 + 7.370 + /* All is good so make the update. */ 7.371 + gdt_pent = map_domain_mem(pa); 7.372 + memcpy(gdt_pent, d, 8); 7.373 + unmap_domain_mem(gdt_pent); 7.374 + 7.375 + put_page_type(page); 7.376 + 7.377 + ret = 0; /* success */ 7.378 + 7.379 + out: 7.380 + put_page(page); 7.381 + return ret; 7.382 +} 7.383 + 7.384 +#ifdef MEMORY_GUARD 7.385 + 7.386 +void *memguard_init(void *heap_start) 7.387 +{ 7.388 + l1_pgentry_t *l1; 7.389 + int i, j; 7.390 + 7.391 + /* Round the allocation pointer up to a page boundary. */ 7.392 + heap_start = (void *)(((unsigned long)heap_start + (PAGE_SIZE-1)) & 7.393 + PAGE_MASK); 7.394 + 7.395 + /* Memory guarding is incompatible with super pages. */ 7.396 + for ( i = 0; i < (xenheap_phys_end >> L2_PAGETABLE_SHIFT); i++ ) 7.397 + { 7.398 + l1 = (l1_pgentry_t *)heap_start; 7.399 + heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE); 7.400 + for ( j = 0; j < ENTRIES_PER_L1_PAGETABLE; j++ ) 7.401 + l1[j] = mk_l1_pgentry((i << L2_PAGETABLE_SHIFT) | 7.402 + (j << L1_PAGETABLE_SHIFT) | 7.403 + __PAGE_HYPERVISOR); 7.404 + idle_pg_table[i] = idle_pg_table[i + l2_table_offset(PAGE_OFFSET)] = 7.405 + mk_l2_pgentry(virt_to_phys(l1) | __PAGE_HYPERVISOR); 7.406 + } 7.407 + 7.408 + return heap_start; 7.409 +} 7.410 + 7.411 +static void __memguard_change_range(void *p, unsigned long l, int guard) 7.412 +{ 7.413 + l1_pgentry_t *l1; 7.414 + l2_pgentry_t *l2; 7.415 + unsigned long _p = (unsigned long)p; 7.416 + unsigned long _l = (unsigned long)l; 7.417 + 7.418 + /* Ensure we are dealing with a page-aligned whole number of pages. */ 7.419 + ASSERT((_p&PAGE_MASK) != 0); 7.420 + ASSERT((_l&PAGE_MASK) != 0); 7.421 + ASSERT((_p&~PAGE_MASK) == 0); 7.422 + ASSERT((_l&~PAGE_MASK) == 0); 7.423 + 7.424 + while ( _l != 0 ) 7.425 + { 7.426 + l2 = &idle_pg_table[l2_table_offset(_p)]; 7.427 + l1 = l2_pgentry_to_l1(*l2) + l1_table_offset(_p); 7.428 + if ( guard ) 7.429 + *l1 = mk_l1_pgentry(l1_pgentry_val(*l1) & ~_PAGE_PRESENT); 7.430 + else 7.431 + *l1 = mk_l1_pgentry(l1_pgentry_val(*l1) | _PAGE_PRESENT); 7.432 + _p += PAGE_SIZE; 7.433 + _l -= PAGE_SIZE; 7.434 + } 7.435 +} 7.436 + 7.437 +void memguard_guard_range(void *p, unsigned long l) 7.438 +{ 7.439 + __memguard_change_range(p, l, 1); 7.440 + local_flush_tlb(); 7.441 +} 7.442 + 7.443 +void memguard_unguard_range(void *p, unsigned long l) 7.444 +{ 7.445 + __memguard_change_range(p, l, 0); 7.446 +} 7.447 + 7.448 +int memguard_is_guarded(void *p) 7.449 +{ 7.450 + l1_pgentry_t *l1; 7.451 + l2_pgentry_t *l2; 7.452 + unsigned long _p = (unsigned long)p; 7.453 + l2 = &idle_pg_table[l2_table_offset(_p)]; 7.454 + l1 = l2_pgentry_to_l1(*l2) + l1_table_offset(_p); 7.455 + return !(l1_pgentry_val(*l1) & _PAGE_PRESENT); 7.456 +} 7.457 + 7.458 +#endif
8.1 --- a/xen/arch/x86/x86_64/xen.lds Tue Dec 14 14:45:51 2004 +0000 8.2 +++ b/xen/arch/x86/x86_64/xen.lds Tue Dec 14 16:38:48 2004 +0000 8.3 @@ -28,6 +28,11 @@ SECTIONS 8.4 __ex_table : { *(__ex_table) } :text 8.5 __stop___ex_table = .; 8.6 8.7 + . = ALIGN(16); /* Pre-exception table */ 8.8 + __start___pre_ex_table = .; 8.9 + __pre_ex_table : { *(__pre_ex_table) } :text 8.10 + __stop___pre_ex_table = .; 8.11 + 8.12 __start___ksymtab = .; /* Kernel symbol table */ 8.13 __ksymtab : { *(__ksymtab) } :text 8.14 __stop___ksymtab = .;
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/xen/include/asm-x86/asm_defns.h Tue Dec 14 16:38:48 2004 +0000 9.3 @@ -0,0 +1,18 @@ 9.4 + 9.5 +#ifndef __X86_ASM_DEFNS_H__ 9.6 +#define __X86_ASM_DEFNS_H__ 9.7 + 9.8 +/* NB. Auto-generated from arch/.../asm-offsets.c */ 9.9 +#include <asm/asm-offsets.h> 9.10 +#include <asm/processor.h> 9.11 + 9.12 +#define __STR(x) #x 9.13 +#define STR(x) __STR(x) 9.14 + 9.15 +#ifdef __x86_64__ 9.16 +#include <asm/x86_64/asm_defns.h> 9.17 +#else 9.18 +#include <asm/x86_32/asm_defns.h> 9.19 +#endif 9.20 + 9.21 +#endif /* __X86_ASM_DEFNS_H__ */
10.1 --- a/xen/include/asm-x86/irq.h Tue Dec 14 14:45:51 2004 +0000 10.2 +++ b/xen/include/asm-x86/irq.h Tue Dec 14 16:38:48 2004 +0000 10.3 @@ -5,7 +5,7 @@ 10.4 10.5 #include <xen/config.h> 10.6 #include <asm/atomic.h> 10.7 -#include <asm/x86_32/asm_defns.h> 10.8 +#include <asm/asm_defns.h> 10.9 10.10 extern void disable_irq(unsigned int); 10.11 extern void disable_irq_nosync(unsigned int);
11.1 --- a/xen/include/asm-x86/multicall.h Tue Dec 14 14:45:51 2004 +0000 11.2 +++ b/xen/include/asm-x86/multicall.h Tue Dec 14 16:38:48 2004 +0000 11.3 @@ -5,7 +5,13 @@ 11.4 #ifndef __ASM_X86_MULTICALL_H__ 11.5 #define __ASM_X86_MULTICALL_H__ 11.6 11.7 -#include <asm-x86/x86_32/asm_defns.h> 11.8 +#include <asm/asm_defns.h> 11.9 + 11.10 +#ifdef __x86_64__ 11.11 + 11.12 +#define do_multicall_call(_call) BUG() 11.13 + 11.14 +#else 11.15 11.16 #define do_multicall_call(_call) \ 11.17 do { \ 11.18 @@ -23,4 +29,6 @@ 11.19 : : "b" (_call) : "eax", "ecx", "edx" ); \ 11.20 } while ( 0 ) 11.21 11.22 +#endif 11.23 + 11.24 #endif /* __ASM_X86_MULTICALL_H__ */
12.1 --- a/xen/include/asm-x86/processor.h Tue Dec 14 14:45:51 2004 +0000 12.2 +++ b/xen/include/asm-x86/processor.h Tue Dec 14 16:38:48 2004 +0000 12.3 @@ -254,18 +254,18 @@ static inline unsigned int cpuid_edx(uns 12.4 }) 12.5 12.6 #define write_cr0(x) \ 12.7 - __asm__("mov"__OS" %0,%%cr0": :"r" (x)); 12.8 + __asm__("mov"__OS" %0,%%cr0": :"r" ((unsigned long)x)); 12.9 12.10 #define read_cr4() ({ \ 12.11 - unsigned int __dummy; \ 12.12 + unsigned long __dummy; \ 12.13 __asm__( \ 12.14 - "movl %%cr4,%0\n\t" \ 12.15 + "mov"__OS" %%cr4,%0\n\t" \ 12.16 :"=r" (__dummy)); \ 12.17 __dummy; \ 12.18 }) 12.19 12.20 #define write_cr4(x) \ 12.21 - __asm__("movl %0,%%cr4": :"r" (x)); 12.22 + __asm__("mov"__OS" %0,%%cr4": :"r" ((unsigned long)x)); 12.23 12.24 /* 12.25 * Save the cr4 feature set we're using (ie 12.26 @@ -290,7 +290,7 @@ static inline void clear_in_cr4 (unsigne 12.27 mmu_cr4_features &= ~mask; 12.28 __asm__("mov"__OS" %%cr4,%%"__OP"ax\n\t" 12.29 "and"__OS" %0,%%"__OP"ax\n\t" 12.30 - "movl"__OS" %%"__OP"ax,%%cr4\n" 12.31 + "mov"__OS" %%"__OP"ax,%%cr4\n" 12.32 : : "irg" (~mask) 12.33 :"ax"); 12.34 }
13.1 --- a/xen/include/asm-x86/uaccess.h Tue Dec 14 14:45:51 2004 +0000 13.2 +++ b/xen/include/asm-x86/uaccess.h Tue Dec 14 16:38:48 2004 +0000 13.3 @@ -1,6 +1,32 @@ 13.4 + 13.5 +#ifndef __X86_UACCESS_H__ 13.6 +#define __X86_UACCESS_H__ 13.7 13.8 #ifdef __x86_64__ 13.9 #include <asm/x86_64/uaccess.h> 13.10 #else 13.11 #include <asm/x86_32/uaccess.h> 13.12 #endif 13.13 + 13.14 +/* 13.15 + * The exception table consists of pairs of addresses: the first is the 13.16 + * address of an instruction that is allowed to fault, and the second is 13.17 + * the address at which the program should continue. No registers are 13.18 + * modified, so it is entirely up to the continuation code to figure out 13.19 + * what to do. 13.20 + * 13.21 + * All the routines below use bits of fixup code that are out of line 13.22 + * with the main instruction path. This means when everything is well, 13.23 + * we don't even have to jump over them. Further, they do not intrude 13.24 + * on our cache or tlb entries. 13.25 + */ 13.26 + 13.27 +struct exception_table_entry 13.28 +{ 13.29 + unsigned long insn, fixup; 13.30 +}; 13.31 + 13.32 +extern unsigned long search_exception_table(unsigned long); 13.33 +extern void sort_exception_tables(void); 13.34 + 13.35 +#endif /* __X86_UACCESS_H__ */
14.1 --- a/xen/include/asm-x86/x86_32/asm_defns.h Tue Dec 14 14:45:51 2004 +0000 14.2 +++ b/xen/include/asm-x86/x86_32/asm_defns.h Tue Dec 14 16:38:48 2004 +0000 14.3 @@ -1,12 +1,5 @@ 14.4 -#ifndef __ASM_DEFNS_H__ 14.5 -#define __ASM_DEFNS_H__ 14.6 - 14.7 -/* NB. Auto-generated from arch/.../asm-offsets.c */ 14.8 -#include <asm/asm-offsets.h> 14.9 -#include <asm/processor.h> 14.10 - 14.11 -#define __STR(x) #x 14.12 -#define STR(x) __STR(x) 14.13 +#ifndef __X86_32_ASM_DEFNS_H__ 14.14 +#define __X86_32_ASM_DEFNS_H__ 14.15 14.16 /* Maybe auto-generate the following two cases (quoted vs. unquoted). */ 14.17 #ifndef __ASSEMBLY__ 14.18 @@ -85,4 +78,4 @@ 14.19 14.20 #endif 14.21 14.22 -#endif /* __ASM_DEFNS_H__ */ 14.23 +#endif /* __X86_32_ASM_DEFNS_H__ */
15.1 --- a/xen/include/asm-x86/x86_32/uaccess.h Tue Dec 14 14:45:51 2004 +0000 15.2 +++ b/xen/include/asm-x86/x86_32/uaccess.h Tue Dec 14 16:38:48 2004 +0000 15.3 @@ -69,27 +69,6 @@ extern struct movsl_mask { 15.4 #define array_access_ok(type,addr,count,size) \ 15.5 (likely(count < (~0UL/size)) && access_ok(type,addr,count*size)) 15.6 15.7 -/* 15.8 - * The exception table consists of pairs of addresses: the first is the 15.9 - * address of an instruction that is allowed to fault, and the second is 15.10 - * the address at which the program should continue. No registers are 15.11 - * modified, so it is entirely up to the continuation code to figure out 15.12 - * what to do. 15.13 - * 15.14 - * All the routines below use bits of fixup code that are out of line 15.15 - * with the main instruction path. This means when everything is well, 15.16 - * we don't even have to jump over them. Further, they do not intrude 15.17 - * on our cache or tlb entries. 15.18 - */ 15.19 - 15.20 -struct exception_table_entry 15.21 -{ 15.22 - unsigned long insn, fixup; 15.23 -}; 15.24 - 15.25 -extern unsigned long search_exception_table(unsigned long); 15.26 -extern void sort_exception_tables(void); 15.27 - 15.28 /** 15.29 * get_user: - Get a simple variable from user space. 15.30 * @x: Variable to store result.
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/xen/include/asm-x86/x86_64/asm_defns.h Tue Dec 14 16:38:48 2004 +0000 16.3 @@ -0,0 +1,6 @@ 16.4 +#ifndef __X86_64_ASM_DEFNS_H__ 16.5 +#define __X86_64_ASM_DEFNS_H__ 16.6 + 16.7 +#define SAVE_ALL(_r) "" 16.8 + 16.9 +#endif /* __X86_64_ASM_DEFNS_H__ */
17.1 --- a/xen/include/asm-x86/x86_64/uaccess.h Tue Dec 14 14:45:51 2004 +0000 17.2 +++ b/xen/include/asm-x86/x86_64/uaccess.h Tue Dec 14 16:38:48 2004 +0000 17.3 @@ -35,31 +35,15 @@ 17.4 17.5 #define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0) 17.6 17.7 +#define array_access_ok(type,addr,count,size) \ 17.8 + (likely(sizeof(count) <= 4) /* disallow 64-bit counts */ && \ 17.9 + access_ok(type,addr,count*size)) 17.10 + 17.11 extern inline int verify_area(int type, const void __user * addr, unsigned long size) 17.12 { 17.13 return access_ok(type,addr,size) ? 0 : -EFAULT; 17.14 } 17.15 17.16 - 17.17 -/* 17.18 - * The exception table consists of pairs of addresses: the first is the 17.19 - * address of an instruction that is allowed to fault, and the second is 17.20 - * the address at which the program should continue. No registers are 17.21 - * modified, so it is entirely up to the continuation code to figure out 17.22 - * what to do. 17.23 - * 17.24 - * All the routines below use bits of fixup code that are out of line 17.25 - * with the main instruction path. This means when everything is well, 17.26 - * we don't even have to jump over them. Further, they do not intrude 17.27 - * on our cache or tlb entries. 17.28 - */ 17.29 - 17.30 -struct exception_table_entry 17.31 -{ 17.32 - unsigned long insn, fixup; 17.33 -}; 17.34 - 17.35 - 17.36 /* 17.37 * These are the main single-value transfer routines. They automatically 17.38 * use the right size if we just have the right pointer type.