direct-io.hg
changeset 2442:d9439135569e
bitkeeper revision 1.1159.1.126 (413cb0edcNgU8KKUhhZaxIAIerLhcA)
Merge freefall.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into freefall.cl.cam.ac.uk:/auto/groups/xeno/users/cl349/BK/xeno.bk-nbsd
Merge freefall.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into freefall.cl.cam.ac.uk:/auto/groups/xeno/users/cl349/BK/xeno.bk-nbsd
author | cl349@freefall.cl.cam.ac.uk |
---|---|
date | Mon Sep 06 18:48:13 2004 +0000 (2004-09-06) |
parents | 25e6d3dde54a 2bbaf6d19a35 |
children | 309c1fb27f87 |
files | xen/Rules.mk xen/arch/x86/memory.c xen/arch/x86/traps.c xen/common/keyhandler.c xen/common/page_alloc.c xen/include/xen/softirq.h |
line diff
1.1 --- a/xen/Rules.mk Mon Sep 06 15:53:59 2004 +0000 1.2 +++ b/xen/Rules.mk Mon Sep 06 18:48:13 2004 +0000 1.3 @@ -1,4 +1,5 @@ 1.4 1.5 +verbose ?= n 1.6 debug ?= n 1.7 debugger ?= n 1.8 perfc ?= n
2.1 --- a/xen/arch/x86/memory.c Mon Sep 06 15:53:59 2004 +0000 2.2 +++ b/xen/arch/x86/memory.c Mon Sep 06 18:48:13 2004 +0000 2.3 @@ -92,6 +92,7 @@ 2.4 #include <xen/errno.h> 2.5 #include <xen/perfc.h> 2.6 #include <xen/irq.h> 2.7 +#include <xen/softirq.h> 2.8 #include <asm/shadow.h> 2.9 #include <asm/page.h> 2.10 #include <asm/flushtlb.h> 2.11 @@ -782,6 +783,9 @@ int alloc_page_type(struct pfn_info *pag 2.12 case PGT_ldt_page: 2.13 return alloc_segdesc_page(page); 2.14 default: 2.15 + printk("Bad type in alloc_page_type %x t=%x c=%x\n", 2.16 + type, page->u.inuse.type_info, 2.17 + page->count_info); 2.18 BUG(); 2.19 } 2.20 2.21 @@ -1792,4 +1796,420 @@ void ptwr_status(void) 2.22 frame_table[pfn].u.inuse.type_info, 2.23 frame_table[pfn].u.inuse.domain->domain)); 2.24 } 2.25 + 2.26 + 2.27 +/************************************************************************/ 2.28 + 2.29 + 2.30 +void audit_domain( struct domain *d) 2.31 +{ 2.32 + int ttot=0, ctot=0; 2.33 + void adjust ( struct pfn_info *page, int dir, int adjtype ) 2.34 + { 2.35 + int count = page->count_info & PGC_count_mask; 2.36 + 2.37 + if (adjtype) 2.38 + { 2.39 + int tcount = page->u.inuse.type_info & PGT_count_mask; 2.40 + 2.41 + ttot++; 2.42 + 2.43 + tcount += dir; 2.44 + 2.45 + if (tcount <0 ) 2.46 + { 2.47 + printk("Audit %d: type count whent below zero pfn=%x taf=%x otaf=%x\n", 2.48 + d->domain, page-frame_table, 2.49 + page->u.inuse.type_info, 2.50 + page->tlbflush_timestamp); 2.51 + return; 2.52 + } 2.53 + 2.54 + page->u.inuse.type_info = 2.55 + (page->u.inuse.type_info & ~PGT_count_mask) | tcount; 2.56 + } 2.57 + 2.58 + ctot++; 2.59 + count += dir; 2.60 + if (count <0 ) 2.61 + { 2.62 + printk("Audit %d: general count whent below zero pfn=%x taf=%x otaf=%x\n", 2.63 + d->domain, page-frame_table, 2.64 + page->u.inuse.type_info, 2.65 + page->tlbflush_timestamp); 2.66 + return; 2.67 + } 2.68 + 2.69 + page->count_info = 2.70 + (page->count_info & ~PGC_count_mask) | count; 2.71 + 2.72 + } 2.73 + 2.74 + void scan_for_pfn( struct domain *d, unsigned long xpfn ) 2.75 + { 2.76 + unsigned long pfn; 2.77 + struct list_head *list_ent; 2.78 + int i; 2.79 + 2.80 + list_ent = d->page_list.next; 2.81 + for ( i = 0; (list_ent != &d->page_list); i++ ) 2.82 + { 2.83 + unsigned long * pt; 2.84 + struct pfn_info *page; 2.85 + pfn = list_entry(list_ent, struct pfn_info, list) - frame_table; 2.86 + page = &frame_table[pfn]; 2.87 + 2.88 + if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table || 2.89 + (page->u.inuse.type_info & PGT_type_mask) == PGT_l2_page_table ) 2.90 + { 2.91 + pt = map_domain_mem( pfn<<PAGE_SHIFT ); 2.92 + 2.93 + for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) 2.94 + { 2.95 + if ( pt[i] & _PAGE_PRESENT ) 2.96 + { 2.97 + unsigned long l1pfn = pt[i]>>PAGE_SHIFT; 2.98 + 2.99 + if( l1pfn == xpfn ) 2.100 + { 2.101 + printk(" found dom=%d i=%x pfn=%lx t=%x c=%x\n", 2.102 + d->domain, 2.103 + i,pfn,page->u.inuse.type_info, 2.104 + page->count_info); 2.105 + } 2.106 + } 2.107 + } 2.108 + 2.109 + unmap_domain_mem(pt); 2.110 + } 2.111 + 2.112 + list_ent = frame_table[pfn].list.next; 2.113 + } 2.114 + 2.115 + } 2.116 + 2.117 + void scan_for_pfn_remote( unsigned long xpfn ) 2.118 + { 2.119 + struct domain *e; 2.120 + 2.121 + for_each_domain ( e ) 2.122 + { 2.123 + scan_for_pfn( e, xpfn ); 2.124 + } 2.125 + } 2.126 + 2.127 + int i; 2.128 + unsigned long pfn; 2.129 + struct list_head *list_ent; 2.130 + 2.131 + if(d!=current)domain_pause(d); 2.132 + synchronise_pagetables(~0UL); 2.133 + 2.134 + printk("pt base=%lx sh_info=%x\n", 2.135 + pagetable_val(d->mm.pagetable)>>PAGE_SHIFT, 2.136 + virt_to_page(d->shared_info)-frame_table); 2.137 + 2.138 + spin_lock(&d->page_alloc_lock); 2.139 + 2.140 + /* phase 0 */ 2.141 + 2.142 + list_ent = d->page_list.next; 2.143 + for ( i = 0; (list_ent != &d->page_list); i++ ) 2.144 + { 2.145 + struct pfn_info *page; 2.146 + pfn = list_entry(list_ent, struct pfn_info, list) - frame_table; 2.147 + page = &frame_table[pfn]; 2.148 + 2.149 + if ( page->u.inuse.domain != d ) 2.150 + BUG(); 2.151 + 2.152 + if ( (page->u.inuse.type_info & PGT_count_mask) > 2.153 + (page->count_info & PGC_count_mask) ) 2.154 + printk("taf > caf %x %x pfn=%lx\n", 2.155 + page->u.inuse.type_info, page->count_info, pfn ); 2.156 + 2.157 +#if 0 // SYSV shared memory pages plus writeable files 2.158 + if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page && 2.159 + (page->u.inuse.type_info & PGT_count_mask) > 1 ) 2.160 + { 2.161 + printk("writeable page with type count >1: pfn=%lx t=%x c=%x\n", 2.162 + pfn, 2.163 + page->u.inuse.type_info, 2.164 + page->count_info ); 2.165 + scan_for_pfn_remote(pfn); 2.166 + } 2.167 #endif 2.168 + if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_none && 2.169 + (page->u.inuse.type_info & PGT_count_mask) > 1 ) 2.170 + { 2.171 + printk("normal page with type count >1: pfn=%lx t=%x c=%x\n", 2.172 + pfn, 2.173 + page->u.inuse.type_info, 2.174 + page->count_info ); 2.175 + } 2.176 + 2.177 + // use tlbflush_timestamp to store original type_info 2.178 + page->tlbflush_timestamp = page->u.inuse.type_info; 2.179 + 2.180 + list_ent = frame_table[pfn].list.next; 2.181 + } 2.182 + 2.183 + 2.184 + /* phase 1 */ 2.185 + 2.186 + adjust( &frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], -1, 1 ); 2.187 + 2.188 + list_ent = d->page_list.next; 2.189 + for ( i = 0; (list_ent != &d->page_list); i++ ) 2.190 + { 2.191 + unsigned long * pt; 2.192 + struct pfn_info *page; 2.193 + pfn = list_entry(list_ent, struct pfn_info, list) - frame_table; 2.194 + page = &frame_table[pfn]; 2.195 + 2.196 + if ( page->u.inuse.domain != d ) 2.197 + BUG(); 2.198 + 2.199 + switch ( page->u.inuse.type_info & PGT_type_mask ) 2.200 + { 2.201 + case PGT_l2_page_table: 2.202 + 2.203 + if ((page->u.inuse.type_info & PGT_validated) != PGT_validated ) 2.204 + printk("Audit %d: L2 not validated %x\n", 2.205 + d->domain, page->u.inuse.type_info); 2.206 + 2.207 + if ((page->u.inuse.type_info & PGT_pinned) != PGT_pinned ) 2.208 + printk("Audit %d: L2 not pinned %x\n", 2.209 + d->domain, page->u.inuse.type_info); 2.210 + else 2.211 + adjust( page, -1, 1 ); 2.212 + 2.213 + pt = map_domain_mem( pfn<<PAGE_SHIFT ); 2.214 + 2.215 + for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ ) 2.216 + { 2.217 + if ( pt[i] & _PAGE_PRESENT ) 2.218 + { 2.219 + unsigned long l1pfn = pt[i]>>PAGE_SHIFT; 2.220 + struct pfn_info *l1page = &frame_table[l1pfn]; 2.221 + 2.222 + if (l1page->u.inuse.domain != d) 2.223 + { 2.224 + printk("Skip page belowing to other dom %p\n", 2.225 + l1page->u.inuse.domain); 2.226 + continue; 2.227 + } 2.228 + 2.229 + if ((l1page->u.inuse.type_info & PGT_type_mask) != 2.230 + PGT_l1_page_table ) 2.231 + printk("Audit %d: [%x] Expected L1 t=%x pfn=%lx\n", 2.232 + d->domain, i, 2.233 + l1page->u.inuse.type_info, 2.234 + l1pfn); 2.235 + 2.236 + adjust( l1page, -1, 1 ); 2.237 + } 2.238 + } 2.239 + 2.240 + unmap_domain_mem(pt); 2.241 + 2.242 + break; 2.243 + 2.244 + 2.245 + case PGT_l1_page_table: 2.246 + 2.247 + if ((page->u.inuse.type_info & PGT_pinned) == PGT_pinned ) 2.248 + { 2.249 + //printk("L1 is pinned\n"); 2.250 + adjust( page, -1, 1 ); 2.251 + } 2.252 + 2.253 + if ((page->u.inuse.type_info & PGT_validated) != PGT_validated ) 2.254 + printk("Audit %d: L1 not validated %x\n", 2.255 + d->domain, page->u.inuse.type_info); 2.256 +#if 0 2.257 + if ((page->u.inuse.type_info & PGT_pinned) != PGT_pinned ) 2.258 + printk("Audit %d: L1 not pinned %x\n", 2.259 + d->domain, page->u.inuse.type_info); 2.260 +#endif 2.261 + pt = map_domain_mem( pfn<<PAGE_SHIFT ); 2.262 + 2.263 + for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) 2.264 + { 2.265 + if ( pt[i] & _PAGE_PRESENT ) 2.266 + { 2.267 + unsigned long l1pfn = pt[i]>>PAGE_SHIFT; 2.268 + struct pfn_info *l1page = &frame_table[l1pfn]; 2.269 + 2.270 + if ( pt[i] & _PAGE_RW ) 2.271 + { 2.272 + 2.273 + if ((l1page->u.inuse.type_info & PGT_type_mask) == 2.274 + PGT_l1_page_table || 2.275 + (l1page->u.inuse.type_info & PGT_type_mask) == 2.276 + PGT_l2_page_table ) 2.277 + printk("Audit %d: [%x] Ilegal RW t=%x pfn=%lx\n", 2.278 + d->domain, i, 2.279 + l1page->u.inuse.type_info, 2.280 + l1pfn); 2.281 + 2.282 + } 2.283 + 2.284 + if (l1page->u.inuse.domain != d) 2.285 + { 2.286 + printk("Skip page belowing to other dom %p\n", 2.287 + l1page->u.inuse.domain); 2.288 + continue; 2.289 + } 2.290 + 2.291 + adjust( l1page, -1, 0 ); 2.292 + } 2.293 + } 2.294 + 2.295 + unmap_domain_mem(pt); 2.296 + 2.297 + break; 2.298 + } 2.299 + 2.300 + 2.301 + 2.302 + list_ent = frame_table[pfn].list.next; 2.303 + } 2.304 + 2.305 + /* phase 2 */ 2.306 + 2.307 + ctot = ttot = 0; 2.308 + list_ent = d->page_list.next; 2.309 + for ( i = 0; (list_ent != &d->page_list); i++ ) 2.310 + { 2.311 + struct pfn_info *page; 2.312 + pfn = list_entry(list_ent, struct pfn_info, list) - frame_table; 2.313 + 2.314 + page = &frame_table[pfn]; 2.315 + 2.316 + 2.317 + switch ( page->u.inuse.type_info & PGT_type_mask) 2.318 + { 2.319 + case PGT_l1_page_table: 2.320 + case PGT_l2_page_table: 2.321 + if ( (page->u.inuse.type_info & PGT_count_mask) != 0 ) 2.322 + { 2.323 + printk("Audit %d: type count!=0 t=%x ot=%x c=%x pfn=%lx\n", 2.324 + d->domain, page->u.inuse.type_info, 2.325 + page->tlbflush_timestamp, 2.326 + page->count_info, pfn ); 2.327 + scan_for_pfn_remote(pfn); 2.328 + } 2.329 + default: 2.330 + if ( (page->count_info & PGC_count_mask) != 1 ) 2.331 + { 2.332 + printk("Audit %d: general count!=1 (c=%x) t=%x ot=%x pfn=%lx\n", 2.333 + d->domain, 2.334 + page->count_info, 2.335 + page->u.inuse.type_info, 2.336 + page->tlbflush_timestamp, pfn ); 2.337 + scan_for_pfn_remote(pfn); 2.338 + } 2.339 + break; 2.340 + } 2.341 + 2.342 + list_ent = frame_table[pfn].list.next; 2.343 + } 2.344 + 2.345 + /* phase 3 */ 2.346 + 2.347 + list_ent = d->page_list.next; 2.348 + for ( i = 0; (list_ent != &d->page_list); i++ ) 2.349 + { 2.350 + unsigned long * pt; 2.351 + struct pfn_info *page; 2.352 + pfn = list_entry(list_ent, struct pfn_info, list) - frame_table; 2.353 + 2.354 + page = &frame_table[pfn]; 2.355 + 2.356 + switch ( page->u.inuse.type_info & PGT_type_mask ) 2.357 + { 2.358 + case PGT_l2_page_table: 2.359 + if ((page->u.inuse.type_info & PGT_pinned) == PGT_pinned ) 2.360 + adjust( page, 1, 1 ); 2.361 + 2.362 + pt = map_domain_mem( pfn<<PAGE_SHIFT ); 2.363 + 2.364 + for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ ) 2.365 + { 2.366 + if ( pt[i] & _PAGE_PRESENT ) 2.367 + { 2.368 + unsigned long l1pfn = pt[i]>>PAGE_SHIFT; 2.369 + struct pfn_info *l1page = &frame_table[l1pfn]; 2.370 + 2.371 + if ( l1page->u.inuse.domain == d) 2.372 + adjust( l1page, 1, 1 ); 2.373 + } 2.374 + } 2.375 + 2.376 + unmap_domain_mem(pt); 2.377 + break; 2.378 + 2.379 + case PGT_l1_page_table: 2.380 + if ((page->u.inuse.type_info & PGT_pinned) == PGT_pinned ) 2.381 + adjust( page, 1, 1 ); 2.382 + 2.383 + pt = map_domain_mem( pfn<<PAGE_SHIFT ); 2.384 + 2.385 + for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) 2.386 + { 2.387 + if ( pt[i] & _PAGE_PRESENT ) 2.388 + { 2.389 +#if 1 2.390 + 2.391 + unsigned long l1pfn = pt[i]>>PAGE_SHIFT; 2.392 + struct pfn_info *l1page = &frame_table[l1pfn]; 2.393 + 2.394 + if ( l1page->u.inuse.domain == d) 2.395 + adjust( l1page, 1, 0 ); 2.396 +#endif 2.397 + } 2.398 + } 2.399 + 2.400 + unmap_domain_mem(pt); 2.401 + break; 2.402 + } 2.403 + 2.404 + 2.405 + page->tlbflush_timestamp = 0; // put back 2.406 + 2.407 + 2.408 + list_ent = frame_table[pfn].list.next; 2.409 + } 2.410 + 2.411 + spin_unlock(&d->page_alloc_lock); 2.412 + 2.413 + adjust( &frame_table[pagetable_val(d->mm.pagetable)>>PAGE_SHIFT], 1, 1 ); 2.414 + 2.415 + printk("Audit %d: Done. ctot=%d ttot=%d\n",d->domain, ctot, ttot ); 2.416 + 2.417 + if(d!=current)domain_unpause(d); 2.418 + 2.419 +} 2.420 + 2.421 + 2.422 +void audit_domains( void ) 2.423 +{ 2.424 + struct domain *d; 2.425 + 2.426 + for_each_domain ( d ) 2.427 + { 2.428 + if ( d->domain > 0 ) 2.429 + audit_domain(d); 2.430 + } 2.431 +} 2.432 + 2.433 +void audit_domains_key (unsigned char key, void *dev_id, 2.434 + struct pt_regs *regs) 2.435 +{ 2.436 + open_softirq( MEMAUDIT_SOFTIRQ, audit_domains ); 2.437 + raise_softirq( MEMAUDIT_SOFTIRQ ); 2.438 +} 2.439 + 2.440 + 2.441 +#endif
3.1 --- a/xen/arch/x86/traps.c Mon Sep 06 15:53:59 2004 +0000 3.2 +++ b/xen/arch/x86/traps.c Mon Sep 06 18:48:13 2004 +0000 3.3 @@ -102,6 +102,25 @@ static inline int kernel_text_address(un 3.4 3.5 } 3.6 3.7 +void show_guest_stack() 3.8 +{ 3.9 + int i; 3.10 + execution_context_t *ec = get_execution_context(); 3.11 + unsigned long *stack = (unsigned long *)ec->esp; 3.12 + printk("Guest EIP is %lx\n",ec->eip); 3.13 + 3.14 + for ( i = 0; i < kstack_depth_to_print; i++ ) 3.15 + { 3.16 + if ( ((long)stack & (STACK_SIZE-1)) == 0 ) 3.17 + break; 3.18 + if ( i && ((i % 8) == 0) ) 3.19 + printk("\n "); 3.20 + printk("%08lx ", *stack++); 3.21 + } 3.22 + printk("\n"); 3.23 + 3.24 +} 3.25 + 3.26 void show_stack(unsigned long *esp) 3.27 { 3.28 unsigned long *stack, addr;
4.1 --- a/xen/common/keyhandler.c Mon Sep 06 15:53:59 2004 +0000 4.2 +++ b/xen/common/keyhandler.c Mon Sep 06 18:48:13 2004 +0000 4.3 @@ -108,6 +108,11 @@ extern void print_sched_histo(unsigned c 4.4 struct pt_regs *regs); 4.5 extern void reset_sched_histo(unsigned char key, void *dev_id, 4.6 struct pt_regs *regs); 4.7 +#ifndef NDEBUG 4.8 +extern void audit_domains_key(unsigned char key, void *dev_id, 4.9 + struct pt_regs *regs); 4.10 +#endif 4.11 + 4.12 #ifdef PERF_COUNTERS 4.13 extern void perfc_printall(unsigned char key, void *dev_id, 4.14 struct pt_regs *regs); 4.15 @@ -124,6 +129,11 @@ void initialize_keytable(void) 4.16 add_key_handler('q', do_task_queues, "dump task queues + guest state"); 4.17 add_key_handler('r', dump_runq, "dump run queues"); 4.18 add_key_handler('R', halt_machine, "reboot machine"); 4.19 + 4.20 +#ifndef NDEBUG 4.21 + add_key_handler('o', audit_domains_key, "audit domains >0 EXPERIMENTAL"); 4.22 +#endif 4.23 + 4.24 #ifdef PERF_COUNTERS 4.25 add_key_handler('p', perfc_printall, "print performance counters"); 4.26 add_key_handler('P', perfc_reset, "reset performance counters");
5.1 --- a/xen/common/page_alloc.c Mon Sep 06 15:53:59 2004 +0000 5.2 +++ b/xen/common/page_alloc.c Mon Sep 06 18:48:13 2004 +0000 5.3 @@ -448,6 +448,11 @@ void free_domheap_pages(struct pfn_info 5.4 5.5 for ( i = 0; i < (1 << order); i++ ) 5.6 { 5.7 +#ifndef NDEBUG 5.8 + if ( pg[i].u.inuse.type_info & PGT_count_mask ) 5.9 + printk("ERROR: type count not zero on free %x\n", 5.10 + pg[i].u.inuse.type_info ); 5.11 +#endif 5.12 pg[i].tlbflush_timestamp = tlbflush_clock; 5.13 pg[i].u.free.cpu_mask = 1 << d->processor; 5.14 list_del(&pg[i].list);
6.1 --- a/xen/include/xen/softirq.h Mon Sep 06 15:53:59 2004 +0000 6.2 +++ b/xen/include/xen/softirq.h Mon Sep 06 18:48:13 2004 +0000 6.3 @@ -6,7 +6,8 @@ 6.4 #define DEBUGGER_SOFTIRQ 2 6.5 #define NMI_SOFTIRQ 3 6.6 #define SCHEDULE_SOFTIRQ 4 6.7 -#define NR_SOFTIRQS 5 6.8 +#define MEMAUDIT_SOFTIRQ 5 6.9 +#define NR_SOFTIRQS 6 6.10 6.11 #ifndef __ASSEMBLY__ 6.12