Changeset 87169 in vbox
- Timestamp:
- Jan 4, 2021 4:54:47 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 142096
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Misc/DevVirtualKD.cpp
r82968 r87169 27 27 #include <VBox/log.h> 28 28 #include <iprt/assert.h> 29 #include <iprt/mem.h> 29 30 #include <iprt/path.h> 30 31 … … 43 44 typedef struct VKDREQUESTHDR 44 45 { 45 u nsignedcbData;46 u nsignedcbReplyMax;46 uint32_t cbData; 47 uint32_t cbReplyMax; 47 48 } VKDREQUESTHDR; 49 AssertCompileSize(VKDREQUESTHDR, 8); 48 50 49 51 #pragma pack(1) 50 52 typedef struct VKDREPLYHDR 51 53 { 52 u nsignedcbData;54 uint32_t cbData; 53 55 char chOne; 54 56 char chSpace; … … 60 62 { 61 63 public: 62 virtual unsigned OnRequest(const char *pRequestIncludingRpcHeader, unsigned RequestSizeWithRpcHeader, char **ppReply) =0;64 virtual unsigned OnRequest(const char *pRequestIncludingRpcHeader, unsigned RequestSizeWithRpcHeader, char **ppReply) = 0; 63 65 virtual ~IKDClient() {} 64 66 }; … … 72 74 RTLDRMOD hLib; 73 75 IKDClient *pKDClient; 74 char abCmdBody[_256K]; 76 char *pbCmdBody; 77 bool fFencedCmdBody; /**< Set if pbCmdBody was allocated using RTMemPageAlloc rather than RTMemAlloc. */ 75 78 } VIRTUALKD; 79 80 #define VIRTUALKB_CMDBODY_SIZE _256K /**< Size of buffer pointed to by VIRTUALKB::pbCmdBody */ 81 #define VIRTUALKB_CMDBODY_PRE_FENCE (PAGE_SIZE * 4) /**< Size of the eletrict fence before the command body. */ 82 #define VIRTUALKB_CMDBODY_POST_FENCE (PAGE_SIZE * 8) /**< Size of the eletrict fence after the command body. */ 76 83 77 84 … … 102 109 if (offPort == 1) 103 110 { 111 /* 112 * Read the request and request body. Ignore empty requests. 113 */ 104 114 RTGCPHYS GCPhys = u32; 105 VKDREQUESTHDR RequestHeader = { 0,};115 VKDREQUESTHDR RequestHeader = { 0, 0 }; 106 116 int rc = PDMDevHlpPhysRead(pDevIns, GCPhys, &RequestHeader, sizeof(RequestHeader)); 107 if ( !RT_SUCCESS(rc) 108 || !RequestHeader.cbData) 109 return VINF_SUCCESS; 110 111 unsigned cbData = RT_MIN(RequestHeader.cbData, sizeof(pThis->abCmdBody)); 112 rc = PDMDevHlpPhysRead(pDevIns, GCPhys + sizeof(RequestHeader), pThis->abCmdBody, cbData); 113 if (!RT_SUCCESS(rc)) 114 return VINF_SUCCESS; 115 116 char *pReply = NULL; 117 unsigned cbReply = pThis->pKDClient->OnRequest(pThis->abCmdBody, cbData, &pReply); 118 119 if (!pReply) 120 cbReply = 0; 121 122 /** @todo r=bird: RequestHeader.cbReplyMax is not taking into account here. */ 123 VKDREPLYHDR ReplyHeader; 124 ReplyHeader.cbData = cbReply + 2; 125 ReplyHeader.chOne = '1'; 126 ReplyHeader.chSpace = ' '; 127 rc = PDMDevHlpPhysWrite(pDevIns, GCPhys, &ReplyHeader, sizeof(ReplyHeader)); 128 if (!RT_SUCCESS(rc)) 129 return VINF_SUCCESS; 130 if (cbReply) 117 if ( RT_SUCCESS(rc) 118 && RequestHeader.cbData > 0) 131 119 { 132 rc = PDMDevHlpPhysWrite(pDevIns, GCPhys + sizeof(ReplyHeader), pReply, cbReply); 133 if (!RT_SUCCESS(rc)) 134 return VINF_SUCCESS; 120 uint32_t cbData = RT_MIN(RequestHeader.cbData, VIRTUALKB_CMDBODY_SIZE); 121 rc = PDMDevHlpPhysRead(pDevIns, GCPhys + sizeof(RequestHeader), pThis->pbCmdBody, cbData); 122 if (RT_SUCCESS(rc)) 123 { 124 /* 125 * Call the plugin module. 126 */ 127 char *pbReply = NULL; 128 unsigned cbReply; 129 try 130 { 131 cbReply = pThis->pKDClient->OnRequest(pThis->pbCmdBody, cbData, &pbReply); 132 if (!pbReply) 133 cbReply = 0; 134 } 135 catch (...) 136 { 137 LogRel(("DevVirtualKB: OnRequest threw exception. sigh.\n")); 138 cbReply = 0; 139 pbReply = NULL; 140 } 141 142 /* 143 * Write the reply to guest memory (overwriting the request): 144 */ 145 /** @todo r=bird: RequestHeader.cbReplyMax is not taken into account here! */ 146 VKDREPLYHDR ReplyHeader; 147 ReplyHeader.cbData = cbReply + 2; 148 ReplyHeader.chOne = '1'; 149 ReplyHeader.chSpace = ' '; 150 rc = PDMDevHlpPhysWrite(pDevIns, GCPhys, &ReplyHeader, sizeof(ReplyHeader)); 151 if (cbReply && RT_SUCCESS(rc)) 152 rc = PDMDevHlpPhysWrite(pDevIns, GCPhys + sizeof(ReplyHeader), pbReply, cbReply); 153 } 135 154 } 136 155 } … … 138 157 { 139 158 Assert(offPort == 0); 140 if (u32 == 0x564D5868)159 if (u32 == UINT32_C(0x564D5868) /* 'VMXh' */) 141 160 pThis->fOpenChannelDetected = true; 142 161 else … … 158 177 if (pThis->pKDClient) 159 178 { 179 /** @todo r=bird: This interface is not safe as the object doesn't overload the 180 * delete operator, thus making our runtime free it rather than that of 181 * the plug-in module IIRC. */ 160 182 delete pThis->pKDClient; 161 183 pThis->pKDClient = NULL; … … 166 188 RTLdrClose(pThis->hLib); 167 189 pThis->hLib = NIL_RTLDRMOD; 190 } 191 192 if (pThis->pbCmdBody) 193 { 194 if (pThis->fFencedCmdBody) 195 RTMemPageFree((uint8_t *)pThis->pbCmdBody - RT_ALIGN_Z(VIRTUALKB_CMDBODY_PRE_FENCE, PAGE_SIZE), 196 RT_ALIGN_Z(VIRTUALKB_CMDBODY_PRE_FENCE, PAGE_SIZE) 197 + RT_ALIGN_Z(VIRTUALKB_CMDBODY_SIZE, PAGE_SIZE) 198 + RT_ALIGN_Z(VIRTUALKB_CMDBODY_POST_FENCE, PAGE_SIZE)); 199 else 200 RTMemFree(pThis->pbCmdBody); 201 pThis->pbCmdBody = NULL; 168 202 } 169 203 … … 185 219 pThis->hLib = NIL_RTLDRMOD; 186 220 pThis->pKDClient = NULL; 187 221 pThis->pbCmdBody = NULL; 222 pThis->fFencedCmdBody = false; 188 223 189 224 PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "Path", ""); … … 197 232 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to get the \"Path\" value")); 198 233 199 rc = RTPathAppend(szPath, sizeof(szPath), HC_ARCH_BITS == 64 ? 234 rc = RTPathAppend(szPath, sizeof(szPath), HC_ARCH_BITS == 64 ? "kdclient64.dll" : "kdclient.dll"); 200 235 AssertRCReturn(rc, rc); 201 236 rc = RTLdrLoad(szPath, &pThis->hLib); … … 209 244 if (pThis->pKDClient) 210 245 { 246 /* We allocate a fenced buffer for reasons of paranoia. */ 247 uint8_t *pbCmdBody = (uint8_t *)RTMemPageAlloc( RT_ALIGN_Z(VIRTUALKB_CMDBODY_PRE_FENCE, PAGE_SIZE) 248 + RT_ALIGN_Z(VIRTUALKB_CMDBODY_SIZE, PAGE_SIZE) 249 + RT_ALIGN_Z(VIRTUALKB_CMDBODY_POST_FENCE, PAGE_SIZE)); 250 if (pbCmdBody) 251 { 252 rc = RTMemProtect(pbCmdBody, RT_ALIGN_Z(VIRTUALKB_CMDBODY_PRE_FENCE, PAGE_SIZE), RTMEM_PROT_NONE); 253 pbCmdBody += RT_ALIGN_Z(VIRTUALKB_CMDBODY_PRE_FENCE, PAGE_SIZE); 254 255 pThis->fFencedCmdBody = true; 256 pThis->pbCmdBody = (char *)pbCmdBody; 257 rc = RTMemProtect(pbCmdBody, RT_ALIGN_Z(VIRTUALKB_CMDBODY_SIZE, PAGE_SIZE), RTMEM_PROT_READ | RTMEM_PROT_WRITE); 258 AssertLogRelRC(rc); 259 pbCmdBody += RT_ALIGN_Z(VIRTUALKB_CMDBODY_SIZE, PAGE_SIZE); 260 261 rc = RTMemProtect(pbCmdBody, RT_ALIGN_Z(VIRTUALKB_CMDBODY_PRE_FENCE, PAGE_SIZE), RTMEM_PROT_NONE); 262 AssertLogRelRC(rc); 263 } 264 else 265 { 266 LogRel(("VirtualKB: RTMemPageAlloc failed, falling back on regular alloc.\n")); 267 pThis->pbCmdBody = (char *)RTMemAllocZ(VIRTUALKB_CMDBODY_SIZE); 268 AssertLogRelReturn(pThis->pbCmdBody, VERR_NO_MEMORY); 269 } 270 211 271 IOMIOPORTHANDLE hIoPorts; 212 272 rc = PDMDevHlpIoPortCreateAndMap(pDevIns, 0x5658 /*uPort*/, 2 /*cPorts*/, vkdPortWrite, vkdPortRead,
Note:
See TracChangeset
for help on using the changeset viewer.