ia64/xen-unstable
changeset 2457:1ae6a24623a9
bitkeeper revision 1.1159.1.136 (413ed5baHUBJ5EA2PO0yZ_45_I8a5w)
g/c support for multiple inactive writable pagetables.
Also use consistent names for bookkeeping data.
g/c support for multiple inactive writable pagetables.
Also use consistent names for bookkeeping data.
author | cl349@freefall.cl.cam.ac.uk |
---|---|
date | Wed Sep 08 09:49:46 2004 +0000 (2004-09-08) |
parents | 56bea31b70e5 |
children | d3c0c3c96dc0 |
files | xen/arch/x86/memory.c xen/arch/x86/traps.c xen/include/asm-x86/mm.h |
line diff
1.1 --- a/xen/arch/x86/memory.c Tue Sep 07 20:24:46 2004 +0000 1.2 +++ b/xen/arch/x86/memory.c Wed Sep 08 09:49:46 2004 +0000 1.3 @@ -1486,8 +1486,8 @@ int do_update_va_mapping_otherdomain(uns 1.4 ptwr_info_t ptwr_info[NR_CPUS] = 1.5 { [ 0 ... NR_CPUS-1 ] = 1.6 { 1.7 - .disconnected = ENTRIES_PER_L2_PAGETABLE, 1.8 - .writable_idx = 0, 1.9 + .disconnected_pteidx = -1, 1.10 + .writable_l1va = 0, 1.11 } 1.12 }; 1.13 1.14 @@ -1498,7 +1498,7 @@ int ptwr_debug = 0; 1.15 #define PTWR_PRINTK(x) 1.16 #endif 1.17 1.18 -void ptwr_reconnect_disconnected(unsigned long addr) 1.19 +void ptwr_reconnect_disconnected(void) 1.20 { 1.21 unsigned long pte; 1.22 unsigned long pfn; 1.23 @@ -1508,11 +1508,11 @@ void ptwr_reconnect_disconnected(unsigne 1.24 int cpu = smp_processor_id(); 1.25 int i; 1.26 unsigned long *writable_pte = (unsigned long *)&linear_pg_table 1.27 - [ptwr_info[cpu].writable_l1>>PAGE_SHIFT]; 1.28 + [ptwr_info[cpu].disconnected_l1va>>PAGE_SHIFT]; 1.29 1.30 - PTWR_PRINTK(("[A] page fault in disconn space: addr %08lx space %08lx\n", 1.31 - addr, ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT)); 1.32 - pl2e = &linear_l2_table[ptwr_info[cpu].disconnected]; 1.33 + PTWR_PRINTK(("[A] page fault in disconn space %08lx\n", 1.34 + ptwr_info[cpu].disconnected_pteidx << L2_PAGETABLE_SHIFT)); 1.35 + pl2e = &linear_l2_table[ptwr_info[cpu].disconnected_pteidx]; 1.36 1.37 if (__get_user(pte, writable_pte)) { 1.38 MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte); 1.39 @@ -1558,21 +1558,21 @@ void ptwr_reconnect_disconnected(unsigne 1.40 frame_table[pfn].u.inuse.type_info, 1.41 frame_table[pfn].count_info, 1.42 frame_table[pfn].u.inuse.domain->domain)); 1.43 - ptwr_info[cpu].disconnected = ENTRIES_PER_L2_PAGETABLE; 1.44 + ptwr_info[cpu].disconnected_pteidx = -1; 1.45 /* make pt page write protected */ 1.46 if (__get_user(pte, writable_pte)) { 1.47 MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte); 1.48 domain_crash(); 1.49 } 1.50 - PTWR_PRINTK(("[A] writable_l1 at %p is %08lx\n", 1.51 + PTWR_PRINTK(("[A] disconnected_l1va at %p is %08lx\n", 1.52 writable_pte, pte)); 1.53 pte &= ~_PAGE_RW; 1.54 if (__put_user(pte, writable_pte)) { 1.55 MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte); 1.56 domain_crash(); 1.57 } 1.58 - __flush_tlb_one(ptwr_info[cpu].writable_l1); 1.59 - PTWR_PRINTK(("[A] writable_l1 at %p now %08lx\n", 1.60 + __flush_tlb_one(ptwr_info[cpu].disconnected_l1va); 1.61 + PTWR_PRINTK(("[A] disconnected_l1va at %p now %08lx\n", 1.62 writable_pte, pte)); 1.63 /* and try again */ 1.64 return; 1.65 @@ -1584,48 +1584,47 @@ void ptwr_flush_inactive(void) 1.66 struct pfn_info *page; 1.67 l1_pgentry_t *pl1e; 1.68 int cpu = smp_processor_id(); 1.69 - int i, idx; 1.70 + int i; 1.71 + 1.72 + unsigned long *writable_pte = (unsigned long *)&linear_pg_table 1.73 + [ptwr_info[cpu].writable_l1va>>PAGE_SHIFT]; 1.74 + if (__get_user(pte, writable_pte)) { 1.75 + MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte); 1.76 + domain_crash(); 1.77 + } 1.78 + pfn = pte >> PAGE_SHIFT; 1.79 + page = &frame_table[pfn]; 1.80 + PTWR_PRINTK(("[I] alloc l1 page %p\n", page)); 1.81 1.82 - for (idx = 0; idx < ptwr_info[cpu].writable_idx; idx++) { 1.83 - unsigned long *writable_pte = (unsigned long *)&linear_pg_table 1.84 - [ptwr_info[cpu].writables[idx]>>PAGE_SHIFT]; 1.85 - if (__get_user(pte, writable_pte)) { 1.86 - MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte); 1.87 + pl1e = map_domain_mem(pfn << PAGE_SHIFT); 1.88 + for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) { 1.89 + l1_pgentry_t ol1e, nl1e; 1.90 + ol1e = ptwr_info[cpu].writable_page[i]; 1.91 + nl1e = pl1e[i]; 1.92 + if (likely(l1_pgentry_val(ol1e) == l1_pgentry_val(nl1e))) 1.93 + continue; 1.94 + if (unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT)) 1.95 + put_page_from_l1e(ol1e, current); 1.96 + if (unlikely(!get_page_from_l1e(nl1e, current))) { 1.97 + MEM_LOG("ptwr: Could not re-validate l1 page\n"); 1.98 domain_crash(); 1.99 } 1.100 - pfn = pte >> PAGE_SHIFT; 1.101 - page = &frame_table[pfn]; 1.102 - PTWR_PRINTK(("[I] alloc l1 page %p\n", page)); 1.103 + } 1.104 + unmap_domain_mem(pl1e); 1.105 1.106 - pl1e = map_domain_mem(pfn << PAGE_SHIFT); 1.107 - for ( i = 0; i < ENTRIES_PER_L1_PAGETABLE; i++ ) { 1.108 - l1_pgentry_t ol1e, nl1e; 1.109 - ol1e = ptwr_info[cpu].writable_page[idx][i]; 1.110 - nl1e = pl1e[i]; 1.111 - if (likely(l1_pgentry_val(ol1e) == l1_pgentry_val(nl1e))) 1.112 - continue; 1.113 - if (unlikely(l1_pgentry_val(ol1e) & _PAGE_PRESENT)) 1.114 - put_page_from_l1e(ol1e, current); 1.115 - if (unlikely(!get_page_from_l1e(nl1e, current))) { 1.116 - MEM_LOG("ptwr: Could not re-validate l1 page\n"); 1.117 - domain_crash(); 1.118 - } 1.119 - } 1.120 - unmap_domain_mem(pl1e); 1.121 + /* make pt page writable */ 1.122 + PTWR_PRINTK(("[I] disconnected_l1va at %p is %08lx\n", 1.123 + writable_pte, pte)); 1.124 + pte &= ~_PAGE_RW; 1.125 + if (__put_user(pte, writable_pte)) { 1.126 + MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte); 1.127 + domain_crash(); 1.128 + } 1.129 + __flush_tlb_one(ptwr_info[cpu].writable_l1va); 1.130 + PTWR_PRINTK(("[I] disconnected_l1va at %p now %08lx\n", 1.131 + writable_pte, pte)); 1.132 1.133 - /* make pt page writable */ 1.134 - PTWR_PRINTK(("[I] writable_l1 at %p is %08lx\n", 1.135 - writable_pte, pte)); 1.136 - pte &= ~_PAGE_RW; 1.137 - if (__put_user(pte, writable_pte)) { 1.138 - MEM_LOG("ptwr: Could not update pte at %p\n", writable_pte); 1.139 - domain_crash(); 1.140 - } 1.141 - __flush_tlb_one(ptwr_info[cpu].writables[idx]); 1.142 - PTWR_PRINTK(("[I] writable_l1 at %p now %08lx\n", 1.143 - writable_pte, pte)); 1.144 - } 1.145 - ptwr_info[cpu].writable_idx = 0; 1.146 + ptwr_info[cpu].writable_l1va = 0; 1.147 } 1.148 1.149 int ptwr_do_page_fault(unsigned long addr) 1.150 @@ -1669,24 +1668,21 @@ int ptwr_do_page_fault(unsigned long add 1.151 PTWR_PRINTK(("[I] freeing l1 page %p taf %08x/%08x\n", page, 1.152 page->u.inuse.type_info, 1.153 page->count_info)); 1.154 - if (ptwr_info[cpu].writable_idx == PTWR_NR_WRITABLES) 1.155 + if (ptwr_info[cpu].writable_l1va) 1.156 ptwr_flush_inactive(); 1.157 - ptwr_info[cpu].writables[ptwr_info[cpu].writable_idx] = addr; 1.158 + ptwr_info[cpu].writable_l1va = addr | 1; 1.159 1.160 pl1e = map_domain_mem(pfn << PAGE_SHIFT); 1.161 - memcpy(&ptwr_info[cpu].writable_page[ 1.162 - ptwr_info[cpu].writable_idx][0], 1.163 + memcpy(&ptwr_info[cpu].writable_page[0], 1.164 pl1e, ENTRIES_PER_L1_PAGETABLE * sizeof(l1_pgentry_t)); 1.165 unmap_domain_mem(pl1e); 1.166 - 1.167 - ptwr_info[cpu].writable_idx++; 1.168 } 1.169 else 1.170 { 1.171 l2_pgentry_t nl2e; 1.172 l1_pgentry_t *pl1e; 1.173 - if ( ptwr_info[cpu].disconnected != ENTRIES_PER_L2_PAGETABLE ) 1.174 - ptwr_reconnect_disconnected(addr); 1.175 + if ( ptwr_info[cpu].disconnected_pteidx >= 0 ) 1.176 + ptwr_reconnect_disconnected(); 1.177 PTWR_PRINTK(("[A] pl2e %p l2e %08lx pfn %08lx " 1.178 "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e), 1.179 l1_pgentry_val(linear_pg_table[(unsigned long)pl2e 1.180 @@ -1699,14 +1695,14 @@ int ptwr_do_page_fault(unsigned long add 1.181 nl2e = mk_l2_pgentry((l2_pgentry_val(*pl2e) & ~_PAGE_PRESENT)); 1.182 update_l2e(pl2e, *pl2e, nl2e); 1.183 1.184 - ptwr_info[cpu].disconnected = 1.185 + ptwr_info[cpu].disconnected_pteidx = 1.186 (page->u.inuse.type_info & PGT_va_mask) >> PGT_va_shift; 1.187 PTWR_PRINTK(("[A] now pl2e %p l2e %08lx " 1.188 "taf %08x/%08x/%u\n", pl2e, l2_pgentry_val(*pl2e), 1.189 frame_table[pfn].u.inuse.type_info, 1.190 frame_table[pfn].count_info, 1.191 frame_table[pfn].u.inuse.domain->domain)); 1.192 - ptwr_info[cpu].writable_l1 = addr; 1.193 + ptwr_info[cpu].disconnected_l1va = addr; 1.194 pl1e = map_domain_mem(l2_pgentry_to_pagenr(nl2e) << 1.195 PAGE_SHIFT); 1.196 memcpy(&ptwr_info[cpu].disconnected_page[0], pl1e, 1.197 @@ -1739,34 +1735,31 @@ void ptwr_status(void) 1.198 l2_pgentry_t *pl2e; 1.199 int cpu = smp_processor_id(); 1.200 1.201 - for ( i = 0; i < ptwr_info[cpu].writable_idx; i++ ) 1.202 - { 1.203 - unsigned long *writable_pte = (unsigned long *)&linear_pg_table 1.204 - [ptwr_info[cpu].writables[i]>>PAGE_SHIFT]; 1.205 + unsigned long *writable_pte = (unsigned long *)&linear_pg_table 1.206 + [ptwr_info[cpu].writable_l1va>>PAGE_SHIFT]; 1.207 1.208 - if ( __get_user(pte, writable_pte) ) { 1.209 - MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte); 1.210 - domain_crash(); 1.211 - } 1.212 - 1.213 - pfn = pte >> PAGE_SHIFT; 1.214 - page = &frame_table[pfn]; 1.215 - printk("need to alloc l1 page %p\n", page); 1.216 - /* make pt page writable */ 1.217 - printk("need to make read-only l1-page at %p is %08lx\n", 1.218 - writable_pte, pte); 1.219 + if ( __get_user(pte, writable_pte) ) { 1.220 + MEM_LOG("ptwr: Could not read pte at %p\n", writable_pte); 1.221 + domain_crash(); 1.222 } 1.223 1.224 - if ( ptwr_info[cpu].disconnected == ENTRIES_PER_L2_PAGETABLE ) 1.225 + pfn = pte >> PAGE_SHIFT; 1.226 + page = &frame_table[pfn]; 1.227 + printk("need to alloc l1 page %p\n", page); 1.228 + /* make pt page writable */ 1.229 + printk("need to make read-only l1-page at %p is %08lx\n", 1.230 + writable_pte, pte); 1.231 + 1.232 + if ( ptwr_info[cpu].disconnected_pteidx < 0 ) 1.233 return; 1.234 1.235 printk("disconnected space: space %08lx\n", 1.236 - ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT); 1.237 - pl2e = &linear_l2_table[ptwr_info[cpu].disconnected]; 1.238 + ptwr_info[cpu].disconnected_pteidx << L2_PAGETABLE_SHIFT); 1.239 + pl2e = &linear_l2_table[ptwr_info[cpu].disconnected_pteidx]; 1.240 1.241 - if ( __get_user(pte, (unsigned long *)ptwr_info[cpu].writable_l1) ) { 1.242 + if ( __get_user(pte, (unsigned long *)ptwr_info[cpu].disconnected_l1va) ) { 1.243 MEM_LOG("ptwr: Could not read pte at %p\n", (unsigned long *) 1.244 - ptwr_info[cpu].writable_l1); 1.245 + ptwr_info[cpu].disconnected_l1va); 1.246 domain_crash(); 1.247 } 1.248 pfn = pte >> PAGE_SHIFT;
2.1 --- a/xen/arch/x86/traps.c Tue Sep 07 20:24:46 2004 +0000 2.2 +++ b/xen/arch/x86/traps.c Wed Sep 08 09:49:46 2004 +0000 2.3 @@ -351,9 +351,10 @@ asmlinkage void do_page_fault(struct pt_ 2.4 2.5 if ( likely(VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) ) 2.6 { 2.7 - if ( unlikely((addr >> L2_PAGETABLE_SHIFT) == ptwr_info[cpu].disconnected )) 2.8 + if ( unlikely((addr >> L2_PAGETABLE_SHIFT) == 2.9 + ptwr_info[cpu].disconnected_pteidx )) 2.10 { 2.11 - ptwr_reconnect_disconnected(addr); 2.12 + ptwr_reconnect_disconnected(); 2.13 return; 2.14 } 2.15
3.1 --- a/xen/include/asm-x86/mm.h Tue Sep 07 20:24:46 2004 +0000 3.2 +++ b/xen/include/asm-x86/mm.h Wed Sep 08 09:49:46 2004 +0000 3.3 @@ -370,14 +370,12 @@ extern vm_assist_info_t vm_assist_info[] 3.4 3.5 3.6 /* Writable Pagetables */ 3.7 -#define PTWR_NR_WRITABLES 1 3.8 typedef struct { 3.9 - unsigned long disconnected; 3.10 + long disconnected_pteidx; 3.11 l1_pgentry_t disconnected_page[ENTRIES_PER_L1_PAGETABLE]; 3.12 - unsigned long writable_l1; 3.13 - unsigned long writables[PTWR_NR_WRITABLES]; 3.14 - int writable_idx; 3.15 - l1_pgentry_t writable_page[PTWR_NR_WRITABLES][ENTRIES_PER_L1_PAGETABLE]; 3.16 + unsigned long disconnected_l1va; 3.17 + unsigned long writable_l1va; 3.18 + l1_pgentry_t writable_page[ENTRIES_PER_L1_PAGETABLE]; 3.19 } __cacheline_aligned ptwr_info_t; 3.20 3.21 extern ptwr_info_t ptwr_info[]; 3.22 @@ -385,19 +383,19 @@ extern ptwr_info_t ptwr_info[]; 3.23 #define PTWR_CLEANUP_ACTIVE 1 3.24 #define PTWR_CLEANUP_INACTIVE 2 3.25 3.26 -void ptwr_reconnect_disconnected(unsigned long addr); 3.27 +void ptwr_reconnect_disconnected(void); 3.28 void ptwr_flush_inactive(void); 3.29 int ptwr_do_page_fault(unsigned long); 3.30 3.31 -#define __cleanup_writable_pagetable(_what) \ 3.32 -do { \ 3.33 - int cpu = smp_processor_id(); \ 3.34 - if ((_what) & PTWR_CLEANUP_ACTIVE) \ 3.35 - if (ptwr_info[cpu].disconnected != ENTRIES_PER_L2_PAGETABLE) \ 3.36 - ptwr_reconnect_disconnected(0L); \ 3.37 - if ((_what) & PTWR_CLEANUP_INACTIVE) \ 3.38 - if (ptwr_info[cpu].writable_idx) \ 3.39 - ptwr_flush_inactive(); \ 3.40 +#define __cleanup_writable_pagetable(_what) \ 3.41 +do { \ 3.42 + int cpu = smp_processor_id(); \ 3.43 + if ((_what) & PTWR_CLEANUP_ACTIVE) \ 3.44 + if (ptwr_info[cpu].disconnected_pteidx >= 0) \ 3.45 + ptwr_reconnect_disconnected(); \ 3.46 + if ((_what) & PTWR_CLEANUP_INACTIVE) \ 3.47 + if (ptwr_info[cpu].writable_l1va) \ 3.48 + ptwr_flush_inactive(); \ 3.49 } while ( 0 ) 3.50 3.51 #define cleanup_writable_pagetable(_d, _w) \