aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2025-03-23 11:03:33 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2025-03-23 11:03:34 -0400
commit3907add7a6016401e58e8dbe5b2ddfa06cd1f66a (patch)
tree9935d6992f8e48a03f2e160bfda35058c286ea72 /hw/intc
parent5eb0849562c9b6988b620493dbea6421e31bfc33 (diff)
parent73c0c904fc99e2ceecbbded84ec76d40d3f2daae (diff)
downloadqemu-3907add7a6016401e58e8dbe5b2ddfa06cd1f66a.zip
qemu-3907add7a6016401e58e8dbe5b2ddfa06cd1f66a.tar.gz
qemu-3907add7a6016401e58e8dbe5b2ddfa06cd1f66a.tar.bz2
Merge tag 'pull-ppc-for-10.0-2-20250321' of https://gitlab.com/npiggin/qemu into staging
* Fix a KVM SMP guest hang. This is not completely trivial, but just small enough to merge it. If this causes any more problems, we can revert it and the timebase patch which exposed the underlying issue for release. * Fix a bunch of Coverity issues reported introduced in ppc, mostly in powernv code. * Fix a NetBSD boot bug on mac99 caused by VSX/VMX decodetree rewrite. * Fix the default CPU selection for older spapr machines. # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEETkN92lZhb0MpsKeVZ7MCdqhiHK4FAmfdBbsACgkQZ7MCdqhi # HK50jxAAi38NfsYBXBFSStwQKTBfbuhjDP2A1wiJVDrcJydQXnZb/xCR+kgRdiZt # I5roIvD2bsbgHJtnCthLo0fQVGPIohsWUnnR6BlEAVN/gwW+8T+tNhLEZZ402+GK # bzc4pxqtFitS9m5gyAat2g8bfLEEpEmUr2uAJXnPMDDrzSwtbtlUgPKGXfppsyhp # P26Ut9M6dmPt+EMdJUTJ4RDOPuj53lXmDnbtpG9sA0zYXlG3sRe7nE9X0iKwXB4g # Yher/IHSyHVqFe3t9TX9m/DY1EU8fFX/GoShoIMLk8v5Sy1viIsUXpWiIn9O3h1E # WoAS6HvH3CdcHz3EC1XXSGEjEz2r75kPVvLC/wDy4DmXMxSnadodjGohbUkYs+26 # IV/Y3cnGTE2sPoP+vwmv7UKzBncKzTQO2luLkTQzX+x6XGr1MQPdAIm4WW9KfQVq # VMS06/oqlQQ8gspAWpNo86P+8/hpFlN42dEE+mzARJkm1JNrO+0yMj8OB/og1o92 # T585TOpPDLm8ZeY8fETpgJ0rR4AKb+5e9KnbmS7XuvIWPK/G7OOt5gF8YXiT9yKw # R77TPm7Evq6zJ9+TQ4KPBqn4LumphXiBWsSpsVcmZqTTf7nKqii0ZdO8asrtn8oN # pgJ9AgAlnlCUIn4a/sDJ6k/HhC19IxyfC+y4bgsevwGOmo8H43s= # =SYBy # -----END PGP SIGNATURE----- # gpg: Signature made Fri 21 Mar 2025 02:22:51 EDT # gpg: using RSA key 4E437DDA56616F4329B0A79567B30276A8621CAE # gpg: Good signature from "Nicholas Piggin <npiggin@gmail.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 4E43 7DDA 5661 6F43 29B0 A795 67B3 0276 A862 1CAE * tag 'pull-ppc-for-10.0-2-20250321' of https://gitlab.com/npiggin/qemu: target/ppc: Fix e200 duplicate SPRs target/ppc: Fix facility interrupt checks for VSX ppc/spapr: fix default cpu for pre-9.0 machines. ppc/amigaone: Constify default_env ppc/amigaone: Check blk_pwrite return value ppc/pnv: Fix system symbols in HOMER structure definitions ppc/pnv: Move the PNOR LPC address into struct PnvPnor ppc/spapr: Fix possible pa_features memory overflow ppc/xive2: Fix logical / bitwise comparison typo pnv/xive: Fix possible undefined shift error in group size calculation ppc/xive: Fix typo in crowd block level calculation ppc/spapr: Fix RTAS stopped state Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/xive.c29
-rw-r--r--hw/intc/xive2.c21
2 files changed, 40 insertions, 10 deletions
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index c77df2c..3eb28c2 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -1662,12 +1662,20 @@ uint32_t xive_get_vpgroup_size(uint32_t nvp_index)
* (starting with the least significant bits) in the NVP index
* gives the size of the group.
*/
- return 1 << (ctz32(~nvp_index) + 1);
+ int first_zero = cto32(nvp_index);
+ if (first_zero >= 31) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid group index 0x%08x",
+ nvp_index);
+ return 0;
+ }
+
+ return 1U << (first_zero + 1);
}
static uint8_t xive_get_group_level(bool crowd, bool ignore,
uint32_t nvp_blk, uint32_t nvp_index)
{
+ int first_zero;
uint8_t level;
if (!ignore) {
@@ -1675,18 +1683,31 @@ static uint8_t xive_get_group_level(bool crowd, bool ignore,
return 0;
}
- level = (ctz32(~nvp_index) + 1) & 0b1111;
+ first_zero = cto32(nvp_index);
+ if (first_zero >= 31) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid group index 0x%08x",
+ nvp_index);
+ return 0;
+ }
+
+ level = (first_zero + 1) & 0b1111;
if (crowd) {
uint32_t blk;
/* crowd level is bit position of first 0 from the right in nvp_blk */
- blk = ctz32(~nvp_blk) + 1;
+ first_zero = cto32(nvp_blk);
+ if (first_zero >= 31) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid crowd block 0x%08x",
+ nvp_blk);
+ return 0;
+ }
+ blk = first_zero + 1;
/*
* Supported crowd sizes are 2^1, 2^2, and 2^4. 2^3 is not supported.
* HW will encode level 4 as the value 3. See xive2_pgofnext().
*/
- switch (level) {
+ switch (blk) {
case 1:
case 2:
break;
diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index f8ef615..7d584df 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -1153,13 +1153,15 @@ static bool xive2_vp_match_mask(uint32_t cam1, uint32_t cam2,
static uint8_t xive2_get_vp_block_mask(uint32_t nvt_blk, bool crowd)
{
- uint8_t size, block_mask = 0b1111;
+ uint8_t block_mask = 0b1111;
/* 3 supported crowd sizes: 2, 4, 16 */
if (crowd) {
- size = xive_get_vpgroup_size(nvt_blk);
- if (size == 8) {
- qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid crowd size of 8n");
+ uint32_t size = xive_get_vpgroup_size(nvt_blk);
+
+ if (size != 2 && size != 4 && size != 16) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid crowd size of %d",
+ size);
return block_mask;
}
block_mask &= ~(size - 1);
@@ -1172,7 +1174,14 @@ static uint32_t xive2_get_vp_index_mask(uint32_t nvt_index, bool cam_ignore)
uint32_t index_mask = 0xFFFFFF; /* 24 bits */
if (cam_ignore) {
- index_mask &= ~(xive_get_vpgroup_size(nvt_index) - 1);
+ uint32_t size = xive_get_vpgroup_size(nvt_index);
+
+ if (size < 2) {
+ qemu_log_mask(LOG_GUEST_ERROR, "XIVE: Invalid group size of %d",
+ size);
+ return index_mask;
+ }
+ index_mask &= ~(size - 1);
}
return index_mask;
}
@@ -1335,7 +1344,7 @@ static void xive2_router_end_notify(Xive2Router *xrtr, uint8_t end_blk,
return;
}
- if (xive2_end_is_crowd(&end) & !xive2_end_is_ignore(&end)) {
+ if (xive2_end_is_crowd(&end) && !xive2_end_is_ignore(&end)) {
qemu_log_mask(LOG_GUEST_ERROR,
"XIVE: invalid END, 'crowd' bit requires 'ignore' bit\n");
return;