Skip to content

Commit

Permalink
x86/traps: Fix load_unaligned_zeropad() handling for shared TDX memory
Browse files Browse the repository at this point in the history
Commit c4e34dd ("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 1e77696 ("x86/tdx: Handle load_unaligned_zeropad()
page-cross to a shared page") for more context.

Signed-off-by: Kirill A. Shutemov <[email protected]>
Reported-by: Michael Kelley <[email protected]>
Fixes: c4e34dd ("x86: simplify load_unaligned_zeropad() implementation")
Acked-by: Dave Hansen <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
kiryl authored and torvalds committed Jul 25, 2023
1 parent 0b4a9fd commit 9f91164
Showing 1 changed file with 11 additions and 7 deletions.
18 changes: 11 additions & 7 deletions arch/x86/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -697,9 +697,10 @@ static bool try_fixup_enqcmd_gp(void)
}

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;

current->thread.error_code = error_code;
Expand Down Expand Up @@ -759,7 +760,7 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
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;

if (error_code)
Expand Down Expand Up @@ -1357,17 +1358,20 @@ DEFINE_IDTENTRY(exc_device_not_available)

#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)) {
gp_user_force_sig_segv(regs, X86_TRAP_VE, error_code, VE_FAULT_STR);
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;
}

die_addr(VE_FAULT_STR, regs, error_code, 0);
die_addr(VE_FAULT_STR, regs, error_code, address);
}

/*
Expand Down Expand Up @@ -1431,7 +1435,7 @@ DEFINE_IDTENTRY(exc_virtualization_exception)
* it successfully, treat it as #GP(0) and handle it.
*/
if (!tdx_handle_virt_exception(regs, &ve))
ve_raise_fault(regs, 0);
ve_raise_fault(regs, 0, ve.gla);

cond_local_irq_disable(regs);
}
Expand Down

0 comments on commit 9f91164

Please sign in to comment.