ia64/xen-unstable
changeset 2428:e7ad903ca36c
bitkeeper revision 1.1159.69.10 (413a1e6ckNNgvyiZ6JU5_vjN5ITSuA)
Add pinning of L1 table sback in, as it helps 2.4 performance. At the same
time I've fixed the 'mutable backptr' support in Xen.
Add pinning of L1 table sback in, as it helps 2.4 performance. At the same
time I've fixed the 'mutable backptr' support in Xen.
author | kaf24@camelot.eng.3leafnetworks.com |
---|---|
date | Sat Sep 04 19:58:36 2004 +0000 (2004-09-04) |
parents | 6f9bf6379bbd |
children | 6b7809060d4a |
files | xen/arch/x86/domain.c xen/arch/x86/memory.c xen/common/dom0_ops.c xen/common/dom_mem_ops.c xen/common/page_alloc.c xen/common/schedule.c xen/include/asm-x86/mm.h xen/include/hypervisor-ifs/dom0_ops.h xen/include/hypervisor-ifs/hypervisor-if.h |
line diff
1.1 --- a/xen/arch/x86/domain.c Sat Sep 04 18:32:45 2004 +0000 1.2 +++ b/xen/arch/x86/domain.c Sat Sep 04 19:58:36 2004 +0000 1.3 @@ -449,12 +449,94 @@ long do_iopl(domid_t domain, unsigned in 1.4 1.5 #endif 1.6 1.7 -void domain_relinquish_memory(struct domain *d) 1.8 + 1.9 +static void relinquish_list(struct domain *d, struct list_head *list) 1.10 { 1.11 - struct list_head *ent, *tmp; 1.12 + struct list_head *ent; 1.13 struct pfn_info *page; 1.14 unsigned long x, y; 1.15 1.16 + /* Use a recursive lock, as we may enter 'free_domheap_page'. */ 1.17 + spin_lock_recursive(&d->page_alloc_lock); 1.18 + 1.19 + /* 1.20 + * Careful! Any time we might decrement a page's reference count we 1.21 + * might invalidate our page pointer or our pointer into the page list. 1.22 + * In such cases we have to exit the current iteration of the loop and 1.23 + * start back at the beginning of the list. We are guaranteed to make 1.24 + * forward progress because nothign will get added to the list (the domain 1.25 + * is dying) and no pages will become pinned after we unpin them. 1.26 + */ 1.27 + ent = list->next; 1.28 + while ( ent != list ) 1.29 + { 1.30 + page = list_entry(ent, struct pfn_info, list); 1.31 + 1.32 + if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) ) 1.33 + { 1.34 + /* NB. Check the allocation pin /before/ put_page_and_type()! */ 1.35 + if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) 1.36 + put_page(page); 1.37 + put_page_and_type(page); 1.38 + /* May have lost our place in the list - start over. */ 1.39 + ent = list->next; 1.40 + continue; 1.41 + } 1.42 + 1.43 + if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) 1.44 + { 1.45 + put_page(page); 1.46 + /* May have lost our place in the list - start over. */ 1.47 + ent = list->next; 1.48 + continue; 1.49 + } 1.50 + 1.51 + /* 1.52 + * Forcibly invalidate base page tables at this point to break circular 1.53 + * 'linear page table' references. This is okay because MMU structures 1.54 + * are not shared across domains and this domain is now dead. Thus base 1.55 + * tables are not in use so a non-zero count means circular reference. 1.56 + */ 1.57 + y = page->u.inuse.type_info; 1.58 + do { 1.59 + x = y; 1.60 + if ( likely((x & (PGT_type_mask|PGT_validated)) != 1.61 + (PGT_base_page_table|PGT_validated)) ) 1.62 + { 1.63 + /* 1.64 + * We have done no work on this iteration, so it is safe 1.65 + * to move on to the next page in the list. 1.66 + */ 1.67 + ent = ent->next; 1.68 + break; 1.69 + } 1.70 + y = cmpxchg(&page->u.inuse.type_info, x, x & ~PGT_validated); 1.71 + if ( likely(y == x) ) 1.72 + { 1.73 + free_page_type(page, PGT_base_page_table); 1.74 + /* May have lost our place in the list - start over. */ 1.75 + ent = list->next; 1.76 + } 1.77 + } 1.78 + while ( unlikely(y != x) ); 1.79 + } 1.80 + 1.81 + spin_unlock_recursive(&d->page_alloc_lock); 1.82 + 1.83 + /* 1.84 + * Another CPU may have raced us to free some pages. Wait for those 1.85 + * to trickle out now that we have released the lock. 1.86 + */ 1.87 + while ( !list_empty(list) ) 1.88 + { 1.89 + smp_mb(); 1.90 + cpu_relax(); 1.91 + } 1.92 +} 1.93 + 1.94 + 1.95 +void domain_relinquish_memory(struct domain *d) 1.96 +{ 1.97 /* Ensure that noone is running over the dead domain's page tables. */ 1.98 synchronise_pagetables(~0UL); 1.99 1.100 @@ -472,49 +554,9 @@ void domain_relinquish_memory(struct dom 1.101 */ 1.102 destroy_gdt(d); 1.103 1.104 - /* Use a recursive lock, as we may enter 'free_domheap_page'. */ 1.105 - spin_lock_recursive(&d->page_alloc_lock); 1.106 - 1.107 - /* Relinquish Xen-heap pages. */ 1.108 - list_for_each_safe ( ent, tmp, &d->xenpage_list ) 1.109 - { 1.110 - page = list_entry(ent, struct pfn_info, list); 1.111 - 1.112 - if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) 1.113 - put_page(page); 1.114 - } 1.115 - 1.116 - /* Relinquish all pages on the domain's allocation list. */ 1.117 - list_for_each_safe ( ent, tmp, &d->page_list ) 1.118 - { 1.119 - page = list_entry(ent, struct pfn_info, list); 1.120 - 1.121 - if ( test_and_clear_bit(_PGC_guest_pinned, &page->count_info) ) 1.122 - put_page_and_type(page); 1.123 - 1.124 - if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) 1.125 - put_page(page); 1.126 - 1.127 - /* 1.128 - * Forcibly invalidate base page tables at this point to break circular 1.129 - * 'linear page table' references. This is okay because MMU structures 1.130 - * are not shared across domains and this domain is now dead. Thus base 1.131 - * tables are not in use so a non-zero count means circular reference. 1.132 - */ 1.133 - y = page->u.inuse.type_info; 1.134 - do { 1.135 - x = y; 1.136 - if ( likely((x & (PGT_type_mask|PGT_validated)) != 1.137 - (PGT_base_page_table|PGT_validated)) ) 1.138 - break; 1.139 - y = cmpxchg(&page->u.inuse.type_info, x, x & ~PGT_validated); 1.140 - if ( likely(y == x) ) 1.141 - free_page_type(page, PGT_base_page_table); 1.142 - } 1.143 - while ( unlikely(y != x) ); 1.144 - } 1.145 - 1.146 - spin_unlock_recursive(&d->page_alloc_lock); 1.147 + /* Relinquish every page of memory. */ 1.148 + relinquish_list(d, &d->xenpage_list); 1.149 + relinquish_list(d, &d->page_list); 1.150 } 1.151 1.152 1.153 @@ -739,7 +781,7 @@ int construct_dom0(struct domain *p, 1.154 /* Get another ref to L2 page so that it can be pinned. */ 1.155 if ( !get_page_and_type(page, p, PGT_l2_page_table) ) 1.156 BUG(); 1.157 - set_bit(_PGC_guest_pinned, &page->count_info); 1.158 + set_bit(_PGT_pinned, &page->u.inuse.type_info); 1.159 } 1.160 else 1.161 {
2.1 --- a/xen/arch/x86/memory.c Sat Sep 04 18:32:45 2004 +0000 2.2 +++ b/xen/arch/x86/memory.c Sat Sep 04 19:58:36 2004 +0000 2.3 @@ -455,7 +455,8 @@ get_page_from_l1e( 2.4 /* NB. Virtual address 'l2e' maps to a machine address within frame 'pfn'. */ 2.5 static int 2.6 get_page_from_l2e( 2.7 - l2_pgentry_t l2e, unsigned long pfn, struct domain *d, unsigned long va_idx) 2.8 + l2_pgentry_t l2e, unsigned long pfn, 2.9 + struct domain *d, unsigned long va_idx) 2.10 { 2.11 int rc; 2.12 2.13 @@ -471,7 +472,7 @@ get_page_from_l2e( 2.14 2.15 rc = get_page_and_type_from_pagenr( 2.16 l2_pgentry_to_pagenr(l2e), 2.17 - PGT_l1_page_table | (va_idx<<PGT_va_shift), d); 2.18 + PGT_l1_page_table | (va_idx<<PGT_va_shift), d); 2.19 2.20 if ( unlikely(!rc) ) 2.21 return get_linear_pagetable(l2e, pfn, d); 2.22 @@ -671,8 +672,8 @@ static int mod_l2_entry(l2_pgentry_t *pl 2.23 return update_l2e(pl2e, ol2e, nl2e); 2.24 2.25 if ( unlikely(!get_page_from_l2e(nl2e, pfn, current, 2.26 - ((unsigned long) 2.27 - pl2e & ~PAGE_MASK) >> 2 )) ) 2.28 + ((unsigned long)pl2e & 2.29 + ~PAGE_MASK) >> 2)) ) 2.30 return 0; 2.31 2.32 if ( unlikely(!update_l2e(pl2e, ol2e, nl2e)) ) 2.33 @@ -828,18 +829,15 @@ static int do_extended_command(unsigned 2.34 { 2.35 case MMUEXT_PIN_L1_TABLE: 2.36 case MMUEXT_PIN_L2_TABLE: 2.37 - 2.38 - /* When we pin an L1 page we now insist that the va 2.39 - backpointer (used for writable page tables) must still be 2.40 - mutable. This is an additional restriction even for guests 2.41 - that don't use writable page tables, but I don't think it 2.42 - will break anything as guests typically pin pages before 2.43 - they are used, hence they'll still be mutable. */ 2.44 - 2.45 + /* 2.46 + * We insist that, if you pin an L1 page, it's the first thing that 2.47 + * you do to it. This is because we require the backptr to still be 2.48 + * mutable. This assumption seems safe. 2.49 + */ 2.50 okay = get_page_and_type_from_pagenr( 2.51 pfn, 2.52 ((cmd==MMUEXT_PIN_L2_TABLE) ? 2.53 - PGT_l2_page_table : (PGT_l1_page_table | PGT_va_mutable) ) , 2.54 + PGT_l2_page_table : (PGT_l1_page_table|PGT_va_mutable)), 2.55 FOREIGNDOM); 2.56 2.57 if ( unlikely(!okay) ) 2.58 @@ -849,8 +847,8 @@ static int do_extended_command(unsigned 2.59 break; 2.60 } 2.61 2.62 - if ( unlikely(test_and_set_bit(_PGC_guest_pinned, 2.63 - &page->count_info)) ) 2.64 + if ( unlikely(test_and_set_bit(_PGT_pinned, 2.65 + &page->u.inuse.type_info)) ) 2.66 { 2.67 MEM_LOG("Pfn %08lx already pinned", pfn); 2.68 put_page_and_type(page); 2.69 @@ -866,8 +864,8 @@ static int do_extended_command(unsigned 2.70 MEM_LOG("Page %08lx bad domain (dom=%p)", 2.71 ptr, page->u.inuse.domain); 2.72 } 2.73 - else if ( likely(test_and_clear_bit(_PGC_guest_pinned, 2.74 - &page->count_info)) ) 2.75 + else if ( likely(test_and_clear_bit(_PGT_pinned, 2.76 + &page->u.inuse.type_info)) ) 2.77 { 2.78 put_page_and_type(page); 2.79 put_page(page); 2.80 @@ -1053,13 +1051,18 @@ static int do_extended_command(unsigned 2.81 2.82 spin_lock(&e->page_alloc_lock); 2.83 2.84 - /* Check that 'e' will accept the page and has reservation headroom. */ 2.85 + /* 2.86 + * Check that 'e' will accept the page and has reservation headroom. 2.87 + * Also, a domain mustn't have PGC_allocated pages when it is dying. 2.88 + */ 2.89 ASSERT(e->tot_pages <= e->max_pages); 2.90 - if ( unlikely(e->tot_pages == e->max_pages) || 2.91 + if ( unlikely(test_bit(DF_DYING, &e->flags)) || 2.92 + unlikely(e->tot_pages == e->max_pages) || 2.93 unlikely(!gnttab_prepare_for_transfer(e, d, gntref)) ) 2.94 { 2.95 MEM_LOG("Transferee has no reservation headroom (%d,%d), or " 2.96 - "provided a bad grant ref.\n", e->tot_pages, e->max_pages); 2.97 + "provided a bad grant ref, or is dying (%08x).\n", 2.98 + e->tot_pages, e->max_pages, e->flags); 2.99 spin_unlock(&e->page_alloc_lock); 2.100 put_domain(e); 2.101 okay = 0; 2.102 @@ -1195,6 +1198,7 @@ int do_mmu_update(mmu_update_t *ureqs, i 2.103 unsigned long prev_spfn = 0; 2.104 l1_pgentry_t *prev_spl1e = 0; 2.105 struct domain *d = current; 2.106 + u32 type_info; 2.107 2.108 perfc_incrc(calls_to_mmu_update); 2.109 perfc_addc(num_page_updates, count); 2.110 @@ -1243,10 +1247,11 @@ int do_mmu_update(mmu_update_t *ureqs, i 2.111 } 2.112 2.113 page = &frame_table[pfn]; 2.114 - switch ( (page->u.inuse.type_info & PGT_type_mask) ) 2.115 + switch ( (type_info = page->u.inuse.type_info) & PGT_type_mask ) 2.116 { 2.117 case PGT_l1_page_table: 2.118 - if ( likely(passive_get_page_type(page, PGT_l1_page_table)) ) 2.119 + if ( likely(get_page_type( 2.120 + page, type_info & (PGT_type_mask|PGT_va_mask))) ) 2.121 { 2.122 okay = mod_l1_entry((l1_pgentry_t *)va, 2.123 mk_l1_pgentry(req.val)); 2.124 @@ -1496,11 +1501,11 @@ void ptwr_reconnect_disconnected(unsigne 2.125 [ptwr_info[cpu].writable_l1>>PAGE_SHIFT]; 2.126 2.127 #ifdef PTWR_TRACK_DOMAIN 2.128 - if (ptwr_domain[cpu] != get_current()->domain) 2.129 + if (ptwr_domain[cpu] != current->domain) 2.130 printk("ptwr_reconnect_disconnected domain mismatch %d != %d\n", 2.131 - ptwr_domain[cpu], get_current()->domain); 2.132 + ptwr_domain[cpu], current->domain); 2.133 #endif 2.134 - PTWR_PRINTK(("[A] page fault in disconnected space: addr %08lx space %08lx\n", 2.135 + PTWR_PRINTK(("[A] page fault in disconn space: addr %08lx space %08lx\n", 2.136 addr, ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT)); 2.137 pl2e = &linear_l2_table[ptwr_info[cpu].disconnected]; 2.138 2.139 @@ -1572,9 +1577,9 @@ void ptwr_flush_inactive(void) 2.140 int i, idx; 2.141 2.142 #ifdef PTWR_TRACK_DOMAIN 2.143 - if (ptwr_info[cpu].domain != get_current()->domain) 2.144 + if (ptwr_info[cpu].domain != current->domain) 2.145 printk("ptwr_flush_inactive domain mismatch %d != %d\n", 2.146 - ptwr_info[cpu].domain, get_current()->domain); 2.147 + ptwr_info[cpu].domain, current->domain); 2.148 #endif 2.149 #if 0 2.150 { 2.151 @@ -1655,9 +1660,9 @@ int ptwr_do_page_fault(unsigned long add 2.152 if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table ) 2.153 { 2.154 #ifdef PTWR_TRACK_DOMAIN 2.155 - if ( ptwr_info[cpu].domain != get_current()->domain ) 2.156 + if ( ptwr_info[cpu].domain != current->domain ) 2.157 printk("ptwr_do_page_fault domain mismatch %d != %d\n", 2.158 - ptwr_info[cpu].domain, get_current()->domain); 2.159 + ptwr_info[cpu].domain, current->domain); 2.160 #endif 2.161 pl2e = &linear_l2_table[(page->u.inuse.type_info & 2.162 PGT_va_mask) >> PGT_va_shift];
3.1 --- a/xen/common/dom0_ops.c Sat Sep 04 18:32:45 2004 +0000 3.2 +++ b/xen/common/dom0_ops.c Sat Sep 04 19:58:36 2004 +0000 3.3 @@ -628,7 +628,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 3.4 break; 3.5 } 3.6 3.7 - if ( page->count_info & PGC_guest_pinned ) 3.8 + if ( page->u.inuse.type_info & PGT_pinned ) 3.9 type |= LPINTAB; 3.10 l_arr[j] |= type; 3.11 put_page(page);
4.1 --- a/xen/common/dom_mem_ops.c Sat Sep 04 18:32:45 2004 +0000 4.2 +++ b/xen/common/dom_mem_ops.c Sat Sep 04 19:58:36 2004 +0000 4.3 @@ -82,7 +82,7 @@ static long free_dom_mem(struct domain * 4.4 return i; 4.5 } 4.6 4.7 - if ( test_and_clear_bit(_PGC_guest_pinned, &page->count_info) ) 4.8 + if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) ) 4.9 put_page_and_type(page); 4.10 4.11 if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
5.1 --- a/xen/common/page_alloc.c Sat Sep 04 18:32:45 2004 +0000 5.2 +++ b/xen/common/page_alloc.c Sat Sep 04 19:58:36 2004 +0000 5.3 @@ -393,10 +393,13 @@ struct pfn_info *alloc_domheap_pages(str 5.4 5.5 spin_lock(&d->page_alloc_lock); 5.6 5.7 - if ( unlikely((d->tot_pages + (1 << order)) > d->max_pages) ) 5.8 + if ( unlikely(test_bit(DF_DYING, &d->flags)) || 5.9 + unlikely((d->tot_pages + (1 << order)) > d->max_pages) ) 5.10 { 5.11 DPRINTK("Over-allocation for domain %u: %u > %u\n", 5.12 d->domain, d->tot_pages + (1 << order), d->max_pages); 5.13 + DPRINTK("...or the domain is dying (%d)\n", 5.14 + !!test_bit(DF_DYING, &d->flags)); 5.15 spin_unlock(&d->page_alloc_lock); 5.16 free_heap_pages(MEMZONE_DOM, pg, order); 5.17 return NULL; 5.18 @@ -427,6 +430,7 @@ void free_domheap_pages(struct pfn_info 5.19 5.20 if ( unlikely(IS_XEN_HEAP_FRAME(pg)) ) 5.21 { 5.22 + /* NB. May recursively lock from domain_relinquish_memory(). */ 5.23 spin_lock_recursive(&d->page_alloc_lock); 5.24 5.25 for ( i = 0; i < (1 << order); i++ )
6.1 --- a/xen/common/schedule.c Sat Sep 04 18:32:45 2004 +0000 6.2 +++ b/xen/common/schedule.c Sat Sep 04 19:58:36 2004 +0000 6.3 @@ -374,20 +374,6 @@ void __enter_scheduler(void) 6.4 cleanup_writable_pagetable( 6.5 prev, PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE); 6.6 6.7 -#ifdef PTWR_TRACK_DOMAIN 6.8 - { 6.9 - extern domid_t ptwr_domain[]; 6.10 - int cpu = smp_processor_id(); 6.11 - if (ptwr_domain[cpu] != prev->domain) 6.12 - printk("switch_to domain mismatch %d != %d\n", 6.13 - ptwr_domain[cpu], prev->domain); 6.14 - ptwr_domain[cpu] = next->domain; 6.15 - if (ptwr_disconnected[cpu] != ENTRIES_PER_L2_PAGETABLE || 6.16 - ptwr_writable_idx[cpu]) 6.17 - printk("switch_to ptwr dirty!!!\n"); 6.18 - } 6.19 -#endif 6.20 - 6.21 perfc_incrc(sched_ctx); 6.22 6.23 #if defined(WAKE_HISTO)
7.1 --- a/xen/include/asm-x86/mm.h Sat Sep 04 18:32:45 2004 +0000 7.2 +++ b/xen/include/asm-x86/mm.h Sat Sep 04 19:58:36 2004 +0000 7.3 @@ -71,27 +71,27 @@ struct pfn_info 7.4 /* Has this page been validated for use as its current type? */ 7.5 #define _PGT_validated 28 7.6 #define PGT_validated (1<<_PGT_validated) 7.7 - /* 10-bit most significant bits of va address if used as l1 page table */ 7.8 -#define PGT_va_shift 18 7.9 + /* Owning guest has pinned this page to its current type? */ 7.10 +#define _PGT_pinned 27 7.11 +#define PGT_pinned (1<<_PGT_pinned) 7.12 + /* The 10 most significant bits of virt address if this is a page table. */ 7.13 +#define PGT_va_shift 17 7.14 #define PGT_va_mask (((1<<10)-1)<<PGT_va_shift) 7.15 -#define PGT_va_mutable PGT_va_mask /* va backpointer is still mutable */ 7.16 - /* 18-bit count of uses of this frame as its current type. */ 7.17 -#define PGT_count_mask ((1<<18)-1) 7.18 +#define PGT_va_mutable PGT_va_mask /* va backpointer is mutable? */ 7.19 + /* 17-bit count of uses of this frame as its current type. */ 7.20 +#define PGT_count_mask ((1<<17)-1) 7.21 7.22 /* For safety, force a TLB flush when this page's type changes. */ 7.23 #define _PGC_tlb_flush_on_type_change 31 7.24 #define PGC_tlb_flush_on_type_change (1<<_PGC_tlb_flush_on_type_change) 7.25 - /* Owning guest has pinned this page to its current type? */ 7.26 -#define _PGC_guest_pinned 30 7.27 -#define PGC_guest_pinned (1<<_PGC_guest_pinned) 7.28 /* Cleared when the owning guest 'frees' this page. */ 7.29 -#define _PGC_allocated 29 7.30 +#define _PGC_allocated 30 7.31 #define PGC_allocated (1<<_PGC_allocated) 7.32 /* This bit is always set, guaranteeing that the count word is never zero. */ 7.33 -#define _PGC_always_set 28 7.34 +#define _PGC_always_set 29 7.35 #define PGC_always_set (1<<_PGC_always_set) 7.36 - /* 27-bit count of references to this frame. */ 7.37 -#define PGC_count_mask ((1<<28)-1) 7.38 + /* 29-bit count of references to this frame. */ 7.39 +#define PGC_count_mask ((1<<29)-1) 7.40 7.41 /* We trust the slab allocator in slab.c, and our use of it. */ 7.42 #define PageSlab(page) (1) 7.43 @@ -199,11 +199,10 @@ static inline void put_page_type(struct 7.44 nx &= ~PGT_validated; 7.45 } 7.46 } 7.47 - else if ( unlikely( ((nx & PGT_count_mask) == 1) && 7.48 - test_bit(_PGC_guest_pinned, &page->count_info)) ) 7.49 + else if ( unlikely((nx & (PGT_pinned | PGT_count_mask)) == 7.50 + (PGT_pinned | 1)) ) 7.51 { 7.52 - /* if the page is pinned, but we're dropping the last reference 7.53 - then make the va backpointer mutable again */ 7.54 + /* Page is now only pinned. Make the back pointer mutable again. */ 7.55 nx |= PGT_va_mutable; 7.56 } 7.57 } 7.58 @@ -230,33 +229,36 @@ static inline int get_page_type(struct p 7.59 nx &= ~(PGT_type_mask | PGT_va_mask | PGT_validated); 7.60 nx |= type; 7.61 /* No extra validation needed for writable pages. */ 7.62 - if ( (type & PGT_type_mask) == PGT_writable_page ) 7.63 + if ( type == PGT_writable_page ) 7.64 nx |= PGT_validated; 7.65 } 7.66 } 7.67 - else if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) ) 7.68 + else if ( unlikely((x & (PGT_type_mask|PGT_va_mask)) != type) ) 7.69 { 7.70 - DPRINTK("Unexpected type (saw %08x != exp %08x) for pfn %08lx\n", 7.71 - x & PGT_type_mask, type, page_to_pfn(page)); 7.72 - return 0; 7.73 - } 7.74 - else if ( (x & PGT_va_mask) == PGT_va_mutable ) 7.75 - { 7.76 - /* The va_backpointer is currently mutable, hence we update it. */ 7.77 - nx &= ~PGT_va_mask; 7.78 - nx |= type; /* we know the actual type is correct */ 7.79 - } 7.80 - else if ( unlikely((x & PGT_va_mask) != (type & PGT_va_mask) ) ) 7.81 - { 7.82 - /* The va backpointer wasn't mutable, and is different :-( */ 7.83 - DPRINTK("Unexpected va backpointer (saw %08x != exp %08x) for pfn %08lx\n", 7.84 - x, type, page_to_pfn(page)); 7.85 - return 0; 7.86 + if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) ) 7.87 + { 7.88 + DPRINTK("Bad type (saw %08x != exp %08x) for pfn %08lx\n", 7.89 + x & PGT_type_mask, type, page_to_pfn(page)); 7.90 + return 0; 7.91 + } 7.92 + else if ( (x & PGT_va_mask) == PGT_va_mutable ) 7.93 + { 7.94 + /* The va backpointer is mutable, hence we update it. */ 7.95 + nx &= ~PGT_va_mask; 7.96 + nx |= type; /* we know the actual type is correct */ 7.97 + } 7.98 + else if ( unlikely((x & PGT_va_mask) != (type & PGT_va_mask)) ) 7.99 + { 7.100 + /* The va backpointer wasn't mutable, and is different. */ 7.101 + DPRINTK("Unexpected va backpointer (saw %08x != exp %08x)" 7.102 + " for pfn %08lx\n", x, type, page_to_pfn(page)); 7.103 + return 0; 7.104 + } 7.105 } 7.106 else if ( unlikely(!(x & PGT_validated)) ) 7.107 { 7.108 /* Someone else is updating validation of this page. Wait... */ 7.109 - while ( (y = page->u.inuse.type_info) != x ) 7.110 + while ( (y = page->u.inuse.type_info) == x ) 7.111 { 7.112 rep_nop(); 7.113 barrier(); 7.114 @@ -286,55 +288,6 @@ static inline int get_page_type(struct p 7.115 return 1; 7.116 } 7.117 7.118 -/* This 'passive' version of get_page_type doesn't attempt to validate 7.119 -the page, but just checks the type and increments the type count. The 7.120 -function is called while doing a NORMAL_PT_UPDATE of an entry in an L1 7.121 -page table: We want to 'lock' the page for the brief beriod while 7.122 -we're doing the update, but we're not actually linking it in to a 7.123 -pagetable. */ 7.124 - 7.125 -static inline int passive_get_page_type(struct pfn_info *page, u32 type) 7.126 -{ 7.127 - u32 nx, x, y = page->u.inuse.type_info; 7.128 - again: 7.129 - do { 7.130 - x = y; 7.131 - nx = x + 1; 7.132 - if ( unlikely((nx & PGT_count_mask) == 0) ) 7.133 - { 7.134 - DPRINTK("Type count overflow on pfn %08lx\n", page_to_pfn(page)); 7.135 - return 0; 7.136 - } 7.137 - else if ( unlikely((x & PGT_count_mask) == 0) ) 7.138 - { 7.139 - if ( (x & (PGT_type_mask|PGT_va_mask)) != type ) 7.140 - { 7.141 - nx &= ~(PGT_type_mask | PGT_va_mask | PGT_validated); 7.142 - nx |= type; 7.143 - } 7.144 - } 7.145 - else if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) ) 7.146 - { 7.147 - DPRINTK("Unexpected type (saw %08x != exp %08x) for pfn %08lx\n", 7.148 - x & PGT_type_mask, type, page_to_pfn(page)); 7.149 - return 0; 7.150 - } 7.151 - else if ( unlikely(!(x & PGT_validated)) ) 7.152 - { 7.153 - /* Someone else is updating validation of this page. Wait... */ 7.154 - while ( (y = page->u.inuse.type_info) != x ) 7.155 - { 7.156 - rep_nop(); 7.157 - barrier(); 7.158 - } 7.159 - goto again; 7.160 - } 7.161 - } 7.162 - while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) ); 7.163 - 7.164 - return 1; 7.165 -} 7.166 - 7.167 7.168 static inline void put_page_and_type(struct pfn_info *page) 7.169 {
8.1 --- a/xen/include/hypervisor-ifs/dom0_ops.h Sat Sep 04 18:32:45 2004 +0000 8.2 +++ b/xen/include/hypervisor-ifs/dom0_ops.h Sat Sep 04 19:58:36 2004 +0000 8.3 @@ -19,7 +19,7 @@ 8.4 * This makes sure that old versions of dom0 tools will stop working in a 8.5 * well-defined way (rather than crashing the machine, for instance). 8.6 */ 8.7 -#define DOM0_INTERFACE_VERSION 0xAAAA0013 8.8 +#define DOM0_INTERFACE_VERSION 0xAAAA0014 8.9 8.10 #define MAX_DOMAIN_NAME 16 8.11
9.1 --- a/xen/include/hypervisor-ifs/hypervisor-if.h Sat Sep 04 18:32:45 2004 +0000 9.2 +++ b/xen/include/hypervisor-ifs/hypervisor-if.h Sat Sep 04 19:58:36 2004 +0000 9.3 @@ -149,16 +149,16 @@ 9.4 #define MMUEXT_PIN_L2_TABLE 1 /* ptr = MA of frame to pin */ 9.5 #define MMUEXT_PIN_L3_TABLE 2 /* ptr = MA of frame to pin */ 9.6 #define MMUEXT_PIN_L4_TABLE 3 /* ptr = MA of frame to pin */ 9.7 -#define MMUEXT_UNPIN_TABLE 1 /* ptr = MA of frame to unpin */ 9.8 -#define MMUEXT_NEW_BASEPTR 2 /* ptr = MA of new pagetable base */ 9.9 -#define MMUEXT_TLB_FLUSH 3 /* ptr = NULL */ 9.10 -#define MMUEXT_INVLPG 4 /* ptr = VA to invalidate */ 9.11 -#define MMUEXT_FLUSH_CACHE 5 9.12 -#define MMUEXT_SET_LDT 6 /* ptr = VA of table; val = # entries */ 9.13 -#define MMUEXT_SET_FOREIGNDOM 7 /* val[31:16] = dom */ 9.14 -#define MMUEXT_CLEAR_FOREIGNDOM 8 9.15 -#define MMUEXT_TRANSFER_PAGE 9 /* ptr = MA of frame; val[31:16] = dom */ 9.16 -#define MMUEXT_REASSIGN_PAGE 10 9.17 +#define MMUEXT_UNPIN_TABLE 4 /* ptr = MA of frame to unpin */ 9.18 +#define MMUEXT_NEW_BASEPTR 5 /* ptr = MA of new pagetable base */ 9.19 +#define MMUEXT_TLB_FLUSH 6 /* ptr = NULL */ 9.20 +#define MMUEXT_INVLPG 7 /* ptr = VA to invalidate */ 9.21 +#define MMUEXT_FLUSH_CACHE 8 9.22 +#define MMUEXT_SET_LDT 9 /* ptr = VA of table; val = # entries */ 9.23 +#define MMUEXT_SET_FOREIGNDOM 10 /* val[31:16] = dom */ 9.24 +#define MMUEXT_CLEAR_FOREIGNDOM 11 9.25 +#define MMUEXT_TRANSFER_PAGE 12 /* ptr = MA of frame; val[31:16] = dom */ 9.26 +#define MMUEXT_REASSIGN_PAGE 13 9.27 #define MMUEXT_CMD_MASK 255 9.28 #define MMUEXT_CMD_SHIFT 8 9.29