aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/nvme.c7
-rw-r--r--docs/system/arm/vexpress.rst3
-rw-r--r--hw/arm/vexpress.c14
-rw-r--r--hw/arm/virt-acpi-build.c4
-rw-r--r--hw/arm/virt.c3
-rw-r--r--hw/core/loader.c2
-rw-r--r--hw/i386/intel_iommu.c23
-rw-r--r--hw/rtc/mc146818rtc.c2
-rw-r--r--io/channel-socket.c5
-rw-r--r--target/arm/tcg/a64.decode2
-rw-r--r--target/arm/tcg/translate.h5
-rw-r--r--tests/data/acpi/virt/DBG2bin87 -> 87 bytes
-rw-r--r--tests/data/acpi/virt/SPCRbin80 -> 80 bytes
-rw-r--r--util/filemonitor-inotify.c25
14 files changed, 64 insertions, 31 deletions
diff --git a/block/nvme.c b/block/nvme.c
index 96b3f8f..0a0a0a6 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);
diff --git a/docs/system/arm/vexpress.rst b/docs/system/arm/vexpress.rst
index 3e3839e..38f29c7 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 8ff37f5..c08ea34 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 */
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 9ce136c..8bc35a4 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[] */
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 92085d2..0a16ab3 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);
}
}
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 4dd5a71..b7bb44b 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;
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index a6f1a7a..5085a6f 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;
diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c
index c27c362..2d391a8 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);
diff --git a/io/channel-socket.c b/io/channel-socket.c
index 02ffb51..3a899b0 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;
diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 0cf1147..8a20dce 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 9efe00c..3c3bb34 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;
diff --git a/tests/data/acpi/virt/DBG2 b/tests/data/acpi/virt/DBG2
index 86e6314..0a05e1a 100644
--- a/tests/data/acpi/virt/DBG2
+++ b/tests/data/acpi/virt/DBG2
Binary files differ
diff --git a/tests/data/acpi/virt/SPCR b/tests/data/acpi/virt/SPCR
index 24e0a57..cf0f2b7 100644
--- a/tests/data/acpi/virt/SPCR
+++ b/tests/data/acpi/virt/SPCR
Binary files differ
diff --git a/util/filemonitor-inotify.c b/util/filemonitor-inotify.c
index 2c45f7f..2121111 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;