qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

hw/i386/pc: Extract e820 memory layout code

Suggested-by: Samuel Ortiz <sameo@linux.intel.com>
Reviewed-by: Li Qiang <liq3ea@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20190818225414.22590-3-philmd@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

authored by

Philippe Mathieu-Daudé and committed by
Paolo Bonzini
d6d059ca 42d400ac

+104 -72
+1 -1
hw/i386/Makefile.objs
··· 1 1 obj-$(CONFIG_KVM) += kvm/ 2 - obj-y += multiboot.o 2 + obj-y += e820_memory_layout.o multiboot.o 3 3 obj-y += pc.o 4 4 obj-$(CONFIG_I440FX) += pc_piix.o 5 5 obj-$(CONFIG_Q35) += pc_q35.o
+59
hw/i386/e820_memory_layout.c
··· 1 + /* 2 + * QEMU BIOS e820 routines 3 + * 4 + * Copyright (c) 2003-2004 Fabrice Bellard 5 + * 6 + * SPDX-License-Identifier: MIT 7 + */ 8 + 9 + #include "qemu/osdep.h" 10 + #include "qemu/bswap.h" 11 + #include "e820_memory_layout.h" 12 + 13 + static size_t e820_entries; 14 + struct e820_table e820_reserve; 15 + struct e820_entry *e820_table; 16 + 17 + int e820_add_entry(uint64_t address, uint64_t length, uint32_t type) 18 + { 19 + int index = le32_to_cpu(e820_reserve.count); 20 + struct e820_entry *entry; 21 + 22 + if (type != E820_RAM) { 23 + /* old FW_CFG_E820_TABLE entry -- reservations only */ 24 + if (index >= E820_NR_ENTRIES) { 25 + return -EBUSY; 26 + } 27 + entry = &e820_reserve.entry[index++]; 28 + 29 + entry->address = cpu_to_le64(address); 30 + entry->length = cpu_to_le64(length); 31 + entry->type = cpu_to_le32(type); 32 + 33 + e820_reserve.count = cpu_to_le32(index); 34 + } 35 + 36 + /* new "etc/e820" file -- include ram too */ 37 + e820_table = g_renew(struct e820_entry, e820_table, e820_entries + 1); 38 + e820_table[e820_entries].address = cpu_to_le64(address); 39 + e820_table[e820_entries].length = cpu_to_le64(length); 40 + e820_table[e820_entries].type = cpu_to_le32(type); 41 + e820_entries++; 42 + 43 + return e820_entries; 44 + } 45 + 46 + int e820_get_num_entries(void) 47 + { 48 + return e820_entries; 49 + } 50 + 51 + bool e820_get_entry(int idx, uint32_t type, uint64_t *address, uint64_t *length) 52 + { 53 + if (idx < e820_entries && e820_table[idx].type == cpu_to_le32(type)) { 54 + *address = le64_to_cpu(e820_table[idx].address); 55 + *length = le64_to_cpu(e820_table[idx].length); 56 + return true; 57 + } 58 + return false; 59 + }
+42
hw/i386/e820_memory_layout.h
··· 1 + /* 2 + * QEMU BIOS e820 routines 3 + * 4 + * Copyright (c) 2003-2004 Fabrice Bellard 5 + * 6 + * SPDX-License-Identifier: MIT 7 + */ 8 + 9 + #ifndef HW_I386_E820_H 10 + #define HW_I386_E820_H 11 + 12 + /* e820 types */ 13 + #define E820_RAM 1 14 + #define E820_RESERVED 2 15 + #define E820_ACPI 3 16 + #define E820_NVS 4 17 + #define E820_UNUSABLE 5 18 + 19 + #define E820_NR_ENTRIES 16 20 + 21 + struct e820_entry { 22 + uint64_t address; 23 + uint64_t length; 24 + uint32_t type; 25 + } QEMU_PACKED __attribute((__aligned__(4))); 26 + 27 + struct e820_table { 28 + uint32_t count; 29 + struct e820_entry entry[E820_NR_ENTRIES]; 30 + } QEMU_PACKED __attribute((__aligned__(4))); 31 + 32 + extern struct e820_table e820_reserve; 33 + extern struct e820_entry *e820_table; 34 + 35 + int e820_add_entry(uint64_t address, uint64_t length, uint32_t type); 36 + int e820_get_num_entries(void); 37 + bool e820_get_entry(int index, uint32_t type, 38 + uint64_t *address, uint64_t *length); 39 + 40 + 41 + 42 + #endif
+1 -60
hw/i386/pc.c
··· 87 87 #include "sysemu/replay.h" 88 88 #include "qapi/qmp/qerror.h" 89 89 #include "config-devices.h" 90 + #include "e820_memory_layout.h" 90 91 91 92 /* debug PC/ISA interrupts */ 92 93 //#define DEBUG_IRQ ··· 98 99 #define DPRINTF(fmt, ...) 99 100 #endif 100 101 101 - #define E820_NR_ENTRIES 16 102 - 103 - struct e820_entry { 104 - uint64_t address; 105 - uint64_t length; 106 - uint32_t type; 107 - } QEMU_PACKED __attribute((__aligned__(4))); 108 - 109 - struct e820_table { 110 - uint32_t count; 111 - struct e820_entry entry[E820_NR_ENTRIES]; 112 - } QEMU_PACKED __attribute((__aligned__(4))); 113 - 114 - static struct e820_table e820_reserve; 115 - static struct e820_entry *e820_table; 116 - static unsigned e820_entries; 117 102 struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; 118 103 119 104 /* Physical Address of PVH entry point read from kernel ELF NOTE */ ··· 878 863 /* XXX: send to all CPUs ? */ 879 864 /* XXX: add logic to handle multiple A20 line sources */ 880 865 x86_cpu_set_a20(cpu, level); 881 - } 882 - 883 - int e820_add_entry(uint64_t address, uint64_t length, uint32_t type) 884 - { 885 - int index = le32_to_cpu(e820_reserve.count); 886 - struct e820_entry *entry; 887 - 888 - if (type != E820_RAM) { 889 - /* old FW_CFG_E820_TABLE entry -- reservations only */ 890 - if (index >= E820_NR_ENTRIES) { 891 - return -EBUSY; 892 - } 893 - entry = &e820_reserve.entry[index++]; 894 - 895 - entry->address = cpu_to_le64(address); 896 - entry->length = cpu_to_le64(length); 897 - entry->type = cpu_to_le32(type); 898 - 899 - e820_reserve.count = cpu_to_le32(index); 900 - } 901 - 902 - /* new "etc/e820" file -- include ram too */ 903 - e820_table = g_renew(struct e820_entry, e820_table, e820_entries + 1); 904 - e820_table[e820_entries].address = cpu_to_le64(address); 905 - e820_table[e820_entries].length = cpu_to_le64(length); 906 - e820_table[e820_entries].type = cpu_to_le32(type); 907 - e820_entries++; 908 - 909 - return e820_entries; 910 - } 911 - 912 - int e820_get_num_entries(void) 913 - { 914 - return e820_entries; 915 - } 916 - 917 - bool e820_get_entry(int idx, uint32_t type, uint64_t *address, uint64_t *length) 918 - { 919 - if (idx < e820_entries && e820_table[idx].type == cpu_to_le32(type)) { 920 - *address = le64_to_cpu(e820_table[idx].address); 921 - *length = le64_to_cpu(e820_table[idx].length); 922 - return true; 923 - } 924 - return false; 925 866 } 926 867 927 868 /* Calculates initial APIC ID for a specific CPU index
-11
include/hw/i386/pc.h
··· 291 291 void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid, 292 292 const CPUArchIdList *apic_ids, GArray *entry); 293 293 294 - /* e820 types */ 295 - #define E820_RAM 1 296 - #define E820_RESERVED 2 297 - #define E820_ACPI 3 298 - #define E820_NVS 4 299 - #define E820_UNUSABLE 5 300 - 301 - int e820_add_entry(uint64_t, uint64_t, uint32_t); 302 - int e820_get_num_entries(void); 303 - bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); 304 - 305 294 extern GlobalProperty pc_compat_4_1[]; 306 295 extern const size_t pc_compat_4_1_len; 307 296
+1
target/i386/kvm.c
··· 41 41 #include "hw/i386/apic-msidef.h" 42 42 #include "hw/i386/intel_iommu.h" 43 43 #include "hw/i386/x86-iommu.h" 44 + #include "hw/i386/e820_memory_layout.h" 44 45 45 46 #include "hw/pci/pci.h" 46 47 #include "hw/pci/msi.h"