diff options
author | Javier <dev.git@javispedro.com> | 2022-03-11 00:40:34 +0100 |
---|---|---|
committer | Javier <dev.git@javispedro.com> | 2022-03-11 00:40:34 +0100 |
commit | a5ae81421c666fe55bbd8c6272cc94da9acd830b (patch) | |
tree | 8e74c9701ebd27bc06f11878901d38267ea02cb3 | |
parent | 97b4a5b95e0f6a3fbe2f785b95dd92663f40c8cc (diff) | |
download | vbados-a5ae81421c666fe55bbd8c6272cc94da9acd830b.tar.gz vbados-a5ae81421c666fe55bbd8c6272cc94da9acd830b.zip |
fix random lock failure with paging on/vds
-rw-r--r-- | vbox.c | 25 | ||||
-rw-r--r-- | vds.h | 16 |
2 files changed, 28 insertions, 13 deletions
@@ -19,7 +19,6 @@ #include <windows.h> #include <i86.h> -#include <string.h> #include "pci.h" #include "vds.h" @@ -119,11 +118,11 @@ int vbox_init(void) /** Allocates the buffers that will be used to communicate with the VirtualBox device. */ int vbox_alloc_buffers(void) { - const unsigned int bufferSize = 48; // This should be the largest of all VMMDevRequest* structs that we can send + const unsigned int bufferSize = 36; // This should be the largest of all VMMDevRequest* structs that we can send int err; - // Allocate the buffer - hBuf = GlobalAlloc(GMEM_FIXED|GMEM_SHARE, bufferSize); + // Allocate the buffer (double the size for reasons explained below) + hBuf = GlobalAlloc(GMEM_FIXED|GMEM_SHARE, bufferSize * 2); if (!hBuf) return -1; // Keep it in memory at a fixed location @@ -132,6 +131,7 @@ int vbox_alloc_buffers(void) // Get the usable pointer / logical address of the buffer pBuf = (LPVOID) GlobalLock(hBuf); + if (!pBuf) return -1; if (vds_available()) { // Use the Virtual DMA Service to get the physical address of this buffer @@ -141,7 +141,22 @@ int vbox_alloc_buffers(void) bufdds.bufferId = 0; bufdds.physicalAddress = 0; - err = vds_lock_dma_buffer_region(&bufdds, VDS_NO_AUTO_ALLOC | VDS_NO_AUTO_REMAP); + err = vds_lock_dma_buffer_region(&bufdds, VDS_NO_AUTO_ALLOC); + if (err == VDS_REGION_NOT_CONTIGUOUS) { + // This is why we made the allocation double the required size + // If the buffer happens to be on a page boundary, + // it may not be contiguous and cause the call to fail. + // So, we try to lock the 2nd half of the allocation, + // which should not be on a page boundary. + vbox_logs("VDS try again\n"); + pBuf = (char FAR*) pBuf + bufferSize; + bufdds.regionSize = bufferSize; + bufdds.offset += bufferSize; + err = vds_lock_dma_buffer_region(&bufdds, VDS_NO_AUTO_ALLOC); + } + if (err) { + vbox_logs("VDS lock failure\n"); + } } else { bufdds.regionSize = 0; // Indicates we don't have to unlock this later on @@ -95,14 +95,14 @@ static vdserr vds_lock_dma_buffer_region(VDS_DDS __far * dds, unsigned char flag "mov ax, 0x8103" \ "int 0x4B" \ "jc fail" \ - "mov ah, 0" \ + "mov al, 0" \ "jmp end" \ - "fail: test ah, ah" \ + "fail: test al, al" \ "jnz end" \ - "mov ah, 0xFF" /* Force a error code if there was none. */ \ + "mov al, 0xFF" /* Force a error code if there was none. */ \ "end:" \ __parm [es di] [dx] \ - __value [ah] \ + __value [al] \ __modify [ax] /** Unlocks a locked buffer. */ @@ -112,14 +112,14 @@ static vdserr vds_unlock_dma_buffer_region(VDS_DDS __far * dds, unsigned char fl "mov ax, 0x8104" \ "int 0x4B" \ "jc fail" \ - "mov ah, 0" \ + "mov al, 0" \ "jmp end" \ - "fail: test ah, ah" \ + "fail: test al, al" \ "jnz end" \ - "mov ah, 0xFF" \ + "mov al, 0xFF" \ "end:" \ __parm [es di] [dx] \ - __value [ah] \ + __value [al] \ __modify [ax] #endif |