From: Thomas Gleixner <tglx@linutronix.de>
To: Xin Li <xin3.li@intel.com>,
linux-kernel@vger.kernel.org, x86@kernel.org,
kvm@vger.kernel.org
Cc: mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
hpa@zytor.com, peterz@infradead.org, andrew.cooper3@citrix.com,
seanjc@google.com, pbonzini@redhat.com, ravi.v.shankar@intel.com,
jiangshanlai@gmail.com, shan.kang@intel.com
Subject: Re: [PATCH v8 20/33] x86/fred: FRED entry/exit and dispatch code
Date: Mon, 05 Jun 2023 15:21:58 +0200 [thread overview]
Message-ID: <87fs766o3t.ffs@tglx> (raw)
In-Reply-To: <20230410081438.1750-21-xin3.li@intel.com>
On Mon, Apr 10 2023 at 01:14, Xin Li wrote:
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * arch/x86/entry/entry_fred.c
Please do not add these completely pointless file names. They are
useless _and_ never get updated when a file is moved.
> + *
> + * This contains the dispatch functions called from the entry point
> + * assembly.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/kdebug.h> /* oops_begin/end, ... */
Please remove this useless tail comment. We really do not have to list
which particular things are pulled in from which header file.
> +#include <linux/nospec.h>
New line between linux and asm includes please.
> +#include <asm/event-type.h>
> +#include <asm/fred.h>
> +#include <asm/idtentry.h>
> +#include <asm/syscall.h>
> +#include <asm/trapnr.h>
> +#include <asm/traps.h>
> +#include <asm/kdebug.h>
> +
> +/*
> + * Badness...
Really useful comment. Not.
> +
> +noinstr void fred_exc_double_fault(struct pt_regs *regs)
Has to be global because the only user is the table below, right?
> +{
> + exc_double_fault(regs, regs->orig_ax);
> +}
Also why is this here and not next to the double fault implementation?
> +/*
> + * Exception entry
> + */
> +static DEFINE_FRED_HANDLER(fred_exception)
Lacks noinstr as most of the functions here.
> +{
> + /*
> + * Exceptions that cannot happen on FRED h/w are set to fred_bad_event().
> + */
> + static const fred_handler exception_handlers[NUM_EXCEPTION_VECTORS] = {
> + [X86_TRAP_DE] = exc_divide_error,
> + [X86_TRAP_DB] = fred_exc_debug,
> + [X86_TRAP_NMI] = fred_bad_event, /* A separate event type, not handled here */
Please make this tabular aligned and get rid of these horrible tail
comments.
> + [X86_TRAP_BP] = exc_int3,
> + [X86_TRAP_OF] = exc_overflow,
> + [X86_TRAP_BR] = exc_bounds,
> + [X86_TRAP_UD] = exc_invalid_op,
> + [X86_TRAP_NM] = exc_device_not_available,
> + [X86_TRAP_DF] = fred_exc_double_fault,
> + [X86_TRAP_OLD_MF] = fred_bad_event, /* 387 only! */
> + [X86_TRAP_TS] = fred_exc_invalid_tss,
> + [X86_TRAP_NP] = fred_exc_segment_not_present,
> + [X86_TRAP_SS] = fred_exc_stack_segment,
> + [X86_TRAP_GP] = fred_exc_general_protection,
> + [X86_TRAP_PF] = fred_exc_page_fault,
> + [X86_TRAP_SPURIOUS] = fred_bad_event, /* Interrupts are their own event type */
> + [X86_TRAP_MF] = exc_coprocessor_error,
> + [X86_TRAP_AC] = fred_exc_alignment_check,
> + [X86_TRAP_MC] = fred_exc_machine_check,
> + [X86_TRAP_XF] = exc_simd_coprocessor_error,
> + [X86_TRAP_VE...NUM_EXCEPTION_VECTORS-1] = fred_bad_event
Can we please have something which makes it entirely clear that anything
from #VE on are exceptions which are installed during boot?
> + };
> + u8 vector = array_index_nospec((u8)regs->vector, NUM_EXCEPTION_VECTORS);
This only "works" when NUM_EXCEPTION_VECTORS is power of two. Also what
catches an out of bounds vector? I.e. vector 0x20 will end up as vector
0x0 due to array_index_nospec(). I know, FRED hardware is going to be
perfect...
> + exception_handlers[vector](regs);
> +}
> +
> +static __always_inline void fred_emulate_trap(struct pt_regs *regs)
> +{
> + regs->type = EVENT_TYPE_SWFAULT;
This type information is used where?
> + regs->orig_ax = 0;
> + fred_exception(regs);
> +}
> +
> +static __always_inline void fred_emulate_fault(struct pt_regs *regs)
> +{
> + regs->ip -= regs->instr_len;
> + fred_emulate_trap(regs);
> +}
> +
> +/*
> + * Emulate SYSENTER if applicable. This is not the preferred system
> + * call in 32-bit mode under FRED, rather int $0x80 is preferred and
> + * exported in the vdso. SYSCALL proper has a hard-coded early out in
> + * fred_entry_from_user().
So we have it nicely distributed all over the code....
> + */
> +static DEFINE_FRED_HANDLER(fred_syscall_slow)
> +{
> + if (IS_ENABLED(CONFIG_IA32_EMULATION) &&
> + likely(regs->vector == FRED_SYSENTER)) {
> + /* Convert frame to a syscall frame */
> + regs->orig_ax = regs->ax;
> + regs->ax = -ENOSYS;
> + do_fast_syscall_32(regs);
> + } else {
> + regs->vector = X86_TRAP_UD;
> + fred_emulate_fault(regs);
> + }
> +}
> +
> +/*
> + * Some software exceptions can also be triggered as int instructions,
> + * for historical reasons. Implement those here. The performance-critical
> + * int $0x80 (32-bit system call) has a hard-coded early out.
This comment starts to annoy me. Can you put comments next to the code
where they actually make sense?
> + */
> +static DEFINE_FRED_HANDLER(fred_sw_interrupt_user)
> +{
i.e.
/*
* In compat mode INT $0x80 (32bit system call) is
* performance-critical. Handle it first.
*/
> + if (IS_ENABLED(CONFIG_IA32_EMULATION) &&
> + likely(regs->vector == IA32_SYSCALL_VECTOR)) {
> + /* Convert frame to a syscall frame */
> + regs->orig_ax = regs->ax;
> + regs->ax = -ENOSYS;
> + return do_int80_syscall_32(regs);
> + }
> +
> + switch (regs->vector) {
> + case X86_TRAP_BP:
> + case X86_TRAP_OF:
> + fred_emulate_trap(regs);
> + break;
> + default:
> + regs->vector = X86_TRAP_GP;
> + fred_emulate_fault(regs);
> + break;
> + }
> +}
> +
> +static DEFINE_FRED_HANDLER(fred_hw_interrupt)
> +{
> + irqentry_state_t state = irqentry_enter(regs);
> +
> + instrumentation_begin();
> + external_interrupt(regs);
> + instrumentation_end();
> + irqentry_exit(regs, state);
> +}
> +
> +__visible noinstr void fred_entry_from_user(struct pt_regs *regs)
> +{
> + static const fred_handler user_handlers[FRED_EVENT_TYPE_COUNT] =
> + {
> + [EVENT_TYPE_HWINT] = fred_hw_interrupt,
> + [EVENT_TYPE_RESERVED] = fred_bad_event,
> + [EVENT_TYPE_NMI] = fred_exc_nmi,
> + [EVENT_TYPE_SWINT] = fred_sw_interrupt_user,
> + [EVENT_TYPE_HWFAULT] = fred_exception,
> + [EVENT_TYPE_SWFAULT] = fred_exception,
> + [EVENT_TYPE_PRIVSW] = fred_exception,
> + [EVENT_TYPE_OTHER] = fred_syscall_slow
> + };
> +
> + /*
> + * FRED employs a two-level event dispatch mechanism, with
> + * the first-level on the type of an event and the second-level
> + * on its vector. Thus a dispatch typically induces 2 calls.
> + * We optimize it by using early outs for the most frequent
> + * events, and syscalls are the first. We may also need early
> + * outs for page faults.
I'm not really convinced that adding more special cases and conditionals
is a win. This should be a true two-level dispatch first for _all_ event
types and then in a separate step optimizations with proper performance
numbers and justifications. Premature optimization is the enemy of
correctness. Don't do it.
> + */
> + if (likely(regs->type == EVENT_TYPE_OTHER &&
> + regs->vector == FRED_SYSCALL)) {
> + /* Convert frame to a syscall frame */
> + regs->orig_ax = regs->ax;
> + regs->ax = -ENOSYS;
> + do_syscall_64(regs, regs->orig_ax);
> + } else {
> + /* Not a system call */
> + u8 type = array_index_nospec((u8)regs->type, FRED_EVENT_TYPE_COUNT);
What's the u8 buying here and in all the other places? This has the same
table issue as all other table handling in this file.
> + user_handlers[type](regs);
> + }
> +}
> diff --git a/arch/x86/include/asm/idtentry.h b/arch/x86/include/asm/idtentry.h
> index 2876ddae02bc..bd43866f9c3e 100644
> --- a/arch/x86/include/asm/idtentry.h
> +++ b/arch/x86/include/asm/idtentry.h
> @@ -82,6 +82,7 @@ static __always_inline void __##func(struct pt_regs *regs)
> #define DECLARE_IDTENTRY_ERRORCODE(vector, func) \
> asmlinkage void asm_##func(void); \
> asmlinkage void xen_asm_##func(void); \
> + __visible void fred_##func(struct pt_regs *regs); \
Wants to be a separate change.
> __visible void func(struct pt_regs *regs, unsigned long error_code)
>
> /**
> @@ -106,6 +107,11 @@ __visible noinstr void func(struct pt_regs *regs, \
> irqentry_exit(regs, state); \
> } \
> \
> +__visible noinstr void fred_##func(struct pt_regs *regs) \
> +{ \
> + func (regs, regs->orig_ax); \
func() ....
Thanks,
tglx
next prev parent reply other threads:[~2023-06-05 13:22 UTC|newest]
Thread overview: 96+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-10 8:14 [PATCH v8 00/33] x86: enable FRED for x86-64 Xin Li
2023-04-10 8:14 ` [PATCH v8 01/33] x86/traps: let common_interrupt() handle IRQ_MOVE_CLEANUP_VECTOR Xin Li
2023-05-07 11:59 ` Borislav Petkov
2023-06-03 19:19 ` Li, Xin3
2023-06-03 20:51 ` Thomas Gleixner
2023-06-05 17:07 ` Thomas Gleixner
2023-06-05 17:09 ` H. Peter Anvin
2023-06-06 20:09 ` Thomas Gleixner
2023-06-06 23:16 ` Li, Xin3
2023-06-19 8:00 ` Li, Xin3
2023-06-19 14:22 ` Thomas Gleixner
2023-06-19 18:47 ` Li, Xin3
2023-06-19 19:16 ` H. Peter Anvin
2023-06-20 0:04 ` Li, Xin3
2023-04-10 8:14 ` [PATCH v8 02/33] x86/fred: make unions for the cs and ss fields in struct pt_regs Xin Li
2023-06-03 9:48 ` Borislav Petkov
2023-06-05 12:07 ` Thomas Gleixner
2023-06-05 17:12 ` H. Peter Anvin
2023-06-05 17:29 ` Thomas Gleixner
2023-04-10 8:14 ` [PATCH v8 03/33] x86/traps: add a system interrupt table for system interrupt dispatch Xin Li
2023-06-05 8:34 ` Thomas Gleixner
2023-06-06 8:05 ` Li, Xin3
2023-06-05 8:38 ` Thomas Gleixner
2023-06-05 8:39 ` Thomas Gleixner
2023-04-10 8:14 ` [PATCH v8 04/33] x86/traps: add install_system_interrupt_handler() Xin Li
2023-06-05 8:57 ` Thomas Gleixner
2023-06-06 5:46 ` Li, Xin3
2023-04-10 8:14 ` [PATCH v8 05/33] x86/traps: add external_interrupt() to dispatch external interrupts Xin Li
2023-06-05 11:56 ` Thomas Gleixner
2023-06-05 17:52 ` Thomas Gleixner
2023-06-19 19:16 ` Li, Xin3
2023-06-19 21:13 ` Thomas Gleixner
2023-06-20 0:16 ` Li, Xin3
2023-04-10 8:14 ` [PATCH v8 06/33] x86/cpufeature: add the cpu feature bit for FRED Xin Li
2023-04-10 8:14 ` [PATCH v8 07/33] x86/opcode: add ERETU, ERETS instructions to x86-opcode-map Xin Li
2023-04-10 8:14 ` [PATCH v8 08/33] x86/objtool: teach objtool about ERETU and ERETS Xin Li
2023-04-10 8:14 ` [PATCH v8 09/33] x86/cpu: add X86_CR4_FRED macro Xin Li
2023-06-05 12:01 ` Thomas Gleixner
2023-06-05 17:06 ` H. Peter Anvin
2023-06-05 17:19 ` H. Peter Anvin
2023-04-10 8:14 ` [PATCH v8 10/33] x86/fred: add Kconfig option for FRED (CONFIG_X86_FRED) Xin Li
2023-04-10 8:14 ` [PATCH v8 11/33] x86/fred: if CONFIG_X86_FRED is disabled, disable FRED support Xin Li
2023-04-10 8:14 ` [PATCH v8 12/33] x86/cpu: add MSR numbers for FRED configuration Xin Li
2023-04-10 8:14 ` [PATCH v8 13/33] x86/fred: header file for event types Xin Li
2023-04-10 8:14 ` [PATCH v8 14/33] x86/fred: header file with FRED definitions Xin Li
2023-04-10 8:14 ` [PATCH v8 15/33] x86/fred: reserve space for the FRED stack frame Xin Li
2023-04-10 8:14 ` [PATCH v8 16/33] x86/fred: add a page fault entry stub for FRED Xin Li
2023-04-10 8:14 ` [PATCH v8 17/33] x86/fred: add a debug " Xin Li
2023-04-10 8:14 ` [PATCH v8 18/33] x86/fred: add a NMI " Xin Li
2023-04-10 8:14 ` [PATCH v8 19/33] x86/fred: add a machine check " Xin Li
2023-04-10 8:14 ` [PATCH v8 20/33] x86/fred: FRED entry/exit and dispatch code Xin Li
2023-06-05 13:21 ` Thomas Gleixner [this message]
2023-04-10 8:14 ` [PATCH v8 21/33] x86/fred: FRED initialization code Xin Li
2023-06-05 12:15 ` Thomas Gleixner
2023-06-05 13:41 ` Thomas Gleixner
2023-04-10 8:14 ` [PATCH v8 22/33] x86/fred: update MSR_IA32_FRED_RSP0 during task switch Xin Li
2023-04-10 8:14 ` [PATCH v8 23/33] x86/fred: let ret_from_fork() jmp to fred_exit_user when FRED is enabled Xin Li
2023-04-10 8:14 ` [PATCH v8 24/33] x86/fred: disallow the swapgs instruction " Xin Li
2023-06-05 13:47 ` Thomas Gleixner
2023-04-10 8:14 ` [PATCH v8 25/33] x86/fred: no ESPFIX needed " Xin Li
2023-04-10 8:14 ` [PATCH v8 26/33] x86/fred: allow single-step trap and NMI when starting a new thread Xin Li
2023-06-05 13:50 ` Thomas Gleixner
2023-06-05 13:52 ` Thomas Gleixner
2023-04-10 8:14 ` [PATCH v8 27/33] x86/fred: fixup fault on ERETU by jumping to fred_entrypoint_user Xin Li
2023-04-10 8:14 ` [PATCH v8 28/33] x86/ia32: do not modify the DPL bits for a null selector Xin Li
2023-04-10 8:14 ` [PATCH v8 29/33] x86/fred: allow FRED systems to use interrupt vectors 0x10-0x1f Xin Li
2023-06-05 14:06 ` Thomas Gleixner
2023-06-05 16:55 ` H. Peter Anvin
2023-04-10 8:14 ` [PATCH v8 30/33] x86/fred: allow dynamic stack frame size Xin Li
2023-06-05 14:11 ` Thomas Gleixner
2023-06-06 6:18 ` Li, Xin3
2023-06-06 13:27 ` Thomas Gleixner
2023-06-06 23:08 ` H. Peter Anvin
2023-04-10 8:14 ` [PATCH v8 31/33] x86/fred: BUG() when ERETU with %rsp not equal to that when the ring 3 event was just delivered Xin Li
2023-06-05 14:15 ` Thomas Gleixner
2023-06-05 16:42 ` H. Peter Anvin
2023-06-05 17:16 ` Thomas Gleixner
2023-04-10 8:14 ` [PATCH v8 32/33] x86/fred: disable FRED by default in its early stage Xin Li
2023-04-10 8:14 ` [PATCH v8 33/33] KVM: x86/vmx: refactor VMX_DO_EVENT_IRQOFF to generate FRED stack frames Xin Li
2023-04-10 21:50 ` Sean Christopherson
2023-04-11 5:06 ` Li, Xin3
2023-04-11 18:34 ` Sean Christopherson
2023-04-11 22:50 ` Li, Xin3
2023-04-12 18:26 ` Li, Xin3
2023-04-12 19:37 ` Sean Christopherson
2023-04-10 18:37 ` [PATCH v8 00/33] x86: enable FRED for x86-64 Dave Hansen
2023-04-10 19:14 ` Li, Xin3
2023-04-10 19:32 ` Borislav Petkov
2023-04-10 19:38 ` Dave Hansen
2023-04-10 20:52 ` Li, Xin3
2023-04-11 4:14 ` Li, Xin3
2023-04-10 18:49 ` Dave Hansen
2023-04-10 19:16 ` Li, Xin3
2023-06-05 17:11 ` Thomas Gleixner
2023-06-05 17:22 ` H. Peter Anvin
2023-06-05 17:32 ` Thomas Gleixner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87fs766o3t.ffs@tglx \
--to=tglx@linutronix.de \
--cc=andrew.cooper3@citrix.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=jiangshanlai@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=ravi.v.shankar@intel.com \
--cc=seanjc@google.com \
--cc=shan.kang@intel.com \
--cc=x86@kernel.org \
--cc=xin3.li@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.