@samitouri / QOSamiQemu / commits / e2bbc72a66

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