Commit dae3270c6e25062b9085da0756b68fafedc9bb2c
1 parent
9b0b8203
suppressed page_unprotect_range() - fixed access_ok()
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3641 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
17 additions
and
23 deletions
cpu-all.h
... | ... | @@ -690,7 +690,6 @@ extern unsigned long qemu_host_page_mask; |
690 | 690 | void page_dump(FILE *f); |
691 | 691 | int page_get_flags(target_ulong address); |
692 | 692 | void page_set_flags(target_ulong start, target_ulong end, int flags); |
693 | -void page_unprotect_range(target_ulong data, target_ulong data_size); | |
694 | 693 | int page_check_range(target_ulong start, target_ulong len, int flags); |
695 | 694 | |
696 | 695 | CPUState *cpu_copy(CPUState *env); | ... | ... |
exec.c
... | ... | @@ -1894,10 +1894,19 @@ int page_check_range(target_ulong start, target_ulong len, int flags) |
1894 | 1894 | if( !(p->flags & PAGE_VALID) ) |
1895 | 1895 | return -1; |
1896 | 1896 | |
1897 | - if (!(p->flags & PAGE_READ) && (flags & PAGE_READ) ) | |
1898 | - return -1; | |
1899 | - if (!(p->flags & PAGE_WRITE) && (flags & PAGE_WRITE) ) | |
1897 | + if ((flags & PAGE_READ) && !(p->flags & PAGE_READ)) | |
1900 | 1898 | return -1; |
1899 | + if (flags & PAGE_WRITE) { | |
1900 | + if (!(p->flags & PAGE_WRITE_ORG)) | |
1901 | + return -1; | |
1902 | + /* unprotect the page if it was put read-only because it | |
1903 | + contains translated code */ | |
1904 | + if (!(p->flags & PAGE_WRITE)) { | |
1905 | + if (!page_unprotect(addr, 0, NULL)) | |
1906 | + return -1; | |
1907 | + } | |
1908 | + return 0; | |
1909 | + } | |
1901 | 1910 | } |
1902 | 1911 | return 0; |
1903 | 1912 | } |
... | ... | @@ -1942,21 +1951,6 @@ int page_unprotect(target_ulong address, unsigned long pc, void *puc) |
1942 | 1951 | return 0; |
1943 | 1952 | } |
1944 | 1953 | |
1945 | -/* call this function when system calls directly modify a memory area */ | |
1946 | -/* ??? This should be redundant now we have lock_user. */ | |
1947 | -void page_unprotect_range(target_ulong data, target_ulong data_size) | |
1948 | -{ | |
1949 | - target_ulong start, end, addr; | |
1950 | - | |
1951 | - start = data; | |
1952 | - end = start + data_size; | |
1953 | - start &= TARGET_PAGE_MASK; | |
1954 | - end = TARGET_PAGE_ALIGN(end); | |
1955 | - for(addr = start; addr < end; addr += TARGET_PAGE_SIZE) { | |
1956 | - page_unprotect(addr, 0, NULL); | |
1957 | - } | |
1958 | -} | |
1959 | - | |
1960 | 1954 | static inline void tlb_set_dirty(CPUState *env, |
1961 | 1955 | unsigned long addr, target_ulong vaddr) |
1962 | 1956 | { | ... | ... |
linux-user/qemu.h
... | ... | @@ -207,8 +207,11 @@ int target_msync(abi_ulong start, abi_ulong len, int flags); |
207 | 207 | #define VERIFY_READ 0 |
208 | 208 | #define VERIFY_WRITE 1 /* implies read access */ |
209 | 209 | |
210 | -#define access_ok(type,addr,size) \ | |
211 | - (page_check_range((target_ulong)addr,size,(type==VERIFY_READ)?PAGE_READ:PAGE_WRITE)==0) | |
210 | +static inline int access_ok(int type, abi_ulong addr, abi_ulong size) | |
211 | +{ | |
212 | + return page_check_range((target_ulong)addr, size, | |
213 | + (type == VERIFY_READ) ? PAGE_READ : (PAGE_READ | PAGE_WRITE)) == 0; | |
214 | +} | |
212 | 215 | |
213 | 216 | /* NOTE __get_user and __put_user use host pointers and don't check access. */ |
214 | 217 | /* These are usually used to access struct data members once the | ... | ... |
linux-user/syscall.c
... | ... | @@ -2773,7 +2773,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
2773 | 2773 | ret = 0; /* avoid warning */ |
2774 | 2774 | break; |
2775 | 2775 | case TARGET_NR_read: |
2776 | - page_unprotect_range(arg2, arg3); | |
2777 | 2776 | if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) |
2778 | 2777 | goto efault; |
2779 | 2778 | ret = get_errno(read(arg1, p, arg3)); |
... | ... | @@ -4537,7 +4536,6 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, |
4537 | 4536 | break; |
4538 | 4537 | #ifdef TARGET_NR_pread |
4539 | 4538 | case TARGET_NR_pread: |
4540 | - page_unprotect_range(arg2, arg3); | |
4541 | 4539 | if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) |
4542 | 4540 | goto efault; |
4543 | 4541 | ret = get_errno(pread(arg1, p, arg3, arg4)); | ... | ... |