target/mips: Require even maskbits in update_pagemask

The number of bits set in PageMask must be even.

Fixes: d40b55bc1b86 ("target/mips: Fix PageMask with variable page size")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20250328175526.368121-3-richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Cc: qemu-stable@nongnu.org
This commit is contained in:
Richard Henderson 2025-03-28 12:55:25 -05:00 committed by Philippe Mathieu-Daudé
parent fca2817fdc
commit d89b9899ba

View File

@ -866,24 +866,17 @@ void helper_mtc0_memorymapid(CPUMIPSState *env, target_ulong arg1)
void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask) void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask)
{ {
uint32_t mask;
int maskbits;
/* Don't care MASKX as we don't support 1KB page */ /* Don't care MASKX as we don't support 1KB page */
mask = extract32((uint32_t)arg1, CP0PM_MASK, 16); uint32_t mask = extract32((uint32_t)arg1, CP0PM_MASK, 16);
maskbits = cto32(mask); int maskbits = cto32(mask);
/* Ensure no more set bit after first zero */ /* Ensure no more set bit after first zero, and maskbits even. */
if ((mask >> maskbits) != 0) { if ((mask >> maskbits) == 0 && maskbits % 2 == 0) {
goto invalid; env->CP0_PageMask = mask << CP0PM_MASK;
} else {
/* When invalid, set to default target page size. */
env->CP0_PageMask = 0;
} }
env->CP0_PageMask = mask << CP0PM_MASK;
return;
invalid:
/* When invalid, set to default target page size. */
env->CP0_PageMask = 0;
} }
void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1) void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)