Changeset 47429 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jul 26, 2013 5:12:55 PM (12 years ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r47427 r47429 710 710 static VBOXSTRICTRC iemMemFetchDataU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem); 711 711 static VBOXSTRICTRC iemMemFetchDataU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem); 712 static VBOXSTRICTRC iemMemFetchSysU8(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem); 713 static VBOXSTRICTRC iemMemFetchSysU16(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem); 712 714 static VBOXSTRICTRC iemMemFetchSysU32(PIEMCPU pIemCpu, uint32_t *pu32Dst, uint8_t iSegReg, RTGCPTR GCPtrMem); 713 715 static VBOXSTRICTRC iemMemFetchSysU64(PIEMCPU pIemCpu, uint64_t *pu64Dst, uint8_t iSegReg, RTGCPTR GCPtrMem); … … 6637 6639 { 6638 6640 return iemMemCommitAndUnmap(pIemCpu, (void *)pvMem, IEM_ACCESS_STACK_R); 6641 } 6642 6643 6644 /** 6645 * Fetches a system table byte. 6646 * 6647 * @returns Strict VBox status code. 6648 * @param pIemCpu The IEM per CPU data. 6649 * @param pbDst Where to return the byte. 6650 * @param iSegReg The index of the segment register to use for 6651 * this access. The base and limits are checked. 6652 * @param GCPtrMem The address of the guest memory. 6653 */ 6654 static VBOXSTRICTRC iemMemFetchSysU8(PIEMCPU pIemCpu, uint8_t *pbDst, uint8_t iSegReg, RTGCPTR GCPtrMem) 6655 { 6656 /* The lazy approach for now... */ 6657 uint8_t const *pbSrc; 6658 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pbSrc, sizeof(*pbSrc), iSegReg, GCPtrMem, IEM_ACCESS_SYS_R); 6659 if (rc == VINF_SUCCESS) 6660 { 6661 *pbDst = *pbSrc; 6662 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pbSrc, IEM_ACCESS_SYS_R); 6663 } 6664 return rc; 6665 } 6666 6667 6668 /** 6669 * Fetches a system table word. 6670 * 6671 * @returns Strict VBox status code. 6672 * @param pIemCpu The IEM per CPU data. 6673 * @param pu16Dst Where to return the word. 6674 * @param iSegReg The index of the segment register to use for 6675 * this access. The base and limits are checked. 6676 * @param GCPtrMem The address of the guest memory. 6677 */ 6678 static VBOXSTRICTRC iemMemFetchSysU16(PIEMCPU pIemCpu, uint16_t *pu16Dst, uint8_t iSegReg, RTGCPTR GCPtrMem) 6679 { 6680 /* The lazy approach for now... */ 6681 uint16_t const *pu16Src; 6682 VBOXSTRICTRC rc = iemMemMap(pIemCpu, (void **)&pu16Src, sizeof(*pu16Src), iSegReg, GCPtrMem, IEM_ACCESS_SYS_R); 6683 if (rc == VINF_SUCCESS) 6684 { 6685 *pu16Dst = *pu16Src; 6686 rc = iemMemCommitAndUnmap(pIemCpu, (void *)pu16Src, IEM_ACCESS_SYS_R); 6687 } 6688 return rc; 6639 6689 } 6640 6690 -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r47379 r47429 21 21 */ 22 22 23 24 /** 25 * Worker function for iemHlpCheckPortIOPermission, don't call directly. 26 * 27 * @returns Strict VBox status code. 28 * 29 * @param pIemCpu The IEM per CPU data. 30 * @param pCtx The register context. 31 * @param u16Port The port number. 32 * @param cbOperand The operand size. 33 */ 34 static VBOXSTRICTRC iemHlpCheckPortIOPermissionBitmap(PIEMCPU pIemCpu, PCCPUMCTX pCtx, uint16_t u16Port, uint8_t cbOperand) 35 { 36 /* The TSS bits we're interested in are the same on 386 and AMD64. */ 37 AssertCompile(AMD64_SEL_TYPE_SYS_TSS_BUSY == X86_SEL_TYPE_SYS_386_TSS_BUSY); 38 AssertCompile(AMD64_SEL_TYPE_SYS_TSS_AVAIL == X86_SEL_TYPE_SYS_386_TSS_AVAIL); 39 AssertCompileMembersAtSameOffset(X86TSS32, offIoBitmap, X86TSS64, offIoBitmap); 40 AssertCompile(sizeof(X86TSS32) == sizeof(X86TSS64)); 41 42 /* 43 * Check the TSS type, 16-bit TSSes doesn't have any I/O permission bitmap. 44 */ 45 Assert(!pCtx->tr.Attr.n.u1DescType); 46 if (RT_UNLIKELY( pCtx->tr.Attr.n.u4Type != AMD64_SEL_TYPE_SYS_TSS_BUSY 47 && pCtx->tr.Attr.n.u4Type != AMD64_SEL_TYPE_SYS_TSS_AVAIL)) 48 { 49 Log(("iomInterpretCheckPortIOAccess: Port=%#x cb=%d - TSS type %#x (attr=%#x) has no I/O bitmap -> #GP(0)\n", 50 u16Port, cbOperand, pCtx->tr.Attr.n.u4Type, pCtx->tr.Attr.u)); 51 return iemRaiseGeneralProtectionFault0(pIemCpu); 52 } 53 54 /* 55 * Read the bitmap offset (may #PF). 56 */ 57 uint16_t offBitmap; 58 VBOXSTRICTRC rcStrict = iemMemFetchSysU16(pIemCpu, &offBitmap, UINT8_MAX, 59 pCtx->tr.u64Base + RT_OFFSETOF(X86TSS64, offIoBitmap)); 60 if (rcStrict != VINF_SUCCESS) 61 { 62 Log(("iomInterpretCheckPortIOAccess: Error reading offIoBitmap (%Rrc)\n", VBOXSTRICTRC_VAL(rcStrict))); 63 return rcStrict; 64 } 65 66 /* 67 * The bit range from u16Port to (u16Port + cbOperand - 1), however intel 68 * describes the CPU actually reading two bytes regardless of whether the 69 * bit range crosses a byte boundrary. Thus the + 1 in the test below. 70 */ 71 uint32_t offFirstBit = (uint32_t)u16Port / 8 + offBitmap; 72 /** @todo check if real CPUs ensures that offBitmap has a minimum value of 73 * for instance sizeof(X86TSS32). */ 74 if (offFirstBit + 1 > pCtx->tr.u32Limit) /* the limit is inclusive */ 75 { 76 Log(("iomInterpretCheckPortIOAccess: offFirstBit=%#x + 1 is beyond u32Limit=%#x -> #GP(0)\n", 77 offFirstBit, pCtx->tr.u32Limit)); 78 return iemRaiseGeneralProtectionFault0(pIemCpu); 79 } 80 81 /* 82 * Read the necessary bits. 83 */ 84 /** @todo Test the assertion in the intel manual that the CPU reads two 85 * bytes. The question is how this works wrt to #PF and #GP on the 86 * 2nd byte when it's not required. */ 87 uint16_t bmBytes = UINT16_MAX; 88 rcStrict = iemMemFetchSysU16(pIemCpu, &bmBytes, UINT8_MAX, pCtx->tr.u64Base + offFirstBit); 89 if (rcStrict != VINF_SUCCESS) 90 { 91 Log(("iomInterpretCheckPortIOAccess: Error reading I/O bitmap @%#x (%Rrc)\n", offFirstBit, VBOXSTRICTRC_VAL(rcStrict))); 92 return rcStrict; 93 } 94 95 /* 96 * Perform the check. 97 */ 98 uint16_t fPortMask = (1 << cbOperand) - 1; 99 bmBytes >>= (u16Port & 7); 100 if (bmBytes & fPortMask) 101 { 102 Log(("iomInterpretCheckPortIOAccess: u16Port=%#x LB %u - access denied (bm=%#x mask=%#x) -> #GP(0)\n", 103 u16Port, cbOperand, bmBytes, fPortMask)); 104 return iemRaiseGeneralProtectionFault0(pIemCpu); 105 } 106 107 return VINF_SUCCESS; 108 } 109 110 23 111 /** 24 112 * Checks if we are allowed to access the given I/O port, raising the … … 40 128 && ( pIemCpu->uCpl > Efl.Bits.u2IOPL 41 129 || Efl.Bits.u1VM) ) 42 { 43 NOREF(u16Port); NOREF(cbOperand); /** @todo I/O port permission bitmap check */ 44 IEM_RETURN_ASPECT_NOT_IMPLEMENTED_LOG(("Implement I/O permission bitmap\n")); 45 } 130 return iemHlpCheckPortIOPermissionBitmap(pIemCpu, pCtx, u16Port, cbOperand); 46 131 return VINF_SUCCESS; 47 132 }
Note:
See TracChangeset
for help on using the changeset viewer.