void page_set_flags(target_ulong start, target_ulong end, int flags)
{
target_ulong addr, len;
- bool reset_target_data;
+ bool reset;
/* This function should never be called with addresses outside the
guest address space. If this assert fires, it probably indicates
if (flags & PAGE_WRITE) {
flags |= PAGE_WRITE_ORG;
}
- reset_target_data = !(flags & PAGE_VALID) || (flags & PAGE_RESET);
+ reset = !(flags & PAGE_VALID) || (flags & PAGE_RESET);
flags &= ~PAGE_RESET;
for (addr = start, len = end - start;
len -= TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
PageDesc *p = page_find_alloc(addr >> TARGET_PAGE_BITS, true);
- /* If the write protection bit is set, then we invalidate
- the code inside. */
- if (!(p->flags & PAGE_WRITE) &&
- (flags & PAGE_WRITE) &&
- p->first_tb) {
+ /*
+ * If the page was executable, but is reset, or is no longer
+ * executable, or has become writable, then invalidate any code.
+ */
+ if ((p->flags & PAGE_EXEC)
+ && (reset ||
+ !(flags & PAGE_EXEC) ||
+ (flags & ~p->flags & PAGE_WRITE))) {
tb_invalidate_phys_page(addr);
}
- if (reset_target_data) {
+ if (reset) {
g_free(p->target_data);
p->target_data = NULL;
p->flags = flags;
page_dump(stdout);
printf("\n");
#endif
- tb_invalidate_phys_range(start, start + len);
mmap_unlock();
return start;
fail:
if (ret == 0) {
page_set_flags(start, start + len, 0);
- tb_invalidate_phys_range(start, start + len);
}
mmap_unlock();
return ret;
}
page_set_flags(start, start + len, page_flags);
- tb_invalidate_phys_range(start, start + len);
ret = 0;
error:
qemu_log_unlock(f);
}
}
- tb_invalidate_phys_range(start, start + len);
mmap_unlock();
return start;
fail:
if (ret == 0) {
page_set_flags(start, start + len, 0);
- tb_invalidate_phys_range(start, start + len);
}
mmap_unlock();
return ret;
page_set_flags(new_addr, new_addr + new_size,
prot | PAGE_VALID | PAGE_RESET);
}
- tb_invalidate_phys_range(new_addr, new_addr + new_size);
mmap_unlock();
return new_addr;
}