x86/traps: Move subarch_percpu_traps_init() into traps-setup.c

... along with the supporting functions.  Switch to Xen coding style, and make
static as there are no external callers.

Rename to legacy_syscall_init() as a more accurate name.

Swap wrmsr{,l}() for wrmsrns().  No serialisation is needed at this point.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
Andrew Cooper committed 2025-08-15 11:13:41 +01:00
1 parent 5222af8bb2
commit 327ca0b545
3 files changed
+95 -96

No files matched your search

-2
View File
@@ -256,6 +256,4 @@ static inline int local_irq_is_enabled(void)
#define BROKEN_ACPI_Sx 0x0001
#define BROKEN_INIT_AFTER_S1 0x0002
void subarch_percpu_traps_init(void);
#endif
+95 -2
View File
@@ -2,13 +2,15 @@
/*
* Configuration of event handling for all CPUs.
*/
#include <xen/domain_page.h>
#include <xen/init.h>
#include <xen/param.h>
#include <asm/endbr.h>
#include <asm/idt.h>
#include <asm/msr.h>
#include <asm/shstk.h>
#include <asm/system.h>
#include <asm/stubs.h>
#include <asm/traps.h>
DEFINE_PER_CPU_READ_MOSTLY(idt_entry_t *, idt);
@@ -19,6 +21,8 @@ static bool __initdata opt_ler;
boolean_param("ler", opt_ler);
void nocall entry_PF(void);
void nocall lstar_enter(void);
void nocall cstar_enter(void);
/*
* Sets up system tables and descriptors for IDT devliery.
@@ -132,6 +136,95 @@ static void load_system_tables(void)
BUG_ON(stack_bottom & 15);
}
static unsigned int write_stub_trampoline(
unsigned char *stub, unsigned long stub_va,
unsigned long stack_bottom, unsigned long target_va)
{
unsigned char *p = stub;
if ( cpu_has_xen_ibt )
{
place_endbr64(p);
p += 4;
}
/* Store guest %rax into %ss slot */
/* movabsq %rax, stack_bottom - 8 */
*p++ = 0x48;
*p++ = 0xa3;
*(uint64_t *)p = stack_bottom - 8;
p += 8;
/* Store guest %rsp in %rax */
/* movq %rsp, %rax */
*p++ = 0x48;
*p++ = 0x89;
*p++ = 0xe0;
/* Switch to Xen stack */
/* movabsq $stack_bottom - 8, %rsp */
*p++ = 0x48;
*p++ = 0xbc;
*(uint64_t *)p = stack_bottom - 8;
p += 8;
/* jmp target_va */
*p++ = 0xe9;
*(int32_t *)p = target_va - (stub_va + (p - stub) + 4);
p += 4;
/* Round up to a multiple of 16 bytes. */
return ROUNDUP(p - stub, 16);
}
static void legacy_syscall_init(void)
{
unsigned long stack_bottom = get_stack_bottom();
unsigned long stub_va = this_cpu(stubs.addr);
unsigned char *stub_page;
unsigned int offset;
/* No PV guests? No need to set up SYSCALL/SYSENTER infrastructure. */
if ( !IS_ENABLED(CONFIG_PV) )
return;
stub_page = map_domain_page(_mfn(this_cpu(stubs.mfn)));
/*
* Trampoline for SYSCALL entry from 64-bit mode. The VT-x HVM vcpu
* context switch logic relies on the SYSCALL trampoline being at the
* start of the stubs.
*/
wrmsrns(MSR_LSTAR, stub_va);
offset = write_stub_trampoline(stub_page + (stub_va & ~PAGE_MASK),
stub_va, stack_bottom,
(unsigned long)lstar_enter);
stub_va += offset;
if ( cpu_has_sep )
{
/* SYSENTER entry. */
wrmsrns(MSR_IA32_SYSENTER_ESP, stack_bottom);
wrmsrns(MSR_IA32_SYSENTER_EIP, (unsigned long)sysenter_entry);
wrmsrns(MSR_IA32_SYSENTER_CS, __HYPERVISOR_CS);
}
/* Trampoline for SYSCALL entry from compatibility mode. */
wrmsrns(MSR_CSTAR, stub_va);
offset += write_stub_trampoline(stub_page + (stub_va & ~PAGE_MASK),
stub_va, stack_bottom,
(unsigned long)cstar_enter);
/* Don't consume more than half of the stub space here. */
ASSERT(offset <= STUB_BUF_SIZE / 2);
unmap_domain_page(stub_page);
/* Common SYSCALL parameters. */
wrmsrns(MSR_STAR, XEN_MSR_STAR);
wrmsrns(MSR_SYSCALL_MASK, XEN_SYSCALL_MASK);
}
static void __init init_ler(void)
{
unsigned int msr = 0;
@@ -235,7 +328,7 @@ void __init bsp_traps_reinit(void)
*/
void percpu_traps_init(void)
{
subarch_percpu_traps_init();
legacy_syscall_init();
if ( cpu_has_xen_lbr )
wrmsrl(MSR_IA32_DEBUGCTLMSR, IA32_DEBUGCTLMSR_LBR);
-92
View File
@@ -311,98 +311,6 @@ void asmlinkage noreturn do_double_fault(struct cpu_user_regs *regs)
panic("DOUBLE FAULT -- system shutdown\n");
}
static unsigned int write_stub_trampoline(
unsigned char *stub, unsigned long stub_va,
unsigned long stack_bottom, unsigned long target_va)
{
unsigned char *p = stub;
if ( cpu_has_xen_ibt )
{
place_endbr64(p);
p += 4;
}
/* Store guest %rax into %ss slot */
/* movabsq %rax, stack_bottom - 8 */
*p++ = 0x48;
*p++ = 0xa3;
*(uint64_t *)p = stack_bottom - 8;
p += 8;
/* Store guest %rsp in %rax */
/* movq %rsp, %rax */
*p++ = 0x48;
*p++ = 0x89;
*p++ = 0xe0;
/* Switch to Xen stack */
/* movabsq $stack_bottom - 8, %rsp */
*p++ = 0x48;
*p++ = 0xbc;
*(uint64_t *)p = stack_bottom - 8;
p += 8;
/* jmp target_va */
*p++ = 0xe9;
*(int32_t *)p = target_va - (stub_va + (p - stub) + 4);
p += 4;
/* Round up to a multiple of 16 bytes. */
return ROUNDUP(p - stub, 16);
}
void nocall lstar_enter(void);
void nocall cstar_enter(void);
void subarch_percpu_traps_init(void)
{
unsigned long stack_bottom = get_stack_bottom();
unsigned long stub_va = this_cpu(stubs.addr);
unsigned char *stub_page;
unsigned int offset;
/* No PV guests? No need to set up SYSCALL/SYSENTER infrastructure. */
if ( !IS_ENABLED(CONFIG_PV) )
return;
stub_page = map_domain_page(_mfn(this_cpu(stubs.mfn)));
/*
* Trampoline for SYSCALL entry from 64-bit mode. The VT-x HVM vcpu
* context switch logic relies on the SYSCALL trampoline being at the
* start of the stubs.
*/
wrmsrl(MSR_LSTAR, stub_va);
offset = write_stub_trampoline(stub_page + (stub_va & ~PAGE_MASK),
stub_va, stack_bottom,
(unsigned long)lstar_enter);
stub_va += offset;
if ( cpu_has_sep )
{
/* SYSENTER entry. */
wrmsrl(MSR_IA32_SYSENTER_ESP, stack_bottom);
wrmsrl(MSR_IA32_SYSENTER_EIP, (unsigned long)sysenter_entry);
wrmsr(MSR_IA32_SYSENTER_CS, __HYPERVISOR_CS, 0);
}
/* Trampoline for SYSCALL entry from compatibility mode. */
wrmsrl(MSR_CSTAR, stub_va);
offset += write_stub_trampoline(stub_page + (stub_va & ~PAGE_MASK),
stub_va, stack_bottom,
(unsigned long)cstar_enter);
/* Don't consume more than half of the stub space here. */
ASSERT(offset <= STUB_BUF_SIZE / 2);
unmap_domain_page(stub_page);
/* Common SYSCALL parameters. */
wrmsrl(MSR_STAR, XEN_MSR_STAR);
wrmsrl(MSR_SYSCALL_MASK, XEN_SYSCALL_MASK);
}
/*
* Local variables:
* mode: C
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.