[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 3/6] Fix last page errors in page_set_flags and page
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 3/6] Fix last page errors in page_set_flags and page_check_range. |
Date: |
Thu, 11 Feb 2010 14:57:35 -0800 |
The addr < end comparison prevents the last page from being
iterated; an iteration based on length avoids this problem.
---
exec.c | 54 +++++++++++++++++++++++++++---------------------------
1 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/exec.c b/exec.c
index 766568b..ebbe6d0 100644
--- a/exec.c
+++ b/exec.c
@@ -2222,35 +2222,31 @@ void page_dump(FILE *f)
int page_get_flags(target_ulong address)
{
- PageDesc *p;
-
- p = page_find(address >> TARGET_PAGE_BITS);
- if (!p)
- return 0;
- return p->flags;
+ PageDesc *p = page_find(address >> TARGET_PAGE_BITS);
+ return p ? p->flags : 0;
}
-/* modify the flags of a page and invalidate the code if
- necessary. The flag PAGE_WRITE_ORG is positioned automatically
- depending on PAGE_WRITE */
+/* Modify the flags of a page and invalidate the code if necessary.
+ The flag PAGE_WRITE_ORG is positioned automatically depending
+ on PAGE_WRITE. The mmap_lock should already be held. */
void page_set_flags(target_ulong start, target_ulong end, int flags)
{
- PageDesc *p;
- target_ulong addr;
+ target_ulong addr, len;
- /* mmap_lock should already be held. */
start = start & TARGET_PAGE_MASK;
end = TARGET_PAGE_ALIGN(end);
- if (flags & PAGE_WRITE)
+
+ if (flags & PAGE_WRITE) {
flags |= PAGE_WRITE_ORG;
- for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
- p = page_find_alloc(addr >> TARGET_PAGE_BITS);
- /* We may be called for host regions that are outside guest
- address space. */
- if (!p)
- return;
- /* if the write protection is set, then we invalidate the code
- inside */
+ }
+
+ for (addr = start, len = end - start;
+ len != 0;
+ len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
+ PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, 1);
+
+ /* If the write protection bit is set, then we invalidate
+ the code inside. */
if (!(p->flags & PAGE_WRITE) &&
(flags & PAGE_WRITE) &&
p->first_tb) {
@@ -2266,18 +2262,22 @@ int page_check_range(target_ulong start, target_ulong
len, int flags)
target_ulong end;
target_ulong addr;
- if (start + len < start)
- /* we've wrapped around */
+ if (start + len - 1 < start) {
+ /* We've wrapped around. */
return -1;
+ }
- end = TARGET_PAGE_ALIGN(start+len); /* must do before we loose bits in the
next step */
+ /* END must be computed before we drop bits from START. */
+ end = TARGET_PAGE_ALIGN(start + len);
start = start & TARGET_PAGE_MASK;
- for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) {
+ for (addr = start, len = end - start;
+ len != 0;
+ len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
p = page_find(addr >> TARGET_PAGE_BITS);
- if( !p )
+ if (!p)
return -1;
- if( !(p->flags & PAGE_VALID) )
+ if (!(p->flags & PAGE_VALID))
return -1;
if ((flags & PAGE_READ) && !(p->flags & PAGE_READ))
--
1.6.6
- [Qemu-devel] [PATCH 0/6] Multi-level page tables and userland mapping fixes., Richard Henderson, 2010/02/11
- [Qemu-devel] [PATCH 3/6] Fix last page errors in page_set_flags and page_check_range.,
Richard Henderson <=
- [Qemu-devel] [PATCH 4/6] Implement multi-level page tables., Richard Henderson, 2010/02/11
- [Qemu-devel] [PATCH 2/6] Use TARGET_VIRT_ADDR_SPACE_BITS in h2g_valid., Richard Henderson, 2010/02/11
- [Qemu-devel] [PATCH 1/6] Move TARGET_PHYS_ADDR_SPACE_BITS to target-*/cpu.h., Richard Henderson, 2010/02/11
- [Qemu-devel] [PATCH 6/6] linux-user: Fix mmap_find_vma returning invalid addresses., Richard Henderson, 2010/02/11
- [Qemu-devel] [PATCH 5/6] linux-user: Use h2g_valid in qemu_vmalloc., Richard Henderson, 2010/02/11