From fa68ecb330dbdfeefa7f4d11e30c939da13853b0 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 6 Nov 2023 15:00:26 +0000 Subject: [PATCH 01/12] hw/arm/virt: fix PMU IRQ registration Since commit 9036e917f8 ("{include/}hw/arm: refactor virt PPI logic") PMU IRQ registration fails for arm64 guests: [ 0.563689] hw perfevents: unable to request IRQ14 for ARM PMU counters [ 0.565160] armv8-pmu: probe of pmu failed with error -22 That commit re-defined VIRTUAL_PMU_IRQ to be a INTID but missed a case where the PMU IRQ is actually referred by its PPI index. Fix that by using INTID_TO_PPI() in that case. Fixes: 9036e917f8 ("{include/}hw/arm: refactor virt PPI logic") Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1960 Signed-off-by: Sebastian Ott Reviewed-by: Peter Maydell Message-id: 475d918d-ab0e-f717-7206-57a5beb28c7b@redhat.com Signed-off-by: Peter Maydell --- hw/arm/virt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 92085d2d8f..0a16ab3095 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -631,7 +631,8 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms) qemu_fdt_setprop(ms->fdt, "/pmu", "compatible", compat, sizeof(compat)); qemu_fdt_setprop_cells(ms->fdt, "/pmu", "interrupts", - GIC_FDT_IRQ_TYPE_PPI, VIRTUAL_PMU_IRQ, irqflags); + GIC_FDT_IRQ_TYPE_PPI, + INTID_TO_PPI(VIRTUAL_PMU_IRQ), irqflags); } } From 1eb2888ecd55ace57b37009492f11cd53a6f4148 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 6 Nov 2023 15:00:26 +0000 Subject: [PATCH 02/12] tests/qtest/bios-tables-test: Allow changes to virt SPCR and DBG2 Allow changes to the virt board SPCR and DBG2 -- we are going to fix an error in the UART descriptions there. Signed-off-by: Peter Maydell --- tests/qtest/bios-tables-test-allowed-diff.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..6673e2c4c1 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,3 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/virt/SPCR", +"tests/data/acpi/virt/DBG2", From 41f7b58b634ec3b60ae874375d2bbb61d790971e Mon Sep 17 00:00:00 2001 From: Udo Steinberg Date: Mon, 6 Nov 2023 15:00:26 +0000 Subject: [PATCH 03/12] hw/arm/virt: Report correct register sizes in ACPI DBG2/SPCR tables. Documentation for using the GAS in ACPI tables to report debug UART addresses at https://learn.microsoft.com/en-us/windows-hardware/drivers/bringup/acpi-debug-port-table states the following: - The Register Bit Width field contains the register stride and must be a power of 2 that is at least as large as the access size. On 32-bit platforms this value cannot exceed 32. On 64-bit platforms this value cannot exceed 64. - The Access Size field is used to determine whether byte, WORD, DWORD, or QWORD accesses are to be used. QWORD accesses are only valid on 64-bit architectures. Documentation for the ARM PL011 at https://developer.arm.com/documentation/ddi0183/latest/ states that the registers are: - spaced 4 bytes apart (see Table 3-2), so register stride must be 32. - 16 bits in size in some cases (see individual registers), so access size must be at least 2. Linux doesn't seem to care about this error in the table, but it does affect at least the NOVA microhypervisor. In theory we therefore have a choice between reporting the access size as 2 (16 bit accesses) or 3 (32-bit accesses). In practice, Linux does not correctly handle the case where the table reports the access size as 2: as of kernel commit 750b95887e5678, the code in acpi_parse_spcr() tries to tell the serial driver to use 16 bit accesses by passing "mmio16" in the option string, but the PL011 driver code in pl011_console_match() only recognizes "mmio" or "mmio32". The result is that unless the user has enabled 'earlycon' there is no console output from the guest kernel. We therefore choose to report the access size as 32 bits; this works for NOVA and also for Linux. It is also what the UEFI firmware on a Raspberry Pi 4 reports, so we're in line with existing real-world practice. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1938 Signed-off-by: Udo Steinberg Reviewed-by: Peter Maydell [PMM: minor commit message tweaks; use 32 bit accesses] Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 9ce136cd88..8bc35a483c 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -482,7 +482,7 @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) build_append_int_noprefix(table_data, 3, 1); /* ARM PL011 UART */ build_append_int_noprefix(table_data, 0, 3); /* Reserved */ /* Base Address */ - build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 8, 0, 1, + build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 32, 0, 3, vms->memmap[VIRT_UART].base); /* Interrupt Type */ build_append_int_noprefix(table_data, @@ -673,7 +673,7 @@ build_dbg2(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) build_append_int_noprefix(table_data, 34, 2); /* BaseAddressRegister[] */ - build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 8, 0, 1, + build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 32, 0, 3, vms->memmap[VIRT_UART].base); /* AddressSize[] */ From 806f71eecf643d029099e57fae2199f678845d98 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 6 Nov 2023 15:00:27 +0000 Subject: [PATCH 04/12] tests/qtest/bios-tables-test: Update virt SPCR and DBG2 golden references Update the virt SPCR and DBG2 golden reference files to have the fix for the description of the UART. Diffs from iasl: @@ -1,57 +1,57 @@ /* * Intel ACPI Component Architecture * AML/ASL+ Disassembler version 20200925 (64-bit version) * Copyright (c) 2000 - 2020 Intel Corporation * - * Disassembly of tests/data/acpi/virt/SPCR, Fri Nov 3 14:12:06 2023 + * Disassembly of /tmp/aml-E6YUD2, Fri Nov 3 14:12:06 2023 * * ACPI Data Table [SPCR] * * Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue */ [000h 0000 4] Signature : "SPCR" [Serial Port Console Redirection table] [004h 0004 4] Table Length : 00000050 [008h 0008 1] Revision : 02 -[009h 0009 1] Checksum : CB +[009h 0009 1] Checksum : B1 [00Ah 0010 6] Oem ID : "BOCHS " [010h 0016 8] Oem Table ID : "BXPC " [018h 0024 4] Oem Revision : 00000001 [01Ch 0028 4] Asl Compiler ID : "BXPC" [020h 0032 4] Asl Compiler Revision : 00000001 [024h 0036 1] Interface Type : 03 [025h 0037 3] Reserved : 000000 [028h 0040 12] Serial Port Register : [Generic Address Structure] [028h 0040 1] Space ID : 00 [SystemMemory] -[029h 0041 1] Bit Width : 08 +[029h 0041 1] Bit Width : 20 [02Ah 0042 1] Bit Offset : 00 -[02Bh 0043 1] Encoded Access Width : 01 [Byte Access:8] +[02Bh 0043 1] Encoded Access Width : 03 [DWord Access:32] [02Ch 0044 8] Address : 0000000009000000 [034h 0052 1] Interrupt Type : 08 [035h 0053 1] PCAT-compatible IRQ : 00 [036h 0054 4] Interrupt : 00000021 [03Ah 0058 1] Baud Rate : 03 [03Bh 0059 1] Parity : 00 [03Ch 0060 1] Stop Bits : 01 [03Dh 0061 1] Flow Control : 02 [03Eh 0062 1] Terminal Type : 00 [04Ch 0076 1] Reserved : 00 [040h 0064 2] PCI Device ID : FFFF [042h 0066 2] PCI Vendor ID : FFFF [044h 0068 1] PCI Bus : 00 [045h 0069 1] PCI Device : 00 [046h 0070 1] PCI Function : 00 [047h 0071 4] PCI Flags : 00000000 [04Bh 0075 1] PCI Segment : 00 [04Ch 0076 4] Reserved : 00000000 Raw Table Data: Length 80 (0x50) - 0000: 53 50 43 52 50 00 00 00 02 CB 42 4F 43 48 53 20 // SPCRP.....BOCHS + 0000: 53 50 43 52 50 00 00 00 02 B1 42 4F 43 48 53 20 // SPCRP.....BOCHS 0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC - 0020: 01 00 00 00 03 00 00 00 00 08 00 01 00 00 00 09 // ................ + 0020: 01 00 00 00 03 00 00 00 00 20 00 03 00 00 00 09 // ......... ...... 0030: 00 00 00 00 08 00 21 00 00 00 03 00 01 02 00 00 // ......!......... 0040: FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 // ................ @@ -1,57 +1,57 @@ /* * Intel ACPI Component Architecture * AML/ASL+ Disassembler version 20200925 (64-bit version) * Copyright (c) 2000 - 2020 Intel Corporation * - * Disassembly of tests/data/acpi/virt/DBG2, Fri Nov 3 14:12:06 2023 + * Disassembly of /tmp/aml-V1YUD2, Fri Nov 3 14:12:06 2023 * * ACPI Data Table [DBG2] * * Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue */ [000h 0000 4] Signature : "DBG2" [Debug Port table type 2] [004h 0004 4] Table Length : 00000057 [008h 0008 1] Revision : 00 -[009h 0009 1] Checksum : CF +[009h 0009 1] Checksum : B5 [00Ah 0010 6] Oem ID : "BOCHS " [010h 0016 8] Oem Table ID : "BXPC " [018h 0024 4] Oem Revision : 00000001 [01Ch 0028 4] Asl Compiler ID : "BXPC" [020h 0032 4] Asl Compiler Revision : 00000001 [024h 0036 4] Info Offset : 0000002C [028h 0040 4] Info Count : 00000001 [02Ch 0044 1] Revision : 00 [02Dh 0045 2] Length : 002B [02Fh 0047 1] Register Count : 01 [030h 0048 2] Namepath Length : 0005 [032h 0050 2] Namepath Offset : 0026 [034h 0052 2] OEM Data Length : 0000 [Optional field not present] [036h 0054 2] OEM Data Offset : 0000 [Optional field not present] [038h 0056 2] Port Type : 8000 [03Ah 0058 2] Port Subtype : 0003 [03Ch 0060 2] Reserved : 0000 [03Eh 0062 2] Base Address Offset : 0016 [040h 0064 2] Address Size Offset : 0022 [042h 0066 12] Base Address Register : [Generic Address Structure] [042h 0066 1] Space ID : 00 [SystemMemory] -[043h 0067 1] Bit Width : 08 +[043h 0067 1] Bit Width : 20 [044h 0068 1] Bit Offset : 00 -[045h 0069 1] Encoded Access Width : 01 [Byte Access:8] +[045h 0069 1] Encoded Access Width : 03 [DWord Access:32] [046h 0070 8] Address : 0000000009000000 [04Eh 0078 4] Address Size : 00001000 [052h 0082 5] Namepath : "COM0" Raw Table Data: Length 87 (0x57) - 0000: 44 42 47 32 57 00 00 00 00 CF 42 4F 43 48 53 20 // DBG2W.....BOCHS + 0000: 44 42 47 32 57 00 00 00 00 B5 42 4F 43 48 53 20 // DBG2W.....BOCHS 0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC 0020: 01 00 00 00 2C 00 00 00 01 00 00 00 00 2B 00 01 // ....,........+.. 0030: 05 00 26 00 00 00 00 00 00 80 03 00 00 00 16 00 // ..&............. - 0040: 22 00 00 08 00 01 00 00 00 09 00 00 00 00 00 10 // "............... + 0040: 22 00 00 20 00 03 00 00 00 09 00 00 00 00 00 10 // ".. ............ 0050: 00 00 43 4F 4D 30 00 // ..COM0. Signed-off-by: Peter Maydell --- tests/data/acpi/virt/DBG2 | Bin 87 -> 87 bytes tests/data/acpi/virt/SPCR | Bin 80 -> 80 bytes tests/qtest/bios-tables-test-allowed-diff.h | 2 -- 3 files changed, 2 deletions(-) diff --git a/tests/data/acpi/virt/DBG2 b/tests/data/acpi/virt/DBG2 index 86e6314f7b0235ef8ed3e0221e09f996c41f5e98..0a05e1a47f9c303c6a6c9ca8414c62ec4ac90f98 100644 GIT binary patch delta 37 ncmWF!=W=m!HwtF}f~^y|EJYL;n1M`A5T8MSfx+3|*MI>4b2kL{ delta 37 ncmWF!=W=m!HwtF}g7Xu(EJZjN7=cVq5T8MSfx+3|*MI>4bG-!j diff --git a/tests/data/acpi/virt/SPCR b/tests/data/acpi/virt/SPCR index 24e0a579e7d73f432a614380e29aa95113344186..cf0f2b75226515097c08d2e2016a83a4f08812ba 100644 GIT binary patch delta 23 ecmWFt;0g|K4hmpkU|`xfkxQOgfq{9VjtT%gOa!L@ delta 23 ecmWFt;0g|K4hmpkU|>2ukxQPLgMo3PjtT%g(gddf diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index 6673e2c4c1..dfb8523c8b 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1,3 +1 @@ /* List of comma-separated changed AML files to ignore */ -"tests/data/acpi/virt/SPCR", -"tests/data/acpi/virt/DBG2", From 212c5fe1914a192b01f337b7392fca75a7ab4071 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Mon, 6 Nov 2023 15:00:27 +0000 Subject: [PATCH 05/12] hw/i386/intel_iommu: vtd_slpte_nonzero_rsvd(): assert no overflow We support only 3- and 4-level page-tables, which is firstly checked in vtd_decide_config(), then setup in vtd_init(). Than level fields are checked by vtd_is_level_supported(). So here we can't have level out from 1..4 inclusive range. Let's assert it. That also explains Coverity that we are not going to overflow the array. CID: 1487158, 1487186 Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Peter Maydell Reviewed-by: Maksim Davydov Message-id: 20231017125941.810461-2-vsementsov@yandex-team.ru Signed-off-by: Peter Maydell --- hw/i386/intel_iommu.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 1c6c18622f..1a44ef696c 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -1045,18 +1045,35 @@ static dma_addr_t vtd_get_iova_pgtbl_base(IntelIOMMUState *s, * Rsvd field masks for spte: * vtd_spte_rsvd 4k pages * vtd_spte_rsvd_large large pages + * + * We support only 3-level and 4-level page tables (see vtd_init() which + * sets only VTD_CAP_SAGAW_39bit and maybe VTD_CAP_SAGAW_48bit bits in s->cap). */ -static uint64_t vtd_spte_rsvd[5]; -static uint64_t vtd_spte_rsvd_large[5]; +#define VTD_SPTE_RSVD_LEN 5 +static uint64_t vtd_spte_rsvd[VTD_SPTE_RSVD_LEN]; +static uint64_t vtd_spte_rsvd_large[VTD_SPTE_RSVD_LEN]; static bool vtd_slpte_nonzero_rsvd(uint64_t slpte, uint32_t level) { - uint64_t rsvd_mask = vtd_spte_rsvd[level]; + uint64_t rsvd_mask; + + /* + * We should have caught a guest-mis-programmed level earlier, + * via vtd_is_level_supported. + */ + assert(level < VTD_SPTE_RSVD_LEN); + /* + * Zero level doesn't exist. The smallest level is VTD_SL_PT_LEVEL=1 and + * checked by vtd_is_last_slpte(). + */ + assert(level); if ((level == VTD_SL_PD_LEVEL || level == VTD_SL_PDP_LEVEL) && (slpte & VTD_SL_PT_PAGE_SIZE_MASK)) { /* large page */ rsvd_mask = vtd_spte_rsvd_large[level]; + } else { + rsvd_mask = vtd_spte_rsvd[level]; } return slpte & rsvd_mask; From 2e12dd405c6607b4f4566d4a93b79422213ba6a3 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Mon, 6 Nov 2023 15:00:27 +0000 Subject: [PATCH 06/12] util/filemonitor-inotify: qemu_file_monitor_watch(): assert no overflow Prefer clear assertions instead of [im]possible array overflow. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Peter Maydell Reviewed-by: Maksim Davydov Message-id: 20231017125941.810461-3-vsementsov@yandex-team.ru Signed-off-by: Peter Maydell --- util/filemonitor-inotify.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/util/filemonitor-inotify.c b/util/filemonitor-inotify.c index 2c45f7f176..2121111f38 100644 --- a/util/filemonitor-inotify.c +++ b/util/filemonitor-inotify.c @@ -81,16 +81,25 @@ static void qemu_file_monitor_watch(void *arg) /* Loop over all events in the buffer */ while (used < len) { - struct inotify_event *ev = - (struct inotify_event *)(buf + used); - const char *name = ev->len ? ev->name : ""; - QFileMonitorDir *dir = g_hash_table_lookup(mon->idmap, - GINT_TO_POINTER(ev->wd)); - uint32_t iev = ev->mask & - (IN_CREATE | IN_MODIFY | IN_DELETE | IN_IGNORED | - IN_MOVED_TO | IN_MOVED_FROM | IN_ATTRIB); + const char *name; + QFileMonitorDir *dir; + uint32_t iev; int qev; gsize i; + struct inotify_event *ev = (struct inotify_event *)(buf + used); + + /* + * We trust the kenel to provide valid buffer with complete event + * records. + */ + assert(len - used >= sizeof(struct inotify_event)); + assert(len - used - sizeof(struct inotify_event) >= ev->len); + + name = ev->len ? ev->name : ""; + dir = g_hash_table_lookup(mon->idmap, GINT_TO_POINTER(ev->wd)); + iev = ev->mask & + (IN_CREATE | IN_MODIFY | IN_DELETE | IN_IGNORED | + IN_MOVED_TO | IN_MOVED_FROM | IN_ATTRIB); used += sizeof(struct inotify_event) + ev->len; From 394bca2fa443cd1c1c3dad931fcce4fa96f88941 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Mon, 6 Nov 2023 15:00:27 +0000 Subject: [PATCH 07/12] mc146818rtc: rtc_set_time(): initialize tm to zeroes set_time() function doesn't set all the fields, so it's better to initialize tm structure. And Coverity will be happier about it. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Peter Maydell Reviewed-by: Maksim Davydov Message-id: 20231017125941.810461-4-vsementsov@yandex-team.ru Signed-off-by: Peter Maydell --- hw/rtc/mc146818rtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c index c27c362db9..2d391a8396 100644 --- a/hw/rtc/mc146818rtc.c +++ b/hw/rtc/mc146818rtc.c @@ -599,7 +599,7 @@ static void rtc_get_time(MC146818RtcState *s, struct tm *tm) static void rtc_set_time(MC146818RtcState *s) { - struct tm tm; + struct tm tm = {}; g_autofree const char *qom_path = object_get_canonical_path(OBJECT(s)); rtc_get_time(s, &tm); From cc8fb0c3ae3c950eb40e969607e17ff16a7519ac Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Mon, 6 Nov 2023 15:00:28 +0000 Subject: [PATCH 08/12] block/nvme: nvme_process_completion() fix bound for cid NVMeQueuePair::reqs has length NVME_NUM_REQS, which less than NVME_QUEUE_SIZE by 1. Fixes: 1086e95da17050 ("block/nvme: switch to a NVMeRequest freelist") Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Stefan Hajnoczi Reviewed-by: Maksim Davydov Message-id: 20231017125941.810461-5-vsementsov@yandex-team.ru Signed-off-by: Peter Maydell --- block/nvme.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/block/nvme.c b/block/nvme.c index 96b3f8f2fa..0a0a0a6b36 100644 --- a/block/nvme.c +++ b/block/nvme.c @@ -417,9 +417,10 @@ static bool nvme_process_completion(NVMeQueuePair *q) q->cq_phase = !q->cq_phase; } cid = le16_to_cpu(c->cid); - if (cid == 0 || cid > NVME_QUEUE_SIZE) { - warn_report("NVMe: Unexpected CID in completion queue: %"PRIu32", " - "queue size: %u", cid, NVME_QUEUE_SIZE); + if (cid == 0 || cid > NVME_NUM_REQS) { + warn_report("NVMe: Unexpected CID in completion queue: %" PRIu32 + ", should be within: 1..%u inclusively", cid, + NVME_NUM_REQS); continue; } trace_nvme_complete_command(s, q->index, cid); From 59a3aff685fdb930244c7aa439e121b60e50f266 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Mon, 6 Nov 2023 15:00:28 +0000 Subject: [PATCH 09/12] hw/core/loader: gunzip(): initialize z_stream Coverity signals that variable as being used uninitialized. And really, when work with external APIs that's better to zero out the structure, where we set some fields by hand. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Peter Maydell Reviewed-by: Maksim Davydov Message-id: 20231017125941.810461-6-vsementsov@yandex-team.ru Signed-off-by: Peter Maydell --- hw/core/loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/core/loader.c b/hw/core/loader.c index 4dd5a71fb7..b7bb44b7f7 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -558,7 +558,7 @@ static void zfree(void *x, void *addr) ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, size_t srclen) { - z_stream s; + z_stream s = {}; ssize_t dstbytes; int r, i, flags; From 35bafa95da671f5a902e87fcc301f76f82cd0831 Mon Sep 17 00:00:00 2001 From: Vladimir Sementsov-Ogievskiy Date: Mon, 6 Nov 2023 15:00:28 +0000 Subject: [PATCH 10/12] io/channel-socket: qio_channel_socket_flush(): improve msg validation For SO_EE_ORIGIN_ZEROCOPY the 32-bit notification range is encoded as [ee_info, ee_data] inclusively, so ee_info should be less or equal to ee_data. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Maksim Davydov Message-id: 20231017125941.810461-7-vsementsov@yandex-team.ru Signed-off-by: Peter Maydell --- io/channel-socket.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/io/channel-socket.c b/io/channel-socket.c index 02ffb51e99..3a899b0608 100644 --- a/io/channel-socket.c +++ b/io/channel-socket.c @@ -782,6 +782,11 @@ static int qio_channel_socket_flush(QIOChannel *ioc, "Error not from zero copy"); return -1; } + if (serr->ee_data < serr->ee_info) { + error_setg_errno(errp, serr->ee_origin, + "Wrong notification bounds"); + return -1; + } /* No errors, count successfully finished sendmsg()*/ sioc->zero_copy_sent += serr->ee_data - serr->ee_info + 1; From 13edcf591e74fd8a0e69f01b8b09f53397562103 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 6 Nov 2023 15:00:29 +0000 Subject: [PATCH 11/12] hw/arm/vexpress-a9: Remove useless mapping of RAM at address 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the vexpress-a9 board we try to map both RAM and flash to address 0, as seen in "info mtree": address-space: memory 0000000000000000-ffffffffffffffff (prio 0, i/o): system 0000000000000000-0000000003ffffff (prio 0, romd): alias vexpress.flashalias @vexpress.flash0 0000000000000000-0000000003ffffff 0000000000000000-0000000003ffffff (prio 0, ram): alias vexpress.lowmem @vexpress.highmem 0000000000000000-0000000003ffffff 0000000010000000-0000000010000fff (prio 0, i/o): arm-sysctl 0000000010004000-0000000010004fff (prio 0, i/o): pl041 (etc) The flash "wins" and the RAM mapping is useless (but also harmless). This happened as a result of commit 6ec1588e in 2014, which changed "we always map the RAM to the low addresses for vexpress-a9" to "we always map flash in the low addresses", but forgot to stop mapping the RAM. In real hardware, this low part of memory is remappable, both at runtime by the guest writing to a control register, and configurably as to what you get out of reset -- you can have the first flash device, or the second, or the DDR2 RAM, or the external AXI bus (which for QEMU means "nothing there"). In an ideal world we would support that remapping both at runtime and via a machine property to select the out-of-reset behaviour. Pending anybody caring enough to implement the full remapping behaviour: * remove the useless mapped-but-inaccessible lowram MR * document that QEMU doesn't support remapping of low memory Fixes: 6ec1588e ("hw/arm/vexpress: Alias NOR flash at 0 for vexpress-a9") Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1761 Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20231103185602.875849-1-peter.maydell@linaro.org --- docs/system/arm/vexpress.rst | 3 +++ hw/arm/vexpress.c | 14 +++----------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/docs/system/arm/vexpress.rst b/docs/system/arm/vexpress.rst index 3e3839e923..38f29c73e7 100644 --- a/docs/system/arm/vexpress.rst +++ b/docs/system/arm/vexpress.rst @@ -58,6 +58,9 @@ Other differences between the hardware and the QEMU model: ``vexpress-a15``, and have IRQs from 40 upwards. If a dtb is provided on the command line then QEMU will edit it to include suitable entries describing these transports for the guest. +- QEMU does not currently support either dynamic or static remapping + of the area of memory at address 0: it is always mapped to alias + the first flash bank Booting a Linux kernel ---------------------- diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 8ff37f52ca..c08ea34e92 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -177,7 +177,6 @@ struct VexpressMachineState { MemoryRegion vram; MemoryRegion sram; MemoryRegion flashalias; - MemoryRegion lowram; MemoryRegion a15sram; bool secure; bool virt; @@ -276,7 +275,6 @@ static void a9_daughterboard_init(VexpressMachineState *vms, { MachineState *machine = MACHINE(vms); MemoryRegion *sysmem = get_system_memory(); - ram_addr_t low_ram_size; if (ram_size > 0x40000000) { /* 1GB is the maximum the address space permits */ @@ -284,17 +282,11 @@ static void a9_daughterboard_init(VexpressMachineState *vms, exit(1); } - low_ram_size = ram_size; - if (low_ram_size > 0x4000000) { - low_ram_size = 0x4000000; - } - /* RAM is from 0x60000000 upwards. The bottom 64MB of the + /* + * RAM is from 0x60000000 upwards. The bottom 64MB of the * address space should in theory be remappable to various - * things including ROM or RAM; we always map the RAM there. + * things including ROM or RAM; we always map the flash there. */ - memory_region_init_alias(&vms->lowram, NULL, "vexpress.lowmem", - machine->ram, 0, low_ram_size); - memory_region_add_subregion(sysmem, 0x0, &vms->lowram); memory_region_add_subregion(sysmem, 0x60000000, machine->ram); /* 0x1e000000 A9MPCore (SCU) private memory region */ From 5722fc471296d5f042df4b005a851cc8008df0c9 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 6 Nov 2023 15:00:29 +0000 Subject: [PATCH 12/12] target/arm: Fix A64 LDRA immediate decode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit be23a049 in the conversion to decodetree we broke the decoding of the immediate value in the LDRA instruction. This should be a 10 bit signed value that is scaled by 8, but in the conversion we incorrectly ended up scaling it only by 2. Fix the scaling factor. Cc: qemu-stable@nongnu.org Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1970 Fixes: be23a049 ("target/arm: Convert load (pointer auth) insns to decodetree") Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Message-id: 20231106113445.1163063-1-peter.maydell@linaro.org --- target/arm/tcg/a64.decode | 2 +- target/arm/tcg/translate.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode index 0cf1147074..8a20dce3c8 100644 --- a/target/arm/tcg/a64.decode +++ b/target/arm/tcg/a64.decode @@ -462,7 +462,7 @@ LDAPR sz:2 111 0 00 1 0 1 11111 1100 00 rn:5 rt:5 # Load/store register (pointer authentication) # LDRA immediate is 10 bits signed and scaled, but the bits aren't all contiguous -%ldra_imm 22:s1 12:9 !function=times_2 +%ldra_imm 22:s1 12:9 !function=times_8 LDRA 11 111 0 00 m:1 . 1 ......... w:1 1 rn:5 rt:5 imm=%ldra_imm diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h index 9efe00cf6c..3c3bb3431a 100644 --- a/target/arm/tcg/translate.h +++ b/target/arm/tcg/translate.h @@ -205,6 +205,11 @@ static inline int times_4(DisasContext *s, int x) return x * 4; } +static inline int times_8(DisasContext *s, int x) +{ + return x * 8; +} + static inline int times_2_plus_1(DisasContext *s, int x) { return x * 2 + 1;