[PATCH] target/i386: helper_wrmsr()/helper_rdmsr(): Raise #GP(0) when accessing unimplemented MSRs
Wang Ziliang <[email protected]>
| Newsgroups | org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
According to intel SDM and AMD manual, RDMSR and WRMSR instructions should raise #GP(0) exception if a reserved or unimplemented MSR is specified in ECX. Currently, both helper_rdmsr and helper_wrmsr functions simply ignore unimplemented MSRs, so the behavior of these functions needs to be modified in such cases. Cc: [email protected] Cc: Paolo Bonzini <[email protected]> Cc: Richard Henderson <[email protected]> Cc: Andrey Polivoda <[email protected]> Fixes: 3c1cf9fa8659 ("dummy rdmsr and wrmsr support - xor reg, reg optimization") Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3218 Signed-off-by: Wang Ziliang <[email protected]> --- target/i386/tcg/system/misc_helper.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/target/i386/tcg/system/misc_helper.c b/target/i386/tcg/system/misc_helper.c index 2998b1aae752c31a487b84dc6c303aac98b9be47..9ac5e167cc3c1a8b2cada34a1388221cde29aeaf 100644 --- a/target/i386/tcg/system/misc_helper.c +++ b/target/i386/tcg/system/misc_helper.c @@ -309,6 +309,7 @@ void helper_wrmsr(CPUX86State *env) break; } default: + /* Machine Check MSRs */ if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) { @@ -319,8 +320,8 @@ void helper_wrmsr(CPUX86State *env) } break; } - /* XXX: exception? */ - break; + /* Unimplemented MSRs */ + goto error; } return; error: @@ -487,6 +488,7 @@ void helper_rdmsr(CPUX86State *env) break; } default: + /* Machine Check MSRs */ if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) { @@ -494,9 +496,8 @@ void helper_rdmsr(CPUX86State *env) val = env->mce_banks[offset]; break; } - /* XXX: exception? */ - val = 0; - break; + /* Unimplemented MSRs */ + raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC()); } env->regs[R_EAX] = (uint32_t)(val); env->regs[R_EDX] = (uint32_t)(val >> 32); --- base-commit: 0345ef676befc1a180d2f63bceaf3fca1d07ee88 change-id: 20260731-unimplemented-msrs-1376256ce2be Best regards, -- Wang Ziliang <[email protected]>