From 35b2d3c58b994a07c8355062ac61ed4c4bf632eb Mon Sep 17 00:00:00 2001 From: Jiabo Feng Date: Wed, 26 Mar 2025 20:13:05 +0800 Subject: [PATCH] QEMU update to version 6.2.0-107: - qemu: Support specifying the cache size presented to guest - hw/core/machine-smp: Initialize caches_bitmap before reading - qapi/qom: Define cache enumeration and properties for machine - linux-aio: fix unbalanced plugged counter in laio_io_unplug() Signed-off-by: Jiabo Feng (cherry picked from commit 5453be865c307703cc43847588fa63ef74ac1ae0) --- ...smp-Initialize-caches_bitmap-before-.patch | 47 +++ ...balanced-plugged-counter-in-laio_io_.patch | 61 ++++ ...cache-enumeration-and-properties-for.patch | 270 +++++++++++++++ ...cifying-the-cache-size-presented-to-.patch | 310 ++++++++++++++++++ qemu.spec | 12 +- 5 files changed, 699 insertions(+), 1 deletion(-) create mode 100644 hw-core-machine-smp-Initialize-caches_bitmap-before-.patch create mode 100644 linux-aio-fix-unbalanced-plugged-counter-in-laio_io_.patch create mode 100644 qapi-qom-Define-cache-enumeration-and-properties-for.patch create mode 100644 qemu-Support-specifying-the-cache-size-presented-to-.patch diff --git a/hw-core-machine-smp-Initialize-caches_bitmap-before-.patch b/hw-core-machine-smp-Initialize-caches_bitmap-before-.patch new file mode 100644 index 00000000..c7c8f1ed --- /dev/null +++ b/hw-core-machine-smp-Initialize-caches_bitmap-before-.patch @@ -0,0 +1,47 @@ +From 4f12da5913773e6beba7edd530d85ebe58889c28 Mon Sep 17 00:00:00 2001 +From: huangchengfei +Date: Fri, 7 Mar 2025 15:51:01 +0800 +Subject: [PATCH] hw/core/machine-smp: Initialize caches_bitmap before reading +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +mainline inclusion +from mainline-master +commit 9c2644948c71db61a04f22398cde72224a98267a +category: feature +Reference: https://github.com/qemu/qemu/commit/9c2644948c71db61a04f22398cde72224a98267a + +commit 9c2644948c71db61a04f22398cde72224a98267a upstream + +The caches_bitmap is defined in machine_parse_smp_cache(), but it was +not initialized. + +Initialize caches_bitmap by clearing all its bits to zero. + +Resolves: Coverity CID 1565389 +Fixes: 4e88e7e ("qapi/qom: Define cache enumeration and properties for machine") +Reported-by: Peter Maydell +Signed-off-by: Zhao Liu +Reviewed-by: Philippe Mathieu-Daudé +Link: https://lore.kernel.org/r/20241110150901.130647-2-zhao1.liu@intel.com +Signed-off-by: Paolo Bonzini +--- + hw/core/machine-smp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c +index 9d1aa3afb3..a421a394d4 100644 +--- a/hw/core/machine-smp.c ++++ b/hw/core/machine-smp.c +@@ -201,6 +201,7 @@ bool machine_parse_smp_cache(MachineState *ms, + const SmpCachePropertiesList *node; + DECLARE_BITMAP(caches_bitmap, CACHE_LEVEL_AND_TYPE__MAX); + ++ bitmap_zero(caches_bitmap, CACHE_LEVEL_AND_TYPE__MAX); + for (node = caches; node; node = node->next) { + /* Prohibit users from repeating settings. */ + if (test_bit(node->value->cache, caches_bitmap)) { +-- +2.41.0.windows.1 + diff --git a/linux-aio-fix-unbalanced-plugged-counter-in-laio_io_.patch b/linux-aio-fix-unbalanced-plugged-counter-in-laio_io_.patch new file mode 100644 index 00000000..f964d46f --- /dev/null +++ b/linux-aio-fix-unbalanced-plugged-counter-in-laio_io_.patch @@ -0,0 +1,61 @@ +From 96faf869b9109de54761b0b6c9a29716803f01fb Mon Sep 17 00:00:00 2001 +From: wangfuqiang49 +Date: Wed, 19 Feb 2025 21:34:43 -0600 +Subject: [PATCH] linux-aio: fix unbalanced plugged counter in laio_io_unplug() + +When the io_submit() in the execution flow of laio_do_submit -> +ioq_submit -> io_submit returns an error, such as returning -EAGAIN, +s->io_q.blocked will set to 1. Consequently, s->io_q.in_queue may grow +to laio_max_batch(), which prevents laio_io_unplug() from decrementing +s->io_q.plugged. This situation can cause laio_do_submit() and +laio_io_unplug to stop submitting AIO requests unless the number of +requests in the queue reaches laio_max_batch(). + +upstream commit: + +commit 18bcfa0ebb39146cc4f7dad0dd989a24c74677d9 +Author: Stefan Hajnoczi +Date: Thu Jun 9 17:47:11 2022 +0100 + + linux-aio: fix unbalanced plugged counter in laio_io_unplug() + + Every laio_io_plug() call has a matching laio_io_unplug() call. There is + a plugged counter that tracks the number of levels of plugging and + allows for nesting. + + The plugged counter must reflect the balance between laio_io_plug() and + laio_io_unplug() calls accurately. Otherwise I/O stalls occur since + io_submit(2) calls are skipped while plugged. + + Reported-by: Nikolay Tenev + Signed-off-by: Stefan Hajnoczi + Reviewed-by: Stefano Garzarella + Message-id: 20220609164712.1539045-2-stefanha@redhat.com + Cc: Stefano Garzarella + Fixes: 68d7946648 ("linux-aio: add `dev_max_batch` parameter to laio_io_unplug()") + [Stefano Garzarella suggested adding a Fixes tag. + --Stefan] + Signed-off-by: Stefan Hajnoczi +--- + block/linux-aio.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/block/linux-aio.c b/block/linux-aio.c +index f53ae72e21..77f17ad596 100644 +--- a/block/linux-aio.c ++++ b/block/linux-aio.c +@@ -360,8 +360,10 @@ void laio_io_unplug(BlockDriverState *bs, LinuxAioState *s, + uint64_t dev_max_batch) + { + assert(s->io_q.plugged); ++ s->io_q.plugged--; ++ + if (s->io_q.in_queue >= laio_max_batch(s, dev_max_batch) || +- (--s->io_q.plugged == 0 && ++ (!s->io_q.plugged && + !s->io_q.blocked && !QSIMPLEQ_EMPTY(&s->io_q.pending))) { + ioq_submit(s); + } +-- +2.41.0.windows.1 + diff --git a/qapi-qom-Define-cache-enumeration-and-properties-for.patch b/qapi-qom-Define-cache-enumeration-and-properties-for.patch new file mode 100644 index 00000000..4cf0f237 --- /dev/null +++ b/qapi-qom-Define-cache-enumeration-and-properties-for.patch @@ -0,0 +1,270 @@ +From 04d1ae325a2a77025558d833840a62bd08136c44 Mon Sep 17 00:00:00 2001 +From: huangchengfei +Date: Fri, 7 Mar 2025 15:25:12 +0800 +Subject: [PATCH] qapi/qom: Define cache enumeration and properties for machine +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +mainline inclusion +from mainline-master +commit 4e88e7e3403df23a0fd7a95daad1f00da80bcf81 +category: feature +Reference: https://github.com/qemu/qemu/commit/4e88e7e3403df23a0fd7a95daad1f00da80bcf81 + +commit 4e88e7e3403df23a0fd7a95daad1f00da80bcf81 upstream + +The x86 and ARM need to allow user to configure cache properties +(current only topology): + * For x86, the default cache topology model (of max/host CPU) does not + always match the Host's real physical cache topology. Performance can + increase when the configured virtual topology is closer to the + physical topology than a default topology would be. + * For ARM, QEMU can't get the cache topology information from the CPU + registers, then user configuration is necessary. Additionally, the + cache information is also needed for MPAM emulation (for TCG) to + build the right PPTT. + +Define smp-cache related enumeration and properties in QAPI, so that +user could configure cache properties for SMP system through -machine in +the subsequent patch. + +Cache enumeration (CacheLevelAndType) is implemented as the combination +of cache level (level 1/2/3) and cache type (data/instruction/unified). + +Currently, separated L1 cache (L1 data cache and L1 instruction cache) +with unified higher-level cache (e.g., unified L2 and L3 caches), is the +most common cache architectures. + +Therefore, enumerate the L1 D-cache, L1 I-cache, L2 cache and L3 cache +with smp-cache object to add the basic cache topology support. Other +kinds of caches (e.g., L1 unified or L2/L3 separated caches) can be +added directly into CacheLevelAndType if necessary. + +Cache properties (SmpCacheProperties) currently only contains cache +topology information, and other cache properties can be added in it +if necessary. + +Note, define cache topology based on CPU topology level with two +reasons: + + 1. In practice, a cache will always be bound to the CPU container + (either private in the CPU container or shared among multiple + containers), and CPU container is often expressed in terms of CPU + topology level. + 2. The x86's cache-related CPUIDs encode cache topology based on APIC + ID's CPU topology layout. And the ACPI PPTT table that ARM/RISCV + relies on also requires CPU containers to help indicate the private + shared hierarchy of the cache. Therefore, for SMP systems, it is + natural to use the CPU topology hierarchy directly in QEMU to define + the cache topology. + +With smp-cache QAPI support, add smp cache topology for machine by +parsing the smp-cache object list. + +Also add the helper to access/update cache topology level of machine. + +Round to openeuler: +*cache topology property is removed + +Suggested-by: Daniel P. Berrange +Signed-off-by: Zhao Liu +Tested-by: Yongwei Ma +Reviewed-by: Jonathan Cameron +Message-ID: <20241101083331.340178-4-zhao1.liu@intel.com> +Signed-off-by: Philippe Mathieu-Daudé +Signed-off-by: huangchengfei +--- + hw/core/machine-smp.c | 23 ++++++++++++++++++++++ + hw/core/machine.c | 42 +++++++++++++++++++++++++++++++++++++++++ + include/hw/boards.h | 8 ++++++++ + qapi/machine.json | 44 +++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 117 insertions(+) + +diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c +index b39ed21e65..9d1aa3afb3 100644 +--- a/hw/core/machine-smp.c ++++ b/hw/core/machine-smp.c +@@ -193,3 +193,26 @@ void machine_parse_smp_config(MachineState *ms, + return; + } + } ++ ++bool machine_parse_smp_cache(MachineState *ms, ++ const SmpCachePropertiesList *caches, ++ Error **errp) ++{ ++ const SmpCachePropertiesList *node; ++ DECLARE_BITMAP(caches_bitmap, CACHE_LEVEL_AND_TYPE__MAX); ++ ++ for (node = caches; node; node = node->next) { ++ /* Prohibit users from repeating settings. */ ++ if (test_bit(node->value->cache, caches_bitmap)) { ++ error_setg(errp, ++ "Invalid cache properties: %s. " ++ "The cache properties are duplicated", ++ CacheLevelAndType_str(node->value->cache)); ++ return false; ++ } ++ ++ set_bit(node->value->cache, caches_bitmap); ++ } ++ ++ return true; ++} +\ No newline at end of file +diff --git a/hw/core/machine.c b/hw/core/machine.c +index cb539104a1..4cdd9a7300 100644 +--- a/hw/core/machine.c ++++ b/hw/core/machine.c +@@ -777,6 +777,39 @@ static void machine_set_smp(Object *obj, Visitor *v, const char *name, + machine_parse_smp_config(ms, config, errp); + } + ++static void machine_get_smp_cache(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ MachineState *ms = MACHINE(obj); ++ SmpCache *cache = &ms->smp_cache; ++ SmpCachePropertiesList *head = NULL; ++ SmpCachePropertiesList **tail = &head; ++ ++ for (int i = 0; i < CACHE_LEVEL_AND_TYPE__MAX; i++) { ++ SmpCacheProperties *node = g_new(SmpCacheProperties, 1); ++ ++ node->cache = cache->props[i].cache; ++ QAPI_LIST_APPEND(tail, node); ++ } ++ ++ visit_type_SmpCachePropertiesList(v, name, &head, errp); ++ qapi_free_SmpCachePropertiesList(head); ++} ++ ++static void machine_set_smp_cache(Object *obj, Visitor *v, const char *name, ++ void *opaque, Error **errp) ++{ ++ MachineState *ms = MACHINE(obj); ++ SmpCachePropertiesList *caches; ++ ++ if (!visit_type_SmpCachePropertiesList(v, name, &caches, errp)) { ++ return; ++ } ++ ++ machine_parse_smp_cache(ms, caches, errp); ++ qapi_free_SmpCachePropertiesList(caches); ++} ++ + static void machine_class_init(ObjectClass *oc, void *data) + { + MachineClass *mc = MACHINE_CLASS(oc); +@@ -821,6 +854,11 @@ static void machine_class_init(ObjectClass *oc, void *data) + object_class_property_set_description(oc, "smp", + "CPU topology"); + ++ object_class_property_add(oc, "smp-cache", "SmpCachePropertiesWrapper", ++ machine_get_smp_cache, machine_set_smp_cache, NULL, NULL); ++ object_class_property_set_description(oc, "smp-cache", ++ "Cache properties list for SMP machine"); ++ + object_class_property_add(oc, "phandle-start", "int", + machine_get_phandle_start, machine_set_phandle_start, + NULL, NULL); +@@ -948,6 +986,10 @@ static void machine_initfn(Object *obj) + ms->smp.clusters = 1; + ms->smp.cores = 1; + ms->smp.threads = 1; ++ ++ for (int i = 0; i < CACHE_LEVEL_AND_TYPE__MAX; i++) { ++ ms->smp_cache.props[i].cache = (CacheLevelAndType)i; ++ } + } + + static void machine_finalize(Object *obj) +diff --git a/include/hw/boards.h b/include/hw/boards.h +index f49a2578ea..59f04caf3f 100644 +--- a/include/hw/boards.h ++++ b/include/hw/boards.h +@@ -36,6 +36,9 @@ void machine_set_cpu_numa_node(MachineState *machine, + Error **errp); + void machine_parse_smp_config(MachineState *ms, + const SMPConfiguration *config, Error **errp); ++bool machine_parse_smp_cache(MachineState *ms, ++ const SmpCachePropertiesList *caches, ++ Error **errp); + + /** + * machine_class_allow_dynamic_sysbus_dev: Add type to list of valid devices +@@ -316,6 +319,10 @@ typedef struct CpuTopology { + unsigned int max_cpus; + } CpuTopology; + ++typedef struct SmpCache { ++ SmpCacheProperties props[CACHE_LEVEL_AND_TYPE__MAX]; ++} SmpCache; ++ + /** + * MachineState: + */ +@@ -359,6 +366,7 @@ struct MachineState { + AccelState *accelerator; + CPUArchIdList *possible_cpus; + CpuTopology smp; ++ SmpCache smp_cache; + struct NVDIMMState *nvdimms_state; + struct NumaState *numa_state; + }; +diff --git a/qapi/machine.json b/qapi/machine.json +index 31b0350b99..676e16477b 100644 +--- a/qapi/machine.json ++++ b/qapi/machine.json +@@ -1570,3 +1570,47 @@ + { 'command': 'x-query-usb', + 'returns': 'HumanReadableText', + 'features': [ 'unstable' ] } ++ ++## ++# @CacheLevelAndType: ++# ++# Caches a system may have. The enumeration value here is the ++# combination of cache level and cache type. ++# ++# @l1d: L1 data cache. ++# ++# @l1i: L1 instruction cache. ++# ++# @l2: L2 (unified) cache. ++# ++# @l3: L3 (unified) cache ++# ++# Since: 9.2 ++## ++{ 'enum': 'CacheLevelAndType', ++ 'data': [ 'l1d', 'l1i', 'l2', 'l3' ] } ++ ++## ++# @SmpCacheProperties: ++# ++# Cache information for SMP system. ++# ++# @cache: Cache name, which is the combination of cache level and cache type. ++# ++# Since: 9.2 ++## ++{ 'struct': 'SmpCacheProperties', ++ 'data': { ++ 'cache': 'CacheLevelAndType' } } ++ ++## ++# @SmpCachePropertiesWrapper: ++# ++# List wrapper of SmpCacheProperties. ++# ++# @caches: the list of SmpCacheProperties. ++# ++# Since 9.2 ++## ++{ 'struct': 'SmpCachePropertiesWrapper', ++ 'data': { 'caches': ['SmpCacheProperties'] } } +-- +2.41.0.windows.1 + diff --git a/qemu-Support-specifying-the-cache-size-presented-to-.patch b/qemu-Support-specifying-the-cache-size-presented-to-.patch new file mode 100644 index 00000000..bb58e1f8 --- /dev/null +++ b/qemu-Support-specifying-the-cache-size-presented-to-.patch @@ -0,0 +1,310 @@ +From 152b6db246ca73a4eb1683afb59e8020645e0f79 Mon Sep 17 00:00:00 2001 +From: huangchengfei +Date: Fri, 7 Mar 2025 16:09:50 +0800 +Subject: [PATCH] qemu: Support specifying the cache size presented to guest + +Add configuration item to specifying the cache size presented to guest in Bytes. +for example: +-machine virt,\ +smp-cache.0.cache=l1i,smp-cache.0.size=32768,\ +smp-cache.1.cache=l1d,smp-cache.1.size=32768,\ +smp-cache.2.cache=l2,smp-cache.2.size=1048576 + +Signed-off-by: huangchengfei +--- + hw/arm/virt-acpi-build.c | 40 ++++++++++++++++++++++++++++------------ + hw/arm/virt.c | 18 +++++++++++++----- + hw/core/machine-smp.c | 14 ++++++++++++++ + hw/core/machine.c | 2 ++ + include/hw/boards.h | 4 ++++ + qapi/machine.json | 15 ++++++++++----- + 6 files changed, 71 insertions(+), 22 deletions(-) + +diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c +index ed220d5d40..5ed23e627a 100644 +--- a/hw/arm/virt-acpi-build.c ++++ b/hw/arm/virt-acpi-build.c +@@ -64,46 +64,62 @@ + * 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) ++static void build_cache_hierarchy_node(MachineState *ms, 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); ++ uint64_t cache_size; + + switch (cache_type) { + case ARM_L1D_CACHE: /* L1 dcache info */ +- build_append_int_noprefix(tbl, ARM_L1DCACHE_SIZE, 4); ++ cache_size = machine_get_cache_size(ms, CACHE_LEVEL_AND_TYPE_L1D); ++ build_append_int_noprefix(tbl, ++ cache_size > 0 ? cache_size : 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); ++ cache_size = machine_get_cache_size(ms, CACHE_LEVEL_AND_TYPE_L1I); ++ build_append_int_noprefix(tbl, ++ cache_size > 0 ? cache_size : 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_L1_CACHE: /* L1 cache info */ +- build_append_int_noprefix(tbl, ARM_L1CACHE_SIZE, 4); ++ cache_size = machine_get_cache_size(ms, CACHE_LEVEL_AND_TYPE_L1); ++ build_append_int_noprefix(tbl, ++ cache_size > 0 ? cache_size : ARM_L1CACHE_SIZE, ++ 4); + build_append_int_noprefix(tbl, ARM_L1CACHE_SETS, 4); + build_append_byte(tbl, ARM_L1CACHE_ASSOCIATIVITY); + build_append_byte(tbl, ARM_L1CACHE_ATTRIBUTES); + build_append_int_noprefix(tbl, ARM_L1CACHE_LINE_SIZE, 2); + break; + case ARM_L2_CACHE: /* L2 cache info */ +- build_append_int_noprefix(tbl, ARM_L2CACHE_SIZE, 4); ++ cache_size = machine_get_cache_size(ms, CACHE_LEVEL_AND_TYPE_L2); ++ build_append_int_noprefix(tbl, ++ cache_size > 0 ? cache_size : 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); ++ cache_size = machine_get_cache_size(ms, CACHE_LEVEL_AND_TYPE_L3); ++ build_append_int_noprefix(tbl, ++ cache_size > 0 ? cache_size : 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); +@@ -140,7 +156,7 @@ static void build_pptt_arm(GArray *table_data, BIOSLinker *linker, MachineState + + 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); ++ build_cache_hierarchy_node(ms, table_data, 0, ARM_L3_CACHE); + + g_queue_push_tail(list, + GUINT_TO_POINTER(table_data->len - pptt_start)); +@@ -179,16 +195,16 @@ static void build_pptt_arm(GArray *table_data, BIOSLinker *linker, MachineState + 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); ++ build_cache_hierarchy_node(ms, table_data, 0, ARM_L2_CACHE); + + if (unified_l1) { + priv_rsrc[1] = table_data->len - pptt_start; /* L1 cache offset */ +- build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1_CACHE); ++ build_cache_hierarchy_node(ms, table_data, priv_rsrc[0], ARM_L1_CACHE); + } else { + priv_rsrc[1] = table_data->len - pptt_start; /* L1 dcache offset */ +- build_cache_hierarchy_node(table_data, priv_rsrc[0], ARM_L1D_CACHE); ++ build_cache_hierarchy_node(ms, 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); ++ build_cache_hierarchy_node(ms, table_data, priv_rsrc[0], ARM_L1I_CACHE); + } + + if (ms->smp.threads > 1) { +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index d31675b0fd..c581f65a22 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -408,6 +408,7 @@ static void fdt_add_l3cache_nodes(const VirtMachineState *vms) + 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; ++ uint64_t cache_size = machine_get_cache_size(ms, CACHE_LEVEL_AND_TYPE_L3); + + for (i = 0; i < sockets; i++) { + char *nodename = g_strdup_printf("/cpus/l3-cache%d", i); +@@ -416,7 +417,8 @@ static void fdt_add_l3cache_nodes(const VirtMachineState *vms) + 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", ARM_L3CACHE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", ++ cache_size > 0 ? cache_size : ARM_L3CACHE_SIZE); + qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", + ARM_L3CACHE_LINE_SIZE); + qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", ARM_L3CACHE_SETS); +@@ -431,6 +433,7 @@ 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; ++ uint64_t cache_size = machine_get_cache_size(ms, CACHE_LEVEL_AND_TYPE_L2); + + for (cpu = 0; cpu < ms->smp.cpus; cpu++) { + char *next_path = g_strdup_printf("/cpus/l3-cache%d", +@@ -440,7 +443,8 @@ static void fdt_add_l2cache_nodes(const VirtMachineState *vms) + qemu_fdt_add_subnode(ms->fdt, nodename); + qemu_fdt_setprop_string(ms->fdt, nodename, "cache-unified", "true"); + qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cache"); +- qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", ARM_L2CACHE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", ++ cache_size > 0 ? cache_size : ARM_L2CACHE_SIZE); + qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", + ARM_L2CACHE_LINE_SIZE); + qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", ARM_L2CACHE_SETS); +@@ -460,21 +464,25 @@ static void fdt_add_l1cache_prop(const VirtMachineState *vms, + const MachineState *ms = MACHINE(vms); + char *next_path = g_strdup_printf("/cpus/l2-cache%d", cpu); + bool unified_l1 = cpu_l1_cache_unified(0); ++ uint64_t l1d_cache_size = machine_get_cache_size(ms, CACHE_LEVEL_AND_TYPE_L1D); ++ uint64_t l1i_cache_size = machine_get_cache_size(ms, CACHE_LEVEL_AND_TYPE_L1I); ++ uint64_t l1_cache_size = machine_get_cache_size(ms, CACHE_LEVEL_AND_TYPE_L1); + + if (unified_l1) { +- qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", ARM_L1CACHE_SIZE); ++ qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-size", ++ l1_cache_size > 0 ? l1_cache_size : ARM_L1CACHE_SIZE); + qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-line-size", + ARM_L1CACHE_LINE_SIZE); + qemu_fdt_setprop_cell(ms->fdt, nodename, "cache-sets", ARM_L1CACHE_SETS); + } else { + qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-size", +- ARM_L1DCACHE_SIZE); ++ l1d_cache_size > 0 ? l1d_cache_size : ARM_L1DCACHE_SIZE); + qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-line-size", + ARM_L1DCACHE_LINE_SIZE); + qemu_fdt_setprop_cell(ms->fdt, nodename, "d-cache-sets", + ARM_L1DCACHE_SETS); + qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-size", +- ARM_L1ICACHE_SIZE); ++ l1i_cache_size > 0 ? l1i_cache_size : ARM_L1ICACHE_SIZE); + qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-line-size", + ARM_L1ICACHE_LINE_SIZE); + qemu_fdt_setprop_cell(ms->fdt, nodename, "i-cache-sets", +diff --git a/hw/core/machine-smp.c b/hw/core/machine-smp.c +index a421a394d4..47922ec4aa 100644 +--- a/hw/core/machine-smp.c ++++ b/hw/core/machine-smp.c +@@ -212,8 +212,22 @@ bool machine_parse_smp_cache(MachineState *ms, + return false; + } + ++ machine_set_cache_size(ms, node->value->cache, ++ node->value->size); + set_bit(node->value->cache, caches_bitmap); + } + + return true; ++} ++ ++uint64_t machine_get_cache_size(const MachineState *ms, ++ CacheLevelAndType cache) ++{ ++ return ms->smp_cache.props[cache].size; ++} ++ ++void machine_set_cache_size(MachineState *ms, CacheLevelAndType cache, ++ uint64_t size) ++{ ++ ms->smp_cache.props[cache].size = size; + } +\ No newline at end of file +diff --git a/hw/core/machine.c b/hw/core/machine.c +index 4cdd9a7300..35a7c1d328 100644 +--- a/hw/core/machine.c ++++ b/hw/core/machine.c +@@ -789,6 +789,7 @@ static void machine_get_smp_cache(Object *obj, Visitor *v, const char *name, + SmpCacheProperties *node = g_new(SmpCacheProperties, 1); + + node->cache = cache->props[i].cache; ++ node->size = cache->props[i].size; + QAPI_LIST_APPEND(tail, node); + } + +@@ -989,6 +990,7 @@ static void machine_initfn(Object *obj) + + for (int i = 0; i < CACHE_LEVEL_AND_TYPE__MAX; i++) { + ms->smp_cache.props[i].cache = (CacheLevelAndType)i; ++ ms->smp_cache.props[i].size = 0; + } + } + +diff --git a/include/hw/boards.h b/include/hw/boards.h +index 59f04caf3f..f7ba05c56a 100644 +--- a/include/hw/boards.h ++++ b/include/hw/boards.h +@@ -39,6 +39,10 @@ void machine_parse_smp_config(MachineState *ms, + bool machine_parse_smp_cache(MachineState *ms, + const SmpCachePropertiesList *caches, + Error **errp); ++uint64_t machine_get_cache_size(const MachineState *ms, ++ CacheLevelAndType cache); ++void machine_set_cache_size(MachineState *ms, CacheLevelAndType cache, ++ uint64_t size); + + /** + * machine_class_allow_dynamic_sysbus_dev: Add type to list of valid devices +diff --git a/qapi/machine.json b/qapi/machine.json +index 676e16477b..c12fa1e399 100644 +--- a/qapi/machine.json ++++ b/qapi/machine.json +@@ -1581,14 +1581,16 @@ + # + # @l1i: L1 instruction cache. + # ++# @l1: L1 (unified) cache. ++# + # @l2: L2 (unified) cache. + # + # @l3: L3 (unified) cache + # +-# Since: 9.2 ++# Since: 6.2 + ## + { 'enum': 'CacheLevelAndType', +- 'data': [ 'l1d', 'l1i', 'l2', 'l3' ] } ++ 'data': [ 'l1d', 'l1i', 'l1', 'l2', 'l3' ] } + + ## + # @SmpCacheProperties: +@@ -1597,11 +1599,14 @@ + # + # @cache: Cache name, which is the combination of cache level and cache type. + # +-# Since: 9.2 ++# @size: Cache size in units of Byte. ++# ++# Since: 6.2 + ## + { 'struct': 'SmpCacheProperties', + 'data': { +- 'cache': 'CacheLevelAndType' } } ++ 'cache': 'CacheLevelAndType', ++ 'size': 'uint64' } } + + ## + # @SmpCachePropertiesWrapper: +@@ -1610,7 +1615,7 @@ + # + # @caches: the list of SmpCacheProperties. + # +-# Since 9.2 ++# Since 6.2 + ## + { 'struct': 'SmpCachePropertiesWrapper', + 'data': { 'caches': ['SmpCacheProperties'] } } +-- +2.41.0.windows.1 + diff --git a/qemu.spec b/qemu.spec index ae0976ba..887b98a5 100644 --- a/qemu.spec +++ b/qemu.spec @@ -3,7 +3,7 @@ Name: qemu Version: 6.2.0 -Release: 106 +Release: 107 Epoch: 10 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -1178,6 +1178,10 @@ Patch1163: iotests-308-Fix-for-CAP_DAC_OVERRIDE.patch Patch1164: edid-set-default-resolution-to-1280x800-WXGA.patch Patch1165: tests-avocado-machine_s390_ccw_virtio-Adapt-test-to-.patch Patch1166: hw-nvme-Remove-redundant-dma_blk_write.patch +Patch1167: linux-aio-fix-unbalanced-plugged-counter-in-laio_io_.patch +Patch1168: qapi-qom-Define-cache-enumeration-and-properties-for.patch +Patch1169: hw-core-machine-smp-Initialize-caches_bitmap-before-.patch +Patch1170: qemu-Support-specifying-the-cache-size-presented-to-.patch BuildRequires: flex BuildRequires: gcc @@ -1776,6 +1780,12 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Wed Mar 26 2025 - 10:6.2.0-107 +- qemu: Support specifying the cache size presented to guest +- hw/core/machine-smp: Initialize caches_bitmap before reading +- qapi/qom: Define cache enumeration and properties for machine +- linux-aio: fix unbalanced plugged counter in laio_io_unplug() + * Fri Feb 21 2025 - 10:6.2.0-106 - hw/nvme: Remove redundant dma_blk_write - tests/avocado/machine_s390_ccw_virtio: Adapt test to new default resolution -- Gitee