Commit 9f911640 authored by Kirill A. Shutemov's avatar Kirill A. Shutemov Committed by Linus Torvalds

x86/traps: Fix load_unaligned_zeropad() handling for shared TDX memory

Commit c4e34dd9 ("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 commit 1e776965 ("x86/tdx: Handle load_unaligned_zeropad()
page-cross to a shared page") for more context.
Signed-off-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Reported-by: default avatarMichael Kelley <mikelley@microsoft.com>
Fixes: c4e34dd9 ("x86: simplify load_unaligned_zeropad() implementation")
Acked-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 0b4a9fdc
...@@ -697,9 +697,10 @@ static bool try_fixup_enqcmd_gp(void) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment