aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2022-03-11 00:40:34 +0100
committerJavier <dev.git@javispedro.com>2022-03-11 00:40:34 +0100
commita5ae81421c666fe55bbd8c6272cc94da9acd830b (patch)
tree8e74c9701ebd27bc06f11878901d38267ea02cb3
parent97b4a5b95e0f6a3fbe2f785b95dd92663f40c8cc (diff)
downloadvbados-a5ae81421c666fe55bbd8c6272cc94da9acd830b.tar.gz
vbados-a5ae81421c666fe55bbd8c6272cc94da9acd830b.zip
fix random lock failure with paging on/vds
-rw-r--r--vbox.c25
-rw-r--r--vds.h16
2 files changed, 28 insertions, 13 deletions
diff --git a/vbox.c b/vbox.c
index 456877b..6278d6b 100644
--- a/vbox.c
+++ b/vbox.c
@@ -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
diff --git a/vds.h b/vds.h
index d09c375..c006e1d 100644
--- a/vds.h
+++ b/vds.h
@@ -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