target/ppc: Validate HTABMASK and reserved bits in SDR1 for 32-bit mode
ppc_store_sdr1() had validation for 64-bit SDR1 values but lacked corresponding checks for the 32-bit case. According to the Power ISA, in 32-bit mode SDR1 bits 16-22 are reserved (must be zero) and HTABMASK (bits 23-31) must consist of a consecutive string of 1-bits starting from the LSB, i.e., be of the form 2^n-1. Add checks to reject invalid HTABMASK values and log a guest error for non-zero reserved bits, following the same pattern used by the existing 64-bit validation. Reviewed-by: Chinmay Rath <rathc@linux.ibm.com> Signed-off-by: Minhang Zhang <zhangminhang@kylinos.cn> Link: https://lore.kernel.org/qemu-devel/tencent_8388D4B38DC5172F5EEE70436D3AD6D02006@qq.com Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Minhang Zhang committed
Aug 14, 2026 at 17:26 UTC
e2bbc72a66674315a8e13c77f5ecaffd7edc398a
1 file changed
+20
-5
target/ppc/mmu_common.c
+20
-5
@@ -42,24 +42,39 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
42
PowerPCCPU *cpu = env_archcpu(env);
43
qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value);
44
assert(!cpu->env.has_hv_mode || !cpu->vhyp);
45
-#if defined(TARGET_PPC64)
45
if (mmu_is_64bit(env->mmu_model)) {
46
+#if defined(TARGET_PPC64)
47
target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE;
48
target_ulong htabsize = value & SDR_64_HTABSIZE;
49
50
if (value & ~sdr_mask) {
51
qemu_log_mask(LOG_GUEST_ERROR, "Invalid bits 0x"TARGET_FMT_lx
52
- " set in SDR1", value & ~sdr_mask);
52
+ " set in SDR1\n", value & ~sdr_mask);
53
value &= sdr_mask;
54
}
55
if (htabsize > 28) {
56
qemu_log_mask(LOG_GUEST_ERROR, "Invalid HTABSIZE 0x" TARGET_FMT_lx
57
- " stored in SDR1", htabsize);
57
+ " stored in SDR1\n", htabsize);
58
return;
59
}
60
- }
60
#endif /* defined(TARGET_PPC64) */
62
- /* FIXME: Should check for valid HTABMASK values in 32-bit case */
61
+ } else {
62
+ target_ulong sdr_mask = SDR_32_HTABORG | SDR_32_HTABMASK;
63
+ target_ulong htabmask = value & SDR_32_HTABMASK;
64
+
65
+ if (value & ~sdr_mask) {
66
+ qemu_log_mask(LOG_GUEST_ERROR,
67
+ "Invalid bits 0x" TARGET_FMT_lx
68
+ " set in SDR1\n", value & ~sdr_mask);
69
+ value &= sdr_mask;
70
+ }
71
+ if ((htabmask & (htabmask + 1)) != 0) {
72
+ qemu_log_mask(LOG_GUEST_ERROR,
73
+ "Invalid HTABMASK 0x" TARGET_FMT_lx
74
+ " in SDR1 (must be of form 2^n-1)\n", htabmask);
75
+ return;
76
+ }
77
+ }
78
env->spr[SPR_SDR1] = value;
79
}
80