Selaa lähdekoodia

Merge tag 'pull-target-arm-20231106' of https://git.linaro.org/people/pmaydell/qemu-arm into staging

target-arm queue:
 * hw/arm/virt: fix PMU IRQ registration
 * hw/arm/virt: Report correct register sizes in ACPI DBG2/SPCR tables
 * hw/i386/intel_iommu: vtd_slpte_nonzero_rsvd(): assert no overflow
 * util/filemonitor-inotify: qemu_file_monitor_watch(): assert no overflow
 * mc146818rtc: rtc_set_time(): initialize tm to zeroes
 * block/nvme: nvme_process_completion() fix bound for cid
 * hw/core/loader: gunzip(): initialize z_stream
 * io/channel-socket: qio_channel_socket_flush(): improve msg validation
 * hw/arm/vexpress-a9: Remove useless mapping of RAM at address 0
 * target/arm: Fix A64 LDRA immediate decode

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmVJBtUZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3qYTEACYqLV57JezgRFXzMEwKX3l
# 9IYbFje+lGemobdJOEHhRvXjCNb+5TwhEfQasri0FBzokw16S3WOOF7roGb6YOU1
# od1SGiS2AbrmiazlBpamVO8z0WAEgbnXIoQa/3xKAGPJXszD2zK+06KnXS5xuCuD
# nHojzIx7Gv4HEIs4huY39/YL2HMaxrqvXC8IAu51eqY+TPnETT+WI3HxlZ2OMIsn
# 1Jnn+FeZfA1bhKx4JsD9MyHM1ovbjOwYkHOlzjU6fmTFFPGKRy0nxnjMNCBcXHQ+
# unemc/9BhEFup76tkX+JIlSBrPre5Mnh93DsGKSapwKPKq+fQhUDmzXY2r3OvQZX
# ryxO4PJkCNTM1wZU6GeEDPWVfhgBKHUMv+tr9Mf9iBlyXRsmXLSEl7AFUUaFlgAL
# dSMyiAaUlfvGa7Gtta9eFAJ/GeaiuJu2CYq6lvtRrNIHflLm3gVCef8gmwM5Eqxm
# 3PNzEoabKyQQfz69j9RCLpoutMBq1sg2IzxW8UjAFupugcIABjLf0Sl11qA0/B89
# YX67B0ynQD9ajI2GS8ULid/tvEiJVgdZ2Ua3U3xpG54vKG1/54EUiCP8TtoIuoMy
# bKg8AU9EIPN962PxoAwS+bSSdCu7/zBjVpg4T/zIzWRdgSjRsE21Swu5Ca934ng5
# VpVUuiwtI/zvHgqaiORu+w==
# =UbqJ
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 06 Nov 2023 23:31:33 HKT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]
# gpg:                 aka "Peter Maydell <peter@archaic.org.uk>" [unknown]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* tag 'pull-target-arm-20231106' of https://git.linaro.org/people/pmaydell/qemu-arm:
  target/arm: Fix A64 LDRA immediate decode
  hw/arm/vexpress-a9: Remove useless mapping of RAM at address 0
  io/channel-socket: qio_channel_socket_flush(): improve msg validation
  hw/core/loader: gunzip(): initialize z_stream
  block/nvme: nvme_process_completion() fix bound for cid
  mc146818rtc: rtc_set_time(): initialize tm to zeroes
  util/filemonitor-inotify: qemu_file_monitor_watch(): assert no overflow
  hw/i386/intel_iommu: vtd_slpte_nonzero_rsvd(): assert no overflow
  tests/qtest/bios-tables-test: Update virt SPCR and DBG2 golden references
  hw/arm/virt: Report correct register sizes in ACPI DBG2/SPCR tables.
  tests/qtest/bios-tables-test: Allow changes to virt SPCR and DBG2
  hw/arm/virt: fix PMU IRQ registration

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Stefan Hajnoczi 1 vuosi sitten
vanhempi
commit
f6b174ff96

+ 4 - 3
block/nvme.c

@@ -417,9 +417,10 @@ static bool nvme_process_completion(NVMeQueuePair *q)
             q->cq_phase = !q->cq_phase;
             q->cq_phase = !q->cq_phase;
         }
         }
         cid = le16_to_cpu(c->cid);
         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;
             continue;
         }
         }
         trace_nvme_complete_command(s, q->index, cid);
         trace_nvme_complete_command(s, q->index, cid);

+ 3 - 0
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
   ``vexpress-a15``, and have IRQs from 40 upwards. If a dtb is
   provided on the command line then QEMU will edit it to include
   provided on the command line then QEMU will edit it to include
   suitable entries describing these transports for the guest.
   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
 Booting a Linux kernel
 ----------------------
 ----------------------

+ 3 - 11
hw/arm/vexpress.c

