Commit 1565b7bcd79c5253fd400cc0ef8b398da788e965
1 parent
b409186b
fixed page_unprotect() if host_page_size > TARGET_PAGE_SIZE
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@179 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
18 additions
and
15 deletions
exec.c
| @@ -394,26 +394,29 @@ TranslationBlock *tb_alloc(unsigned long pc, | @@ -394,26 +394,29 @@ TranslationBlock *tb_alloc(unsigned long pc, | ||
| 394 | page. Return TRUE if the fault was succesfully handled. */ | 394 | page. Return TRUE if the fault was succesfully handled. */ |
| 395 | int page_unprotect(unsigned long address) | 395 | int page_unprotect(unsigned long address) |
| 396 | { | 396 | { |
| 397 | - unsigned int page_index, prot; | ||
| 398 | - PageDesc *p; | 397 | + unsigned int page_index, prot, pindex; |
| 398 | + PageDesc *p, *p1; | ||
| 399 | unsigned long host_start, host_end, addr; | 399 | unsigned long host_start, host_end, addr; |
| 400 | 400 | ||
| 401 | - page_index = address >> TARGET_PAGE_BITS; | ||
| 402 | - p = page_find(page_index); | ||
| 403 | - if (!p) | 401 | + host_start = address & host_page_mask; |
| 402 | + page_index = host_start >> TARGET_PAGE_BITS; | ||
| 403 | + p1 = page_find(page_index); | ||
| 404 | + if (!p1) | ||
| 404 | return 0; | 405 | return 0; |
| 405 | - if ((p->flags & (PAGE_WRITE_ORG | PAGE_WRITE)) == PAGE_WRITE_ORG) { | ||
| 406 | - /* if the page was really writable, then we change its | ||
| 407 | - protection back to writable */ | ||
| 408 | - host_start = address & host_page_mask; | ||
| 409 | - host_end = host_start + host_page_size; | ||
| 410 | - prot = 0; | ||
| 411 | - for(addr = host_start; addr < host_end; addr += TARGET_PAGE_SIZE) | ||
| 412 | - prot |= page_get_flags(addr); | 406 | + host_end = host_start + host_page_size; |
| 407 | + p = p1; | ||
| 408 | + prot = 0; | ||
| 409 | + for(addr = host_start;addr < host_end; addr += TARGET_PAGE_SIZE) { | ||
| 410 | + prot |= p->flags; | ||
| 411 | + p++; | ||
| 412 | + } | ||
| 413 | + /* if the page was really writable, then we change its | ||
| 414 | + protection back to writable */ | ||
| 415 | + if (prot & PAGE_WRITE_ORG) { | ||
| 413 | mprotect((void *)host_start, host_page_size, | 416 | mprotect((void *)host_start, host_page_size, |
| 414 | (prot & PAGE_BITS) | PAGE_WRITE); | 417 | (prot & PAGE_BITS) | PAGE_WRITE); |
| 415 | - p->flags |= PAGE_WRITE; | ||
| 416 | - | 418 | + pindex = (address - host_start) >> TARGET_PAGE_BITS; |
| 419 | + p1[pindex].flags |= PAGE_WRITE; | ||
| 417 | /* and since the content will be modified, we must invalidate | 420 | /* and since the content will be modified, we must invalidate |
| 418 | the corresponding translated code. */ | 421 | the corresponding translated code. */ |
| 419 | tb_invalidate_page(address); | 422 | tb_invalidate_page(address); |