[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 10/97] spapr/xive: fix EQ page addresses above 64GB
From: |
Michael Roth |
Subject: |
[PATCH 10/97] spapr/xive: fix EQ page addresses above 64GB |
Date: |
Tue, 1 Oct 2019 18:44:49 -0500 |
From: Cédric Le Goater <address@hidden>
The high order bits of the address of the OS event queue is stored in
bits [4-31] of word2 of the XIVE END internal structures and the low
order bits in word3. This structure is using Big Endian ordering and
computing the value requires some simple arithmetic which happens to
be wrong. The mask removing bits [0-3] of word2 is applied to the
wrong value and the resulting address is bogus when above 64GB.
Guests with more than 64GB of RAM will allocate pages for the OS event
queues which will reside above the 64GB limit. In this case, the XIVE
device model will wake up the CPUs in case of a notification, such as
IPIs, but the update of the event queue will be written at the wrong
place in memory. The result is uncertain as the guest memory is
trashed and IPI are not delivered.
Introduce a helper xive_end_qaddr() to compute this value correctly in
all places where it is used.
Signed-off-by: Cédric Le Goater <address@hidden>
Message-Id: <address@hidden>
Reviewed-by: Greg Kurz <address@hidden>
Signed-off-by: David Gibson <address@hidden>
(cherry picked from commit 13df93244efbd4bb8b4cf4e26104a26033178674)
Signed-off-by: Michael Roth <address@hidden>
---
hw/intc/spapr_xive.c | 3 +--
hw/intc/xive.c | 9 +++------
include/hw/ppc/xive_regs.h | 6 ++++++
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index 097f88d460..db75f5d608 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -1144,8 +1144,7 @@ static target_ulong h_int_get_queue_config(PowerPCCPU
*cpu,
}
if (xive_end_is_enqueue(end)) {
- args[1] = (uint64_t) be32_to_cpu(end->w2 & 0x0fffffff) << 32
- | be32_to_cpu(end->w3);
+ args[1] = xive_end_qaddr(end);
args[2] = xive_get_field32(END_W0_QSIZE, end->w0) + 12;
} else {
args[1] = 0;
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index a0b87001da..dcf2fcd108 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1042,8 +1042,7 @@ static const TypeInfo xive_source_info = {
void xive_end_queue_pic_print_info(XiveEND *end, uint32_t width, Monitor *mon)
{
- uint64_t qaddr_base = (uint64_t) be32_to_cpu(end->w2 & 0x0fffffff) << 32
- | be32_to_cpu(end->w3);
+ uint64_t qaddr_base = xive_end_qaddr(end);
uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
uint32_t qentries = 1 << (qsize + 10);
@@ -1072,8 +1071,7 @@ void xive_end_queue_pic_print_info(XiveEND *end, uint32_t
width, Monitor *mon)
void xive_end_pic_print_info(XiveEND *end, uint32_t end_idx, Monitor *mon)
{
- uint64_t qaddr_base = (uint64_t) be32_to_cpu(end->w2 & 0x0fffffff) << 32
- | be32_to_cpu(end->w3);
+ uint64_t qaddr_base = xive_end_qaddr(end);
uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
uint32_t qgen = xive_get_field32(END_W1_GENERATION, end->w1);
uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
@@ -1101,8 +1099,7 @@ void xive_end_pic_print_info(XiveEND *end, uint32_t
end_idx, Monitor *mon)
static void xive_end_enqueue(XiveEND *end, uint32_t data)
{
- uint64_t qaddr_base = (uint64_t) be32_to_cpu(end->w2 & 0x0fffffff) << 32
- | be32_to_cpu(end->w3);
+ uint64_t qaddr_base = xive_end_qaddr(end);
uint32_t qsize = xive_get_field32(END_W0_QSIZE, end->w0);
uint32_t qindex = xive_get_field32(END_W1_PAGE_OFF, end->w1);
uint32_t qgen = xive_get_field32(END_W1_GENERATION, end->w1);
diff --git a/include/hw/ppc/xive_regs.h b/include/hw/ppc/xive_regs.h
index bf36678a24..1a8c5b5e64 100644
--- a/include/hw/ppc/xive_regs.h
+++ b/include/hw/ppc/xive_regs.h
@@ -208,6 +208,12 @@ typedef struct XiveEND {
#define xive_end_is_backlog(end) (be32_to_cpu((end)->w0) & END_W0_BACKLOG)
#define xive_end_is_escalate(end) (be32_to_cpu((end)->w0) &
END_W0_ESCALATE_CTL)
+static inline uint64_t xive_end_qaddr(XiveEND *end)
+{
+ return ((uint64_t) be32_to_cpu(end->w2) & 0x0fffffff) << 32 |
+ be32_to_cpu(end->w3);
+}
+
/* Notification Virtual Target (NVT) */
typedef struct XiveNVT {
uint32_t w0;
--
2.17.1
- [PATCH 52/97] virtio-balloon: Use temporary PBP only, (continued)
- [PATCH 52/97] virtio-balloon: Use temporary PBP only, Michael Roth, 2019/10/01
- [PATCH 54/97] virtio-balloon: free pbp more aggressively, Michael Roth, 2019/10/01
- [PATCH 73/97] target/arm: Don't abort on M-profile exception return in linux-user mode, Michael Roth, 2019/10/01
- [PATCH 94/97] slirp: ip_reass: Fix use after free, Michael Roth, 2019/10/01
- [PATCH 83/97] block/create: Do not abort if a block driver is not available, Michael Roth, 2019/10/01
- [PATCH 17/97] block: Drain source node in bdrv_replace_node(), Michael Roth, 2019/10/01
- [PATCH 80/97] iotests: Restrict nbd Python tests to nbd, Michael Roth, 2019/10/01
- [PATCH 90/97] curl: Report only ready sockets, Michael Roth, 2019/10/01
- [PATCH 96/97] hw/core/loader: Fix possible crash in rom_copy(), Michael Roth, 2019/10/01
- [PATCH 97/97] scsi: lsi: exit infinite loop while executing script (CVE-2019-12068), Michael Roth, 2019/10/01
- [PATCH 10/97] spapr/xive: fix EQ page addresses above 64GB,
Michael Roth <=
- [PATCH 66/97] iotests: Test incremental backup after truncation, Michael Roth, 2019/10/01
- [PATCH 64/97] iotests: Test backup job with two guest writes, Michael Roth, 2019/10/01
- [PATCH 68/97] iotests: Test unaligned blocking mirror write, Michael Roth, 2019/10/01
- [PATCH 07/97] cutils: Fix size_to_str() on 32-bit platforms, Michael Roth, 2019/10/01
- [PATCH 72/97] dma-helpers: ensure AIO callback is invoked after cancellation, Michael Roth, 2019/10/01
- [PATCH 62/97] block/backup: refactor: split out backup_calculate_cluster_size, Michael Roth, 2019/10/01
- [PATCH 08/97] Makefile: add nit-picky mode to sphinx-build, Michael Roth, 2019/10/01
- [PATCH 04/97] megasas: fix mapped frame size, Michael Roth, 2019/10/01
- [PATCH 69/97] block/backup: disable copy_range for compressed backup, Michael Roth, 2019/10/01
- [PATCH 59/97] block/backup: move to copy_bitmap with granularity, Michael Roth, 2019/10/01