- vfio/migration: Add support for manual clear vfio dirty log - vfio: Maintain DMA mapping range for the container - linux-headers: update against 5.10 and manual clear vfio dirty log series - arm/acpi: Fix when make qemu-system-aarch64 at x86_64 host bios_tables_test fail reason: __aarch64__ macro let build_pptt at x86_64 and aarch64 host build different function that let bios_tables_test fail. - pl031: support rtc-timer property for pl031 - feature: Add logs for vm start and destroy - feature: Add log for each modules - log: Add log at boot & cpu init for aarch64 - bugfix: irq: Avoid covering object refcount of qemu_irq - i386: cache passthrough: Update AMD 8000_001D.EAX[25:14] based on vCPU topo - freeclock: set rtc_date_diff for X86 - freeclock: set rtc_date_diff for arm - freeclock: add qmp command to get time offset of vm in seconds - tests: Disable filemonitor testcase - shadow_dev: introduce shadow dev for virtio-net device - pl011: reset read FIFO when UARTTIMSC=0 & UARTICR=0xffff - tests: virt: Update expected ACPI tables for virt test(update BinDir) - arm64: Add the cpufreq device to show cpufreq info to guest - hw/arm64: add vcpu cache info support - tests: virt: Allow changes to PPTT test table - cpu: add Cortex-A72 processor kvm target support - cpu: add Kunpeng-920 cpu support - net: eepro100: validate various address valuesi(CVE-2021-20255) - ide: ahci: add check to avoid null dereference (CVE-2019-12067) - vdpa: set vring enable only if the vring address has already been set - docs: Add generic vhost-vdpa device documentation - vdpa: don't suspend/resume device when vdpa device not started - vdpa: correct param passed in when unregister save - vdpa: suspend function return 0 when the vdpa device is stopped - vdpa: support vdpa device suspend/resume - vdpa: move memory listener to the realize stage - vdpa: implement vdpa device migration - vhost: implement migration state notifier for vdpa device - vhost: implement post resume bh - vhost: implement savevm_handler for vdpa device - vhost: implement vhost_vdpa_device_suspend/resume - vhost: implement vhost-vdpa suspend/resume - vhost: add vhost_dev_suspend/resume_op - vhost: introduce bytemap for vhost backend logging - vhost-vdpa: add migration log ops for VhostOps - vhost-vdpa: add VHOST_BACKEND_F_BYTEMAPLOG - hw/usb: reduce the vpcu cost of UHCI when VNC disconnect - virtio-net: update the default and max of rx/tx_queue_size - virtio-net: set the max of queue size to 4096 - virtio-net: fix max vring buf size when set ring num - virtio-net: bugfix: do not delete netdev before virtio net - monitor: Discard BLOCK_IO_ERROR event when VM rebooted - vhost-user: add unregister_savevm when vhost-user cleanup - vhost-user: add vhost_set_mem_table when vm load_setup at destination - vhost-user: quit infinite loop while used memslots is more than the backend limit - fix qemu-core when vhost-user-net config with server mode - vhost-user: Add support reconnect vhost-user socket - vhost-user: Set the acked_features to vm's featrue - i6300esb watchdog: bugfix: Add a runstate transition - hw/net/rocker_of_dpa: fix double free bug of rocker device - net/dump.c: Suppress spurious compiler warning - pcie: Add pcie-root-port fast plug/unplug feature - pcie: Compat with devices which do not support Link Width, such as ioh3420 - qdev/monitors: Fix reundant error_setg of qdev_add_device - qemu-nbd: set timeout to qemu-nbd socket - qemu-nbd: make native as the default aio mode - nbd/server.c: fix invalid read after client was already free - virtio-scsi: bugfix: fix qemu crash for hotplug scsi disk with dataplane - virtio: bugfix: check the value of caches before accessing it - virtio: print the guest virtio_net features that host does not support - virtio: bugfix: add rcu_read_lock when vring_avail_idx is called - virtio: check descriptor numbers - migration: report multiFd related thread pid to libvirt - migration: report migration related thread pid to libvirt - cpu/features: fix bug for memory leakage - doc: Update multi-thread compression doc - migration: Add compress_level sanity check - migration: Add zstd support in multi-thread compression - migration: Add multi-thread compress ops - migration: Refactoring multi-thread compress migration - migration: Add multi-thread compress method - migration: skip cache_drop for bios bootloader and nvram template - oslib-posix: optimise vm startup time for 1G hugepage - monitor/qmp: drop inflight rsp if qmp client broken - ps2: fix oob in ps2 kbd - Currently, while kvm and qemu can not handle some kvm exit, qemu will do vm_stop, which will make vm in pause state. This action make vm unrecoverable, so send guest panic to libvirt instead. - vhost: cancel migration when vhost-user restarted during migraiton Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
353 lines
13 KiB
Diff
353 lines
13 KiB
Diff
From 7d3d37d3af4278aee627952d6a81b63dec6ac62b Mon Sep 17 00:00:00 2001
|
|
From: Ying Fang <fangying1@huawei.com>
|
|
Date: Sun, 17 Mar 2024 18:56:09 +0800
|
|
Subject: [PATCH] hw/arm64: add vcpu cache info support
|
|
|
|
Support VCPU Cache info by dtb and PPTT table, including L1, L2 and L3 Cache.
|
|
|
|
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
|
|
Signed-off-by: Honghao <honghao5@huawei.com>
|
|
Signed-off-by: Ying Fang <fangying1@huawei.com>
|
|
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
|
|
Signed-off-by: Yuan Zhang <zhangyuan162@huawei.com>
|
|
---
|
|
hw/acpi/aml-build.c | 158 ++++++++++++++++++++++++++++++++++++
|
|
hw/arm/virt.c | 72 ++++++++++++++++
|
|
include/hw/acpi/aml-build.h | 47 +++++++++++
|
|
3 files changed, 277 insertions(+)
|
|
|
|
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
|
|
index af66bde0f5..2968df5562 100644
|
|
--- a/hw/acpi/aml-build.c
|
|
+++ b/hw/acpi/aml-build.c
|
|
@@ -1994,6 +1994,163 @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
|
|
}
|
|
}
|
|
|
|
+#ifdef __aarch64__
|
|
+/*
|
|
+ * ACPI spec, Revision 6.3
|
|
+ * 5.2.29.2 Cache Type Structure (Type 1)
|
|
+ */
|
|
+static void build_cache_hierarchy_node(GArray *tbl, uint32_t next_level,
|
|
+ uint32_t cache_type)
|
|
+{
|
|
+ build_append_byte(tbl, 1);
|
|
+ build_append_byte(tbl, 24);
|
|
+ build_append_int_noprefix(tbl, 0, 2);
|
|
+ build_append_int_noprefix(tbl, 127, 4);
|
|
+ build_append_int_noprefix(tbl, next_level, 4);
|
|
+
|
|
+ switch (cache_type) {
|
|
+ case ARM_L1D_CACHE: /* L1 dcache info */
|
|
+ build_append_int_noprefix(tbl, ARM_L1DCACHE_SIZE, 4);
|
|
+ build_append_int_noprefix(tbl, ARM_L1DCACHE_SETS, 4);
|
|
+ build_append_byte(tbl, ARM_L1DCACHE_ASSOCIATIVITY);
|
|
+ build_append_byte(tbl, ARM_L1DCACHE_ATTRIBUTES);
|
|
+ build_append_int_noprefix(tbl, ARM_L1DCACHE_LINE_SIZE, 2);
|
|
+ break;
|
|
+ case ARM_L1I_CACHE: /* L1 icache info */
|
|
+ build_append_int_noprefix(tbl, ARM_L1ICACHE_SIZE, 4);
|
|
+ build_append_int_noprefix(tbl, ARM_L1ICACHE_SETS, 4);
|
|
+ build_append_byte(tbl, ARM_L1ICACHE_ASSOCIATIVITY);
|
|
+ build_append_byte(tbl, ARM_L1ICACHE_ATTRIBUTES);
|
|
+ build_append_int_noprefix(tbl, ARM_L1ICACHE_LINE_SIZE, 2);
|
|
+ break;
|
|
+ case ARM_L2_CACHE: /* L2 cache info */
|
|
+ build_append_int_noprefix(tbl, ARM_L2CACHE_SIZE, 4);
|
|
+ build_append_int_noprefix(tbl, ARM_L2CACHE_SETS, 4);
|
|
+ build_append_byte(tbl, ARM_L2CACHE_ASSOCIATIVITY);
|
|
+ build_append_byte(tbl, ARM_L2CACHE_ATTRIBUTES);
|
|
+ build_append_int_noprefix(tbl, ARM_L2CACHE_LINE_SIZE, 2);
|
|
+ break;
|
|
+ case ARM_L3_CACHE: /* L3 cache info */
|
|
+ build_append_int_noprefix(tbl, ARM_L3CACHE_SIZE, 4);
|
|
+ build_append_int_noprefix(tbl, ARM_L3CACHE_SETS, 4);
|
|
+ build_append_byte(tbl, ARM_L3CACHE_ASSOCIATIVITY);
|
|
+ build_append_byte(tbl, ARM_L3CACHE_ATTRIBUTES);
|
|
+ build_append_int_noprefix(tbl, ARM_L3CACHE_LINE_SIZE, 2);
|
|
+ break;
|
|
+ default:
|
|
+ build_append_int_noprefix(tbl, 0, 4);
|
|
+ build_append_int_noprefix(tbl, 0, 4);
|
|
+ build_append_byte(tbl, 0);
|
|
+ build_append_byte(tbl, 0);
|
|
+ build_append_int_noprefix(tbl, 0, 2);
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ * ACPI spec, Revision 6.3
|
|
+ * 5.2.29 Processor Properties Topology Table (PPTT)
|
|
+ */
|
|
+void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
|
+ const char *oem_id, const char *oem_table_id)
|
|
+{
|
|
+ MachineClass *mc = MACHINE_GET_CLASS(ms);
|
|
+ GQueue *list = g_queue_new();
|
|
+ guint pptt_start = table_data->len;
|
|
+ guint parent_offset;
|
|
+ guint length, i;
|
|
+ int uid = 0;
|
|
+ int socket;
|
|
+ AcpiTable table = { .sig = "PPTT", .rev = 2,
|
|
+ .oem_id = oem_id, .oem_table_id = oem_table_id };
|
|
+
|
|
+ acpi_table_begin(&table, table_data);
|
|
+
|
|
+ for (socket = 0; socket < ms->smp.sockets; socket++) {
|
|
+ uint32_t l3_cache_offset = table_data->len - pptt_start;
|
|
+ build_cache_hierarchy_node(table_data, 0, ARM_L3_CACHE);
|
|
+
|
|
+ g_queue_push_tail(list,
|
|
+ GUINT_TO_POINTER(table_data->len - pptt_start));
|
|
+ build_processor_hierarchy_node(
|
|
+ table_data,
|
|
+ /*
|
|
+ * Physical package - represents the boundary
|
|
+ * of a physical package
|
|
+ */
|
|
+ (1 << 0),
|
|
+ 0, socket, &l3_cache_offset, 1);
|
|
+ }
|
|
+
|
|
+ if (mc->smp_props.clusters_supported) {
|
|
+ length = g_queue_get_length(list);
|
|
+ for (i = 0; i < length; i++) {
|
|
+ int cluster;
|
|
+
|
|
+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
|
|
+ for (cluster = 0; cluster < ms->smp.clusters; cluster++) {
|
|
+ g_queue_push_tail(list,
|
|
+ GUINT_TO_POINTER(table_data->len - pptt_start));
|
|
+ build_processor_hierarchy_node(
|
|
+ table_data,
|
|
+ (0 << 0), /* not a physical package */
|
|
+ parent_offset, cluster, NULL, 0);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ length = g_queue_get_length(list);
|
|
+ for (i = 0; i < length; i++) {
|
|
+ int core;
|
|
+
|
|
+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
|
|
+ for (core = 0; core < ms->smp.cores; core++) {
|
|
+ uint32_t priv_rsrc[3] = {};
|
|
+ priv_rsrc[0] = table_data->len - pptt_start; /* L2 cache offset */
|
|
+ build_cache_hierarchy_node(table_data, 0, ARM_L2_CACHE);
|
|
+
|
|
+ priv_rsrc[1] = table_data->len - pptt_start; /* L1 dcache offset */
|
|
+ build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1D_CACHE);
|
|
+
|
|
+ priv_rsrc[2] = table_data->len - pptt_start; /* L1 icache offset */
|
|
+ build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1I_CACHE);
|
|
+
|
|
+ if (ms->smp.threads > 1) {
|
|
+ g_queue_push_tail(list,
|
|
+ GUINT_TO_POINTER(table_data->len - pptt_start));
|
|
+ build_processor_hierarchy_node(
|
|
+ table_data,
|
|
+ (0 << 0), /* not a physical package */
|
|
+ parent_offset, core, priv_rsrc, 3);
|
|
+ } else {
|
|
+ build_processor_hierarchy_node(
|
|
+ table_data,
|
|
+ (1 << 1) | /* ACPI Processor ID valid */
|
|
+ (1 << 3), /* Node is a Leaf */
|
|
+ parent_offset, uid++, priv_rsrc, 3);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ length = g_queue_get_length(list);
|
|
+ for (i = 0; i < length; i++) {
|
|
+ int thread;
|
|
+
|
|
+ parent_offset = GPOINTER_TO_UINT(g_queue_pop_head(list));
|
|
+ for (thread = 0; thread < ms->smp.threads; thread++) {
|
|
+ build_processor_hierarchy_node(
|
|
+ table_data,
|
|
+ (1 << 1) | /* ACPI Processor ID valid */
|
|
+ (1 << 2) | /* Processor is a Thread */
|
|
+ (1 << 3), /* Node is a Leaf */
|
|
+ parent_offset, uid++, NULL, 0);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ g_queue_free(list);
|
|
+ acpi_table_end(linker, &table);
|
|
+}
|
|
+
|
|
+#else
|
|
/*
|
|
* ACPI spec, Revision 6.3
|
|
* 5.2.29 Processor Properties Topology Table (PPTT)
|
|
@@ -2069,6 +2226,7 @@ void build_pptt(GArray *table_data, BIOSLinker *linker, MachineState *ms,
|
|
|
|
acpi_table_end(linker, &table);
|
|
}
|
|
+#endif
|
|
|
|
/* build rev1/rev3/rev5.1/rev6.0 FADT */
|
|
void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
|
|
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
|
index 500a15aa5b..b82bd1b8c8 100644
|
|
--- a/hw/arm/virt.c
|
|
+++ b/hw/arm/virt.c
|
|
@@ -379,6 +379,72 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
|
|
INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
|
|
}
|
|
|
|
+static void fdt_add_l3cache_nodes(const VirtMachineState *vms)
|
|
+{
|
|
+ int i;
|
|
+ const MachineState *ms = MACHINE(vms);
|
|
+ int cpus_per_socket = ms->smp.clusters * ms->smp.cores * ms->smp.threads;
|
|
+ int sockets = (ms->smp.cpus + cpus_per_socket - 1) / cpus_per_socket;
|
|
+
|
|
+ for (i = 0; i < sockets; i++) {
|
|
+ char *nodename = g_strdup_printf("/cpus/l3-cache%d", i);
|
|
+
|
|
+ qemu_fdt_add_subnode(ms->fdt, nodename);
|
|
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cache");
|
|
+ qemu_fdt_setprop_string(ms->fdt, nodename, "cache-unified", "true");
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-level", 3);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", 0x2000000);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", 128);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", 2048);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
|
|
+ qemu_fdt_alloc_phandle(ms->fdt));
|
|
+ g_free(nodename);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void fdt_add_l2cache_nodes(const VirtMachineState *vms)
|
|
+{
|
|
+ const MachineState *ms = MACHINE(vms);
|
|
+ int cpus_per_socket = ms->smp.clusters * ms->smp.cores * ms->smp.threads;
|
|
+ int cpu;
|
|
+
|
|
+ for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
|
|
+ char *next_path = g_strdup_printf("/cpus/l3-cache%d",
|
|
+ cpu / cpus_per_socket);
|
|
+ char *nodename = g_strdup_printf("/cpus/l2-cache%d", cpu);
|
|
+
|
|
+ qemu_fdt_add_subnode(ms->fdt, nodename);
|
|
+ qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cache");
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", 0x80000);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", 64);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", 1024);
|
|
+ qemu_fdt_setprop_phandle(ms->fdt, nodename, "next-level-cache",
|
|
+ next_path);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
|
|
+ qemu_fdt_alloc_phandle(ms->fdt));
|
|
+
|
|
+ g_free(next_path);
|
|
+ g_free(nodename);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void fdt_add_l1cache_prop(const VirtMachineState *vms,
|
|
+ char *nodename, int cpu)
|
|
+{
|
|
+ const MachineState *ms = MACHINE(vms);
|
|
+ char *cachename = g_strdup_printf("/cpus/l2-cache%d", cpu);
|
|
+
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-size", 0x10000);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-line-size", 64);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-sets", 256);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-size", 0x10000);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-line-size", 64);
|
|
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-sets", 256);
|
|
+ qemu_fdt_setprop_phandle(ms->fdt, nodename, "next-level-cache",
|
|
+ cachename);
|
|
+ g_free(cachename);
|
|
+}
|
|
+
|
|
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
|
{
|
|
int cpu;
|
|
@@ -413,6 +479,11 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
|
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", addr_cells);
|
|
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
|
|
|
|
+ if (!vmc->no_cpu_topology) {
|
|
+ fdt_add_l3cache_nodes(vms);
|
|
+ fdt_add_l2cache_nodes(vms);
|
|
+ }
|
|
+
|
|
for (cpu = smp_cpus - 1; cpu >= 0; cpu--) {
|
|
char *nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
|
|
ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(cpu));
|
|
@@ -442,6 +513,7 @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
|
|
}
|
|
|
|
if (!vmc->no_cpu_topology) {
|
|
+ fdt_add_l1cache_prop(vms, nodename, cpu);
|
|
qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
|
|
qemu_fdt_alloc_phandle(ms->fdt));
|
|
}
|
|
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
|
|
index ff2a310270..84ded2ecd3 100644
|
|
--- a/include/hw/acpi/aml-build.h
|
|
+++ b/include/hw/acpi/aml-build.h
|
|
@@ -221,6 +221,53 @@ struct AcpiBuildTables {
|
|
BIOSLinker *linker;
|
|
} AcpiBuildTables;
|
|
|
|
+#ifdef __aarch64__
|
|
+/* Definitions of the hardcoded cache info*/
|
|
+
|
|
+typedef enum {
|
|
+ ARM_L1D_CACHE,
|
|
+ ARM_L1I_CACHE,
|
|
+ ARM_L2_CACHE,
|
|
+ ARM_L3_CACHE
|
|
+} ArmCacheType;
|
|
+
|
|
+/* L1 data cache: */
|
|
+#define ARM_L1DCACHE_SIZE 65536
|
|
+#define ARM_L1DCACHE_SETS 256
|
|
+#define ARM_L1DCACHE_ASSOCIATIVITY 4
|
|
+#define ARM_L1DCACHE_ATTRIBUTES 2
|
|
+#define ARM_L1DCACHE_LINE_SIZE 64
|
|
+
|
|
+/* L1 instruction cache: */
|
|
+#define ARM_L1ICACHE_SIZE 65536
|
|
+#define ARM_L1ICACHE_SETS 256
|
|
+#define ARM_L1ICACHE_ASSOCIATIVITY 4
|
|
+#define ARM_L1ICACHE_ATTRIBUTES 4
|
|
+#define ARM_L1ICACHE_LINE_SIZE 64
|
|
+
|
|
+/* Level 2 unified cache: */
|
|
+#define ARM_L2CACHE_SIZE 524288
|
|
+#define ARM_L2CACHE_SETS 1024
|
|
+#define ARM_L2CACHE_ASSOCIATIVITY 8
|
|
+#define ARM_L2CACHE_ATTRIBUTES 10
|
|
+#define ARM_L2CACHE_LINE_SIZE 64
|
|
+
|
|
+/* Level 3 unified cache: */
|
|
+#define ARM_L3CACHE_SIZE 33554432
|
|
+#define ARM_L3CACHE_SETS 2048
|
|
+#define ARM_L3CACHE_ASSOCIATIVITY 15
|
|
+#define ARM_L3CACHE_ATTRIBUTES 10
|
|
+#define ARM_L3CACHE_LINE_SIZE 128
|
|
+
|
|
+struct offset_status {
|
|
+ uint32_t parent;
|
|
+ uint32_t l2_offset;
|
|
+ uint32_t l1d_offset;
|
|
+ uint32_t l1i_offset;
|
|
+};
|
|
+
|
|
+#endif
|
|
+
|
|
typedef
|
|
struct CrsRangeEntry {
|
|
uint64_t base;
|
|
--
|
|
2.27.0
|
|
|