@@ -177,7 +177,6 @@ struct VexpressMachineState {
     MemoryRegion vram;
     MemoryRegion vram;
     MemoryRegion sram;
     MemoryRegion sram;
     MemoryRegion flashalias;
     MemoryRegion flashalias;
-    MemoryRegion lowram;
     MemoryRegion a15sram;
     MemoryRegion a15sram;
     bool secure;
     bool secure;
     bool virt;
     bool virt;
@@ -276,7 +275,6 @@ static void a9_daughterboard_init(VexpressMachineState *vms,
 {
 {
     MachineState *machine = MACHINE(vms);
     MachineState *machine = MACHINE(vms);
     MemoryRegion *sysmem = get_system_memory();
     MemoryRegion *sysmem = get_system_memory();
-    ram_addr_t low_ram_size;
 
 
     if (ram_size > 0x40000000) {
     if (ram_size > 0x40000000) {
         /* 1GB is the maximum the address space permits */
         /* 1GB is the maximum the address space permits */
@@ -284,17 +282,11 @@ static void a9_daughterboard_init(VexpressMachineState *vms,
         exit(1);
         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
      * 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);
     memory_region_add_subregion(sysmem, 0x60000000, machine->ram);
 
 
     /* 0x1e000000 A9MPCore (SCU) private memory region */
     /* 0x1e000000 A9MPCore (SCU) private memory region */

+ 2 - 2
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, 3, 1); /* ARM PL011 UART */
     build_append_int_noprefix(table_data, 0, 3); /* Reserved */
     build_append_int_noprefix(table_data, 0, 3); /* Reserved */
     /* Base Address */
     /* 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);
                      vms->memmap[VIRT_UART].base);
     /* Interrupt Type */
     /* Interrupt Type */
     build_append_int_noprefix(table_data,
     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);
     build_append_int_noprefix(table_data, 34, 2);
 
 
     /* BaseAddressRegister[] */
     /* 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);
                      vms->memmap[VIRT_UART].base);
 
 
     /* AddressSize[] */
     /* AddressSize[] */

+ 2 - 1
hw/arm/virt.c

@@ -631,7 +631,8 @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
         qemu_fdt_setprop(ms->fdt, "/pmu", "compatible",
         qemu_fdt_setprop(ms->fdt, "/pmu", "compatible",
                          compat, sizeof(compat));
                          compat, sizeof(compat));
         qemu_fdt_setprop_cells(ms->fdt, "/pmu", "interrupts",
         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);
     }
     }
 }
 }
 
 

+ 1 - 1
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)
 ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src, size_t srclen)
 {
 {
-    z_stream s;
+    z_stream s = {};
     ssize_t dstbytes;
     ssize_t dstbytes;
     int r, i, flags;
     int r, i, flags;
 
 

+ 20 - 3
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:
  * Rsvd field masks for spte:
  *     vtd_spte_rsvd 4k pages
  *     vtd_spte_rsvd 4k pages
  *     vtd_spte_rsvd_large large 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)
 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) &&
     if ((level == VTD_SL_PD_LEVEL || level == VTD_SL_PDP_LEVEL) &&
         (slpte & VTD_SL_PT_PAGE_SIZE_MASK)) {
         (slpte & VTD_SL_PT_PAGE_SIZE_MASK)) {
         /* large page */
         /* large page */
         rsvd_mask = vtd_spte_rsvd_large[level];
         rsvd_mask = vtd_spte_rsvd_large[level];
+    } else {
+        rsvd_mask = vtd_spte_rsvd[level];
     }
     }
 
 
     return slpte & rsvd_mask;
     return slpte & rsvd_mask;

+ 1 - 1
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)
 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));
     g_autofree const char *qom_path = object_get_canonical_path(OBJECT(s));
 
 
     rtc_get_time(s, &tm);
     rtc_get_time(s, &tm);

+ 5 - 0
io/channel-socket.c

@@ -782,6 +782,11 @@ static int qio_channel_socket_flush(QIOChannel *ioc,
                              "Error not from zero copy");
                              "Error not from zero copy");
             return -1;
             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()*/
         /* No errors, count successfully finished sendmsg()*/
         sioc->zero_copy_sent += serr->ee_data - serr->ee_info + 1;
         sioc->zero_copy_sent += serr->ee_data - serr->ee_info + 1;

+ 1 - 1
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)
 # Load/store register (pointer authentication)
 
 
 # LDRA immediate is 10 bits signed and scaled, but the bits aren't all contiguous
 # 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
 LDRA            11 111 0 00 m:1 . 1 ......... w:1 1 rn:5 rt:5 imm=%ldra_imm
 
 

+ 5 - 0
target/arm/tcg/translate.h

@@ -205,6 +205,11 @@ static inline int times_4(DisasContext *s, int x)
     return x * 4;
     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)
 static inline int times_2_plus_1(DisasContext *s, int x)
 {
 {
     return x * 2 + 1;
     return x * 2 + 1;

BIN
tests/data/acpi/virt/DBG2


BIN
tests/data/acpi/virt/SPCR


+ 17 - 8
util/filemonitor-inotify.c

@@ -81,16 +81,25 @@ static void qemu_file_monitor_watch(void *arg)
 
 
     /* Loop over all events in the buffer */
     /* Loop over all events in the buffer */
     while (used < len) {
     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;
         int qev;
         gsize i;
         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;
         used += sizeof(struct inotify_event) + ev->len;