Changeset 41090 in vbox
- Timestamp:
- Apr 27, 2012 11:26:51 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 77678
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp
r41077 r41090 67 67 68 68 /** 69 * HACK ALERT! 70 * 71 * Touch the pages to force the kernel to create the page 72 * table entries. This is necessary since the kernel gets 73 * upset if we take a page fault when preemption is disabled 74 * and/or we own a simple lock. It has no problems with us 75 * disabling interrupts when taking the traps, weird stuff. 69 * Touch the pages to force the kernel to create or write-enable the page table 70 * entries. 71 * 72 * This is necessary since the kernel gets upset if we take a page fault when 73 * preemption is disabled and/or we own a simple lock (same thing). It has no 74 * problems with us disabling interrupts when taking the traps, weird stuff. 75 * 76 * (This is basically a way of invoking vm_fault on a range of pages.) 76 77 * 77 78 * @param pv Pointer to the first page. … … 84 85 { 85 86 ASMAtomicCmpXchgU32(pu32, 0xdeadbeef, 0xdeadbeef); 87 if (cb <= PAGE_SIZE) 88 break; 89 cb -= PAGE_SIZE; 90 pu32 += PAGE_SIZE / sizeof(uint32_t); 91 } 92 } 93 94 95 /** 96 * Read (sniff) every page in the range to make sure there are some page tables 97 * entries backing it. 98 * 99 * This is just to be sure vm_protect didn't remove stuff without re-adding it 100 * if someone should try write-protect something. 101 * 102 * @param pv Pointer to the first page. 103 * @param cb The number of bytes. 104 */ 105 static void rtR0MemObjDarwinSniffPages(void const *pv, size_t cb) 106 { 107 uint32_t volatile *pu32 = (uint32_t volatile *)pv; 108 uint32_t volatile u32Counter = 0; 109 for (;;) 110 { 111 u32Counter += *pu32; 112 86 113 if (cb <= PAGE_SIZE) 87 114 break; … … 508 535 } 509 536 510 #if 0/* Experimental code. */537 #if 1 /* Experimental code. */ 511 538 if (fExecutable) 512 539 { … … 514 541 # ifdef RT_STRICT 515 542 /* check that the memory is actually mapped. */ 516 //addr64_t Addr = pMemDesc->getPhysicalSegment64(0, NULL);517 //printf("rtR0MemObjNativeAllocWorker: pv=%p %8llx %8llx\n", pv, rtR0MemObjDarwinGetPTE(pv), Addr);518 543 RTTHREADPREEMPTSTATE State = RTTHREADPREEMPTSTATE_INITIALIZER; 519 544 RTThreadPreemptDisable(&State); … … 858 883 rtR0MemObjDarwinTouchPages(pv, cbSub); 859 884 /** @todo First, the memory should've been mapped by now, and second, it 860 * should have the wired attribute in the PTE (bit 9). Neither is885 * should have the wired attribute in the PTE (bit 9). Neither 861 886 * seems to be the case. The disabled locking code doesn't make any 862 887 * difference, which is extremely odd, and breaks … … 967 992 return VERR_NOT_SUPPORTED; 968 993 969 /* Convert the protection. */ 994 /* 995 * Convert the protection. 996 */ 970 997 vm_prot_t fMachProt; 971 998 switch (fProt) … … 983 1010 fMachProt = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE; 984 1011 break; 1012 case RTMEM_PROT_WRITE: 1013 fMachProt = VM_PROT_WRITE | VM_PROT_READ; /* never write-only */ 1014 break; 985 1015 case RTMEM_PROT_WRITE | RTMEM_PROT_EXEC: 986 fMachProt = VM_PROT_WRITE | VM_PROT_EXECUTE ;1016 fMachProt = VM_PROT_WRITE | VM_PROT_EXECUTE | VM_PROT_READ; /* never write-only or execute-only */ 987 1017 break; 988 1018 case RTMEM_PROT_EXEC: 989 fMachProt = VM_PROT_EXECUTE ;1019 fMachProt = VM_PROT_EXECUTE | VM_PROT_READ; /* never execute-only */ 990 1020 break; 991 1021 default: … … 993 1023 } 994 1024 995 /* do the job. */ 1025 /* 1026 * Do the job. 1027 */ 996 1028 vm_offset_t Start = (uintptr_t)pMem->pv + offSub; 997 1029 kern_return_t krc = vm_protect(pVmMap, … … 1002 1034 if (krc != KERN_SUCCESS) 1003 1035 return RTErrConvertFromDarwinKern(krc); 1036 1037 /* 1038 * Touch the pages if they should be writable afterwards and accessible 1039 * from code which should never fault. vm_protect() may leave pages 1040 * temporarily write protected, possibly due to pmap no-upgrade rules? 1041 * 1042 * This is the same trick (or HACK ALERT if you like) as applied in 1043 * rtR0MemObjNativeMapKernel. 1044 */ 1045 if ( pMem->enmType != RTR0MEMOBJTYPE_MAPPING 1046 || pMem->u.Mapping.R0Process == NIL_RTR0PROCESS) 1047 { 1048 if (fProt & RTMEM_PROT_WRITE) 1049 rtR0MemObjDarwinTouchPages((void *)Start, cbSub); 1050 /* 1051 * Sniff (read) read-only pages too, just to be sure. 1052 */ 1053 else if (fProt & (RTMEM_PROT_READ | RTMEM_PROT_EXEC)) 1054 rtR0MemObjDarwinSniffPages((void const *)Start, cbSub); 1055 } 1056 1004 1057 return VINF_SUCCESS; 1005 1058 }
Note:
See TracChangeset
for help on using the changeset viewer.