Fixed a very bad flaw in mem.c which was causing lookup arrays for memory above 1 MB but below 2 MB to point to a bogus area of memory, also fixes 64-bit 86Box.
This commit is contained in:
@@ -80,7 +80,8 @@ page_t *pages, /* RAM page table */
|
||||
**page_lookup; /* pagetable lookup */
|
||||
uint32_t pages_sz; /* #pages in table */
|
||||
|
||||
uint8_t *ram, *ram2; /* the virtual RAM */
|
||||
uint8_t *low_ram,
|
||||
*ram, *ram2; /* the virtual RAM */
|
||||
uint8_t page_ff[4096];
|
||||
uint32_t rammask;
|
||||
|
||||
@@ -588,10 +589,12 @@ addreadlookup(uint32_t virt, uint32_t phys)
|
||||
if (readlookup[readlnext] != (int) 0xffffffff)
|
||||
readlookup2[readlookup[readlnext]] = LOOKUP_INV;
|
||||
|
||||
a = (uintptr_t)(phys & ~0xfff) - (uintptr_t)(virt & ~0xfff);
|
||||
a = (uint32_t)(phys & ~0xfff) - (uint32_t)(virt & ~0xfff);
|
||||
|
||||
if ((phys & ~0xfff) >= (1 << 30))
|
||||
readlookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)];
|
||||
else if (a >= 0xfff00000)
|
||||
readlookup2[virt>>12] = (uintptr_t)&low_ram[a & 0x000fffff];
|
||||
else
|
||||
readlookup2[virt>>12] = (uintptr_t)&ram[a];
|
||||
|
||||
@@ -632,10 +635,12 @@ addwritelookup(uint32_t virt, uint32_t phys)
|
||||
#endif
|
||||
page_lookup[virt >> 12] = &pages[phys >> 12];
|
||||
else {
|
||||
a = (uintptr_t)(phys & ~0xfff) - (uintptr_t)(virt & ~0xfff);
|
||||
a = (uint32_t)(phys & ~0xfff) - (uint32_t)(virt & ~0xfff);
|
||||
|
||||
if ((phys & ~0xfff) >= (1 << 30))
|
||||
writelookup2[virt>>12] = (uintptr_t)&ram2[a - (1 << 30)];
|
||||
else if (a >= 0xfff00000)
|
||||
writelookup2[virt>>12] = (uintptr_t)&low_ram[a & 0x000fffff];
|
||||
else
|
||||
writelookup2[virt>>12] = (uintptr_t)&ram[a];
|
||||
}
|
||||
@@ -2526,26 +2531,36 @@ mem_reset(void)
|
||||
memset(page_ff, 0xff, sizeof(page_ff));
|
||||
|
||||
m = 1024UL * mem_size;
|
||||
if (ram != NULL) {
|
||||
free(ram);
|
||||
ram = NULL;
|
||||
if (low_ram != NULL) {
|
||||
free(low_ram);
|
||||
low_ram = NULL;
|
||||
}
|
||||
#if (defined __amd64__ || defined _M_X64)
|
||||
if (ram2 != NULL) {
|
||||
free(ram2);
|
||||
ram2 = NULL;
|
||||
}
|
||||
#endif
|
||||
if (mem_size > 2097152)
|
||||
fatal("Attempting to use more than 2 GB of guest RAM\n");
|
||||
|
||||
#if (defined __amd64__ || defined _M_X64)
|
||||
if (mem_size > 1048576) {
|
||||
ram = (uint8_t *)malloc(1 << 30); /* allocate and clear the RAM block of the first 1 GB */
|
||||
memset(ram, 0x00, 1 << 30);
|
||||
low_ram = (uint8_t *)malloc((1 << 30) + (1 << 10)); /* allocate and clear the RAM block of the first 1 GB */
|
||||
memset(low_ram, 0x00, (1 << 30) + (1 << 10));
|
||||
ram2 = (uint8_t *)malloc(m - (1 << 30)); /* allocate and clear the RAM block above 1 GB */
|
||||
memset(ram2, 0x00, m - (1 << 30));
|
||||
} else {
|
||||
ram = (uint8_t *)malloc(m); /* allocate and clear the RAM block */
|
||||
memset(ram, 0x00, m);
|
||||
low_ram = (uint8_t *)malloc(m + (1 << 10)); /* allocate and clear the RAM block */
|
||||
memset(low_ram, 0x00, m + (1 << 10));
|
||||
}
|
||||
#else
|
||||
low_ram = (uint8_t *)malloc(m + (1 << 10)); /* allocate and clear the RAM block */
|
||||
memset(low_ram, 0x00, m + (1 << 10));
|
||||
if (mem_size > 1048576)
|
||||
ram2 = &(low_ram[(1 << 30) + (1 << 10)]);
|
||||
#endif
|
||||
ram = &(low_ram[1 << 10]);
|
||||
|
||||
/*
|
||||
* Allocate the page table based on how much RAM we have.
|
||||
@@ -2758,6 +2773,7 @@ void
|
||||
mem_init(void)
|
||||
{
|
||||
/* Perform a one-time init. */
|
||||
low_ram = NULL;
|
||||
ram = rom = NULL;
|
||||
ram2 = NULL;
|
||||
pages = NULL;
|
||||
|
Reference in New Issue
Block a user