x86/traps: Fix load_unaligned_zeropad() handling for shared TDX memory
[ Upstream commit 9f9116406120638b4d8db3831ffbc430dd2e1e95 ] Commitc4e34dd99f("x86: simplify load_unaligned_zeropad() implementation") changes how exceptions around load_unaligned_zeropad() handled. The kernel now uses the fault_address in fixup_exception() to verify the address calculations for the load_unaligned_zeropad(). It works fine for #PF, but breaks on #VE since no fault address is passed down to fixup_exception(). Propagating ve_info.gla down to fixup_exception() resolves the issue. See commit1e7769653b("x86/tdx: Handle load_unaligned_zeropad() page-cross to a shared page") for more context. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Reported-by: Michael Kelley <mikelley@microsoft.com> Fixes:c4e34dd99f("x86: simplify load_unaligned_zeropad() implementation") Acked-by: Dave Hansen <dave.hansen@linux.intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
cb160f4f90
commit
1ecdbf2467
1 changed files with 11 additions and 7 deletions
|
|
@ -697,9 +697,10 @@ static bool try_fixup_enqcmd_gp(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gp_try_fixup_and_notify(struct pt_regs *regs, int trapnr,
|
static bool gp_try_fixup_and_notify(struct pt_regs *regs, int trapnr,
|
||||||
unsigned long error_code, const char *str)
|
unsigned long error_code, const char *str,
|
||||||
|
unsigned long address)
|
||||||
{
|
{
|
||||||
if (fixup_exception(regs, trapnr, error_code, 0))
|
if (fixup_exception(regs, trapnr, error_code, address))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
current->thread.error_code = error_code;
|
current->thread.error_code = error_code;
|
||||||
|
|
@ -759,7 +760,7 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gp_try_fixup_and_notify(regs, X86_TRAP_GP, error_code, desc))
|
if (gp_try_fixup_and_notify(regs, X86_TRAP_GP, error_code, desc, 0))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
if (error_code)
|
if (error_code)
|
||||||
|
|
@ -1357,17 +1358,20 @@ DEFINE_IDTENTRY(exc_device_not_available)
|
||||||
|
|
||||||
#define VE_FAULT_STR "VE fault"
|
#define VE_FAULT_STR "VE fault"
|
||||||
|
|
||||||
static void ve_raise_fault(struct pt_regs *regs, long error_code)
|
static void ve_raise_fault(struct pt_regs *regs, long error_code,
|
||||||
|
unsigned long address)
|
||||||
{
|
{
|
||||||
if (user_mode(regs)) {
|
if (user_mode(regs)) {
|
||||||
gp_user_force_sig_segv(regs, X86_TRAP_VE, error_code, VE_FAULT_STR);
|
gp_user_force_sig_segv(regs, X86_TRAP_VE, error_code, VE_FAULT_STR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gp_try_fixup_and_notify(regs, X86_TRAP_VE, error_code, VE_FAULT_STR))
|
if (gp_try_fixup_and_notify(regs, X86_TRAP_VE, error_code,
|
||||||
|
VE_FAULT_STR, address)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
die_addr(VE_FAULT_STR, regs, error_code, 0);
|
die_addr(VE_FAULT_STR, regs, error_code, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1431,7 +1435,7 @@ DEFINE_IDTENTRY(exc_virtualization_exception)
|
||||||
* it successfully, treat it as #GP(0) and handle it.
|
* it successfully, treat it as #GP(0) and handle it.
|
||||||
*/
|
*/
|
||||||
if (!tdx_handle_virt_exception(regs, &ve))
|
if (!tdx_handle_virt_exception(regs, &ve))
|
||||||
ve_raise_fault(regs, 0);
|
ve_raise_fault(regs, 0, ve.gla);
|
||||||
|
|
||||||
cond_local_irq_disable(regs);
|
cond_local_irq_disable(regs);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue