Commit 227671c93ba454a4687ba0ddc5c7f3c55a166900
1 parent
f881a0d4
PAGE_EXEC support (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1692 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
31 additions
and
15 deletions
target-sparc/helper.c
| ... | ... | @@ -75,10 +75,27 @@ static const int access_table[8][8] = { |
| 75 | 75 | { 2, 2, 2, 0, 2, 2, 2, 0 } |
| 76 | 76 | }; |
| 77 | 77 | |
| 78 | -/* 1 = write OK */ | |
| 79 | -static const int rw_table[2][8] = { | |
| 80 | - { 0, 1, 0, 1, 0, 1, 0, 1 }, | |
| 81 | - { 0, 1, 0, 1, 0, 0, 0, 0 } | |
| 78 | +static const int perm_table[2][8] = { | |
| 79 | + { | |
| 80 | + PAGE_READ, | |
| 81 | + PAGE_READ | PAGE_WRITE, | |
| 82 | + PAGE_READ | PAGE_EXEC, | |
| 83 | + PAGE_READ | PAGE_WRITE | PAGE_EXEC, | |
| 84 | + PAGE_EXEC, | |
| 85 | + PAGE_READ | PAGE_WRITE, | |
| 86 | + PAGE_READ | PAGE_EXEC, | |
| 87 | + PAGE_READ | PAGE_WRITE | PAGE_EXEC | |
| 88 | + }, | |
| 89 | + { | |
| 90 | + PAGE_READ, | |
| 91 | + PAGE_READ | PAGE_WRITE, | |
| 92 | + PAGE_READ | PAGE_EXEC, | |
| 93 | + PAGE_READ | PAGE_WRITE | PAGE_EXEC, | |
| 94 | + PAGE_EXEC, | |
| 95 | + PAGE_READ, | |
| 96 | + 0, | |
| 97 | + 0, | |
| 98 | + } | |
| 82 | 99 | }; |
| 83 | 100 | |
| 84 | 101 | int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot, |
| ... | ... | @@ -95,7 +112,7 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot |
| 95 | 112 | virt_addr = address & TARGET_PAGE_MASK; |
| 96 | 113 | if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */ |
| 97 | 114 | *physical = address; |
| 98 | - *prot = PAGE_READ | PAGE_WRITE; | |
| 115 | + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; | |
| 99 | 116 | return 0; |
| 100 | 117 | } |
| 101 | 118 | |
| ... | ... | @@ -177,12 +194,11 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot |
| 177 | 194 | return error_code; |
| 178 | 195 | |
| 179 | 196 | /* the page can be put in the TLB */ |
| 180 | - *prot = PAGE_READ; | |
| 181 | - if (pde & PG_MODIFIED_MASK) { | |
| 197 | + *prot = perm_table[is_user][access_perms]; | |
| 198 | + if (!(pde & PG_MODIFIED_MASK)) { | |
| 182 | 199 | /* only set write access if already dirty... otherwise wait |
| 183 | 200 | for dirty access */ |
| 184 | - if (rw_table[is_user][access_perms]) | |
| 185 | - *prot |= PAGE_WRITE; | |
| 201 | + *prot &= ~PAGE_WRITE; | |
| 186 | 202 | } |
| 187 | 203 | |
| 188 | 204 | /* Even if large ptes, we map only one 4KB page in the cache to |
| ... | ... | @@ -206,7 +222,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
| 206 | 222 | #ifdef DEBUG_MMU |
| 207 | 223 | printf("Translate at 0x%lx -> 0x%lx, vaddr 0x%lx\n", (long)address, (long)paddr, (long)vaddr); |
| 208 | 224 | #endif |
| 209 | - ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu); | |
| 225 | + ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); | |
| 210 | 226 | return ret; |
| 211 | 227 | } |
| 212 | 228 | |
| ... | ... | @@ -221,8 +237,8 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
| 221 | 237 | // neverland. Fake/overridden mappings will be flushed when |
| 222 | 238 | // switching to normal mode. |
| 223 | 239 | vaddr = address & TARGET_PAGE_MASK; |
| 224 | - prot = PAGE_READ | PAGE_WRITE; | |
| 225 | - ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu); | |
| 240 | + prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; | |
| 241 | + ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); | |
| 226 | 242 | return ret; |
| 227 | 243 | } else { |
| 228 | 244 | if (rw & 2) |
| ... | ... | @@ -405,7 +421,7 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical |
| 405 | 421 | |
| 406 | 422 | if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */ |
| 407 | 423 | *physical = address; |
| 408 | - *prot = PAGE_READ; | |
| 424 | + *prot = PAGE_EXEC; | |
| 409 | 425 | return 0; |
| 410 | 426 | } |
| 411 | 427 | |
| ... | ... | @@ -441,7 +457,7 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical |
| 441 | 457 | return 1; |
| 442 | 458 | } |
| 443 | 459 | *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL); |
| 444 | - *prot = PAGE_READ; | |
| 460 | + *prot = PAGE_EXEC; | |
| 445 | 461 | return 0; |
| 446 | 462 | } |
| 447 | 463 | } |
| ... | ... | @@ -477,7 +493,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
| 477 | 493 | #ifdef DEBUG_MMU |
| 478 | 494 | printf("Translate at 0x%llx -> 0x%llx, vaddr 0x%llx\n", address, paddr, vaddr); |
| 479 | 495 | #endif |
| 480 | - ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu); | |
| 496 | + ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); | |
| 481 | 497 | return ret; |
| 482 | 498 | } |
| 483 | 499 | // XXX | ... | ... |