diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index b12bec3f55..aee332c1a0 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -61,6 +61,11 @@ #include "migration/misc.h" #include "sysemu/numa.h" +#ifdef QEMU_NYX +#include "nyx/state/state.h" +#include "nyx/mem_split.h" +#endif + #define MAX_IDE_BUS 2 #ifdef CONFIG_IDE_ISA @@ -147,9 +152,15 @@ static void pc_init1(MachineState *machine, if (machine->ram_size >= lowmem) { x86ms->above_4g_mem_size = machine->ram_size - lowmem; x86ms->below_4g_mem_size = lowmem; +#ifdef QEMU_NYX + GET_GLOBAL_STATE()->mem_mapping_type = PC_PIIX_MEM_TYPE; +#endif } else { x86ms->above_4g_mem_size = 0; x86ms->below_4g_mem_size = machine->ram_size; +#ifdef QEMU_NYX + GET_GLOBAL_STATE()->mem_mapping_type = PC_PIIX_MEM_LOW_TYPE; +#endif } } diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index e2c5a9bc6a..93e6a2aa03 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -53,6 +53,11 @@ #include "qapi/error.h" #include "qemu/error-report.h" #include "sysemu/numa.h" +#ifdef QEMU_NYX +#include "nyx/state/state.h" +#include "nyx/mem_split.h" + +#endif /* ICH9 AHCI has 6 ports */ #define MAX_SATA_PORTS 6 @@ -145,8 +150,14 @@ static void pc_q35_init(MachineState *machine) */ if (machine->ram_size >= 0xb0000000) { lowmem = 0x80000000; +#ifdef QEMU_NYX + GET_GLOBAL_STATE()->mem_mapping_type = Q35_MEM_MEM_TYPE; +#endif } else { lowmem = 0xb0000000; +#ifdef QEMU_NYX + GET_GLOBAL_STATE()->mem_mapping_type = Q35_MEM_MEM_LOW_TYPE; +#endif } /* Handle the machine opt max-ram-below-4g. It is basically doing diff --git a/nyx/Makefile.objs b/nyx/Makefile.objs index 93db8e07bb..bf485bbe0a 100644 --- a/nyx/Makefile.objs +++ b/nyx/Makefile.objs @@ -33,5 +33,6 @@ hypercall/configuration.o \ hypercall/debug.o \ state/state.o \ state/snapshot_state.o \ -pt.o +pt.o \ +mem_split.o diff --git a/nyx/hypercall/debug.c b/nyx/hypercall/debug.c index b656421488..73f7e856fb 100644 --- a/nyx/hypercall/debug.c +++ b/nyx/hypercall/debug.c @@ -6,6 +6,7 @@ #include "nyx/fast_vm_reload.h" #include "nyx/hypercall/debug.h" +#include "nyx/mem_split.h" #include "nyx/memory_access.h" #include "nyx/state/state.h" #include "nyx/synchronization.h" diff --git a/nyx/mem_split.c b/nyx/mem_split.c new file mode 100644 index 0000000000..ea8dd4a810 --- /dev/null +++ b/nyx/mem_split.c @@ -0,0 +1,85 @@ +#include "qemu/osdep.h" +#include "nyx/state/state.h" +#include "nyx/mem_split.h" + +#define PC_PIIX_LOW_MEM_SPLIT_START 0xe0000000 + +#define PC_PIIX_MEM_SPLIT_START 0x0C0000000 +#define PC_PIXX_MEM_SPLIT_END 0x100000000 + +#define Q35_MEM_SPLIT_START 0x080000000 +#define Q35_MEM_SPLIT_END 0x100000000 + +#define Q35_LOW_MEM_SPLIT_START 0x0b0000000 + +bool is_mem_mapping_supported(MemSplitType type){ + return type == PC_PIIX_MEM_LOW_TYPE || type == PC_PIIX_MEM_TYPE || type == Q35_MEM_MEM_LOW_TYPE || type == Q35_MEM_MEM_TYPE; +} + +uint64_t get_mem_split_start(void){ + switch(GET_GLOBAL_STATE()->mem_mapping_type){ + case PC_PIIX_MEM_LOW_TYPE: + return PC_PIIX_LOW_MEM_SPLIT_START; + case PC_PIIX_MEM_TYPE: + return PC_PIIX_MEM_SPLIT_START; + case Q35_MEM_MEM_LOW_TYPE: + return Q35_LOW_MEM_SPLIT_START; + case Q35_MEM_MEM_TYPE: + return Q35_MEM_SPLIT_START; + default: + abort(); + } +} + +uint64_t get_mem_split_end(void){ + switch(GET_GLOBAL_STATE()->mem_mapping_type){ + case PC_PIIX_MEM_TYPE: + return PC_PIXX_MEM_SPLIT_END; + case Q35_MEM_MEM_TYPE: + return Q35_MEM_SPLIT_END; + default: + abort(); + } +} + +uint64_t address_to_ram_offset(uint64_t offset){ + switch(GET_GLOBAL_STATE()->mem_mapping_type){ + case PC_PIIX_MEM_LOW_TYPE: + if(offset >= PC_PIIX_LOW_MEM_SPLIT_START){ + abort(); + } + return offset; + case PC_PIIX_MEM_TYPE: + return offset >= PC_PIXX_MEM_SPLIT_END ? (offset - PC_PIXX_MEM_SPLIT_END) + PC_PIIX_MEM_SPLIT_START : offset; + case Q35_MEM_MEM_TYPE: + return offset >= Q35_MEM_SPLIT_END ? (offset - Q35_MEM_SPLIT_END) + Q35_MEM_SPLIT_START : offset; + case Q35_MEM_MEM_LOW_TYPE: + if(offset >= Q35_LOW_MEM_SPLIT_START){ + abort(); + } + return offset; + default: + abort(); + } +} + +uint64_t ram_offset_to_address(uint64_t offset){ + switch(GET_GLOBAL_STATE()->mem_mapping_type){ + case PC_PIIX_MEM_LOW_TYPE: + if(offset >= PC_PIIX_LOW_MEM_SPLIT_START){ + abort(); + } + return offset; + case PC_PIIX_MEM_TYPE: + return offset >= PC_PIIX_MEM_SPLIT_START ? (offset - PC_PIIX_MEM_SPLIT_START) + PC_PIXX_MEM_SPLIT_END : offset;; + case Q35_MEM_MEM_TYPE: + return offset >= Q35_MEM_SPLIT_START ? (offset - Q35_MEM_SPLIT_START) + Q35_MEM_SPLIT_END : offset; + case Q35_MEM_MEM_LOW_TYPE: + if(offset >= Q35_LOW_MEM_SPLIT_START){ + abort(); + } + return offset; + default: + abort(); + } +} diff --git a/nyx/mem_split.h b/nyx/mem_split.h new file mode 100644 index 0000000000..12b933c5ae --- /dev/null +++ b/nyx/mem_split.h @@ -0,0 +1,21 @@ +#pragma once + +#include "nyx/types.h" +#include "stdlib.h" +#include "stdint.h" + +typedef enum MemSplitType { + MEM_SPLIT_TYPE_INVALID, + PC_PIIX_MEM_LOW_TYPE, + PC_PIIX_MEM_TYPE, + Q35_MEM_MEM_LOW_TYPE, + Q35_MEM_MEM_TYPE, +} MemSplitType; + + +bool is_mem_mapping_supported(MemSplitType type); +uint64_t get_mem_split_start(void); +uint64_t get_mem_split_end(void); + +uint64_t address_to_ram_offset(uint64_t offset); +uint64_t ram_offset_to_address(uint64_t offset); diff --git a/nyx/memory_access.c b/nyx/memory_access.c index 8837cd52f2..a54e619cac 100644 --- a/nyx/memory_access.c +++ b/nyx/memory_access.c @@ -34,6 +34,7 @@ along with QEMU-PT. If not, see . #include "nyx/helpers.h" #include "nyx/hypercall/hypercall.h" #include "nyx/state/state.h" +#include "nyx/mem_split.h" #define INVALID_ADDRESS 0xFFFFFFFFFFFFFFFFULL diff --git a/nyx/memory_access.h b/nyx/memory_access.h index 934a2191eb..7354a3b023 100644 --- a/nyx/memory_access.h +++ b/nyx/memory_access.h @@ -27,14 +27,6 @@ along with QEMU-PT. If not, see . #include "nyx/types.h" #include -#define MEM_SPLIT_START 0x0C0000000 -#define MEM_SPLIT_END 0x100000000 - -/* i386 pc_piix low_mem address translation */ -#define address_to_ram_offset(offset) \ - (offset >= MEM_SPLIT_END ? (offset - MEM_SPLIT_END) + MEM_SPLIT_START : offset) -#define ram_offset_to_address(offset) \ - (offset >= MEM_SPLIT_START ? (offset - MEM_SPLIT_START) + MEM_SPLIT_END : offset) mem_mode_t get_current_mem_mode(CPUState *cpu); diff --git a/nyx/snapshot/memory/block_list.c b/nyx/snapshot/memory/block_list.c index 6746d519ce..10050fd242 100644 --- a/nyx/snapshot/memory/block_list.c +++ b/nyx/snapshot/memory/block_list.c @@ -11,6 +11,7 @@ #include "nyx/snapshot/helper.h" #include "nyx/snapshot/memory/block_list.h" #include "nyx/snapshot/memory/shadow_memory.h" +#include "nyx/mem_split.h" #define REALLOC_SIZE 0x8000 @@ -25,16 +26,16 @@ snapshot_page_blocklist_t *snapshot_page_blocklist_init(void) snapshot_page_blocklist_t *self = malloc(sizeof(snapshot_page_blocklist_t)); uint64_t ram_size = get_ram_size(); - self->phys_area_size = ram_size <= MEM_SPLIT_START ? + self->phys_area_size = ram_size <= get_mem_split_start() ? ram_size : - ram_size + (MEM_SPLIT_END - MEM_SPLIT_START); + ram_size + (get_mem_split_end() - get_mem_split_start()); self->phys_bitmap = malloc(BITMAP_SIZE(self->phys_area_size)); memset(self->phys_bitmap, 0x0, BITMAP_SIZE(self->phys_area_size)); - if (ram_size > MEM_SPLIT_START) { - memset(self->phys_bitmap + BITMAP_SIZE(MEM_SPLIT_START), 0xff, - BITMAP_SIZE((MEM_SPLIT_END - MEM_SPLIT_START))); + if (ram_size > get_mem_split_start()) { + memset(self->phys_bitmap + BITMAP_SIZE(get_mem_split_start()), 0xff, + BITMAP_SIZE((get_mem_split_end() - get_mem_split_start()))); } self->pages_num = 0; diff --git a/nyx/snapshot/memory/nyx_fdl_user.c b/nyx/snapshot/memory/nyx_fdl_user.c index 2f721c9338..9b438022af 100644 --- a/nyx/snapshot/memory/nyx_fdl_user.c +++ b/nyx/snapshot/memory/nyx_fdl_user.c @@ -13,6 +13,7 @@ #include "nyx/snapshot/helper.h" #include "nyx/snapshot/memory/nyx_fdl_user.h" #include "nyx/snapshot/memory/shadow_memory.h" +#include "nyx/mem_split.h" /* debug option */ // #define DEBUG_USER_FDL diff --git a/nyx/snapshot/memory/shadow_memory.c b/nyx/snapshot/memory/shadow_memory.c index 7efd9ee61a..e1e4614657 100644 --- a/nyx/snapshot/memory/shadow_memory.c +++ b/nyx/snapshot/memory/shadow_memory.c @@ -13,6 +13,7 @@ #include "nyx/snapshot/helper.h" #include "nyx/snapshot/memory/shadow_memory.h" +#include "nyx/mem_split.h" typedef struct fast_reload_dump_head_s { uint32_t shadow_memory_regions; @@ -95,10 +96,10 @@ shadow_memory_t *shadow_memory_init(void) for (uint8_t i = 0; i < regions_num; i++) { block = block_array[i]; if (!block->mr->readonly) { - if (self->ram_regions_num == 0 && block->used_length >= MEM_SPLIT_START) { + if (self->ram_regions_num == 0 && block->used_length >= get_mem_split_start()) { self->ram_regions[self->ram_regions_num].ram_region = i; self->ram_regions[self->ram_regions_num].base = block->mr->addr; - self->ram_regions[self->ram_regions_num].size = MEM_SPLIT_START; + self->ram_regions[self->ram_regions_num].size = get_mem_split_start(); self->ram_regions[self->ram_regions_num].offset = snapshot_ptr_offset_array[i] - snapshot_ptr_offset_array[0]; self->ram_regions[self->ram_regions_num].host_region_ptr = block->host; @@ -113,16 +114,14 @@ shadow_memory_t *shadow_memory_init(void) self->ram_regions_num++; self->ram_regions[self->ram_regions_num].ram_region = i; - self->ram_regions[self->ram_regions_num].base = -MEM_SPLIT_END -; -self->ram_regions[self->ram_regions_num].size = block->used_length - MEM_SPLIT_START; + self->ram_regions[self->ram_regions_num].base = get_mem_split_end(); +self->ram_regions[self->ram_regions_num].size = block->used_length - get_mem_split_start(); self->ram_regions[self->ram_regions_num].offset = - (snapshot_ptr_offset_array[i] + MEM_SPLIT_START) - snapshot_ptr_offset_array[0]; + (snapshot_ptr_offset_array[i] + get_mem_split_start()) - snapshot_ptr_offset_array[0]; self->ram_regions[self->ram_regions_num].host_region_ptr = - block->host + MEM_SPLIT_START; + block->host + get_mem_split_start(); self->ram_regions[self->ram_regions_num].snapshot_region_ptr = - snapshot_ptr_offset_array[i] + MEM_SPLIT_START; + snapshot_ptr_offset_array[i] + get_mem_split_start(); self->ram_regions[self->ram_regions_num].idstr = malloc(strlen(block->idstr) + 1); memset(self->ram_regions[self->ram_regions_num].idstr, 0, strlen(block->idstr) + 1); strcpy(self->ram_regions[self->ram_regions_num].idstr, block->idstr); @@ -169,7 +168,7 @@ shadow_memory_t *shadow_memory_init_from_snapshot(const char *snapshot_folder, /* count number of ram regions */ QLIST_FOREACH_RCU (block, &ram_list.blocks, next) { if (!block->mr->readonly) { - if (self->ram_regions_num == 0 && block->used_length >= MEM_SPLIT_START) { + if (self->ram_regions_num == 0 && block->used_length >= get_mem_split_start()) { self->ram_regions_num++; } self->ram_regions_num++; @@ -240,10 +239,10 @@ shadow_memory_t *shadow_memory_init_from_snapshot(const char *snapshot_folder, for (uint8_t i = 0; i < regions_num; i++) { block = block_array[i]; if (!block->mr->readonly) { - if (self->ram_regions_num == 0 && block->used_length >= MEM_SPLIT_START) { + if (self->ram_regions_num == 0 && block->used_length >= get_mem_split_start()) { self->ram_regions[self->ram_regions_num].ram_region = i; self->ram_regions[self->ram_regions_num].base = block->mr->addr; - self->ram_regions[self->ram_regions_num].size = MEM_SPLIT_START; + self->ram_regions[self->ram_regions_num].size = get_mem_split_start(); self->ram_regions[self->ram_regions_num].offset = snapshot_ptr_offset_array[i] - snapshot_ptr_offset_array[0]; self->ram_regions[self->ram_regions_num].host_region_ptr = block->host; @@ -258,16 +257,14 @@ shadow_memory_t *shadow_memory_init_from_snapshot(const char *snapshot_folder, self->ram_regions_num++; self->ram_regions[self->ram_regions_num].ram_region = i; - self->ram_regions[self->ram_regions_num].base = -MEM_SPLIT_END -; -self->ram_regions[self->ram_regions_num].size = block->used_length - MEM_SPLIT_START; + self->ram_regions[self->ram_regions_num].base = get_mem_split_end(); +self->ram_regions[self->ram_regions_num].size = block->used_length - get_mem_split_start(); self->ram_regions[self->ram_regions_num].offset = - (snapshot_ptr_offset_array[i] + MEM_SPLIT_START) - snapshot_ptr_offset_array[0]; + (snapshot_ptr_offset_array[i] + get_mem_split_start()) - snapshot_ptr_offset_array[0]; self->ram_regions[self->ram_regions_num].host_region_ptr = - block->host + MEM_SPLIT_START; + block->host + get_mem_split_start(); self->ram_regions[self->ram_regions_num].snapshot_region_ptr = - snapshot_ptr_offset_array[i] + MEM_SPLIT_START; + snapshot_ptr_offset_array[i] + get_mem_split_start(); self->ram_regions[self->ram_regions_num].idstr = malloc(strlen(block->idstr) + 1); memset(self->ram_regions[self->ram_regions_num].idstr, 0, strlen(block->idstr) + 1); strcpy(self->ram_regions[self->ram_regions_num].idstr, block->idstr); diff --git a/nyx/state/state.c b/nyx/state/state.c index f03de20702..bd5a2b6dc4 100644 --- a/nyx/state/state.c +++ b/nyx/state/state.c @@ -117,6 +117,8 @@ void state_init_global(void) global_state.get_host_config_done = false; global_state.set_agent_config_done = false; + global_state.mem_mapping_type = MEM_SPLIT_TYPE_INVALID; + global_state.sharedir = sharedir_new(); diff --git a/nyx/state/state.h b/nyx/state/state.h index 08513325a5..7da8c3f720 100644 --- a/nyx/state/state.h +++ b/nyx/state/state.h @@ -30,6 +30,7 @@ along with QEMU-PT. If not, see . #include "nyx/sharedir.h" #include "nyx/synchronization.h" #include "nyx/types.h" +#include "nyx/mem_split.h" #include @@ -137,6 +138,8 @@ typedef struct qemu_nyx_state_s { bool get_host_config_done; bool set_agent_config_done; + MemSplitType mem_mapping_type; + /* capabilites */ uint8_t cap_timeout_detection; uint8_t cap_only_reload_mode; diff --git a/vl.c b/vl.c index 45323ee185..4e22f5d264 100644 --- a/vl.c +++ b/vl.c @@ -143,6 +143,7 @@ int main(int argc, char **argv) #include "nyx/pt.h" #include "nyx/state/state.h" #include "nyx/synchronization.h" +#include "nyx/mem_split.h" // clang-format off #endif @@ -4588,6 +4589,11 @@ int main(int argc, char **argv, char **envp) #ifdef QEMU_NYX // clang-format on + if(is_mem_mapping_supported(GET_GLOBAL_STATE()->mem_mapping_type) == false){ + nyx_error("Unsupported memory mapping type (only q35 and pc_piix are supported)\n"); + exit(1); + } + fast_reload_init(GET_GLOBAL_STATE()->fast_reload_snapshot); if (fast_vm_reload) {