aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64
diff options
context:
space:
mode:
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/acpica/acpi_machdep.c3
-rw-r--r--sys/amd64/amd64/elf_machdep.c31
-rw-r--r--sys/amd64/amd64/exec_machdep.c13
-rw-r--r--sys/amd64/amd64/fpu.c31
-rw-r--r--sys/amd64/amd64/gdb_machdep.c2
-rw-r--r--sys/amd64/amd64/genassym.c27
-rw-r--r--sys/amd64/amd64/machdep.c28
-rw-r--r--sys/amd64/amd64/minidump_machdep.c4
-rw-r--r--sys/amd64/amd64/pmap.c66
-rw-r--r--sys/amd64/amd64/ptrace_machdep.c102
-rw-r--r--sys/amd64/amd64/sigtramp.S69
-rw-r--r--sys/amd64/amd64/trap.c8
-rw-r--r--sys/amd64/amd64/vm_machdep.c35
-rw-r--r--sys/amd64/amd64/xen-locore.S2
-rw-r--r--sys/amd64/conf/GENERIC5
-rw-r--r--sys/amd64/conf/LINT-NOIP1
-rw-r--r--sys/amd64/conf/NOTES19
-rw-r--r--sys/amd64/ia32/ia32_reg.c50
-rw-r--r--sys/amd64/ia32/ia32_signal.c32
-rw-r--r--sys/amd64/ia32/ia32_sigtramp.S75
-rw-r--r--sys/amd64/ia32/ia32_syscall.c10
-rw-r--r--sys/amd64/include/atomic.h120
-rw-r--r--sys/amd64/include/clock.h45
-rw-r--r--sys/amd64/include/cpu.h1
-rw-r--r--sys/amd64/include/cpufunc.h73
-rw-r--r--sys/amd64/include/ieeefp.h10
-rw-r--r--sys/amd64/include/in_cksum.h6
-rw-r--r--sys/amd64/include/limits.h4
-rw-r--r--sys/amd64/include/md_var.h5
-rw-r--r--sys/amd64/include/pcpu.h12
-rw-r--r--sys/amd64/include/proc.h7
-rw-r--r--sys/amd64/include/profile.h6
-rw-r--r--sys/amd64/include/tls.h5
-rw-r--r--sys/amd64/include/vmm.h2
-rw-r--r--sys/amd64/include/vmm_dev.h1
-rw-r--r--sys/amd64/include/xen/hypercall.h3
-rw-r--r--sys/amd64/linux/linux.h137
-rw-r--r--sys/amd64/linux/linux_dummy_machdep.c1
-rw-r--r--sys/amd64/linux/linux_genassym.c25
-rw-r--r--sys/amd64/linux/linux_locore.asm109
-rw-r--r--sys/amd64/linux/linux_machdep.c27
-rw-r--r--sys/amd64/linux/linux_proto.h207
-rw-r--r--sys/amd64/linux/linux_support.s2
-rw-r--r--sys/amd64/linux/linux_syscall.h2
-rw-r--r--sys/amd64/linux/linux_syscalls.c2
-rw-r--r--sys/amd64/linux/linux_sysent.c10
-rw-r--r--sys/amd64/linux/linux_systrace_args.c102
-rw-r--r--sys/amd64/linux/linux_sysvec.c152
-rw-r--r--sys/amd64/linux/linux_vdso.lds.s1
-rw-r--r--sys/amd64/linux/linux_vdso_gtod.c3
-rw-r--r--sys/amd64/linux/syscalls.conf1
-rw-r--r--sys/amd64/linux/syscalls.master31
-rw-r--r--sys/amd64/linux32/linux.h166
-rw-r--r--sys/amd64/linux32/linux32_dummy_machdep.c7
-rw-r--r--sys/amd64/linux32/linux32_genassym.c23
-rw-r--r--sys/amd64/linux32/linux32_locore.asm195
-rw-r--r--sys/amd64/linux32/linux32_machdep.c30
-rw-r--r--sys/amd64/linux32/linux32_proto.h253
-rw-r--r--sys/amd64/linux32/linux32_support.s2
-rw-r--r--sys/amd64/linux32/linux32_syscall.h2
-rw-r--r--sys/amd64/linux32/linux32_syscalls.c2
-rw-r--r--sys/amd64/linux32/linux32_sysent.c20
-rw-r--r--sys/amd64/linux32/linux32_systrace_args.c248
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c159
-rw-r--r--sys/amd64/linux32/linux32_vdso.lds.s4
-rw-r--r--sys/amd64/linux32/linux32_vdso_gtod.c22
-rw-r--r--sys/amd64/linux32/syscalls.conf1
-rw-r--r--sys/amd64/linux32/syscalls.master72
-rw-r--r--sys/amd64/sgx/sgx.c2
-rw-r--r--sys/amd64/vmm/amd/amdiommu.c4
-rw-r--r--sys/amd64/vmm/amd/amdvi_hw.c7
-rw-r--r--sys/amd64/vmm/amd/ivrs_drv.c5
-rw-r--r--sys/amd64/vmm/amd/svm.c16
-rw-r--r--sys/amd64/vmm/amd/svm_msr.c16
-rw-r--r--sys/amd64/vmm/amd/svm_softc.h3
-rw-r--r--sys/amd64/vmm/intel/vmcs.h4
-rw-r--r--sys/amd64/vmm/intel/vmx.c12
-rw-r--r--sys/amd64/vmm/intel/vmx.h2
-rw-r--r--sys/amd64/vmm/intel/vmx_msr.c17
-rw-r--r--sys/amd64/vmm/io/ppt.c3
-rw-r--r--sys/amd64/vmm/io/vlapic.c9
-rw-r--r--sys/amd64/vmm/io/vrtc.c15
-rw-r--r--sys/amd64/vmm/vmm.c16
-rw-r--r--sys/amd64/vmm/vmm_dev.c48
-rw-r--r--sys/amd64/vmm/vmm_instruction_emul.c3
-rw-r--r--sys/amd64/vmm/vmm_ioport.c2
-rw-r--r--sys/amd64/vmm/vmm_stat.c23
-rw-r--r--sys/amd64/vmm/vmm_stat.h6
-rw-r--r--sys/amd64/vmm/x86.c82
-rw-r--r--sys/amd64/vmm/x86.h20
90 files changed, 1631 insertions, 1615 deletions
diff --git a/sys/amd64/acpica/acpi_machdep.c b/sys/amd64/acpica/acpi_machdep.c
index a443c8693aa3..bbeb7cef44c5 100644
--- a/sys/amd64/acpica/acpi_machdep.c
+++ b/sys/amd64/acpica/acpi_machdep.c
@@ -286,6 +286,5 @@ static device_method_t nexus_acpi_methods[] = {
};
DEFINE_CLASS_1(nexus, nexus_acpi_driver, nexus_acpi_methods, 1, nexus_driver);
-static devclass_t nexus_devclass;
-DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, nexus_devclass, 0, 0);
+DRIVER_MODULE(nexus_acpi, root, nexus_acpi_driver, 0, 0);
diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c
index 6535d4bd2446..3dc606edc04d 100644
--- a/sys/amd64/amd64/elf_machdep.c
+++ b/sys/amd64/amd64/elf_machdep.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/imgact.h>
#include <sys/linker.h>
#include <sys/proc.h>
+#include <sys/reg.h>
#include <sys/sysent.h>
#include <sys/imgact_elf.h>
#include <sys/syscall.h>
@@ -49,14 +50,20 @@ __FBSDID("$FreeBSD$");
#include <machine/fpu.h>
#include <machine/md_var.h>
+#include "vdso_offsets.h"
+
+extern const char _binary_elf_vdso_so_1_start[];
+extern const char _binary_elf_vdso_so_1_end[];
+extern char _binary_elf_vdso_so_1_size;
+
struct sysentvec elf64_freebsd_sysvec_la48 = {
.sv_size = SYS_MAXSYSCALL,
.sv_table = sysent,
- .sv_transtrap = NULL,
.sv_fixup = __elfN(freebsd_fixup),
.sv_sendsig = sendsig,
- .sv_sigcode = sigcode,
- .sv_szsigcode = &szsigcode,
+ .sv_sigcode = _binary_elf_vdso_so_1_start,
+ .sv_szsigcode = (int *)&_binary_elf_vdso_so_1_size,
+ .sv_sigcodeoff = VDSO_SIGCODE_OFFSET,
.sv_name = "FreeBSD ELF64",
.sv_coredump = __elfN(coredump),
.sv_elf_core_osabi = ELFOSABI_FREEBSD,
@@ -68,6 +75,7 @@ struct sysentvec elf64_freebsd_sysvec_la48 = {
.sv_maxuser = VM_MAXUSER_ADDRESS_LA48,
.sv_usrstack = USRSTACK_LA48,
.sv_psstrings = PS_STRINGS_LA48,
+ .sv_psstringssz = sizeof(struct ps_strings),
.sv_stackprot = VM_PROT_ALL,
.sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs),
.sv_copyout_strings = exec_copyout_strings,
@@ -75,7 +83,7 @@ struct sysentvec elf64_freebsd_sysvec_la48 = {
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_FREEBSD | SV_ASLR | SV_LP64 | SV_SHP |
- SV_TIMEKEEP | SV_RNG_SEED_VER,
+ SV_TIMEKEEP | SV_RNG_SEED_VER | SV_DSO_SIG,
.sv_set_syscall_retval = cpu_set_syscall_retval,
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
@@ -84,20 +92,21 @@ struct sysentvec elf64_freebsd_sysvec_la48 = {
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
.sv_trap = NULL,
- .sv_stackgap = elf64_stackgap,
.sv_onexec_old = exec_onexec_old,
.sv_onexit = exit_onexit,
.sv_set_fork_retval = x86_set_fork_retval,
+ .sv_regset_begin = SET_BEGIN(__elfN(regset)),
+ .sv_regset_end = SET_LIMIT(__elfN(regset)),
};
struct sysentvec elf64_freebsd_sysvec_la57 = {
.sv_size = SYS_MAXSYSCALL,
.sv_table = sysent,
- .sv_transtrap = NULL,
.sv_fixup = __elfN(freebsd_fixup),
.sv_sendsig = sendsig,
- .sv_sigcode = sigcode,
- .sv_szsigcode = &szsigcode,
+ .sv_sigcode = _binary_elf_vdso_so_1_start,
+ .sv_szsigcode = (int *)&_binary_elf_vdso_so_1_size,
+ .sv_sigcodeoff = VDSO_SIGCODE_OFFSET,
.sv_name = "FreeBSD ELF64",
.sv_coredump = __elfN(coredump),
.sv_elf_core_osabi = ELFOSABI_FREEBSD,
@@ -109,6 +118,7 @@ struct sysentvec elf64_freebsd_sysvec_la57 = {
.sv_maxuser = VM_MAXUSER_ADDRESS_LA57,
.sv_usrstack = USRSTACK_LA57,
.sv_psstrings = PS_STRINGS_LA57,
+ .sv_psstringssz = sizeof(struct ps_strings),
.sv_stackprot = VM_PROT_ALL,
.sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs),
.sv_copyout_strings = exec_copyout_strings,
@@ -116,7 +126,7 @@ struct sysentvec elf64_freebsd_sysvec_la57 = {
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_FREEBSD | SV_ASLR | SV_LP64 | SV_SHP |
- SV_TIMEKEEP | SV_RNG_SEED_VER,
+ SV_TIMEKEEP | SV_RNG_SEED_VER | SV_DSO_SIG,
.sv_set_syscall_retval = cpu_set_syscall_retval,
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
.sv_syscallnames = syscallnames,
@@ -125,10 +135,11 @@ struct sysentvec elf64_freebsd_sysvec_la57 = {
.sv_schedtail = NULL,
.sv_thread_detach = NULL,
.sv_trap = NULL,
- .sv_stackgap = elf64_stackgap,
.sv_onexec_old = exec_onexec_old,
.sv_onexit = exit_onexit,
.sv_set_fork_retval= x86_set_fork_retval,
+ .sv_regset_begin = SET_BEGIN(__elfN(regset)),
+ .sv_regset_end = SET_LIMIT(__elfN(regset)),
};
static void
diff --git a/sys/amd64/amd64/exec_machdep.c b/sys/amd64/amd64/exec_machdep.c
index b93fe7c4b3c7..f66203d1812e 100644
--- a/sys/amd64/amd64/exec_machdep.c
+++ b/sys/amd64/amd64/exec_machdep.c
@@ -95,10 +95,9 @@ __FBSDID("$FreeBSD$");
#include <machine/specialreg.h>
#include <machine/trap.h>
-static void get_fpcontext(struct thread *td, mcontext_t *mcp,
- char **xfpusave, size_t *xfpusave_len);
-static int set_fpcontext(struct thread *td, mcontext_t *mcp,
- char *xfpustate, size_t xfpustate_len);
+_Static_assert(sizeof(mcontext_t) == 800, "mcontext_t size incorrect");
+_Static_assert(sizeof(ucontext_t) == 880, "ucontext_t size incorrect");
+_Static_assert(sizeof(siginfo_t) == 80, "siginfo_t size incorrect");
/*
* Send an interrupt to process.
@@ -631,7 +630,7 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
mcp->mc_gs = tp->tf_gs;
mcp->mc_flags = tp->tf_flags;
mcp->mc_len = sizeof(*mcp);
- get_fpcontext(td, mcp, NULL, 0);
+ get_fpcontext(td, mcp, NULL, NULL);
update_pcb_bases(pcb);
mcp->mc_fsbase = pcb->pcb_fsbase;
mcp->mc_gsbase = pcb->pcb_gsbase;
@@ -714,7 +713,7 @@ set_mcontext(struct thread *td, mcontext_t *mcp)
return (0);
}
-static void
+void
get_fpcontext(struct thread *td, mcontext_t *mcp, char **xfpusave,
size_t *xfpusave_len)
{
@@ -735,7 +734,7 @@ get_fpcontext(struct thread *td, mcontext_t *mcp, char **xfpusave,
}
}
-static int
+int
set_fpcontext(struct thread *td, mcontext_t *mcp, char *xfpustate,
size_t xfpustate_len)
{
diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c
index 24986958d4ca..dedb174dbe47 100644
--- a/sys/amd64/amd64/fpu.c
+++ b/sys/amd64/amd64/fpu.c
@@ -69,8 +69,6 @@ __FBSDID("$FreeBSD$");
* Floating point support.
*/
-#if defined(__GNUCLIKE_ASM) && !defined(lint)
-
#define fldcw(cw) __asm __volatile("fldcw %0" : : "m" (cw))
#define fnclex() __asm __volatile("fnclex")
#define fninit() __asm __volatile("fninit")
@@ -145,26 +143,6 @@ xsaveopt64(char *addr, uint64_t mask)
"memory");
}
-#else /* !(__GNUCLIKE_ASM && !lint) */
-
-void fldcw(u_short cw);
-void fnclex(void);
-void fninit(void);
-void fnstcw(caddr_t addr);
-void fnstsw(caddr_t addr);
-void fxsave(caddr_t addr);
-void fxrstor(caddr_t addr);
-void ldmxcsr(u_int csr);
-void stmxcsr(u_int *csr);
-void xrstor32(char *addr, uint64_t mask);
-void xrstor64(char *addr, uint64_t mask);
-void xsave32(char *addr, uint64_t mask);
-void xsave64(char *addr, uint64_t mask);
-void xsaveopt32(char *addr, uint64_t mask);
-void xsaveopt64(char *addr, uint64_t mask);
-
-#endif /* __GNUCLIKE_ASM && !lint */
-
#define start_emulating() load_cr0(rcr0() | CR0_TS)
#define stop_emulating() clts()
@@ -472,7 +450,8 @@ fpuinitstate(void *arg __unused)
/*
* Create a table describing the layout of the CPU Extended
- * Save Area.
+ * Save Area. See Intel SDM rev. 075 Vol. 1 13.4.1 "Legacy
+ * Region of an XSAVE Area" for the source of offsets/sizes.
*/
if (use_xsave) {
xstate_bv = (uint64_t *)((char *)(fpu_initialstate + 1) +
@@ -484,7 +463,7 @@ fpuinitstate(void *arg __unused)
xsave_area_desc[0].size = 160;
/* XMM */
xsave_area_desc[1].offset = 160;
- xsave_area_desc[1].size = 288 - 160;
+ xsave_area_desc[1].size = 416 - 160;
for (i = 2; i < max_ext_n; i++) {
cpuid_count(0xd, i, cp);
@@ -1081,9 +1060,7 @@ static driver_t fpupnp_driver = {
1, /* no softc */
};
-static devclass_t fpupnp_devclass;
-
-DRIVER_MODULE(fpupnp, acpi, fpupnp_driver, fpupnp_devclass, 0, 0);
+DRIVER_MODULE(fpupnp, acpi, fpupnp_driver, 0, 0);
ISA_PNP_INFO(fpupnp_ids);
#endif /* DEV_ISA */
diff --git a/sys/amd64/amd64/gdb_machdep.c b/sys/amd64/amd64/gdb_machdep.c
index b5acce216fe6..02b76a35d7ae 100644
--- a/sys/amd64/amd64/gdb_machdep.c
+++ b/sys/amd64/amd64/gdb_machdep.c
@@ -136,7 +136,7 @@ int
gdb_cpu_signal(int type, int code)
{
- switch (type & ~T_USER) {
+ switch (type) {
case T_BPTFLT: return (SIGTRAP);
case T_ARITHTRAP: return (SIGFPE);
case T_PROTFLT: return (SIGSEGV);
diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c
index 7c29368828d0..f61ce120d156 100644
--- a/sys/amd64/amd64/genassym.c
+++ b/sys/amd64/amd64/genassym.c
@@ -205,6 +205,33 @@ ASSYM(PTI_SIZE, sizeof(struct pti_frame));
ASSYM(SIGF_HANDLER, offsetof(struct sigframe, sf_ahu.sf_handler));
ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc));
ASSYM(UC_EFLAGS, offsetof(ucontext_t, uc_mcontext.mc_rflags));
+ASSYM(UC_RDI, offsetof(ucontext_t, uc_mcontext.mc_rdi));
+ASSYM(UC_RSI, offsetof(ucontext_t, uc_mcontext.mc_rsi));
+ASSYM(UC_RDX, offsetof(ucontext_t, uc_mcontext.mc_rdx));
+ASSYM(UC_RCX, offsetof(ucontext_t, uc_mcontext.mc_rcx));
+ASSYM(UC_R8, offsetof(ucontext_t, uc_mcontext.mc_r8));
+ASSYM(UC_R9, offsetof(ucontext_t, uc_mcontext.mc_r9));
+ASSYM(UC_RAX, offsetof(ucontext_t, uc_mcontext.mc_rax));
+ASSYM(UC_RBX, offsetof(ucontext_t, uc_mcontext.mc_rbx));
+ASSYM(UC_RBP, offsetof(ucontext_t, uc_mcontext.mc_rbp));
+ASSYM(UC_R10, offsetof(ucontext_t, uc_mcontext.mc_r10));
+ASSYM(UC_R11, offsetof(ucontext_t, uc_mcontext.mc_r11));
+ASSYM(UC_R12, offsetof(ucontext_t, uc_mcontext.mc_r12));
+ASSYM(UC_R13, offsetof(ucontext_t, uc_mcontext.mc_r13));
+ASSYM(UC_R14, offsetof(ucontext_t, uc_mcontext.mc_r14));
+ASSYM(UC_R15, offsetof(ucontext_t, uc_mcontext.mc_r15));
+ASSYM(UC_FS, offsetof(ucontext_t, uc_mcontext.mc_fs));
+ASSYM(UC_GS, offsetof(ucontext_t, uc_mcontext.mc_gs));
+ASSYM(UC_ES, offsetof(ucontext_t, uc_mcontext.mc_es));
+ASSYM(UC_DS, offsetof(ucontext_t, uc_mcontext.mc_ds));
+ASSYM(UC_RIP, offsetof(ucontext_t, uc_mcontext.mc_rip));
+ASSYM(UC_CS, offsetof(ucontext_t, uc_mcontext.mc_cs));
+ASSYM(UC_RFLAGS, offsetof(ucontext_t, uc_mcontext.mc_rflags));
+ASSYM(UC_RSP, offsetof(ucontext_t, uc_mcontext.mc_rsp));
+ASSYM(UC_SS, offsetof(ucontext_t, uc_mcontext.mc_ss));
+ASSYM(UC_FSBASE, offsetof(ucontext_t, uc_mcontext.mc_fsbase));
+ASSYM(UC_GSBASE, offsetof(ucontext_t, uc_mcontext.mc_gsbase));
+
ASSYM(ENOENT, ENOENT);
ASSYM(EFAULT, EFAULT);
ASSYM(ENAMETOOLONG, ENAMETOOLONG);
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index c629db566528..55a278de6020 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -169,6 +169,9 @@ extern u_int64_t hammer_time(u_int64_t, u_int64_t);
static void cpu_startup(void *);
SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
+/* Probe 8254 PIT and TSC. */
+static void native_clock_source_init(void);
+
/* Preload data parse function */
static caddr_t native_parse_preload_data(u_int64_t);
@@ -177,8 +180,8 @@ static void native_parse_memmap(caddr_t, vm_paddr_t *, int *);
/* Default init_ops implementation. */
struct init_ops init_ops = {
- .parse_preload_data = native_parse_preload_data,
- .early_clock_source_init = i8254_init,
+ .parse_preload_data = native_parse_preload_data,
+ .early_clock_source_init = native_clock_source_init,
.early_delay = i8254_delay,
.parse_memmap = native_parse_memmap,
};
@@ -813,7 +816,7 @@ add_efi_map_entries(struct efi_map_header *efihdr, vm_paddr_t *physmap,
continue;
}
- if (!add_physmap_entry(p->md_phys, (p->md_pages * PAGE_SIZE),
+ if (!add_physmap_entry(p->md_phys, p->md_pages * EFI_PAGE_SIZE,
physmap, physmap_idx))
break;
}
@@ -1161,6 +1164,12 @@ native_parse_preload_data(u_int64_t modulep)
}
static void
+native_clock_source_init(void)
+{
+ i8254_init();
+}
+
+static void
amd64_kdb_init(void)
{
kdb_init();
@@ -1448,12 +1457,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
lidt(&r_idt);
/*
- * Initialize the clock before the console so that console
- * initialization can use DELAY().
- */
- clock_init();
-
- /*
* Use vt(4) by default for UEFI boot (during the sc(4)/vt(4)
* transition).
* Once bootblocks have updated, we can test directly for
@@ -1480,6 +1483,13 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
&x86_rngds_mitg_enable);
finishidentcpu(); /* Final stage of CPU initialization */
+
+ /*
+ * Initialize the clock before the console so that console
+ * initialization can use DELAY().
+ */
+ clock_init();
+
initializecpu(); /* Initialize CPU registers */
amd64_bsp_ist_init(pc);
diff --git a/sys/amd64/amd64/minidump_machdep.c b/sys/amd64/amd64/minidump_machdep.c
index de8433ae5a05..3b9c39ad58da 100644
--- a/sys/amd64/amd64/minidump_machdep.c
+++ b/sys/amd64/amd64/minidump_machdep.c
@@ -75,7 +75,7 @@ blk_flush(struct dumperinfo *di)
if (fragsz == 0)
return (0);
- error = dump_append(di, dump_va, 0, fragsz);
+ error = dump_append(di, dump_va, fragsz);
fragsz = 0;
return (error);
}
@@ -128,7 +128,7 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
}
if (ptr) {
- error = dump_append(di, ptr, 0, len);
+ error = dump_append(di, ptr, len);
if (error)
return (error);
ptr += len;
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index e9973a420de3..5350bff2fef4 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -1516,40 +1516,28 @@ pmap_pt_page_count_adj(pmap_t pmap, int count)
}
}
+pt_entry_t vtoptem __read_mostly = ((1ul << (NPTEPGSHIFT + NPDEPGSHIFT +
+ NPDPEPGSHIFT + NPML4EPGSHIFT)) - 1) << 3;
+vm_offset_t PTmap __read_mostly = (vm_offset_t)P4Tmap;
+
PMAP_INLINE pt_entry_t *
vtopte(vm_offset_t va)
{
- u_int64_t mask;
-
KASSERT(va >= VM_MAXUSER_ADDRESS, ("vtopte on a uva/gpa 0x%0lx", va));
- if (la57) {
- mask = ((1ul << (NPTEPGSHIFT + NPDEPGSHIFT + NPDPEPGSHIFT +
- NPML4EPGSHIFT + NPML5EPGSHIFT)) - 1);
- return (P5Tmap + ((va >> PAGE_SHIFT) & mask));
- } else {
- mask = ((1ul << (NPTEPGSHIFT + NPDEPGSHIFT + NPDPEPGSHIFT +
- NPML4EPGSHIFT)) - 1);
- return (P4Tmap + ((va >> PAGE_SHIFT) & mask));
- }
+ return ((pt_entry_t *)(PTmap + ((va >> (PAGE_SHIFT - 3)) & vtoptem)));
}
+pd_entry_t vtopdem __read_mostly = ((1ul << (NPDEPGSHIFT + NPDPEPGSHIFT +
+ NPML4EPGSHIFT)) - 1) << 3;
+vm_offset_t PDmap __read_mostly = (vm_offset_t)P4Dmap;
+
static __inline pd_entry_t *
vtopde(vm_offset_t va)
{
- u_int64_t mask;
-
KASSERT(va >= VM_MAXUSER_ADDRESS, ("vtopde on a uva/gpa 0x%0lx", va));
- if (la57) {
- mask = ((1ul << (NPDEPGSHIFT + NPDPEPGSHIFT +
- NPML4EPGSHIFT + NPML5EPGSHIFT)) - 1);
- return (P5Dmap + ((va >> PDRSHIFT) & mask));
- } else {
- mask = ((1ul << (NPDEPGSHIFT + NPDPEPGSHIFT +
- NPML4EPGSHIFT)) - 1);
- return (P4Dmap + ((va >> PDRSHIFT) & mask));
- }
+ return ((pt_entry_t *)(PDmap + ((va >> (PDRSHIFT - 3)) & vtopdem)));
}
static u_int64_t
@@ -2241,6 +2229,13 @@ pmap_bootstrap_la57(void *arg __unused)
*/
v_pml5[PML5PML5I] = KPML5phys | X86_PG_RW | X86_PG_V | pg_nx;
+ vtoptem = ((1ul << (NPTEPGSHIFT + NPDEPGSHIFT + NPDPEPGSHIFT +
+ NPML4EPGSHIFT + NPML5EPGSHIFT)) - 1) << 3;
+ PTmap = (vm_offset_t)P5Tmap;
+ vtopdem = ((1ul << (NPDEPGSHIFT + NPDPEPGSHIFT +
+ NPML4EPGSHIFT + NPML5EPGSHIFT)) - 1) << 3;
+ PDmap = (vm_offset_t)P5Dmap;
+
kernel_pmap->pm_cr3 = KPML5phys;
kernel_pmap->pm_pmltop = v_pml5;
pmap_pt_page_count_adj(kernel_pmap, 1);
@@ -3732,7 +3727,8 @@ pmap_flush_cache_phys_range(vm_paddr_t spa, vm_paddr_t epa, vm_memattr_t mattr)
{
pt_entry_t *pte;
vm_offset_t vaddr;
- int error, pte_bits;
+ int error __diagused;
+ int pte_bits;
KASSERT((spa & PAGE_MASK) == 0,
("pmap_flush_cache_phys_range: spa not page-aligned"));
@@ -3901,7 +3897,8 @@ pmap_kenter(vm_offset_t va, vm_paddr_t pa)
pt_entry_t *pte;
pte = vtopte(va);
- pte_store(pte, pa | X86_PG_RW | X86_PG_V | pg_g | pg_nx);
+ pte_store(pte, pa | pg_g | pg_nx | X86_PG_A | X86_PG_M |
+ X86_PG_RW | X86_PG_V);
}
static __inline void
@@ -3912,7 +3909,8 @@ pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode)
pte = vtopte(va);
cache_bits = pmap_cache_bits(kernel_pmap, mode, 0);
- pte_store(pte, pa | X86_PG_RW | X86_PG_V | pg_g | pg_nx | cache_bits);
+ pte_store(pte, pa | pg_g | pg_nx | X86_PG_A | X86_PG_M |
+ X86_PG_RW | X86_PG_V | cache_bits);
}
/*
@@ -3971,7 +3969,8 @@ pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count)
pa = VM_PAGE_TO_PHYS(m) | cache_bits;
if ((*pte & (PG_FRAME | X86_PG_PTE_CACHE)) != pa) {
oldpte |= *pte;
- pte_store(pte, pa | pg_g | pg_nx | X86_PG_RW | X86_PG_V);
+ pte_store(pte, pa | pg_g | pg_nx | X86_PG_A |
+ X86_PG_M | X86_PG_RW | X86_PG_V);
}
pte++;
}
@@ -6140,7 +6139,7 @@ pmap_remove_pde(pmap_t pmap, pd_entry_t *pdq, vm_offset_t sva,
if (mpte != NULL) {
KASSERT(mpte->valid == VM_PAGE_BITS_ALL,
("pmap_remove_pde: pte page not promoted"));
- pmap_resident_count_adj(pmap, -1);
+ pmap_pt_page_count_adj(pmap, -1);
KASSERT(mpte->ref_count == NPTEPG,
("pmap_remove_pde: pte page ref count error"));
mpte->ref_count = 0;
@@ -7729,7 +7728,7 @@ pmap_unwire(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
pml4_entry_t *pml4e;
pdp_entry_t *pdpe;
pd_entry_t *pde;
- pt_entry_t *pte, PG_V, PG_G;
+ pt_entry_t *pte, PG_V, PG_G __diagused;
PG_V = pmap_valid_bit(pmap);
PG_G = pmap_global_bit(pmap);
@@ -8043,7 +8042,7 @@ pmap_zero_page(vm_page_t m)
}
/*
- * Zero an an area within a single hardware page. off and size must not
+ * Zero an area within a single hardware page. off and size must not
* cover an area beyond a single hardware page.
*/
void
@@ -8289,7 +8288,7 @@ pmap_remove_pages(pmap_t pmap)
other_cpus = all_cpus;
critical_enter();
CPU_CLR(PCPU_GET(cpuid), &other_cpus);
- CPU_AND(&other_cpus, &pmap->pm_active);
+ CPU_AND(&other_cpus, &other_cpus, &pmap->pm_active);
critical_exit();
KASSERT(CPU_EMPTY(&other_cpus), ("pmap active %p", pmap));
}
@@ -8408,7 +8407,7 @@ pmap_remove_pages(pmap_t pmap)
if (mpte != NULL) {
KASSERT(mpte->valid == VM_PAGE_BITS_ALL,
("pmap_remove_pages: pte page not promoted"));
- pmap_resident_count_adj(pmap, -1);
+ pmap_pt_page_count_adj(pmap, -1);
KASSERT(mpte->ref_count == NPTEPG,
("pmap_remove_pages: pte page reference count error"));
mpte->ref_count = 0;
@@ -8566,6 +8565,11 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
boolean_t rv;
PG_V = pmap_valid_bit(pmap);
+
+ /*
+ * Return TRUE if and only if the PTE for the specified virtual
+ * address is allocated but invalid.
+ */
rv = FALSE;
PMAP_LOCK(pmap);
pde = pmap_pde(pmap, addr);
diff --git a/sys/amd64/amd64/ptrace_machdep.c b/sys/amd64/amd64/ptrace_machdep.c
index 74fd48c68492..069a5b4cdb9d 100644
--- a/sys/amd64/amd64/ptrace_machdep.c
+++ b/sys/amd64/amd64/ptrace_machdep.c
@@ -32,11 +32,13 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/elf.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/ptrace.h>
+#include <sys/reg.h>
#include <sys/sysent.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -52,6 +54,106 @@ struct ptrace_xstate_info32 {
};
#endif
+static bool
+get_segbases(struct regset *rs, struct thread *td, void *buf,
+ size_t *sizep)
+{
+ struct segbasereg *reg;
+ struct pcb *pcb;
+
+ if (buf != NULL) {
+ KASSERT(*sizep == sizeof(*reg), ("%s: invalid size", __func__));
+ reg = buf;
+
+ pcb = td->td_pcb;
+ if (td == curthread)
+ update_pcb_bases(pcb);
+ reg->r_fsbase = pcb->pcb_fsbase;
+ reg->r_gsbase = pcb->pcb_gsbase;
+ }
+ *sizep = sizeof(*reg);
+ return (true);
+}
+
+static bool
+set_segbases(struct regset *rs, struct thread *td, void *buf,
+ size_t size)
+{
+ struct segbasereg *reg;
+ struct pcb *pcb;
+
+ KASSERT(size == sizeof(*reg), ("%s: invalid size", __func__));
+ reg = buf;
+
+ pcb = td->td_pcb;
+ set_pcb_flags(pcb, PCB_FULL_IRET);
+ pcb->pcb_fsbase = reg->r_fsbase;
+ td->td_frame->tf_fs = _ufssel;
+ pcb->pcb_gsbase = reg->r_gsbase;
+ td->td_frame->tf_gs = _ugssel;
+
+ return (true);
+}
+
+static struct regset regset_segbases = {
+ .note = NT_X86_SEGBASES,
+ .size = sizeof(struct segbasereg),
+ .get = get_segbases,
+ .set = set_segbases,
+};
+ELF_REGSET(regset_segbases);
+
+#ifdef COMPAT_FREEBSD32
+static bool
+get_segbases32(struct regset *rs, struct thread *td, void *buf,
+ size_t *sizep)
+{
+ struct segbasereg32 *reg;
+ struct pcb *pcb;
+
+ if (buf != NULL) {
+ KASSERT(*sizep == sizeof(*reg), ("%s: invalid size", __func__));
+ reg = buf;
+
+ pcb = td->td_pcb;
+ if (td == curthread)
+ update_pcb_bases(pcb);
+ reg->r_fsbase = (uint32_t)pcb->pcb_fsbase;
+ reg->r_gsbase = (uint32_t)pcb->pcb_gsbase;
+ }
+ *sizep = sizeof(*reg);
+ return (true);
+}
+
+static bool
+set_segbases32(struct regset *rs, struct thread *td, void *buf,
+ size_t size)
+{
+ struct segbasereg32 *reg;
+ struct pcb *pcb;
+
+ KASSERT(size == sizeof(*reg), ("%s: invalid size", __func__));
+ reg = buf;
+
+ pcb = td->td_pcb;
+ set_pcb_flags(pcb, PCB_FULL_IRET);
+ pcb->pcb_fsbase = reg->r_fsbase;
+ td->td_frame->tf_fs = _ufssel;
+ pcb->pcb_gsbase = reg->r_gsbase;
+ td->td_frame->tf_gs = _ugssel;
+
+ return (true);
+}
+
+static struct regset regset_segbases32 = {
+ .note = NT_X86_SEGBASES,
+ .size = sizeof(struct segbasereg32),
+ .get = get_segbases32,
+ .set = set_segbases32,
+};
+ELF32_REGSET(regset_segbases32);
+#endif
+
static int
cpu_ptrace_xstate(struct thread *td, int req, void *addr, int data)
{
diff --git a/sys/amd64/amd64/sigtramp.S b/sys/amd64/amd64/sigtramp.S
index 9983edf229a3..f951ee14c2f7 100644
--- a/sys/amd64/amd64/sigtramp.S
+++ b/sys/amd64/amd64/sigtramp.S
@@ -2,6 +2,11 @@
* Copyright (c) 2003 Peter Wemm <peter@freeBSD.org>
* All rights reserved.
*
+ * Copyright (c) 2021 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -27,30 +32,70 @@
*/
#include <sys/syscall.h>
-
#include <machine/asmacros.h>
#include "assym.inc"
.text
-/**********************************************************************
+/*
+ * Signal trampoline, mapped as vdso into shared page.
+ */
+ENTRY(__vdso_sigcode)
+ .cfi_startproc
+ .cfi_signal_frame
+ .cfi_def_cfa %rsp, 0
+ .cfi_offset %rdi, SIGF_UC + UC_RDI
+ .cfi_offset %rsi, SIGF_UC + UC_RSI
+ .cfi_offset %rdx, SIGF_UC + UC_RDX
+ .cfi_offset %rcx, SIGF_UC + UC_RCX
+ .cfi_offset %r8, SIGF_UC + UC_R8
+ .cfi_offset %r9, SIGF_UC + UC_R9
+ .cfi_offset %rax, SIGF_UC + UC_RAX
+ .cfi_offset %rbx, SIGF_UC + UC_RBX
+ .cfi_offset %rbp, SIGF_UC + UC_RBP
+ .cfi_offset %r10, SIGF_UC + UC_R10
+ .cfi_offset %r11, SIGF_UC + UC_R11
+ .cfi_offset %r12, SIGF_UC + UC_R12
+ .cfi_offset %r13, SIGF_UC + UC_R13
+ .cfi_offset %r14, SIGF_UC + UC_R14
+ .cfi_offset %r15, SIGF_UC + UC_R15
+#if 0
+/*
+ * Gnu as complains about %fs/%gs/%es/%ds registers offsets not being
+ * multiple of 8, but gas + ld.bfd work for %cs/%ss.
*
- * Signal trampoline, copied to top of user stack
+ * Clang IAS + ld.lld combination cannot handle any of the segment
+ * registers. Also, clang IAS does not know %rflags/%fs.base/%gs.base
+ * registers names, use dwarf registers numbers from psABI directly.
*
- */
-ENTRY(sigcode)
+ * LLVM libunwind from stable/13 cannot parse register numbers higher
+ * than 32. Disable %rflags, %fs.base, and %gs.base annotations.
+ */
+ .cfi_offset %fs, SIGF_UC + UC_FS
+ .cfi_offset %gs, SIGF_UC + UC_GS
+ .cfi_offset %es, SIGF_UC + UC_ES
+ .cfi_offset %ds, SIGF_UC + UC_DS
+#endif
+ .cfi_offset %rip, SIGF_UC + UC_RIP
+#if 0
+ .cfi_offset %cs, SIGF_UC + UC_CS
+ .cfi_offset 49 /* %rflags */, SIGF_UC + UC_RFLAGS
+#endif
+ .cfi_offset %rsp, SIGF_UC + UC_RSP
+#if 0
+ .cfi_offset %ss, SIGF_UC + UC_SS
+ .cfi_offset 58 /* %fs.base */, SIGF_UC + UC_FSBASE
+ .cfi_offset 59 /* %gs.base */, SIGF_UC + UC_GSBASE
+#endif
call *SIGF_HANDLER(%rsp) /* call signal handler */
lea SIGF_UC(%rsp),%rdi /* get ucontext_t */
pushq $0 /* junk to fake return addr. */
+ .cfi_def_cfa %rsp, 8
movq $SYS_sigreturn,%rax
syscall /* enter kernel with args */
0: hlt /* trap priviliged instruction */
jmp 0b
+ .cfi_endproc
+END(__vdso_sigcode)
- ALIGN_TEXT
-esigcode:
-
- .data
- .globl szsigcode
-szsigcode:
- .long esigcode-sigcode
+ .section .note.GNU-stack,"",%progbits
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index ff4bccebed5b..df26797ca129 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -309,7 +309,7 @@ trap(struct trapframe *frame)
td->td_pticks = 0;
td->td_frame = frame;
addr = frame->tf_rip;
- if (td->td_cowgen != p->p_cowgen)
+ if (td->td_cowgen != atomic_load_int(&p->p_cowgen))
thread_cow_update(td);
switch (type) {
@@ -620,10 +620,6 @@ trap(struct trapframe *frame)
return;
}
- /* Translate fault for emulators (e.g. Linux) */
- if (*p->p_sysent->sv_transtrap != NULL)
- signo = (*p->p_sysent->sv_transtrap)(signo, type);
-
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = signo;
ksi.ksi_code = ucode;
@@ -1011,7 +1007,7 @@ cpu_fetch_syscall_args_fallback(struct thread *td, struct syscall_args *sa)
{
struct proc *p;
struct trapframe *frame;
- register_t *argp;
+ syscallarg_t *argp;
caddr_t params;
int reg, regcnt, error;
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index c0456c1d958c..c9c498180c7e 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -690,38 +690,3 @@ cpu_set_user_tls(struct thread *td, void *tls_base)
pcb->pcb_fsbase = (register_t)tls_base;
return (0);
}
-
-/*
- * Software interrupt handler for queued VM system processing.
- */
-void
-swi_vm(void *dummy)
-{
- if (busdma_swi_pending != 0)
- busdma_swi();
-}
-
-/*
- * Tell whether this address is in some physical memory region.
- * Currently used by the kernel coredump code in order to avoid
- * dumping the ``ISA memory hole'' which could cause indefinite hangs,
- * or other unpredictable behaviour.
- */
-
-int
-is_physical_memory(vm_paddr_t addr)
-{
-
-#ifdef DEV_ISA
- /* The ISA ``memory hole''. */
- if (addr >= 0xa0000 && addr < 0x100000)
- return 0;
-#endif
-
- /*
- * stuff other tests for known memory-mapped devices (PCI?)
- * here
- */
-
- return 1;
-}
diff --git a/sys/amd64/amd64/xen-locore.S b/sys/amd64/amd64/xen-locore.S
index c112fa909adf..7dc5d1d93842 100644
--- a/sys/amd64/amd64/xen-locore.S
+++ b/sys/amd64/amd64/xen-locore.S
@@ -38,7 +38,7 @@
#include <xen/xen-os.h>
#define __ASSEMBLY__
-#include <xen/interface/elfnote.h>
+#include <contrib/xen/elfnote.h>
#include "assym.inc"
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 4d679e89c92d..53c6043a0146 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -226,9 +226,8 @@ device vt_vbefb
device agp # support several AGP chipsets
-# PCCARD (PCMCIA) support
-# PCMCIA and cardbus bridge support
-device cbb # cardbus (yenta) bridge
+# CardBus bridge support
+device cbb # CardBus (yenta) bridge
device cardbus # CardBus (32-bit) bus
# Serial (COM) ports
diff --git a/sys/amd64/conf/LINT-NOIP b/sys/amd64/conf/LINT-NOIP
index bb306691388a..e951a0878b29 100644
--- a/sys/amd64/conf/LINT-NOIP
+++ b/sys/amd64/conf/LINT-NOIP
@@ -13,6 +13,7 @@ nodevice bxe
nodevice em
nodevice fxp
nodevice jme
+nodevice lio
nodevice msk
nodevice mxge
nodevice sge
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index 8cb84d6248c2..df1b2097e406 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -142,7 +142,7 @@ device isa
#
# AUTO_EOI_2 enables the `automatic EOI' feature for the slave 8259A
# interrupt controller. This saves about 0.7-1.25 usec for each interrupt.
-# Automatic EOI is documented not to work for for the slave with the
+# Automatic EOI is documented not to work for the slave with the
# original i8259A, but it works for some clones and some integrated
# versions.
#
@@ -283,6 +283,8 @@ device cpufreq
# Network interfaces:
#
+# axp: AMD EPYC integrated NIC
+# Requires the miibus module
# bxe: Broadcom NetXtreme II (BCM5771X/BCM578XX) PCIe 10Gb Ethernet
# adapters.
# ice: Intel 800 Series Physical Function
@@ -299,17 +301,16 @@ device cpufreq
# mlx4ib: Mellanox ConnectX HCA InfiniBand
# mlx4en: Mellanox ConnectX HCA Ethernet
# nfe: nVidia nForce MCP on-board Ethernet Networking (BSD open source)
+# qlxgb: QLogic 3200 and 8200 series 10 Gigabit Ethernet & CNA Adapter
+# qlxgbe: QLogic 8300 series 10 Gigabit Ethernet & CNA Adapter
+# qlxge: QLogic 8100 series 10 Gigabit Ethernet & CNA Adapter
# sfxge: Solarflare SFC9000 family 10Gb Ethernet adapters
# vmx: VMware VMXNET3 Ethernet (BSD open source)
# wpi: Intel 3945ABG Wireless LAN controller
# Requires the wpi firmware module
-# axp: AMD EPYC integrated NIC
-# Requires the miibus module
+device axp # AMD EPYC integrated NIC
device bxe # Broadcom NetXtreme II BCM5771X/BCM578XX 10GbE
-options ED_3C503
-options ED_HPP
-options ED_SIC
device igc # Intel I225 2.5G Ethernet
device ipw # Intel 2100 wireless NICs.
device iwi # Intel 2200BG/2225BG/2915ABG wireless NICs.
@@ -323,10 +324,12 @@ device mlx4 # Shared code module between IB and Ethernet
device mlx4ib # Mellanox ConnectX HCA InfiniBand
device mlx4en # Mellanox ConnectX HCA Ethernet
device nfe # nVidia nForce MCP on-board Ethernet
+device qlxgb # QLogic 3200/8200 Ethernet
+device qlxgbe # QLogic 8300 Ethernet
+device qlxge # QLogic 8100 Ethernet
device sfxge # Solarflare SFC9000 10Gb Ethernet
device vmx # VMware VMXNET3 Ethernet
device wpi # Intel 3945ABG wireless NICs.
-device axp # AMD EPYC integrated NIC
# IEEE 802.11 adapter firmware modules
@@ -642,8 +645,6 @@ options PV_STATS
# More undocumented options for linting.
# Note that documenting these are not considered an affront.
-options FB_INSTALL_CDEV # install a CDEV entry in /dev
-
options KBDIO_DEBUG=2
options KBD_MAXRETRY=4
options KBD_MAXWAIT=6
diff --git a/sys/amd64/ia32/ia32_reg.c b/sys/amd64/ia32/ia32_reg.c
index 343d1564e1ff..539a268ef350 100644
--- a/sys/amd64/ia32/ia32_reg.c
+++ b/sys/amd64/ia32/ia32_reg.c
@@ -32,6 +32,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/elf.h>
#include <sys/exec.h>
#include <sys/fcntl.h>
#include <sys/imgact.h>
@@ -266,3 +267,52 @@ set_dbregs32(struct thread *td, struct dbreg32 *regs)
dr.dr[i] = 0;
return (set_dbregs(td, &dr));
}
+
+static bool
+get_i386_segbases(struct regset *rs, struct thread *td, void *buf,
+ size_t *sizep)
+{
+ struct segbasereg32 *reg;
+ struct pcb *pcb;
+
+ if (buf != NULL) {
+ KASSERT(*sizep == sizeof(*reg), ("%s: invalid size", __func__));
+ reg = buf;
+
+ pcb = td->td_pcb;
+ if (td == curthread)
+ update_pcb_bases(pcb);
+ reg->r_fsbase = pcb->pcb_fsbase;
+ reg->r_gsbase = pcb->pcb_gsbase;
+ }
+ *sizep = sizeof(*reg);
+ return (true);
+}
+
+static bool
+set_i386_segbases(struct regset *rs, struct thread *td, void *buf,
+ size_t size)
+{
+ struct segbasereg32 *reg;
+ struct pcb *pcb;
+
+ KASSERT(size == sizeof(*reg), ("%s: invalid size", __func__));
+ reg = buf;
+
+ pcb = td->td_pcb;
+ set_pcb_flags(pcb, PCB_FULL_IRET);
+ pcb->pcb_fsbase = reg->r_fsbase;
+ td->td_frame->tf_fs = _ufssel;
+ pcb->pcb_gsbase = reg->r_gsbase;
+ td->td_frame->tf_gs = _ugssel;
+
+ return (true);
+}
+
+static struct regset regset_i386_segbases = {
+ .note = NT_X86_SEGBASES,
+ .size = sizeof(struct segbasereg),
+ .get = get_i386_segbases,
+ .set = set_i386_segbases,
+};
+ELF32_REGSET(regset_i386_segbases);
diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c
index 52a9af0f64d2..6d0370a14f7f 100644
--- a/sys/amd64/ia32/ia32_signal.c
+++ b/sys/amd64/ia32/ia32_signal.c
@@ -81,6 +81,12 @@ __FBSDID("$FreeBSD$");
#include <machine/cpufunc.h>
#include <machine/trap.h>
+#include "vdso_ia32_offsets.h"
+
+extern const char _binary_elf_vdso32_so_1_start[];
+extern const char _binary_elf_vdso32_so_1_end[];
+extern char _binary_elf_vdso32_so_1_size;
+
#ifdef COMPAT_FREEBSD4
static void freebsd4_ia32_sendsig(sig_t, ksiginfo_t *, sigset_t *);
#endif
@@ -333,7 +339,7 @@ freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap)
static void
ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
- struct ia32_sigframe3 sf, *fp;
+ struct ia32_osigframe sf, *fp;
struct proc *p;
struct thread *td;
struct sigacts *psp;
@@ -353,11 +359,11 @@ ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/* Allocate space for the signal handler context. */
if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
- fp = (struct ia32_sigframe3 *)((uintptr_t)td->td_sigstk.ss_sp +
+ fp = (struct ia32_osigframe *)((uintptr_t)td->td_sigstk.ss_sp +
td->td_sigstk.ss_size - sizeof(sf));
td->td_sigstk.ss_flags |= SS_ONSTACK;
} else
- fp = (struct ia32_sigframe3 *)regs->tf_rsp - 1;
+ fp = (struct ia32_osigframe *)regs->tf_rsp - 1;
/* Build the argument list for the signal handler. */
sf.sf_signum = sig;
@@ -416,7 +422,9 @@ ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
}
regs->tf_rsp = (uintptr_t)fp;
- regs->tf_rip = p->p_sysent->sv_psstrings - sz_ia32_osigcode;
+ regs->tf_rip = PROC_PS_STRINGS(p) -
+ (_binary_elf_vdso32_so_1_end - _binary_elf_vdso32_so_1_start) +
+ VDSO_IA32_OSIGCODE_OFFSET;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ds = _udatasel;
@@ -433,7 +441,7 @@ ia32_osendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
static void
freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
{
- struct ia32_sigframe4 sf, *sfp;
+ struct ia32_freebsd4_sigframe sf, *sfp;
struct siginfo32 siginfo;
struct proc *p;
struct thread *td;
@@ -489,10 +497,10 @@ freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/* Allocate space for the signal handler context. */
if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
- sfp = (struct ia32_sigframe4 *)((uintptr_t)td->td_sigstk.ss_sp +
+ sfp = (struct ia32_freebsd4_sigframe *)((uintptr_t)td->td_sigstk.ss_sp +
td->td_sigstk.ss_size - sizeof(sf));
} else
- sfp = (struct ia32_sigframe4 *)regs->tf_rsp - 1;
+ sfp = (struct ia32_freebsd4_sigframe *)regs->tf_rsp - 1;
PROC_UNLOCK(p);
/* Build the argument list for the signal handler. */
@@ -527,8 +535,8 @@ freebsd4_ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
}
regs->tf_rsp = (uintptr_t)sfp;
- regs->tf_rip = p->p_sysent->sv_sigcode_base + sz_ia32_sigcode -
- sz_freebsd4_ia32_sigcode;
+ regs->tf_rip = p->p_sysent->sv_sigcode_base +
+ VDSO_FREEBSD4_IA32_SIGCODE_OFFSET - VDSO_IA32_SIGCODE_OFFSET;
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ss = _udatasel;
@@ -688,7 +696,7 @@ ia32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
int
ofreebsd32_sigreturn(struct thread *td, struct ofreebsd32_sigreturn_args *uap)
{
- struct ia32_sigcontext3 sc, *scp;
+ struct ia32_osigcontext sc, *scp;
struct trapframe *regs;
int eflags, error;
ksiginfo_t ksi;
@@ -746,9 +754,9 @@ int
freebsd4_freebsd32_sigreturn(struct thread *td,
struct freebsd4_freebsd32_sigreturn_args *uap)
{
- struct ia32_ucontext4 uc;
+ struct ia32_freebsd4_ucontext uc;
struct trapframe *regs;
- struct ia32_ucontext4 *ucp;
+ struct ia32_freebsd4_ucontext *ucp;
int cs, eflags, error;
ksiginfo_t ksi;
diff --git a/sys/amd64/ia32/ia32_sigtramp.S b/sys/amd64/ia32/ia32_sigtramp.S
index c76852c91b06..f7f3fd129cc7 100644
--- a/sys/amd64/ia32/ia32_sigtramp.S
+++ b/sys/amd64/ia32/ia32_sigtramp.S
@@ -2,6 +2,11 @@
* Copyright (c) 2003 Peter Wemm
* All rights reserved.
*
+ * Copyright (c) 2021 The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -32,27 +37,57 @@
#include "ia32_assym.h"
.text
- .code32
/*
- * Signal trampoline, copied to top of user stack
- * XXX may need to be MD to match backend sendsig handoff protocol
+ * Signal trampoline, mapped as vdso into shared page, or copied to
+ * top of user stack for old binaries.
*/
ALIGN_TEXT
- .globl ia32_sigcode
-ia32_sigcode:
+ .globl __vdso_ia32_sigcode
+__vdso_ia32_sigcode:
+ .cfi_startproc
+ .cfi_signal_frame
+ .cfi_def_cfa %esp, 0
+#if 0
+ .cfi_offset %gs, IA32_SIGF_UC + IA32_UC_GS
+ .cfi_offset %fs, IA32_SIGF_UC + IA32_UC_FS
+ .cfi_offset %es, IA32_SIGF_UC + IA32_UC_ES
+ .cfi_offset %ds, IA32_SIGF_UC + IA32_UC_DS
+#endif
+ .cfi_offset %edi, IA32_SIGF_UC + IA32_UC_EDI
+ .cfi_offset %esi, IA32_SIGF_UC + IA32_UC_ESI
+ .cfi_offset %ebp, IA32_SIGF_UC + IA32_UC_EBP
+ .cfi_offset %ebx, IA32_SIGF_UC + IA32_UC_EBX
+ .cfi_offset %edx, IA32_SIGF_UC + IA32_UC_EDX
+ .cfi_offset %ecx, IA32_SIGF_UC + IA32_UC_ECX
+ .cfi_offset %eax, IA32_SIGF_UC + IA32_UC_EAX
+ .cfi_offset %eip, IA32_SIGF_UC + IA32_UC_EIP
+#if 0
+ .cfi_offset %cs, IA32_SIGF_UC + IA32_UC_CS
+ .cfi_offset %flags, IA32_SIGF_UC + IA32_UC_EFLAGS
+#endif
+ .cfi_offset %esp, IA32_SIGF_UC + IA32_UC_ESP
+#if 0
+ .cfi_offset %ss, IA32_SIGF_UC + IA32_UC_SS
+ .cfi_offset 93 /* %fs.base */, IA32_SIGF_UC + IA32_UC_FSBASE
+ .cfi_offset 94 /* %gs.base */, IA32_SIGF_UC + IA32_UC_GSBASE
+#endif
calll *IA32_SIGF_HANDLER(%esp)
leal IA32_SIGF_UC(%esp),%eax /* get ucontext */
pushl %eax
+ .cfi_def_cfa %esp, 4
movl $SYS_sigreturn,%eax
pushl %eax /* junk to fake return addr. */
+ .cfi_def_cfa %esp, 8
int $0x80 /* enter kernel with args */
/* on stack */
1:
jmp 1b
+ .cfi_endproc
#ifdef COMPAT_FREEBSD4
ALIGN_TEXT
-freebsd4_ia32_sigcode:
+ .globl __vdso_freebsd4_ia32_sigcode
+__vdso_freebsd4_ia32_sigcode:
calll *IA32_SIGF_HANDLER(%esp)
leal IA32_SIGF_UC4(%esp),%eax/* get ucontext */
pushl %eax
@@ -66,7 +101,8 @@ freebsd4_ia32_sigcode:
#ifdef COMPAT_43
ALIGN_TEXT
-ia32_osigcode:
+ .globl __vdso_ia32_osigcode
+__vdso_ia32_osigcode:
calll *IA32_SIGF_HANDLER(%esp)/* call signal handler */
leal IA32_SIGF_SC(%esp),%eax /* get sigcontext */
pushl %eax
@@ -90,28 +126,9 @@ ia32_osigcode:
* vfork() and harder for other syscalls.
*/
ALIGN_TEXT
-lcall_tramp:
+ .globl __vdso_lcall_tramp
+__vdso_lcall_tramp:
int $0x80
1: jmp 1b
#endif
-
- ALIGN_TEXT
-esigcode:
-
- .data
- .globl sz_ia32_sigcode
-sz_ia32_sigcode:
- .long esigcode-ia32_sigcode
-#ifdef COMPAT_FREEBSD4
- .globl sz_freebsd4_ia32_sigcode
-sz_freebsd4_ia32_sigcode:
- .long esigcode-freebsd4_ia32_sigcode
-#endif
-#ifdef COMPAT_43
- .globl sz_ia32_osigcode
-sz_ia32_osigcode:
- .long esigcode-ia32_osigcode
- .globl sz_lcall_tramp
-sz_lcall_tramp:
- .long esigcode-lcall_tramp
-#endif
+ .p2align 1
diff --git a/sys/amd64/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c
index 4e95d056d7fa..2643b13fa547 100644
--- a/sys/amd64/ia32/ia32_syscall.c
+++ b/sys/amd64/ia32/ia32_syscall.c
@@ -92,6 +92,12 @@ __FBSDID("$FreeBSD$");
#include <machine/pcb.h>
#include <machine/cpufunc.h>
+#include "vdso_ia32_offsets.h"
+
+extern const char _binary_elf_vdso32_so_1_start[];
+extern const char _binary_elf_vdso32_so_1_end[];
+extern char _binary_elf_vdso32_so_1_size;
+
#define IDTVEC(name) __CONCAT(X,name)
extern inthand_t IDTVEC(int0x80_syscall), IDTVEC(int0x80_syscall_pti),
@@ -264,7 +270,9 @@ setup_lcall_gate(void)
bzero(&uap, sizeof(uap));
uap.start = 0;
uap.num = 1;
- lcall_addr = curproc->p_sysent->sv_psstrings - sz_lcall_tramp;
+ lcall_addr = PROC_PS_STRINGS(curproc) -
+ (_binary_elf_vdso32_so_1_end - _binary_elf_vdso32_so_1_start) +
+ VDSO_LCALL_TRAMP_OFFSET;
bzero(&desc, sizeof(desc));
desc.sd_type = SDT_MEMERA;
desc.sd_dpl = SEL_UPL;
diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h
index 4a9095ca831b..159d807f777c 100644
--- a/sys/amd64/include/atomic.h
+++ b/sys/amd64/include/atomic.h
@@ -30,10 +30,6 @@
#ifndef _MACHINE_ATOMIC_H_
#define _MACHINE_ATOMIC_H_
-#ifndef _SYS_CDEFS_H_
-#error this file needs sys/cdefs.h as a prerequisite
-#endif
-
/*
* To express interprocessor (as opposed to processor and device) memory
* ordering constraints, use the atomic_*() functions with acquire and release
@@ -103,56 +99,10 @@
*/
/*
- * The above functions are expanded inline in the statically-linked
- * kernel. Lock prefixes are generated if an SMP kernel is being
- * built.
+ * Always use lock prefixes. The result is slighly less optimal for
+ * UP systems, but it matters less now, and sometimes UP is emulated
+ * over SMP.
*
- * Kernel modules call real functions which are built into the kernel.
- * This allows kernel modules to be portable between UP and SMP systems.
- */
-#if !defined(__GNUCLIKE_ASM)
-#define ATOMIC_ASM(NAME, TYPE, OP, CONS, V) \
-void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v); \
-void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
-
-int atomic_cmpset_char(volatile u_char *dst, u_char expect, u_char src);
-int atomic_cmpset_short(volatile u_short *dst, u_short expect, u_short src);
-int atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src);
-int atomic_cmpset_long(volatile u_long *dst, u_long expect, u_long src);
-int atomic_fcmpset_char(volatile u_char *dst, u_char *expect, u_char src);
-int atomic_fcmpset_short(volatile u_short *dst, u_short *expect,
- u_short src);
-int atomic_fcmpset_int(volatile u_int *dst, u_int *expect, u_int src);
-int atomic_fcmpset_long(volatile u_long *dst, u_long *expect, u_long src);
-u_int atomic_fetchadd_int(volatile u_int *p, u_int v);
-u_long atomic_fetchadd_long(volatile u_long *p, u_long v);
-int atomic_testandset_int(volatile u_int *p, u_int v);
-int atomic_testandset_long(volatile u_long *p, u_int v);
-int atomic_testandclear_int(volatile u_int *p, u_int v);
-int atomic_testandclear_long(volatile u_long *p, u_int v);
-void atomic_thread_fence_acq(void);
-void atomic_thread_fence_acq_rel(void);
-void atomic_thread_fence_rel(void);
-void atomic_thread_fence_seq_cst(void);
-
-#define ATOMIC_LOAD(TYPE) \
-u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p)
-#define ATOMIC_STORE(TYPE) \
-void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
-
-#else /* !KLD_MODULE && __GNUCLIKE_ASM */
-
-/*
- * For userland, always use lock prefixes so that the binaries will run
- * on both SMP and !SMP systems.
- */
-#if defined(SMP) || !defined(_KERNEL) || defined(KLD_MODULE)
-#define MPLOCKED "lock ; "
-#else
-#define MPLOCKED
-#endif
-
-/*
* The assembly is volatilized to avoid code chunk removal by the compiler.
* GCC aggressively reorders operations and memory clobbering is necessary
* in order to avoid that for memory barriers.
@@ -161,7 +111,7 @@ void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
static __inline void \
atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
{ \
- __asm __volatile(MPLOCKED OP \
+ __asm __volatile("lock; " OP \
: "+m" (*p) \
: CONS (V) \
: "cc"); \
@@ -170,7 +120,7 @@ atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
static __inline void \
atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
{ \
- __asm __volatile(MPLOCKED OP \
+ __asm __volatile("lock; " OP \
: "+m" (*p) \
: CONS (V) \
: "memory", "cc"); \
@@ -199,8 +149,7 @@ atomic_cmpset_##TYPE(volatile u_##TYPE *dst, u_##TYPE expect, u_##TYPE src) \
u_char res; \
\
__asm __volatile( \
- " " MPLOCKED " " \
- " cmpxchg %3,%1 ; " \
+ " lock; cmpxchg %3,%1 ; " \
"# atomic_cmpset_" #TYPE " " \
: "=@cce" (res), /* 0 */ \
"+m" (*dst), /* 1 */ \
@@ -216,8 +165,7 @@ atomic_fcmpset_##TYPE(volatile u_##TYPE *dst, u_##TYPE *expect, u_##TYPE src) \
u_char res; \
\
__asm __volatile( \
- " " MPLOCKED " " \
- " cmpxchg %3,%1 ; " \
+ " lock; cmpxchg %3,%1 ; " \
"# atomic_fcmpset_" #TYPE " " \
: "=@cce" (res), /* 0 */ \
"+m" (*dst), /* 1 */ \
@@ -241,8 +189,7 @@ atomic_fetchadd_int(volatile u_int *p, u_int v)
{
__asm __volatile(
- " " MPLOCKED " "
- " xaddl %0,%1 ; "
+ " lock; xaddl %0,%1 ; "
"# atomic_fetchadd_int"
: "+r" (v), /* 0 */
"+m" (*p) /* 1 */
@@ -259,8 +206,7 @@ atomic_fetchadd_long(volatile u_long *p, u_long v)
{
__asm __volatile(
- " " MPLOCKED " "
- " xaddq %0,%1 ; "
+ " lock; xaddq %0,%1 ; "
"# atomic_fetchadd_long"
: "+r" (v), /* 0 */
"+m" (*p) /* 1 */
@@ -274,8 +220,7 @@ atomic_testandset_int(volatile u_int *p, u_int v)
u_char res;
__asm __volatile(
- " " MPLOCKED " "
- " btsl %2,%1 ; "
+ " lock; btsl %2,%1 ; "
"# atomic_testandset_int"
: "=@ccc" (res), /* 0 */
"+m" (*p) /* 1 */
@@ -290,8 +235,7 @@ atomic_testandset_long(volatile u_long *p, u_int v)
u_char res;
__asm __volatile(
- " " MPLOCKED " "
- " btsq %2,%1 ; "
+ " lock; btsq %2,%1 ; "
"# atomic_testandset_long"
: "=@ccc" (res), /* 0 */
"+m" (*p) /* 1 */
@@ -306,8 +250,7 @@ atomic_testandclear_int(volatile u_int *p, u_int v)
u_char res;
__asm __volatile(
- " " MPLOCKED " "
- " btrl %2,%1 ; "
+ " lock; btrl %2,%1 ; "
"# atomic_testandclear_int"
: "=@ccc" (res), /* 0 */
"+m" (*p) /* 1 */
@@ -322,8 +265,7 @@ atomic_testandclear_long(volatile u_long *p, u_int v)
u_char res;
__asm __volatile(
- " " MPLOCKED " "
- " btrq %2,%1 ; "
+ " lock; btrq %2,%1 ; "
"# atomic_testandclear_long"
: "=@ccc" (res), /* 0 */
"+m" (*p) /* 1 */
@@ -344,39 +286,18 @@ atomic_testandclear_long(volatile u_long *p, u_int v)
* special address for "mem". In the kernel, we use a private per-cpu
* cache line. In user space, we use a word in the stack's red zone
* (-8(%rsp)).
- *
- * For UP kernels, however, the memory of the single processor is
- * always consistent, so we only need to stop the compiler from
- * reordering accesses in a way that violates the semantics of acquire
- * and release.
*/
-#if defined(_KERNEL)
-
-#if defined(SMP) || defined(KLD_MODULE)
static __inline void
__storeload_barrier(void)
{
-
+#if defined(_KERNEL)
__asm __volatile("lock; addl $0,%%gs:%0"
: "+m" (*(u_int *)OFFSETOF_MONITORBUF) : : "memory", "cc");
-}
-#else /* _KERNEL && UP */
-static __inline void
-__storeload_barrier(void)
-{
-
- __compiler_membar();
-}
-#endif /* SMP */
#else /* !_KERNEL */
-static __inline void
-__storeload_barrier(void)
-{
-
__asm __volatile("lock; addl $0,-8(%%rsp)" : : : "memory", "cc");
-}
#endif /* _KERNEL*/
+}
#define ATOMIC_LOAD(TYPE) \
static __inline u_##TYPE \
@@ -428,8 +349,6 @@ atomic_thread_fence_seq_cst(void)
__storeload_barrier();
}
-#endif /* KLD_MODULE || !__GNUCLIKE_ASM */
-
ATOMIC_ASM(set, char, "orb %b1,%0", "iq", v);
ATOMIC_ASM(clear, char, "andb %b1,%0", "iq", ~v);
ATOMIC_ASM(add, char, "addb %b1,%0", "iq", v);
@@ -466,8 +385,6 @@ ATOMIC_LOADSTORE(long);
#ifndef WANT_FUNCTIONS
/* Read the current value and store a new value in the destination. */
-#ifdef __GNUCLIKE_ASM
-
static __inline u_int
atomic_swap_int(volatile u_int *p, u_int v)
{
@@ -492,13 +409,6 @@ atomic_swap_long(volatile u_long *p, u_long v)
return (v);
}
-#else /* !__GNUCLIKE_ASM */
-
-u_int atomic_swap_int(volatile u_int *p, u_int v);
-u_long atomic_swap_long(volatile u_long *p, u_long v);
-
-#endif /* __GNUCLIKE_ASM */
-
#define atomic_set_acq_char atomic_set_barr_char
#define atomic_set_rel_char atomic_set_barr_char
#define atomic_clear_acq_char atomic_clear_barr_char
diff --git a/sys/amd64/include/clock.h b/sys/amd64/include/clock.h
index 86a4541568ed..57233651aef3 100644
--- a/sys/amd64/include/clock.h
+++ b/sys/amd64/include/clock.h
@@ -1,46 +1,5 @@
-/*-
- * Kernel interface to machine-dependent clock driver.
- * Garrett Wollman, September 1994.
- * This file is in the public domain.
- *
- * $FreeBSD$
- */
-
-#ifndef _MACHINE_CLOCK_H_
-#define _MACHINE_CLOCK_H_
-
-#ifdef _KERNEL
-/*
- * i386 to clock driver interface.
- * XXX large parts of the driver and its interface are misplaced.
- */
-extern int clkintr_pending;
-extern u_int i8254_freq;
-extern int i8254_max_count;
-extern uint64_t tsc_freq;
-extern int tsc_is_invariant;
-extern int tsc_perf_stat;
-#ifdef SMP
-extern int smp_tsc;
-#endif
-
-void i8254_init(void);
-void i8254_delay(int);
-void clock_init(void);
-
/*
- * Driver to clock driver interface.
+ * This file is in the public domain.
*/
-void startrtclock(void);
-void init_TSC(void);
-void resume_TSC(void);
-
-#define HAS_TIMER_SPKR 1
-int timer_spkr_acquire(void);
-int timer_spkr_release(void);
-void timer_spkr_setfreq(int freq);
-
-#endif /* _KERNEL */
-
-#endif /* !_MACHINE_CLOCK_H_ */
+#include <x86/clock.h>
diff --git a/sys/amd64/include/cpu.h b/sys/amd64/include/cpu.h
index 1b8a552d3e7c..f7732435fc39 100644
--- a/sys/amd64/include/cpu.h
+++ b/sys/amd64/include/cpu.h
@@ -80,7 +80,6 @@ void cpu_halt(void);
void cpu_lock_delay(void);
void cpu_reset(void);
void fork_trampoline(void);
-void swi_vm(void *);
/*
* Return contents of in-cpu fast counter as a sort of "bogo-time"
diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index bca74d8ead67..99d8c82aa111 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -41,10 +41,6 @@
#ifndef _MACHINE_CPUFUNC_H_
#define _MACHINE_CPUFUNC_H_
-#ifndef _SYS_CDEFS_H_
-#error this file needs sys/cdefs.h as a prerequisite
-#endif
-
struct region_descriptor;
#define readb(va) (*(volatile uint8_t *) (va))
@@ -57,8 +53,6 @@ struct region_descriptor;
#define writel(va, d) (*(volatile uint32_t *) (va) = (d))
#define writeq(va, d) (*(volatile uint64_t *) (va) = (d))
-#if defined(__GNUCLIKE_ASM) && defined(__CC_SUPPORTS___INLINE)
-
static __inline void
breakpoint(void)
{
@@ -964,73 +958,6 @@ sgx_eremove(void *epc)
return (sgx_encls(SGX_EREMOVE, 0, (uint64_t)epc, 0));
}
-#else /* !(__GNUCLIKE_ASM && __CC_SUPPORTS___INLINE) */
-
-int breakpoint(void);
-u_int bsfl(u_int mask);
-u_int bsrl(u_int mask);
-void clflush(u_long addr);
-void clts(void);
-void cpuid_count(u_int ax, u_int cx, u_int *p);
-void disable_intr(void);
-void do_cpuid(u_int ax, u_int *p);
-void enable_intr(void);
-void halt(void);
-void ia32_pause(void);
-u_char inb(u_int port);
-u_int inl(u_int port);
-void insb(u_int port, void *addr, size_t count);
-void insl(u_int port, void *addr, size_t count);
-void insw(u_int port, void *addr, size_t count);
-register_t intr_disable(void);
-void intr_restore(register_t rf);
-void invd(void);
-void invlpg(u_int addr);
-void invltlb(void);
-u_short inw(u_int port);
-void lidt(struct region_descriptor *addr);
-void lldt(u_short sel);
-void load_cr0(u_long cr0);
-void load_cr3(u_long cr3);
-void load_cr4(u_long cr4);
-void load_dr0(uint64_t dr0);
-void load_dr1(uint64_t dr1);
-void load_dr2(uint64_t dr2);
-void load_dr3(uint64_t dr3);
-void load_dr6(uint64_t dr6);
-void load_dr7(uint64_t dr7);
-void load_fs(u_short sel);
-void load_gs(u_short sel);
-void ltr(u_short sel);
-void outb(u_int port, u_char data);
-void outl(u_int port, u_int data);
-void outsb(u_int port, const void *addr, size_t count);
-void outsl(u_int port, const void *addr, size_t count);
-void outsw(u_int port, const void *addr, size_t count);
-void outw(u_int port, u_short data);
-u_long rcr0(void);
-u_long rcr2(void);
-u_long rcr3(void);
-u_long rcr4(void);
-uint64_t rdmsr(u_int msr);
-uint32_t rdmsr32(u_int msr);
-uint64_t rdpmc(u_int pmc);
-uint64_t rdr0(void);
-uint64_t rdr1(void);
-uint64_t rdr2(void);
-uint64_t rdr3(void);
-uint64_t rdr6(void);
-uint64_t rdr7(void);
-uint64_t rdtsc(void);
-u_long read_rflags(void);
-u_int rfs(void);
-u_int rgs(void);
-void wbinvd(void);
-void write_rflags(u_int rf);
-void wrmsr(u_int msr, uint64_t newval);
-
-#endif /* __GNUCLIKE_ASM && __CC_SUPPORTS___INLINE */
-
void reset_dbregs(void);
#ifdef _KERNEL
diff --git a/sys/amd64/include/ieeefp.h b/sys/amd64/include/ieeefp.h
index 96ee7e9040d8..48d879f0b80b 100644
--- a/sys/amd64/include/ieeefp.h
+++ b/sys/amd64/include/ieeefp.h
@@ -67,8 +67,6 @@
#define SSE_RND_OFF 13 /* rounding control offset */
#define SSE_FZ_OFF 15 /* flush to zero offset */
-#ifdef __GNUCLIKE_ASM
-
/*
* General notes about conflicting SSE vs FP status bits.
* This code assumes that software will not fiddle with the control
@@ -184,9 +182,7 @@ __fpgetsticky(void)
return ((fp_except_t)_ex);
}
-#endif /* __GNUCLIKE_ASM */
-
-#if !defined(__IEEEFP_NOINLINES__) && defined(__GNUCLIKE_ASM)
+#if !defined(__IEEEFP_NOINLINES__)
#define fpgetmask() __fpgetmask()
#define fpgetprec() __fpgetprec()
@@ -196,7 +192,7 @@ __fpgetsticky(void)
#define fpsetprec(m) __fpsetprec(m)
#define fpsetround(m) __fpsetround(m)
-#else /* !(!__IEEEFP_NOINLINES__ && __GNUCLIKE_ASM) */
+#else /* __IEEEFP_NOINLINES__ */
/* Augment the userland declarations. */
__BEGIN_DECLS
@@ -210,6 +206,6 @@ fp_prec_t fpgetprec(void);
fp_prec_t fpsetprec(fp_prec_t);
__END_DECLS
-#endif /* !__IEEEFP_NOINLINES__ && __GNUCLIKE_ASM */
+#endif /* !__IEEEFP_NOINLINES__ */
#endif /* !_MACHINE_IEEEFP_H_ */
diff --git a/sys/amd64/include/in_cksum.h b/sys/amd64/include/in_cksum.h
index 89ff1097f369..d9830168f5ab 100644
--- a/sys/amd64/include/in_cksum.h
+++ b/sys/amd64/include/in_cksum.h
@@ -37,12 +37,6 @@
#ifndef _MACHINE_IN_CKSUM_H_
#define _MACHINE_IN_CKSUM_H_ 1
-#ifndef _SYS_CDEFS_H_
-#error this file needs sys/cdefs.h as a prerequisite
-#endif
-
-#include <sys/cdefs.h>
-
#define in_cksum(m, len) in_cksum_skip(m, len, 0)
#ifdef _KERNEL
diff --git a/sys/amd64/include/limits.h b/sys/amd64/include/limits.h
index 5a7b831b3089..f2a4bf75fe2c 100644
--- a/sys/amd64/include/limits.h
+++ b/sys/amd64/include/limits.h
@@ -35,11 +35,7 @@
#ifndef _MACHINE_LIMITS_H_
#define _MACHINE_LIMITS_H_
-#include <sys/cdefs.h>
-
-#ifdef __CC_SUPPORTS_WARNING
#warning "machine/limits.h is deprecated. Include sys/limits.h instead."
-#endif
#include <sys/limits.h>
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index 53139711bbff..53358600dc79 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -54,6 +54,7 @@ extern vm_paddr_t KERNend;
extern bool efi_boot;
+struct __mcontext;
struct savefpu;
struct sysentvec;
@@ -88,5 +89,9 @@ void set_top_of_stack_td(struct thread *td);
struct savefpu *get_pcb_user_save_td(struct thread *td);
struct savefpu *get_pcb_user_save_pcb(struct pcb *pcb);
void pci_early_quirks(void);
+void get_fpcontext(struct thread *td, struct __mcontext *mcp,
+ char **xfpusave, size_t *xfpusave_len);
+int set_fpcontext(struct thread *td, struct __mcontext *mcp,
+ char *xfpustate, size_t xfpustate_len);
#endif /* !_MACHINE_MD_VAR_H_ */
diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h
index dc99d4249bd2..a671f01dbad5 100644
--- a/sys/amd64/include/pcpu.h
+++ b/sys/amd64/include/pcpu.h
@@ -31,10 +31,6 @@
#ifndef _MACHINE_PCPU_H_
#define _MACHINE_PCPU_H_
-#ifndef _SYS_CDEFS_H_
-#error "sys/cdefs.h is a prerequisite for this file"
-#endif
-
#include <machine/segments.h>
#include <machine/tss.h>
@@ -109,8 +105,6 @@ _Static_assert(sizeof(struct monitorbuf) == 128, "2x cache line");
#define MONITOR_STOPSTATE_RUNNING 0
#define MONITOR_STOPSTATE_STOPPED 1
-#if defined(__GNUCLIKE_ASM) && defined(__GNUCLIKE___TYPEOF)
-
/*
* Evaluates to the byte offset of the per-cpu variable name.
*/
@@ -277,12 +271,6 @@ _Static_assert(sizeof(struct monitorbuf) == 128, "2x cache line");
} \
} while (0);
-#else /* !__GNUCLIKE_ASM || !__GNUCLIKE___TYPEOF */
-
-#error "this file needs to be ported to your compiler"
-
-#endif /* __GNUCLIKE_ASM && __GNUCLIKE___TYPEOF */
-
#endif /* _KERNEL */
#endif /* !_MACHINE_PCPU_H_ */
diff --git a/sys/amd64/include/proc.h b/sys/amd64/include/proc.h
index 6b0d0e66d0ee..763f2a293e90 100644
--- a/sys/amd64/include/proc.h
+++ b/sys/amd64/include/proc.h
@@ -91,13 +91,6 @@ struct mdproc {
#define KINFO_PROC_SIZE 1088
#define KINFO_PROC32_SIZE 768
-struct syscall_args {
- u_int code;
- u_int original_code;
- struct sysent *callp;
- register_t args[8];
-};
-
#ifdef _KERNEL
/* Get the current kernel thread stack usage. */
diff --git a/sys/amd64/include/profile.h b/sys/amd64/include/profile.h
index b0fb469f5354..e86fd582b407 100644
--- a/sys/amd64/include/profile.h
+++ b/sys/amd64/include/profile.h
@@ -45,7 +45,6 @@
static void _mcount(uintfptr_t frompc, uintfptr_t selfpc) __used; \
static void _mcount
-#ifdef __GNUCLIKE_ASM
#define MCOUNT __asm(" \n\
.text \n\
.p2align 4,0x90 \n\
@@ -101,9 +100,6 @@ mcount() \
_mcount(frompc, selfpc); \
}
#endif
-#else /* !__GNUCLIKE_ASM */
-#define MCOUNT
-#endif /* __GNUCLIKE_ASM */
typedef u_long uintfptr_t;
@@ -114,9 +110,7 @@ typedef u_long uintfptr_t;
typedef u_long fptrdiff_t;
__BEGIN_DECLS
-#ifdef __GNUCLIKE_ASM
void mcount(void) __asm(".mcount");
-#endif
__END_DECLS
#endif /* !_KERNEL */
diff --git a/sys/amd64/include/tls.h b/sys/amd64/include/tls.h
new file mode 100644
index 000000000000..15a4a407c0e0
--- /dev/null
+++ b/sys/amd64/include/tls.h
@@ -0,0 +1,5 @@
+/*-
+ * This file is in the public domain.
+ */
+
+#include <x86/tls.h>
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index f265237a5303..d7d1509248f1 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -469,7 +469,9 @@ void vm_copyout(struct vm *vm, int vcpuid, const void *kaddr,
int vcpu_trace_exceptions(struct vm *vm, int vcpuid);
#endif /* KERNEL */
+#ifdef _KERNEL
#define VM_MAXCPU 16 /* maximum virtual cpus */
+#endif
/*
* Identifiers for optional vmm capabilities
diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h
index a048e05d4b7c..9ed8f32302ae 100644
--- a/sys/amd64/include/vmm_dev.h
+++ b/sys/amd64/include/vmm_dev.h
@@ -174,6 +174,7 @@ struct vm_nmi {
#define MAX_VM_STATS 64
struct vm_stats {
int cpuid; /* in */
+ int index; /* in */
int num_entries; /* out */
struct timeval tv;
uint64_t statbuf[MAX_VM_STATS];
diff --git a/sys/amd64/include/xen/hypercall.h b/sys/amd64/include/xen/hypercall.h
index 6d00d4a6ebd8..60da390ef4c6 100644
--- a/sys/amd64/include/xen/hypercall.h
+++ b/sys/amd64/include/xen/hypercall.h
@@ -145,6 +145,9 @@ privcmd_hypercall(long op, long a1, long a2, long a3, long a4, long a5)
register long __arg5 __asm__("r8") = (long)(a5);
long __call = (long)&hypercall_page + (op * 32);
+ if (op >= PAGE_SIZE / 32)
+ return -EINVAL;
+
__asm__ volatile (
"call *%[call]"
: "=a" (__res), "=D" (__ign1), "=S" (__ign2),
diff --git a/sys/amd64/linux/linux.h b/sys/amd64/linux/linux.h
index 920ca98ce01b..02aede96ce23 100644
--- a/sys/amd64/linux/linux.h
+++ b/sys/amd64/linux/linux.h
@@ -74,6 +74,8 @@ typedef l_int l_mqd_t;
typedef l_size_t l_socklen_t;
typedef l_ulong l_fd_mask;
+#include <compat/linux/linux_siginfo.h>
+
typedef struct {
l_int val[2];
} l_fsid_t;
@@ -182,141 +184,6 @@ typedef struct {
l_size_t ss_size;
} l_stack_t;
-struct l_fpstate {
- u_int16_t cwd;
- u_int16_t swd;
- u_int16_t twd;
- u_int16_t fop;
- u_int64_t rip;
- u_int64_t rdp;
- u_int32_t mxcsr;
- u_int32_t mxcsr_mask;
- u_int32_t st_space[32];
- u_int32_t xmm_space[64];
- u_int32_t reserved2[24];
-};
-
-struct l_sigcontext {
- l_ulong sc_r8;
- l_ulong sc_r9;
- l_ulong sc_r10;
- l_ulong sc_r11;
- l_ulong sc_r12;
- l_ulong sc_r13;
- l_ulong sc_r14;
- l_ulong sc_r15;
- l_ulong sc_rdi;
- l_ulong sc_rsi;
- l_ulong sc_rbp;
- l_ulong sc_rbx;
- l_ulong sc_rdx;
- l_ulong sc_rax;
- l_ulong sc_rcx;
- l_ulong sc_rsp;
- l_ulong sc_rip;
- l_ulong sc_rflags;
- l_ushort sc_cs;
- l_ushort sc_gs;
- l_ushort sc_fs;
- l_ushort sc___pad0;
- l_ulong sc_err;
- l_ulong sc_trapno;
- l_sigset_t sc_mask;
- l_ulong sc_cr2;
- struct l_fpstate *sc_fpstate;
- l_ulong sc_reserved1[8];
-};
-
-struct l_ucontext {
- l_ulong uc_flags;
- l_uintptr_t uc_link;
- l_stack_t uc_stack;
- struct l_sigcontext uc_mcontext;
- l_sigset_t uc_sigmask;
-};
-
-#define LINUX_SI_PREAMBLE_SIZE (4 * sizeof(int))
-#define LINUX_SI_MAX_SIZE 128
-#define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE - \
- LINUX_SI_PREAMBLE_SIZE) / sizeof(l_int))
-typedef union l_sigval {
- l_int sival_int;
- l_uintptr_t sival_ptr;
-} l_sigval_t;
-
-typedef struct l_siginfo {
- l_int lsi_signo;
- l_int lsi_errno;
- l_int lsi_code;
- union {
- l_int _pad[LINUX_SI_PAD_SIZE];
-
- struct {
- l_pid_t _pid;
- l_uid_t _uid;
- } _kill;
-
- struct {
- l_timer_t _tid;
- l_int _overrun;
- char _pad[sizeof(l_uid_t) - sizeof(int)];
- union l_sigval _sigval;
- l_uint _sys_private;
- } _timer;
-
- struct {
- l_pid_t _pid; /* sender's pid */
- l_uid_t _uid; /* sender's uid */
- union l_sigval _sigval;
- } _rt;
-
- struct {
- l_pid_t _pid; /* which child */
- l_uid_t _uid; /* sender's uid */
- l_int _status; /* exit code */
- l_clock_t _utime;
- l_clock_t _stime;
- } _sigchld;
-
- struct {
- l_uintptr_t _addr; /* Faulting insn/memory ref. */
- } _sigfault;
-
- struct {
- l_long _band; /* POLL_IN,POLL_OUT,POLL_MSG */
- l_int _fd;
- } _sigpoll;
- } _sifields;
-} l_siginfo_t;
-
-#define lsi_pid _sifields._kill._pid
-#define lsi_uid _sifields._kill._uid
-#define lsi_tid _sifields._timer._tid
-#define lsi_overrun _sifields._timer._overrun
-#define lsi_sys_private _sifields._timer._sys_private
-#define lsi_status _sifields._sigchld._status
-#define lsi_utime _sifields._sigchld._utime
-#define lsi_stime _sifields._sigchld._stime
-#define lsi_value _sifields._rt._sigval
-#define lsi_int _sifields._rt._sigval.sival_int
-#define lsi_ptr _sifields._rt._sigval.sival_ptr
-#define lsi_addr _sifields._sigfault._addr
-#define lsi_band _sifields._sigpoll._band
-#define lsi_fd _sifields._sigpoll._fd
-
-/*
- * We make the stack look like Linux expects it when calling a signal
- * handler, but use the BSD way of calling the handler and sigreturn().
- * This means that we need to pass the pointer to the handler too.
- * It is appended to the frame to not interfere with the rest of it.
- */
-
-struct l_rt_sigframe {
- struct l_ucontext sf_sc;
- struct l_siginfo sf_si;
- l_handler_t sf_handler;
-};
-
/*
* mount flags
*/
diff --git a/sys/amd64/linux/linux_dummy_machdep.c b/sys/amd64/linux/linux_dummy_machdep.c
index 4e4d0f9c0d8b..3ce407af291c 100644
--- a/sys/amd64/linux/linux_dummy_machdep.c
+++ b/sys/amd64/linux/linux_dummy_machdep.c
@@ -68,6 +68,5 @@ DUMMY(mq_notify);
DUMMY(mq_getsetattr);
DUMMY(readahead);
DUMMY(restart_syscall);
-DUMMY(semtimedop);
/* Linux 3.15: */
DUMMY(kexec_file_load);
diff --git a/sys/amd64/linux/linux_genassym.c b/sys/amd64/linux/linux_genassym.c
index 0edb6a043531..14880afcc89b 100644
--- a/sys/amd64/linux/linux_genassym.c
+++ b/sys/amd64/linux/linux_genassym.c
@@ -8,8 +8,27 @@ __FBSDID("$FreeBSD$");
#include <amd64/linux/linux.h>
#include <compat/linux/linux_mib.h>
-ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler));
-ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc));
+#include <x86/linux/linux_x86_sigframe.h>
+
+ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_uc));
ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext));
+ASSYM(L_SC_R8, offsetof(struct l_sigcontext, sc_r8));
+ASSYM(L_SC_R9, offsetof(struct l_sigcontext, sc_r9));
+ASSYM(L_SC_R10, offsetof(struct l_sigcontext, sc_r10));
+ASSYM(L_SC_R11, offsetof(struct l_sigcontext, sc_r11));
+ASSYM(L_SC_R12, offsetof(struct l_sigcontext, sc_r12));
+ASSYM(L_SC_R13, offsetof(struct l_sigcontext, sc_r13));
+ASSYM(L_SC_R14, offsetof(struct l_sigcontext, sc_r14));
+ASSYM(L_SC_R15, offsetof(struct l_sigcontext, sc_r15));
+ASSYM(L_SC_RDI, offsetof(struct l_sigcontext, sc_rdi));
+ASSYM(L_SC_RSI, offsetof(struct l_sigcontext, sc_rsi));
+ASSYM(L_SC_RBP, offsetof(struct l_sigcontext, sc_rbp));
+ASSYM(L_SC_RBX, offsetof(struct l_sigcontext, sc_rbx));
+ASSYM(L_SC_RDX, offsetof(struct l_sigcontext, sc_rdx));
+ASSYM(L_SC_RAX, offsetof(struct l_sigcontext, sc_rax));
+ASSYM(L_SC_RCX, offsetof(struct l_sigcontext, sc_rcx));
+ASSYM(L_SC_RSP, offsetof(struct l_sigcontext, sc_rsp));
+ASSYM(L_SC_RIP, offsetof(struct l_sigcontext, sc_rip));
+ASSYM(L_SC_RFLAGS, offsetof(struct l_sigcontext, sc_rflags));
+ASSYM(L_SC_CS, offsetof(struct l_sigcontext, sc_cs));
ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE);
-ASSYM(LINUX_SC_RSP, offsetof(struct l_sigcontext, sc_rsp));
diff --git a/sys/amd64/linux/linux_locore.asm b/sys/amd64/linux/linux_locore.asm
index dd482cb87cc8..f26996980007 100644
--- a/sys/amd64/linux/linux_locore.asm
+++ b/sys/amd64/linux/linux_locore.asm
@@ -1,4 +1,31 @@
-/* $FreeBSD$ */
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2015-2022 Dmitry Chagin <dchagin@freeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
#include "linux_assym.h" /* system definitions */
#include <machine/asmacros.h> /* miscellaneous asm macros */
@@ -11,27 +38,40 @@
linux_platform:
.asciz "x86_64"
-
.text
-/*
- * To avoid excess stack frame the signal trampoline code emulates
- * the 'call' instruction.
- */
+
ENTRY(linux_rt_sigcode)
- movq %rsp, %rbx /* preserve sigframe */
- call .getip
-.getip:
- popq %rax
- add $.startrtsigcode-.getip, %rax /* ret address */
- pushq %rax
- jmp *LINUX_RT_SIGF_HANDLER(%rbx)
-.startrtsigcode:
- movq $LINUX_SYS_linux_rt_sigreturn,%rax /* linux_rt_sigreturn() */
- syscall /* enter kernel with args */
- hlt
-.endrtsigcode:
-0: jmp 0b
+ .cfi_startproc
+ .cfi_signal_frame
+ .cfi_def_cfa %rsp, LINUX_RT_SIGF_SC
+ .cfi_offset %r8, L_SC_R8
+ .cfi_offset %r9, L_SC_R9
+ .cfi_offset %r10, L_SC_R10
+ .cfi_offset %r11, L_SC_R11
+ .cfi_offset %r12, L_SC_R12
+ .cfi_offset %r13, L_SC_R13
+ .cfi_offset %r14, L_SC_R14
+ .cfi_offset %r15, L_SC_R15
+ .cfi_offset %rdi, L_SC_RDI
+ .cfi_offset %rsi, L_SC_RSI
+ .cfi_offset %rbp, L_SC_RBP
+ .cfi_offset %rbx, L_SC_RBX
+ .cfi_offset %rdx, L_SC_RDX
+ .cfi_offset %rax, L_SC_RAX
+ .cfi_offset %rcx, L_SC_RCX
+ .cfi_offset %rip, L_SC_RIP
+ .cfi_offset 49, L_SC_RFLAGS
+ .cfi_offset %cs, L_SC_CS
+ .cfi_offset %rsp, L_SC_RSP
+ movq %rsp, %rbx /* rt_sigframe for rt_sigreturn */
+ call *%rcx /* call signal handler */
+ movq $LINUX_SYS_linux_rt_sigreturn, %rax
+ syscall
+0: hlt
+ jmp 0b
+ .cfi_endproc
+END(linux_rt_sigcode)
#if 0
.section .note.Linux, "a",@note
@@ -49,34 +89,3 @@ ENTRY(linux_rt_sigcode)
.balign 4
.previous
#endif
-
- .section .eh_frame,"a",@progbits
-.LSTARTFRAMEDLSI0:
- .long .LENDCIEDLSI0-.LSTARTCIEDLSI0
-.LSTARTCIEDLSI0:
- .long 0 /* CIE ID */
- .byte 1 /* Version number */
- .string "zR" /* NULL-terminated
- * augmentation string
- */
- .uleb128 1 /* Code alignment factor */
- .sleb128 -4 /* Data alignment factor */
- .byte 8 /* Return address register column */
- .uleb128 1 /* Augmentation value length */
- .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
- .byte 0x0c /* DW_CFA_def_cfa */
- .uleb128 4
- .uleb128 4
- .byte 0x88 /* DW_CFA_offset, column 0x8 */
- .uleb128 1
- .align 4
-.LENDCIEDLSI0:
- .long .LENDFDEDLSI0-.LSTARTFDEDLSI0 /* Length FDE */
-.LSTARTFDEDLSI0:
- .long .LSTARTFDEDLSI0-.LSTARTFRAMEDLSI0 /* CIE pointer */
- .long .startrtsigcode-. /* PC-relative start address */
- .long .endrtsigcode-.startrtsigcode
- .uleb128 0
- .align 4
-.LENDFDEDLSI0:
- .previous
diff --git a/sys/amd64/linux/linux_machdep.c b/sys/amd64/linux/linux_machdep.c
index 18be62dab9ae..1c042424f3ea 100644
--- a/sys/amd64/linux/linux_machdep.c
+++ b/sys/amd64/linux/linux_machdep.c
@@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
-#include <sys/imgact.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
#include <sys/limits.h>
@@ -83,8 +82,6 @@ __FBSDID("$FreeBSD$");
#include <x86/reg.h>
#include <x86/sysarch.h>
-#include <security/audit/audit.h>
-
#include <amd64/linux/linux.h>
#include <amd64/linux/linux_proto.h>
#include <compat/linux/linux_emul.h>
@@ -99,30 +96,6 @@ __FBSDID("$FreeBSD$");
#define LINUX_ARCH_AMD64 0xc000003e
int
-linux_execve(struct thread *td, struct linux_execve_args *args)
-{
- struct image_args eargs;
- char *path;
- int error;
-
- LINUX_CTR(execve);
-
- if (!LUSECONVPATH(td)) {
- error = exec_copyin_args(&eargs, args->path, UIO_USERSPACE,
- args->argp, args->envp);
- } else {
- LCONVPATHEXIST(args->path, &path);
- error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, args->argp,
- args->envp);
- LFREEPATH(path);
- }
- if (error == 0)
- error = linux_common_execve(td, &eargs);
- AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td);
- return (error);
-}
-
-int
linux_set_upcall(struct thread *td, register_t stack)
{
diff --git a/sys/amd64/linux/linux_proto.h b/sys/amd64/linux/linux_proto.h
index e609d3deeb31..8b4ea2bb42fc 100644
--- a/sys/amd64/linux/linux_proto.h
+++ b/sys/amd64/linux/linux_proto.h
@@ -23,8 +23,8 @@ struct proc;
struct thread;
-#define PAD_(t) (sizeof(register_t) <= sizeof(t) ? \
- 0 : sizeof(register_t) - sizeof(t))
+#define PAD_(t) (sizeof(syscallarg_t) <= sizeof(t) ? \
+ 0 : sizeof(syscallarg_t) - sizeof(t))
#if BYTE_ORDER == LITTLE_ENDIAN
#define PADL_(t) 0
@@ -162,7 +162,7 @@ struct linux_shmctl_args {
char buf_l_[PADL_(struct l_shmid_ds *)]; struct l_shmid_ds * buf; char buf_r_[PADR_(struct l_shmid_ds *)];
};
struct linux_pause_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_nanosleep_args {
char rqtp_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * rqtp; char rqtp_r_[PADR_(const struct l_timespec *)];
@@ -181,7 +181,7 @@ struct linux_setitimer_args {
char oitv_l_[PADL_(struct l_itimerval *)]; struct l_itimerval * oitv; char oitv_r_[PADR_(struct l_itimerval *)];
};
struct linux_getpid_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_sendfile_args {
char out_l_[PADL_(l_int)]; l_int out; char out_r_[PADR_(l_int)];
@@ -281,10 +281,10 @@ struct linux_clone_args {
char tls_l_[PADL_(l_ulong)]; l_ulong tls; char tls_r_[PADR_(l_ulong)];
};
struct linux_fork_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_vfork_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_execve_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
@@ -312,11 +312,6 @@ struct linux_semget_args {
char nsems_l_[PADL_(l_int)]; l_int nsems; char nsems_r_[PADR_(l_int)];
char semflg_l_[PADL_(l_int)]; l_int semflg; char semflg_r_[PADR_(l_int)];
};
-struct linux_semop_args {
- char semid_l_[PADL_(l_int)]; l_int semid; char semid_r_[PADR_(l_int)];
- char tsops_l_[PADL_(struct l_sembuf *)]; struct l_sembuf * tsops; char tsops_r_[PADR_(struct l_sembuf *)];
- char nsops_l_[PADL_(l_uint)]; l_uint nsops; char nsops_r_[PADR_(l_uint)];
-};
struct linux_semctl_args {
char semid_l_[PADL_(l_int)]; l_int semid; char semid_r_[PADR_(l_int)];
char semnum_l_[PADL_(l_int)]; l_int semnum; char semnum_r_[PADR_(l_int)];
@@ -438,7 +433,7 @@ struct linux_ptrace_args {
char data_l_[PADL_(l_ulong)]; l_ulong data; char data_r_[PADR_(l_ulong)];
};
struct linux_getuid_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_syslog_args {
char type_l_[PADL_(l_int)]; l_int type; char type_r_[PADR_(l_int)];
@@ -446,10 +441,10 @@ struct linux_syslog_args {
char len_l_[PADL_(l_int)]; l_int len; char len_r_[PADR_(l_int)];
};
struct linux_getgid_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_getppid_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_getgroups_args {
char gidsetsize_l_[PADL_(l_int)]; l_int gidsetsize; char gidsetsize_r_[PADR_(l_int)];
@@ -559,13 +554,13 @@ struct linux_sched_rr_get_interval_args {
char interval_l_[PADL_(struct l_timespec *)]; struct l_timespec * interval; char interval_r_[PADR_(struct l_timespec *)];
};
struct linux_vhangup_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_modify_ldt_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_pivot_root_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_sysctl_args {
char args_l_[PADL_(struct l___sysctl_args *)]; struct l___sysctl_args * args; char args_r_[PADR_(struct l___sysctl_args *)];
@@ -582,7 +577,7 @@ struct linux_arch_prctl_args {
char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)];
};
struct linux_adjtimex_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_setrlimit_args {
char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)];
@@ -600,7 +595,7 @@ struct linux_umount_args {
char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_swapoff_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_reboot_args {
char magic1_l_[PADL_(l_int)]; l_int magic1; char magic1_r_[PADR_(l_int)];
@@ -620,22 +615,22 @@ struct linux_iopl_args {
char level_l_[PADL_(l_uint)]; l_uint level; char level_r_[PADR_(l_uint)];
};
struct linux_ioperm_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_init_module_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_delete_module_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_quotactl_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_gettid_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_readahead_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_setxattr_args {
char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
@@ -729,28 +724,28 @@ struct linux_sched_getaffinity_args {
char user_mask_ptr_l_[PADL_(l_ulong *)]; l_ulong * user_mask_ptr; char user_mask_ptr_r_[PADR_(l_ulong *)];
};
struct linux_io_setup_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_io_destroy_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_io_getevents_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_io_submit_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_io_cancel_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_lookup_dcookie_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_epoll_create_args {
char size_l_[PADL_(l_int)]; l_int size; char size_r_[PADR_(l_int)];
};
struct linux_remap_file_pages_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_getdents64_args {
char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
@@ -761,10 +756,13 @@ struct linux_set_tid_address_args {
char tidptr_l_[PADL_(l_int *)]; l_int * tidptr; char tidptr_r_[PADR_(l_int *)];
};
struct linux_restart_syscall_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_semtimedop_args {
- register_t dummy;
+ char semid_l_[PADL_(l_int)]; l_int semid; char semid_r_[PADR_(l_int)];
+ char tsops_l_[PADL_(struct sembuf *)]; struct sembuf * tsops; char tsops_r_[PADR_(struct sembuf *)];
+ char nsops_l_[PADL_(l_size_t)]; l_size_t nsops; char nsops_r_[PADR_(l_size_t)];
+ char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)];
};
struct linux_fadvise64_args {
char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
@@ -836,13 +834,13 @@ struct linux_utimes_args {
char tptr_l_[PADL_(struct l_timeval *)]; struct l_timeval * tptr; char tptr_r_[PADR_(struct l_timeval *)];
};
struct linux_mbind_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_set_mempolicy_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_get_mempolicy_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_mq_open_args {
char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
@@ -877,7 +875,7 @@ struct linux_mq_getsetattr_args {
char oattr_l_[PADL_(struct mq_attr *)]; struct mq_attr * oattr; char oattr_r_[PADR_(struct mq_attr *)];
};
struct linux_kexec_load_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_waitid_args {
char idtype_l_[PADL_(l_int)]; l_int idtype; char idtype_r_[PADR_(l_int)];
@@ -887,31 +885,31 @@ struct linux_waitid_args {
char rusage_l_[PADL_(struct rusage *)]; struct rusage * rusage; char rusage_r_[PADR_(struct rusage *)];
};
struct linux_add_key_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_request_key_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_keyctl_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_ioprio_set_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_ioprio_get_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_inotify_init_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_inotify_add_watch_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_inotify_rm_watch_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_migrate_pages_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_openat_args {
char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
@@ -1003,7 +1001,7 @@ struct linux_ppoll_args {
char ssize_l_[PADL_(l_size_t)]; l_size_t ssize; char ssize_r_[PADR_(l_size_t)];
};
struct linux_unshare_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_set_robust_list_args {
char head_l_[PADL_(struct linux_robust_list_head *)]; struct linux_robust_list_head * head; char head_r_[PADR_(struct linux_robust_list_head *)];
@@ -1023,7 +1021,7 @@ struct linux_splice_args {
char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
};
struct linux_tee_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_sync_file_range_args {
char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
@@ -1032,10 +1030,10 @@ struct linux_sync_file_range_args {
char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
};
struct linux_vmsplice_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_move_pages_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_utimensat_args {
char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
@@ -1052,7 +1050,7 @@ struct linux_epoll_pwait_args {
char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
};
struct linux_signalfd_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_timerfd_create_args {
char clockid_l_[PADL_(l_int)]; l_int clockid; char clockid_r_[PADR_(l_int)];
@@ -1084,7 +1082,7 @@ struct linux_accept4_args {
char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_signalfd4_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_eventfd2_args {
char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)];
@@ -1126,7 +1124,7 @@ struct linux_rt_tgsigqueueinfo_args {
char uinfo_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * uinfo; char uinfo_r_[PADR_(l_siginfo_t *)];
};
struct linux_perf_event_open_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_recvmmsg_args {
char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
@@ -1136,10 +1134,10 @@ struct linux_recvmmsg_args {
char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)];
};
struct linux_fanotify_init_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_fanotify_mark_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_prlimit64_args {
char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
@@ -1160,7 +1158,7 @@ struct linux_open_by_handle_at_args {
char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_clock_adjtime_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_syncfs_args {
char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
@@ -1316,10 +1314,13 @@ struct linux_statx_args {
char statxbuf_l_[PADL_(void *)]; void * statxbuf; char statxbuf_r_[PADR_(void *)];
};
struct linux_io_pgetevents_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_rseq_args {
- register_t dummy;
+ char rseq_l_[PADL_(struct linux_rseq *)]; struct linux_rseq * rseq; char rseq_r_[PADR_(struct linux_rseq *)];
+ char rseq_len_l_[PADL_(uint32_t)]; uint32_t rseq_len; char rseq_len_r_[PADR_(uint32_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+ char sig_l_[PADL_(uint32_t)]; uint32_t sig; char sig_r_[PADR_(uint32_t)];
};
struct linux_pidfd_send_signal_args {
char pidfd_l_[PADL_(l_int)]; l_int pidfd; char pidfd_r_[PADR_(l_int)];
@@ -1328,47 +1329,47 @@ struct linux_pidfd_send_signal_args {
char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
};
struct linux_io_uring_setup_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_io_uring_enter_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_io_uring_register_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_open_tree_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_move_mount_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_fsopen_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_fsconfig_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_fsmount_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_fspick_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_pidfd_open_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_clone3_args {
char uargs_l_[PADL_(struct l_user_clone_args *)]; struct l_user_clone_args * uargs; char uargs_r_[PADR_(struct l_user_clone_args *)];
char usize_l_[PADL_(l_size_t)]; l_size_t usize; char usize_r_[PADR_(l_size_t)];
};
struct linux_close_range_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_openat2_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_pidfd_getfd_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_faccessat2_args {
char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
@@ -1377,13 +1378,18 @@ struct linux_faccessat2_args {
char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_process_madvise_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_epoll_pwait2_args {
- register_t dummy;
+ char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)];
+ char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)];
+ char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)];
+ char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)];
+ char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)];
+ char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
};
struct linux_mount_setattr_args {
- register_t dummy;
+ syscallarg_t dummy;
};
#define nosys linux_nosys
int linux_open(struct thread *, struct linux_open_args *);
@@ -1442,7 +1448,6 @@ int linux_wait4(struct thread *, struct linux_wait4_args *);
int linux_kill(struct thread *, struct linux_kill_args *);
int linux_newuname(struct thread *, struct linux_newuname_args *);
int linux_semget(struct thread *, struct linux_semget_args *);
-int linux_semop(struct thread *, struct linux_semop_args *);
int linux_semctl(struct thread *, struct linux_semctl_args *);
int linux_shmdt(struct thread *, struct linux_shmdt_args *);
int linux_msgget(struct thread *, struct linux_msgget_args *);
@@ -1684,55 +1689,6 @@ int linux_faccessat2(struct thread *, struct linux_faccessat2_args *);
int linux_process_madvise(struct thread *, struct linux_process_madvise_args *);
int linux_epoll_pwait2(struct thread *, struct linux_epoll_pwait2_args *);
int linux_mount_setattr(struct thread *, struct linux_mount_setattr_args *);
-
-#ifdef COMPAT_43
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_43 */
-
-
-#ifdef COMPAT_FREEBSD4
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD4 */
-
-
-#ifdef COMPAT_FREEBSD6
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD6 */
-
-
-#ifdef COMPAT_FREEBSD7
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD7 */
-
-
-#ifdef COMPAT_FREEBSD10
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD10 */
-
-
-#ifdef COMPAT_FREEBSD11
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD11 */
-
-
-#ifdef COMPAT_FREEBSD12
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD12 */
-
#define LINUX_SYS_AUE_linux_open AUE_OPEN_RWTC
#define LINUX_SYS_AUE_linux_newstat AUE_STAT
#define LINUX_SYS_AUE_linux_newfstat AUE_FSTAT
@@ -1789,7 +1745,6 @@ int linux_mount_setattr(struct thread *, struct linux_mount_setattr_args *);
#define LINUX_SYS_AUE_linux_kill AUE_KILL
#define LINUX_SYS_AUE_linux_newuname AUE_NULL
#define LINUX_SYS_AUE_linux_semget AUE_NULL
-#define LINUX_SYS_AUE_linux_semop AUE_NULL
#define LINUX_SYS_AUE_linux_semctl AUE_NULL
#define LINUX_SYS_AUE_linux_shmdt AUE_NULL
#define LINUX_SYS_AUE_linux_msgget AUE_NULL
diff --git a/sys/amd64/linux/linux_support.s b/sys/amd64/linux/linux_support.s
index 79e361867f1d..1e9ad45b9623 100644
--- a/sys/amd64/linux/linux_support.s
+++ b/sys/amd64/linux/linux_support.s
@@ -39,7 +39,7 @@ futex_fault:
je 1f
clac
1: movq $0,PCB_ONFAULT(%r8)
- movl $-EFAULT,%eax
+ movl $EFAULT,%eax
ret
ENTRY(futex_xchgl_nosmap)
diff --git a/sys/amd64/linux/linux_syscall.h b/sys/amd64/linux/linux_syscall.h
index ca83b9d33483..9fc5e8ca877f 100644
--- a/sys/amd64/linux/linux_syscall.h
+++ b/sys/amd64/linux/linux_syscall.h
@@ -70,7 +70,7 @@
#define LINUX_SYS_linux_kill 62
#define LINUX_SYS_linux_newuname 63
#define LINUX_SYS_linux_semget 64
-#define LINUX_SYS_linux_semop 65
+#define LINUX_SYS_semop 65
#define LINUX_SYS_linux_semctl 66
#define LINUX_SYS_linux_shmdt 67
#define LINUX_SYS_linux_msgget 68
diff --git a/sys/amd64/linux/linux_syscalls.c b/sys/amd64/linux/linux_syscalls.c
index 285e9d47c461..68d3561e5fa7 100644
--- a/sys/amd64/linux/linux_syscalls.c
+++ b/sys/amd64/linux/linux_syscalls.c
@@ -72,7 +72,7 @@ const char *linux_syscallnames[] = {
"linux_kill", /* 62 = linux_kill */
"linux_newuname", /* 63 = linux_newuname */
"linux_semget", /* 64 = linux_semget */
- "linux_semop", /* 65 = linux_semop */
+ "semop", /* 65 = semop */
"linux_semctl", /* 66 = linux_semctl */
"linux_shmdt", /* 67 = linux_shmdt */
"linux_msgget", /* 68 = linux_msgget */
diff --git a/sys/amd64/linux/linux_sysent.c b/sys/amd64/linux/linux_sysent.c
index c866076fa9d3..7716c34305d8 100644
--- a/sys/amd64/linux/linux_sysent.c
+++ b/sys/amd64/linux/linux_sysent.c
@@ -12,7 +12,7 @@
#include <amd64/linux/linux.h>
#include <amd64/linux/linux_proto.h>
-#define AS(name) (sizeof(struct name) / sizeof(register_t))
+#define AS(name) (sizeof(struct name) / sizeof(syscallarg_t))
/* The casts are bogus but will do for now. */
struct sysent linux_sysent[] = {
@@ -82,7 +82,7 @@ struct sysent linux_sysent[] = {
{ .sy_narg = AS(linux_kill_args), .sy_call = (sy_call_t *)linux_kill, .sy_auevent = AUE_KILL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 62 = linux_kill */
{ .sy_narg = AS(linux_newuname_args), .sy_call = (sy_call_t *)linux_newuname, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 63 = linux_newuname */
{ .sy_narg = AS(linux_semget_args), .sy_call = (sy_call_t *)linux_semget, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 64 = linux_semget */
- { .sy_narg = AS(linux_semop_args), .sy_call = (sy_call_t *)linux_semop, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 65 = linux_semop */
+ { .sy_narg = AS(semop_args), .sy_call = (sy_call_t *)sys_semop, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 65 = semop */
{ .sy_narg = AS(linux_semctl_args), .sy_call = (sy_call_t *)linux_semctl, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 66 = linux_semctl */
{ .sy_narg = AS(linux_shmdt_args), .sy_call = (sy_call_t *)linux_shmdt, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 67 = linux_shmdt */
{ .sy_narg = AS(linux_msgget_args), .sy_call = (sy_call_t *)linux_msgget, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 68 = linux_msgget */
@@ -237,7 +237,7 @@ struct sysent linux_sysent[] = {
{ .sy_narg = AS(linux_getdents64_args), .sy_call = (sy_call_t *)linux_getdents64, .sy_auevent = AUE_GETDIRENTRIES, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 217 = linux_getdents64 */
{ .sy_narg = AS(linux_set_tid_address_args), .sy_call = (sy_call_t *)linux_set_tid_address, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 218 = linux_set_tid_address */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_restart_syscall, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 219 = linux_restart_syscall */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_semtimedop, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 220 = linux_semtimedop */
+ { .sy_narg = AS(linux_semtimedop_args), .sy_call = (sy_call_t *)linux_semtimedop, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 220 = linux_semtimedop */
{ .sy_narg = AS(linux_fadvise64_args), .sy_call = (sy_call_t *)linux_fadvise64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 221 = linux_fadvise64 */
{ .sy_narg = AS(linux_timer_create_args), .sy_call = (sy_call_t *)linux_timer_create, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 222 = linux_timer_create */
{ .sy_narg = AS(linux_timer_settime_args), .sy_call = (sy_call_t *)linux_timer_settime, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 223 = linux_timer_settime */
@@ -351,7 +351,7 @@ struct sysent linux_sysent[] = {
{ .sy_narg = AS(linux_pkey_free_args), .sy_call = (sy_call_t *)linux_pkey_free, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 331 = linux_pkey_free */
{ .sy_narg = AS(linux_statx_args), .sy_call = (sy_call_t *)linux_statx, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 332 = linux_statx */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_io_pgetevents, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 333 = linux_io_pgetevents */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_rseq, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 334 = linux_rseq */
+ { .sy_narg = AS(linux_rseq_args), .sy_call = (sy_call_t *)linux_rseq, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 334 = linux_rseq */
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 335 = nosys */
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 336 = nosys */
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 337 = nosys */
@@ -458,7 +458,7 @@ struct sysent linux_sysent[] = {
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_pidfd_getfd, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 438 = linux_pidfd_getfd */
{ .sy_narg = AS(linux_faccessat2_args), .sy_call = (sy_call_t *)linux_faccessat2, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 439 = linux_faccessat2 */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_process_madvise, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 440 = linux_process_madvise */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_epoll_pwait2, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 441 = linux_epoll_pwait2 */
+ { .sy_narg = AS(linux_epoll_pwait2_args), .sy_call = (sy_call_t *)linux_epoll_pwait2, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 441 = linux_epoll_pwait2 */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_mount_setattr, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 442 = linux_mount_setattr */
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 443 = nosys */
};
diff --git a/sys/amd64/linux/linux_systrace_args.c b/sys/amd64/linux/linux_systrace_args.c
index eec96830a242..c0d079200f62 100644
--- a/sys/amd64/linux/linux_systrace_args.c
+++ b/sys/amd64/linux/linux_systrace_args.c
@@ -577,12 +577,12 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 3;
break;
}
- /* linux_semop */
+ /* semop */
case 65: {
- struct linux_semop_args *p = params;
+ struct semop_args *p = params;
iarg[a++] = p->semid; /* l_int */
- uarg[a++] = (intptr_t)p->tsops; /* struct l_sembuf * */
- iarg[a++] = p->nsops; /* l_uint */
+ uarg[a++] = (intptr_t)p->sops; /* struct sembuf * */
+ iarg[a++] = p->nsops; /* l_size_t */
*n_args = 3;
break;
}
@@ -1656,7 +1656,12 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_semtimedop */
case 220: {
- *n_args = 0;
+ struct linux_semtimedop_args *p = params;
+ iarg[a++] = p->semid; /* l_int */
+ uarg[a++] = (intptr_t)p->tsops; /* struct sembuf * */
+ iarg[a++] = p->nsops; /* l_size_t */
+ uarg[a++] = (intptr_t)p->timeout; /* struct l_timespec * */
+ *n_args = 4;
break;
}
/* linux_fadvise64 */
@@ -2613,7 +2618,12 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_rseq */
case 334: {
- *n_args = 0;
+ struct linux_rseq_args *p = params;
+ uarg[a++] = (intptr_t)p->rseq; /* struct linux_rseq * */
+ uarg[a++] = p->rseq_len; /* uint32_t */
+ iarg[a++] = p->flags; /* l_int */
+ uarg[a++] = p->sig; /* uint32_t */
+ *n_args = 4;
break;
}
/* linux_pidfd_send_signal */
@@ -2716,7 +2726,14 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_epoll_pwait2 */
case 441: {
- *n_args = 0;
+ struct linux_epoll_pwait2_args *p = params;
+ iarg[a++] = p->epfd; /* l_int */
+ uarg[a++] = (intptr_t)p->events; /* struct epoll_event * */
+ iarg[a++] = p->maxevents; /* l_int */
+ uarg[a++] = (intptr_t)p->timeout; /* struct l_timespec * */
+ uarg[a++] = (intptr_t)p->mask; /* l_sigset_t * */
+ iarg[a++] = p->sigsetsize; /* l_size_t */
+ *n_args = 6;
break;
}
/* linux_mount_setattr */
@@ -3707,17 +3724,17 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
- /* linux_semop */
+ /* semop */
case 65:
switch (ndx) {
case 0:
p = "l_int";
break;
case 1:
- p = "userland struct l_sembuf *";
+ p = "userland struct sembuf *";
break;
case 2:
- p = "l_uint";
+ p = "l_size_t";
break;
default:
break;
@@ -5361,6 +5378,22 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_semtimedop */
case 220:
+ switch (ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "userland struct sembuf *";
+ break;
+ case 2:
+ p = "l_size_t";
+ break;
+ case 3:
+ p = "userland struct l_timespec *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_fadvise64 */
case 221:
@@ -6964,6 +6997,22 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_rseq */
case 334:
+ switch (ndx) {
+ case 0:
+ p = "userland struct linux_rseq *";
+ break;
+ case 1:
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "uint32_t";
+ break;
+ default:
+ break;
+ };
break;
/* linux_pidfd_send_signal */
case 424:
@@ -7060,6 +7109,28 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_epoll_pwait2 */
case 441:
+ switch (ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "userland struct epoll_event *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "userland struct l_timespec *";
+ break;
+ case 4:
+ p = "userland l_sigset_t *";
+ break;
+ case 5:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
break;
/* linux_mount_setattr */
case 442:
@@ -7386,7 +7457,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
- /* linux_semop */
+ /* semop */
case 65:
if (ndx == 0 || ndx == 1)
p = "int";
@@ -8009,6 +8080,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 219:
/* linux_semtimedop */
case 220:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_fadvise64 */
case 221:
if (ndx == 0 || ndx == 1)
@@ -8499,6 +8573,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 333:
/* linux_rseq */
case 334:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_pidfd_send_signal */
case 424:
if (ndx == 0 || ndx == 1)
@@ -8544,6 +8621,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 440:
/* linux_epoll_pwait2 */
case 441:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_mount_setattr */
case 442:
default:
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
index b7aedff23536..acfc4d6831f3 100644
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -86,6 +86,8 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_util.h>
#include <compat/linux/linux_vdso.h>
+#include <x86/linux/linux_x86_sigframe.h>
+
MODULE_VERSION(linux64, 1);
#define LINUX_VDSOPAGE_SIZE PAGE_SIZE * 2
@@ -129,72 +131,11 @@ static int linux_on_exec_vmspace(struct proc *p,
static void linux_set_fork_retval(struct thread *td);
static int linux_vsyscall(struct thread *td);
-#define LINUX_T_UNKNOWN 255
-static int _bsd_to_linux_trapcode[] = {
- LINUX_T_UNKNOWN, /* 0 */
- 6, /* 1 T_PRIVINFLT */
- LINUX_T_UNKNOWN, /* 2 */
- 3, /* 3 T_BPTFLT */
- LINUX_T_UNKNOWN, /* 4 */
- LINUX_T_UNKNOWN, /* 5 */
- 16, /* 6 T_ARITHTRAP */
- 254, /* 7 T_ASTFLT */
- LINUX_T_UNKNOWN, /* 8 */
- 13, /* 9 T_PROTFLT */
- 1, /* 10 T_TRCTRAP */
- LINUX_T_UNKNOWN, /* 11 */
- 14, /* 12 T_PAGEFLT */
- LINUX_T_UNKNOWN, /* 13 */
- 17, /* 14 T_ALIGNFLT */
- LINUX_T_UNKNOWN, /* 15 */
- LINUX_T_UNKNOWN, /* 16 */
- LINUX_T_UNKNOWN, /* 17 */
- 0, /* 18 T_DIVIDE */
- 2, /* 19 T_NMI */
- 4, /* 20 T_OFLOW */
- 5, /* 21 T_BOUND */
- 7, /* 22 T_DNA */
- 8, /* 23 T_DOUBLEFLT */
- 9, /* 24 T_FPOPFLT */
- 10, /* 25 T_TSSFLT */
- 11, /* 26 T_SEGNPFLT */
- 12, /* 27 T_STKFLT */
- 18, /* 28 T_MCHK */
- 19, /* 29 T_XMMFLT */
- 15 /* 30 T_RESERVED */
-};
-#define bsd_to_linux_trapcode(code) \
- ((code)<nitems(_bsd_to_linux_trapcode)? \
- _bsd_to_linux_trapcode[(code)]: \
- LINUX_T_UNKNOWN)
-
LINUX_VDSO_SYM_INTPTR(linux_rt_sigcode);
LINUX_VDSO_SYM_CHAR(linux_platform);
LINUX_VDSO_SYM_INTPTR(kern_timekeep_base);
LINUX_VDSO_SYM_INTPTR(kern_tsc_selector);
-
-/*
- * If FreeBSD & Linux have a difference of opinion about what a trap
- * means, deal with it here.
- *
- * MPSAFE
- */
-static int
-linux_translate_traps(int signal, int trap_code)
-{
-
- if (signal != SIGBUS)
- return (signal);
- switch (trap_code) {
- case T_PROTFLT:
- case T_TSSFLT:
- case T_DOUBLEFLT:
- case T_PAGEFLT:
- return (SIGSEGV);
- default:
- return (signal);
- }
-}
+LINUX_VDSO_SYM_INTPTR(kern_cpu_selector);
static int
linux_fetch_syscall_args(struct thread *td)
@@ -358,17 +299,12 @@ linux_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
size_t execpath_len;
struct proc *p;
- /* Calculate string base and vector table pointers. */
- if (imgp->execpath != NULL && imgp->auxargs != NULL)
- execpath_len = strlen(imgp->execpath) + 1;
- else
- execpath_len = 0;
-
p = imgp->proc;
- arginfo = (struct ps_strings *)p->p_sysent->sv_psstrings;
+ arginfo = (struct ps_strings *)PROC_PS_STRINGS(p);
destp = (uintptr_t)arginfo;
- if (execpath_len != 0) {
+ if (imgp->execpath != NULL && imgp->auxargs != NULL) {
+ execpath_len = strlen(imgp->execpath) + 1;
destp -= execpath_len;
destp = rounddown2(destp, sizeof(void *));
imgp->execpathp = (void *)destp;
@@ -629,7 +565,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
td = curthread;
p = td->td_proc;
PROC_LOCK_ASSERT(p, MA_OWNED);
- sig = ksi->ksi_signo;
+ sig = linux_translate_traps(ksi->ksi_signo, ksi->ksi_trapno);
psp = p->p_sigacts;
code = ksi->ksi_code;
mtx_assert(&psp->ps_mtx, MA_OWNED);
@@ -641,44 +577,44 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/* Save user context. */
bzero(&sf, sizeof(sf));
- bsd_to_linux_sigset(mask, &sf.sf_sc.uc_sigmask);
- bsd_to_linux_sigset(mask, &sf.sf_sc.uc_mcontext.sc_mask);
+ bsd_to_linux_sigset(mask, &sf.sf_uc.uc_sigmask);
+ bsd_to_linux_sigset(mask, &sf.sf_uc.uc_mcontext.sc_mask);
- sf.sf_sc.uc_stack.ss_sp = PTROUT(td->td_sigstk.ss_sp);
- sf.sf_sc.uc_stack.ss_size = td->td_sigstk.ss_size;
- sf.sf_sc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
+ sf.sf_uc.uc_stack.ss_sp = PTROUT(td->td_sigstk.ss_sp);
+ sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size;
+ sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
- sf.sf_sc.uc_mcontext.sc_rdi = regs->tf_rdi;
- sf.sf_sc.uc_mcontext.sc_rsi = regs->tf_rsi;
- sf.sf_sc.uc_mcontext.sc_rdx = regs->tf_rdx;
- sf.sf_sc.uc_mcontext.sc_rbp = regs->tf_rbp;
- sf.sf_sc.uc_mcontext.sc_rbx = regs->tf_rbx;
- sf.sf_sc.uc_mcontext.sc_rcx = regs->tf_rcx;
- sf.sf_sc.uc_mcontext.sc_rax = regs->tf_rax;
- sf.sf_sc.uc_mcontext.sc_rip = regs->tf_rip;
- sf.sf_sc.uc_mcontext.sc_rsp = regs->tf_rsp;
- sf.sf_sc.uc_mcontext.sc_r8 = regs->tf_r8;
- sf.sf_sc.uc_mcontext.sc_r9 = regs->tf_r9;
- sf.sf_sc.uc_mcontext.sc_r10 = regs->tf_r10;
- sf.sf_sc.uc_mcontext.sc_r11 = regs->tf_r11;
- sf.sf_sc.uc_mcontext.sc_r12 = regs->tf_r12;
- sf.sf_sc.uc_mcontext.sc_r13 = regs->tf_r13;
- sf.sf_sc.uc_mcontext.sc_r14 = regs->tf_r14;
- sf.sf_sc.uc_mcontext.sc_r15 = regs->tf_r15;
- sf.sf_sc.uc_mcontext.sc_cs = regs->tf_cs;
- sf.sf_sc.uc_mcontext.sc_rflags = regs->tf_rflags;
- sf.sf_sc.uc_mcontext.sc_err = regs->tf_err;
- sf.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
- sf.sf_sc.uc_mcontext.sc_cr2 = (register_t)ksi->ksi_addr;
+ sf.sf_uc.uc_mcontext.sc_rdi = regs->tf_rdi;
+ sf.sf_uc.uc_mcontext.sc_rsi = regs->tf_rsi;
+ sf.sf_uc.uc_mcontext.sc_rdx = regs->tf_rdx;
+ sf.sf_uc.uc_mcontext.sc_rbp = regs->tf_rbp;
+ sf.sf_uc.uc_mcontext.sc_rbx = regs->tf_rbx;
+ sf.sf_uc.uc_mcontext.sc_rcx = regs->tf_rcx;
+ sf.sf_uc.uc_mcontext.sc_rax = regs->tf_rax;
+ sf.sf_uc.uc_mcontext.sc_rip = regs->tf_rip;
+ sf.sf_uc.uc_mcontext.sc_rsp = regs->tf_rsp;
+ sf.sf_uc.uc_mcontext.sc_r8 = regs->tf_r8;
+ sf.sf_uc.uc_mcontext.sc_r9 = regs->tf_r9;
+ sf.sf_uc.uc_mcontext.sc_r10 = regs->tf_r10;
+ sf.sf_uc.uc_mcontext.sc_r11 = regs->tf_r11;
+ sf.sf_uc.uc_mcontext.sc_r12 = regs->tf_r12;
+ sf.sf_uc.uc_mcontext.sc_r13 = regs->tf_r13;
+ sf.sf_uc.uc_mcontext.sc_r14 = regs->tf_r14;
+ sf.sf_uc.uc_mcontext.sc_r15 = regs->tf_r15;
+ sf.sf_uc.uc_mcontext.sc_cs = regs->tf_cs;
+ sf.sf_uc.uc_mcontext.sc_rflags = regs->tf_rflags;
+ sf.sf_uc.uc_mcontext.sc_err = regs->tf_err;
+ sf.sf_uc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
+ sf.sf_uc.uc_mcontext.sc_cr2 = (register_t)ksi->ksi_addr;
/* Allocate space for the signal handler context. */
if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
SIGISMEMBER(psp->ps_sigonstack, sig)) {
- sp = (caddr_t)td->td_sigstk.ss_sp + td->td_sigstk.ss_size -
- sizeof(struct l_rt_sigframe);
+ sp = (caddr_t)td->td_sigstk.ss_sp + td->td_sigstk.ss_size;
} else
- sp = (caddr_t)regs->tf_rsp - sizeof(struct l_rt_sigframe) - 128;
+ sp = (caddr_t)regs->tf_rsp - 128;
+ sp -= sizeof(struct l_rt_sigframe);
/* Align to 16 bytes. */
sfp = (struct l_rt_sigframe *)((unsigned long)sp & ~0xFul);
@@ -689,17 +625,19 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
regs->tf_rdi = sig; /* arg 1 in %rdi */
regs->tf_rax = 0;
regs->tf_rsi = (register_t)&sfp->sf_si; /* arg 2 in %rsi */
- regs->tf_rdx = (register_t)&sfp->sf_sc; /* arg 3 in %rdx */
+ regs->tf_rdx = (register_t)&sfp->sf_uc; /* arg 3 in %rdx */
+ regs->tf_rcx = (register_t)catcher;
/* Fill in POSIX parts. */
siginfo_to_lsiginfo(&ksi->ksi_info, &sf.sf_si, sig);
- sf.sf_handler = catcher;
mtx_unlock(&psp->ps_mtx);
PROC_UNLOCK(p);
/* Copy the sigframe out to the user's stack. */
if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
+ uprintf("pid %d comm %s has trashed its stack, killing\n",
+ p->p_pid, p->p_comm);
PROC_LOCK(p);
sigexit(td, SIGILL);
}
@@ -763,7 +701,6 @@ linux_vsyscall(struct thread *td)
struct sysentvec elf_linux_sysvec = {
.sv_size = LINUX_SYS_MAXSYSCALL,
.sv_table = linux_sysent,
- .sv_transtrap = linux_translate_traps,
.sv_fixup = linux_fixup_elf,
.sv_sendsig = linux_rt_sendsig,
.sv_sigcode = &_binary_linux_vdso_so_o_start,
@@ -779,6 +716,7 @@ struct sysentvec elf_linux_sysvec = {
.sv_maxuser = VM_MAXUSER_ADDRESS_LA48,
.sv_usrstack = LINUX_USRSTACK_LA48,
.sv_psstrings = LINUX_PS_STRINGS_LA48,
+ .sv_psstringssz = sizeof(struct ps_strings),
.sv_stackprot = VM_PROT_ALL,
.sv_copyout_auxargs = linux_copyout_auxargs,
.sv_copyout_strings = linux_copyout_strings,
@@ -839,6 +777,12 @@ linux_exec_sysvec_init(void *param)
*ktsc_selector = linux_vdso_tsc_selector_idx();
if (bootverbose)
printf("Linux x86-64 vDSO tsc_selector: %lu\n", *ktsc_selector);
+
+ tkoff = kern_cpu_selector - linux_vdso_base;
+ ktsc_selector = (l_uintptr_t *)(linux_vdso_mapping + tkoff);
+ *ktsc_selector = linux_vdso_cpu_selector_idx();
+ if (bootverbose)
+ printf("Linux x86-64 vDSO cpu_selector: %lu\n", *ktsc_selector);
}
SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC + 1, SI_ORDER_ANY,
linux_exec_sysvec_init, &elf_linux_sysvec);
diff --git a/sys/amd64/linux/linux_vdso.lds.s b/sys/amd64/linux/linux_vdso.lds.s
index ccf7c80565bb..24d8cab162f8 100644
--- a/sys/amd64/linux/linux_vdso.lds.s
+++ b/sys/amd64/linux/linux_vdso.lds.s
@@ -68,6 +68,7 @@ VERSION
linux_platform;
kern_timekeep_base;
kern_tsc_selector;
+ kern_cpu_selector;
local: *;
};
}
diff --git a/sys/amd64/linux/linux_vdso_gtod.c b/sys/amd64/linux/linux_vdso_gtod.c
index 57d3f4b45dd4..3d18b551e6fb 100644
--- a/sys/amd64/linux/linux_vdso_gtod.c
+++ b/sys/amd64/linux/linux_vdso_gtod.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <stdbool.h>
#include <machine/atomic.h>
+#include <machine/cpufunc.h>
#include <machine/stdarg.h>
#include <amd64/linux/linux.h>
@@ -48,8 +49,10 @@ __FBSDID("$FreeBSD$");
/* The kernel fixup this at vDSO install */
uintptr_t *kern_timekeep_base = NULL;
uint32_t kern_tsc_selector = 0;
+uint32_t kern_cpu_selector = 0;
#include <x86/linux/linux_vdso_gettc_x86.inc>
+#include <x86/linux/linux_vdso_getcpu_x86.inc>
/* for debug purpose */
static int
diff --git a/sys/amd64/linux/syscalls.conf b/sys/amd64/linux/syscalls.conf
index 29f37920bba6..a47f80444c2a 100644
--- a/sys/amd64/linux/syscalls.conf
+++ b/sys/amd64/linux/syscalls.conf
@@ -9,3 +9,4 @@ syscallprefix="LINUX_SYS_"
switchname="linux_sysent"
namesname="linux_syscallnames"
systrace="linux_systrace_args.c"
+compat_set=""
diff --git a/sys/amd64/linux/syscalls.master b/sys/amd64/linux/syscalls.master
index d3ebedbfed01..896bbcc5e652 100644
--- a/sys/amd64/linux/syscalls.master
+++ b/sys/amd64/linux/syscalls.master
@@ -472,11 +472,11 @@
l_int semflg
);
}
-65 AUE_NULL STD {
- int linux_semop(
+65 AUE_NULL NOPROTO {
+ int semop(
l_int semid,
- struct l_sembuf *tsops,
- l_uint nsops
+ struct sembuf *sops,
+ l_size_t nsops
);
}
66 AUE_NULL STD {
@@ -1282,7 +1282,12 @@
int linux_restart_syscall(void);
}
220 AUE_NULL STD {
- int linux_semtimedop(void);
+ int linux_semtimedop(
+ l_int semid,
+ struct sembuf *tsops,
+ l_size_t nsops,
+ struct l_timespec *timeout
+ );
}
221 AUE_NULL STD {
int linux_fadvise64(
@@ -2039,7 +2044,12 @@
int linux_io_pgetevents(void);
}
334 AUE_NULL STD {
- int linux_rseq(void);
+ int linux_rseq(
+ struct linux_rseq *rseq,
+ uint32_t rseq_len,
+ l_int flags,
+ uint32_t sig
+ );
}
; Linux 5.0:
335-423 AUE_NULL UNIMPL nosys
@@ -2108,7 +2118,14 @@
int linux_process_madvise(void);
}
441 AUE_NULL STD {
- int linux_epoll_pwait2(void);
+ int linux_epoll_pwait2(
+ l_int epfd,
+ struct epoll_event *events,
+ l_int maxevents,
+ struct l_timespec *timeout,
+ l_sigset_t *mask,
+ l_size_t sigsetsize
+ );
}
442 AUE_NULL STD {
int linux_mount_setattr(void);
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h
index f1f877181e47..5cdf7624fef5 100644
--- a/sys/amd64/linux32/linux.h
+++ b/sys/amd64/linux32/linux.h
@@ -82,6 +82,8 @@ typedef l_int l_timer_t;
typedef l_int l_mqd_t;
typedef l_ulong l_fd_mask;
+#include <compat/linux/linux_siginfo.h>
+
typedef struct {
l_int val[2];
} l_fsid_t;
@@ -287,168 +289,6 @@ typedef struct {
l_size_t ss_size;
} l_stack_t;
-/* The Linux sigcontext, pretty much a standard 386 trapframe. */
-struct l_sigcontext {
- l_uint sc_gs;
- l_uint sc_fs;
- l_uint sc_es;
- l_uint sc_ds;
- l_uint sc_edi;
- l_uint sc_esi;
- l_uint sc_ebp;
- l_uint sc_esp;
- l_uint sc_ebx;
- l_uint sc_edx;
- l_uint sc_ecx;
- l_uint sc_eax;
- l_uint sc_trapno;
- l_uint sc_err;
- l_uint sc_eip;
- l_uint sc_cs;
- l_uint sc_eflags;
- l_uint sc_esp_at_signal;
- l_uint sc_ss;
- l_uint sc_387;
- l_uint sc_mask;
- l_uint sc_cr2;
-};
-
-struct l_ucontext {
- l_ulong uc_flags;
- l_uintptr_t uc_link;
- l_stack_t uc_stack;
- struct l_sigcontext uc_mcontext;
- l_sigset_t uc_sigmask;
-} __packed;
-
-#define LINUX_SI_MAX_SIZE 128
-#define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE/sizeof(l_int)) - 3)
-
-typedef union l_sigval {
- l_int sival_int;
- l_uintptr_t sival_ptr;
-} l_sigval_t;
-
-typedef struct l_siginfo {
- l_int lsi_signo;
- l_int lsi_errno;
- l_int lsi_code;
- union {
- l_int _pad[LINUX_SI_PAD_SIZE];
-
- struct {
- l_pid_t _pid;
- l_uid_t _uid;
- } _kill;
-
- struct {
- l_timer_t _tid;
- l_int _overrun;
- char _pad[sizeof(l_uid_t) - sizeof(l_int)];
- l_sigval_t _sigval;
- l_int _sys_private;
- } _timer;
-
- struct {
- l_pid_t _pid; /* sender's pid */
- l_uid_t _uid; /* sender's uid */
- l_sigval_t _sigval;
- } _rt;
-
- struct {
- l_pid_t _pid; /* which child */
- l_uid_t _uid; /* sender's uid */
- l_int _status; /* exit code */
- l_clock_t _utime;
- l_clock_t _stime;
- } _sigchld;
-
- struct {
- l_uintptr_t _addr; /* Faulting insn/memory ref. */
- } _sigfault;
-
- struct {
- l_long _band; /* POLL_IN,POLL_OUT,POLL_MSG */
- l_int _fd;
- } _sigpoll;
- } _sifields;
-} l_siginfo_t;
-
-#define lsi_pid _sifields._kill._pid
-#define lsi_uid _sifields._kill._uid
-#define lsi_tid _sifields._timer._tid
-#define lsi_overrun _sifields._timer._overrun
-#define lsi_sys_private _sifields._timer._sys_private
-#define lsi_status _sifields._sigchld._status
-#define lsi_utime _sifields._sigchld._utime
-#define lsi_stime _sifields._sigchld._stime
-#define lsi_value _sifields._rt._sigval
-#define lsi_int _sifields._rt._sigval.sival_int
-#define lsi_ptr _sifields._rt._sigval.sival_ptr
-#define lsi_addr _sifields._sigfault._addr
-#define lsi_band _sifields._sigpoll._band
-#define lsi_fd _sifields._sigpoll._fd
-
-struct l_fpreg {
- u_int16_t significand[4];
- u_int16_t exponent;
-};
-
-struct l_fpxreg {
- u_int16_t significand[4];
- u_int16_t exponent;
- u_int16_t padding[3];
-};
-
-struct l_xmmreg {
- u_int32_t element[4];
-};
-
-struct l_fpstate {
- /* Regular FPU environment */
- u_int32_t cw;
- u_int32_t sw;
- u_int32_t tag;
- u_int32_t ipoff;
- u_int32_t cssel;
- u_int32_t dataoff;
- u_int32_t datasel;
- struct l_fpreg _st[8];
- u_int16_t status;
- u_int16_t magic; /* 0xffff = regular FPU data */
-
- /* FXSR FPU environment */
- u_int32_t _fxsr_env[6]; /* env is ignored. */
- u_int32_t mxcsr;
- u_int32_t reserved;
- struct l_fpxreg _fxsr_st[8]; /* reg data is ignored. */
- struct l_xmmreg _xmm[8];
- u_int32_t padding[56];
-};
-
-/*
- * We make the stack look like Linux expects it when calling a signal
- * handler, but use the BSD way of calling the handler and sigreturn().
- * This means that we need to pass the pointer to the handler too.
- * It is appended to the frame to not interfere with the rest of it.
- */
-struct l_sigframe {
- l_int sf_sig;
- struct l_sigcontext sf_sc;
- struct l_fpstate sf_fpstate;
- l_uint sf_extramask[1];
- l_handler_t sf_handler;
-};
-
-struct l_rt_sigframe {
- l_int sf_sig;
- l_uintptr_t sf_siginfo;
- l_uintptr_t sf_ucontext;
- l_siginfo_t sf_si;
- struct l_ucontext sf_sc;
- l_handler_t sf_handler;
-} __packed;
-
/*
* arch specific open/fcntl flags
*/
@@ -637,4 +477,6 @@ struct reg32;
void bsd_to_linux_regset32(const struct reg32 *b_reg,
struct linux_pt_regset32 *l_regset);
+extern bool linux32_emulate_i386;
+
#endif /* !_AMD64_LINUX_H_ */
diff --git a/sys/amd64/linux32/linux32_dummy_machdep.c b/sys/amd64/linux32/linux32_dummy_machdep.c
index fb7c88629af7..f3bd8717524a 100644
--- a/sys/amd64/linux32/linux32_dummy_machdep.c
+++ b/sys/amd64/linux32/linux32_dummy_machdep.c
@@ -68,13 +68,6 @@ DUMMY(mq_getsetattr);
DUMMY(arch_prctl);
/* Linux 5.0: */
DUMMY(clock_adjtime64);
-DUMMY(timer_gettime64);
-DUMMY(timer_settime64);
-DUMMY(timerfd_gettime64);
-DUMMY(timerfd_settime64);
DUMMY(io_pgetevents_time64);
-DUMMY(recvmmsg_time64);
DUMMY(mq_timedsend_time64);
DUMMY(mq_timedreceive_time64);
-DUMMY(semtimedop_time64);
-DUMMY(sched_rr_get_interval_time64);
diff --git a/sys/amd64/linux32/linux32_genassym.c b/sys/amd64/linux32/linux32_genassym.c
index bc94139c226d..4a87b5a423bc 100644
--- a/sys/amd64/linux32/linux32_genassym.c
+++ b/sys/amd64/linux32/linux32_genassym.c
@@ -9,10 +9,25 @@ __FBSDID("$FreeBSD$");
#include <amd64/linux32/linux.h>
#include <compat/linux/linux_mib.h>
-ASSYM(LINUX_SIGF_HANDLER, offsetof(struct l_sigframe, sf_handler));
+#include <x86/linux/linux_x86_sigframe.h>
+
ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc));
-ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler));
-ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc));
+ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_uc));
ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext));
+ASSYM(L_SC_GS, offsetof(struct l_sigcontext, sc_gs));
+ASSYM(L_SC_FS, offsetof(struct l_sigcontext, sc_fs));
+ASSYM(L_SC_ES, offsetof(struct l_sigcontext, sc_es));
+ASSYM(L_SC_DS, offsetof(struct l_sigcontext, sc_ds));
+ASSYM(L_SC_CS, offsetof(struct l_sigcontext, sc_cs));
+ASSYM(L_SC_SS, offsetof(struct l_sigcontext, sc_ss));
+ASSYM(L_SC_EFLAGS, offsetof(struct l_sigcontext, sc_eflags));
+ASSYM(L_SC_EDI, offsetof(struct l_sigcontext, sc_edi));
+ASSYM(L_SC_ESI, offsetof(struct l_sigcontext, sc_esi));
+ASSYM(L_SC_EBP, offsetof(struct l_sigcontext, sc_ebp));
+ASSYM(L_SC_EBX, offsetof(struct l_sigcontext, sc_ebx));
+ASSYM(L_SC_EDX, offsetof(struct l_sigcontext, sc_edx));
+ASSYM(L_SC_ECX, offsetof(struct l_sigcontext, sc_ecx));
+ASSYM(L_SC_EAX, offsetof(struct l_sigcontext, sc_eax));
+ASSYM(L_SC_EIP, offsetof(struct l_sigcontext, sc_eip));
+ASSYM(L_SC_ESP, offsetof(struct l_sigcontext, sc_esp_at_signal));
ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE);
-ASSYM(LINUX_SC_ESP, offsetof(struct l_sigcontext, sc_esp));
diff --git a/sys/amd64/linux32/linux32_locore.asm b/sys/amd64/linux32/linux32_locore.asm
index f96b3e730f9f..f4cdc5fc1559 100644
--- a/sys/amd64/linux32/linux32_locore.asm
+++ b/sys/amd64/linux32/linux32_locore.asm
@@ -14,46 +14,96 @@ linux_platform:
.text
.code32
-/*
- * To avoid excess stack frame the signal trampoline code emulates
- * the 'call' instruction.
- */
+ENTRY(linux32_vdso_sigcode)
+ .cfi_startproc
+ .cfi_signal_frame
+ .cfi_def_cfa %esp, LINUX_SIGF_SC
+ .cfi_offset %gs, L_SC_GS
+ .cfi_offset %fs, L_SC_FS
+ .cfi_offset %es, L_SC_ES
+ .cfi_offset %ds, L_SC_DS
+ .cfi_offset %cs, L_SC_CS
+ .cfi_offset %ss, L_SC_SS
+ .cfi_offset %flags, L_SC_EFLAGS
+ .cfi_offset %edi, L_SC_EDI
+ .cfi_offset %esi, L_SC_ESI
+ .cfi_offset %ebp, L_SC_EBP
+ .cfi_offset %ebx, L_SC_EBX
+ .cfi_offset %edx, L_SC_EDX
+ .cfi_offset %ecx, L_SC_ECX
+ .cfi_offset %eax, L_SC_EAX
+ .cfi_offset %eip, L_SC_EIP
+ .cfi_offset %esp, L_SC_ESP
+
+ movl %esp, %ebx /* sigframe for sigreturn */
+ call *%edi /* call signal handler */
+ popl %eax /* gcc unwind code need this */
+ .cfi_def_cfa %esp, LINUX_SIGF_SC-4
+ movl $LINUX32_SYS_linux_sigreturn, %eax
+ int $0x80
+0: jmp 0b
+ .cfi_endproc
+END(linux32_vdso_sigcode)
+
+
+ENTRY(linux32_vdso_rt_sigcode)
+ .cfi_startproc
+ .cfi_signal_frame
+ .cfi_def_cfa %esp, LINUX_RT_SIGF_UC + LINUX_RT_SIGF_SC
+ .cfi_offset %gs, L_SC_GS
+ .cfi_offset %fs, L_SC_FS
+ .cfi_offset %es, L_SC_ES
+ .cfi_offset %ds, L_SC_DS
+ .cfi_offset %cs, L_SC_CS
+ .cfi_offset %ss, L_SC_SS
+ .cfi_offset %flags, L_SC_EFLAGS
+ .cfi_offset %edi, L_SC_EDI
+ .cfi_offset %esi, L_SC_ESI
+ .cfi_offset %ebp, L_SC_EBP
+ .cfi_offset %ebx, L_SC_EBX
+ .cfi_offset %edx, L_SC_EDX
+ .cfi_offset %ecx, L_SC_ECX
+ .cfi_offset %eax, L_SC_EAX
+ .cfi_offset %eip, L_SC_EIP
+ .cfi_offset %esp, L_SC_ESP
+
+ leal LINUX_RT_SIGF_UC(%esp), %ebx /* linux ucontext for rt_sigreturn */
+ call *%edi /* call signal handler */
+ movl $LINUX32_SYS_linux_rt_sigreturn, %eax
+ int $0x80
+0: jmp 0b
+ .cfi_endproc
+END(linux32_vdso_rt_sigcode)
+
ENTRY(__kernel_sigreturn)
- movl %esp, %ebx /* preserve sigframe */
- call .getip0
-.getip0:
- popl %eax
- add $.startsigcode-.getip0, %eax /* ret address */
- push %eax
- jmp *LINUX_SIGF_HANDLER(%ebx)
-.startsigcode:
- popl %eax
- movl $LINUX32_SYS_linux_sigreturn,%eax /* linux_sigreturn() */
- int $0x80 /* enter kernel with args */
-.endsigcode:
+ .cfi_startproc
+ .cfi_signal_frame
+ movl %esp, %ebx /* sigframe for sigreturn */
+ call *%edi /* call signal handler */
+ popl %eax /* gcc unwind code need this */
+ movl $LINUX32_SYS_linux_sigreturn, %eax
+ int $0x80
0: jmp 0b
+ .cfi_endproc
+END(__kernel_sigreturn)
ENTRY(__kernel_rt_sigreturn)
- leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */
- leal LINUX_RT_SIGF_SC(%ebx),%ecx /* linux sigcontext */
- movl %esp, %edi
- call .getip1
-.getip1:
- popl %eax
- add $.startrtsigcode-.getip1, %eax /* ret address */
- push %eax
- jmp *LINUX_RT_SIGF_HANDLER(%edi)
-.startrtsigcode:
- movl $LINUX32_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */
- int $0x80 /* enter kernel with args */
-.endrtsigcode:
+ .cfi_startproc
+ .cfi_signal_frame
+ leal LINUX_RT_SIGF_UC(%esp), %ebx /* linux ucontext for rt_sigreturn */
+ call *%edi /* call signal handler */
+ movl $LINUX32_SYS_linux_rt_sigreturn, %eax
+ int $0x80
0: jmp 0b
+ .cfi_endproc
+END(__kernel_rt_sigreturn)
ENTRY(__kernel_vsyscall)
-.startvsyscall:
+ .cfi_startproc
int $0x80
ret
-.endvsyscall:
+ .cfi_endproc
+END(__kernel_vsyscall)
#if 0
.section .note.Linux, "a",@note
@@ -71,86 +121,3 @@ ENTRY(__kernel_vsyscall)
.balign 4
.previous
#endif
-
-#define do_cfa_expr(offset) \
- .byte 0x0f; /* DW_CFA_def_cfa_expression */ \
- .uleb128 11f-10f; /* length */ \
-10: .byte 0x74; /* DW_OP_breg4 */ \
- .sleb128 offset; /* offset */ \
- .byte 0x06; /* DW_OP_deref */ \
-11:
-
-
- /* CIE */
- .section .eh_frame,"a",@progbits
-.LSTARTFRAMEDLSI1:
- .long .LENDCIEDLSI1-.LSTARTCIEDLSI1
-.LSTARTCIEDLSI1:
- .long 0 /* CIE ID */
- .byte 1 /* Version number */
- .string "zRS" /* NULL-terminated
- * augmentation string
- */
- .uleb128 1 /* Code alignment factor */
- .sleb128 -4 /* Data alignment factor */
- .byte 8 /* Return address
- * register column
- */
- .uleb128 1 /* Augmentation value length */
- .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
- .byte 0 /* DW_CFA_nop */
- .align 4
-.LENDCIEDLSI1:
-
- /* FDE */
- .long .LENDFDEDLSI1-.LSTARTFDEDLSI1 /* Length FDE */
-.LSTARTFDEDLSI1:
- .long .LSTARTFDEDLSI1-.LSTARTFRAMEDLSI1 /* CIE pointer */
- .long .startsigcode-. /* PC-relative start address */
- .long .endsigcode-.startsigcode
- .uleb128 0 /* Augmentation */
- do_cfa_expr(LINUX_SIGF_SC-8)
- .align 4
-.LENDFDEDLSI1:
-
- .long .LENDFDEDLSI2-.LSTARTFDEDLSI2 /* Length FDE */
-.LSTARTFDEDLSI2:
- .long .LSTARTFDEDLSI2-.LSTARTFRAMEDLSI1 /* CIE pointer */
- .long .startrtsigcode-. /* PC-relative start address */
- .long .endrtsigcode-.startrtsigcode
- .uleb128 0 /* Augmentation */
- do_cfa_expr(LINUX_RT_SIGF_SC-4+LINUX_SC_ESP)
- .align 4
-.LENDFDEDLSI2:
- .previous
-
- .section .eh_frame,"a",@progbits
-.LSTARTFRAMEDLSI2:
- .long .LENDCIEDLSI2-.LSTARTCIEDLSI2
-.LSTARTCIEDLSI2:
- .long 0 /* CIE ID */
- .byte 1 /* Version number */
- .string "zR" /* NULL-terminated
- * augmentation string
- */
- .uleb128 1 /* Code alignment factor */
- .sleb128 -4 /* Data alignment factor */
- .byte 8 /* Return address register column */
- .uleb128 1 /* Augmentation value length */
- .byte 0x1b /* DW_EH_PE_pcrel|DW_EH_PE_sdata4. */
- .byte 0x0c /* DW_CFA_def_cfa */
- .uleb128 4
- .uleb128 4
- .byte 0x88 /* DW_CFA_offset, column 0x8 */
- .uleb128 1
- .align 4
-.LENDCIEDLSI2:
- .long .LENDFDEDLSI3-.LSTARTFDEDLSI3 /* Length FDE */
-.LSTARTFDEDLSI3:
- .long .LSTARTFDEDLSI3-.LSTARTFRAMEDLSI2 /* CIE pointer */
- .long .startvsyscall-. /* PC-relative start address */
- .long .endvsyscall-.startvsyscall
- .uleb128 0
- .align 4
-.LENDFDEDLSI3:
- .previous
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index 9dd988452a1c..9746c4bd7cdf 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -134,11 +134,15 @@ linux_execve(struct thread *td, struct linux_execve_args *args)
char *path;
int error;
- LCONVPATHEXIST(args->path, &path);
-
- error = freebsd32_exec_copyin_args(&eargs, path, UIO_SYSSPACE,
- args->argp, args->envp);
- free(path, M_TEMP);
+ if (!LUSECONVPATH(td)) {
+ error = freebsd32_exec_copyin_args(&eargs, args->path, UIO_USERSPACE,
+ args->argp, args->envp);
+ } else {
+ LCONVPATHEXIST(args->path, &path);
+ error = freebsd32_exec_copyin_args(&eargs, path, UIO_SYSSPACE,
+ args->argp, args->envp);
+ LFREEPATH(path);
+ }
if (error == 0)
error = linux_common_execve(td, &eargs);
AUDIT_SYSCALL_EXIT(error == EJUSTRETURN ? 0 : error, td);
@@ -255,12 +259,9 @@ linux_ipc(struct thread *td, struct linux_ipc_args *args)
switch (args->what & 0xFFFF) {
case LINUX_SEMOP: {
- struct linux_semop_args a;
- a.semid = args->arg1;
- a.tsops = PTRIN(args->ptr);
- a.nsops = args->arg2;
- return (linux_semop(td, &a));
+ return (kern_semop(td, args->arg1, PTRIN(args->ptr),
+ args->arg2, NULL));
}
case LINUX_SEMGET: {
struct linux_semget_args a;
@@ -282,6 +283,15 @@ linux_ipc(struct thread *td, struct linux_ipc_args *args)
return (error);
return (linux_semctl(td, &a));
}
+ case LINUX_SEMTIMEDOP: {
+ struct linux_semtimedop_args a;
+
+ a.semid = args->arg1;
+ a.tsops = PTRIN(args->ptr);
+ a.nsops = args->arg2;
+ a.timeout = PTRIN(args->arg5);
+ return (linux_semtimedop(td, &a));
+ }
case LINUX_MSGSND: {
struct linux_msgsnd_args a;
diff --git a/sys/amd64/linux32/linux32_proto.h b/sys/amd64/linux32/linux32_proto.h
index 819ec994d0c9..219f0f09f8c9 100644
--- a/sys/amd64/linux32/linux32_proto.h
+++ b/sys/amd64/linux32/linux32_proto.h
@@ -23,8 +23,8 @@ struct proc;
struct thread;
-#define PAD_(t) (sizeof(register_t) <= sizeof(t) ? \
- 0 : sizeof(register_t) - sizeof(t))
+#define PAD_(t) (sizeof(syscallarg_t) <= sizeof(t) ? \
+ 0 : sizeof(syscallarg_t) - sizeof(t))
#if BYTE_ORDER == LITTLE_ENDIAN
#define PADL_(t) 0
@@ -39,7 +39,7 @@ struct linux_exit_args {
char rval_l_[PADL_(int)]; int rval; char rval_r_[PADR_(int)];
};
struct linux_fork_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_open_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
@@ -97,7 +97,7 @@ struct linux_lseek_args {
char whence_l_[PADL_(l_int)]; l_int whence; char whence_r_[PADR_(l_int)];
};
struct linux_getpid_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_mount_args {
char specialfile_l_[PADL_(char *)]; char * specialfile; char specialfile_r_[PADR_(char *)];
@@ -113,10 +113,10 @@ struct linux_setuid16_args {
char uid_l_[PADL_(l_uid16_t)]; l_uid16_t uid; char uid_r_[PADR_(l_uid16_t)];
};
struct linux_getuid16_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_stime_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_ptrace_args {
char req_l_[PADL_(l_long)]; l_long req; char req_r_[PADR_(l_long)];
@@ -128,7 +128,7 @@ struct linux_alarm_args {
char secs_l_[PADL_(l_uint)]; l_uint secs; char secs_r_[PADR_(l_uint)];
};
struct linux_pause_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_utime_args {
char fname_l_[PADL_(char *)]; char * fname; char fname_r_[PADR_(char *)];
@@ -169,17 +169,17 @@ struct linux_setgid16_args {
char gid_l_[PADL_(l_gid16_t)]; l_gid16_t gid; char gid_r_[PADR_(l_gid16_t)];
};
struct linux_getgid16_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_signal_args {
char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)];
char handler_l_[PADL_(l_handler_t)]; l_handler_t handler; char handler_r_[PADR_(l_handler_t)];
};
struct linux_geteuid16_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_getegid16_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_umount_args {
char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
@@ -196,14 +196,14 @@ struct linux_fcntl_args {
char arg_l_[PADL_(uintptr_t)]; uintptr_t arg; char arg_r_[PADR_(uintptr_t)];
};
struct linux_olduname_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_ustat_args {
char dev_l_[PADL_(l_dev_t)]; l_dev_t dev; char dev_r_[PADR_(l_dev_t)];
char ubuf_l_[PADL_(struct l_ustat *)]; struct l_ustat * ubuf; char ubuf_r_[PADR_(struct l_ustat *)];
};
struct linux_getppid_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_sigaction_args {
char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)];
@@ -211,7 +211,7 @@ struct linux_sigaction_args {
char osa_l_[PADL_(l_osigaction_t *)]; l_osigaction_t * osa; char osa_r_[PADR_(l_osigaction_t *)];
};
struct linux_sgetmask_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_ssetmask_args {
char mask_l_[PADL_(l_osigset_t)]; l_osigset_t mask; char mask_r_[PADR_(l_osigset_t)];
@@ -345,13 +345,13 @@ struct linux_newfstat_args {
char buf_l_[PADL_(struct l_newstat *)]; struct l_newstat * buf; char buf_r_[PADR_(struct l_newstat *)];
};
struct linux_uname_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_iopl_args {
char level_l_[PADL_(l_int)]; l_int level; char level_r_[PADR_(l_int)];
};
struct linux_vhangup_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_wait4_args {
char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
@@ -360,7 +360,7 @@ struct linux_wait4_args {
char rusage_l_[PADL_(struct l_rusage *)]; struct l_rusage * rusage; char rusage_r_[PADR_(struct l_rusage *)];
};
struct linux_swapoff_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_sysinfo_args {
char info_l_[PADL_(struct l_sysinfo *)]; struct l_sysinfo * info; char info_r_[PADR_(struct l_sysinfo *)];
@@ -391,7 +391,7 @@ struct linux_newuname_args {
char buf_l_[PADL_(struct l_new_utsname *)]; struct l_new_utsname * buf; char buf_r_[PADR_(struct l_new_utsname *)];
};
struct linux_adjtimex_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_mprotect_args {
char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
@@ -404,16 +404,16 @@ struct linux_sigprocmask_args {
char omask_l_[PADL_(l_osigset_t *)]; l_osigset_t * omask; char omask_r_[PADR_(l_osigset_t *)];
};
struct linux_init_module_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_delete_module_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_quotactl_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_bdflush_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_sysfs_args {
char option_l_[PADL_(l_int)]; l_int option; char option_r_[PADR_(l_int)];
@@ -536,10 +536,10 @@ struct linux_getresgid16_args {
};
struct linux_prctl_args {
char option_l_[PADL_(l_int)]; l_int option; char option_r_[PADR_(l_int)];
- char arg2_l_[PADL_(l_int)]; l_int arg2; char arg2_r_[PADR_(l_int)];
- char arg3_l_[PADL_(l_int)]; l_int arg3; char arg3_r_[PADR_(l_int)];
- char arg4_l_[PADL_(l_int)]; l_int arg4; char arg4_r_[PADR_(l_int)];
- char arg5_l_[PADL_(l_int)]; l_int arg5; char arg5_r_[PADR_(l_int)];
+ char arg2_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg2; char arg2_r_[PADR_(l_uintptr_t)];
+ char arg3_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg3; char arg3_r_[PADR_(l_uintptr_t)];
+ char arg4_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg4; char arg4_r_[PADR_(l_uintptr_t)];
+ char arg5_l_[PADL_(l_uintptr_t)]; l_uintptr_t arg5; char arg5_r_[PADR_(l_uintptr_t)];
};
struct linux_rt_sigreturn_args {
char ucp_l_[PADL_(struct l_ucontext *)]; struct l_ucontext * ucp; char ucp_r_[PADR_(struct l_ucontext *)];
@@ -617,7 +617,7 @@ struct linux_sendfile_args {
char count_l_[PADL_(l_size_t)]; l_size_t count; char count_r_[PADR_(l_size_t)];
};
struct linux_vfork_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_getrlimit_args {
char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)];
@@ -659,10 +659,10 @@ struct linux_lchown_args {
char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)];
};
struct linux_getuid_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_getgid_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_getgroups_args {
char gidsetsize_l_[PADL_(l_int)]; l_int gidsetsize; char gidsetsize_r_[PADR_(l_int)];
@@ -708,7 +708,7 @@ struct linux_fcntl64_args {
char arg_l_[PADL_(uintptr_t)]; uintptr_t arg; char arg_r_[PADR_(uintptr_t)];
};
struct linux_gettid_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_setxattr_args {
char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
@@ -818,7 +818,7 @@ struct linux_exit_group_args {
char error_code_l_[PADL_(int)]; int error_code; char error_code_r_[PADR_(int)];
};
struct linux_lookup_dcookie_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_epoll_create_args {
char size_l_[PADL_(l_int)]; l_int size; char size_r_[PADR_(l_int)];
@@ -836,7 +836,7 @@ struct linux_epoll_wait_args {
char timeout_l_[PADL_(l_int)]; l_int timeout; char timeout_r_[PADR_(l_int)];
};
struct linux_remap_file_pages_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_set_tid_address_args {
char tidptr_l_[PADL_(int *)]; int * tidptr; char tidptr_r_[PADR_(int *)];
@@ -908,13 +908,13 @@ struct linux_fadvise64_64_args {
char advice_l_[PADL_(int)]; int advice; char advice_r_[PADR_(int)];
};
struct linux_mbind_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_get_mempolicy_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_set_mempolicy_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_mq_open_args {
char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
@@ -949,7 +949,7 @@ struct linux_mq_getsetattr_args {
char oattr_l_[PADL_(struct mq_attr *)]; struct mq_attr * oattr; char oattr_r_[PADR_(struct mq_attr *)];
};
struct linux_kexec_load_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_waitid_args {
char idtype_l_[PADL_(int)]; int idtype; char idtype_r_[PADR_(int)];
@@ -959,31 +959,31 @@ struct linux_waitid_args {
char rusage_l_[PADL_(struct l_rusage *)]; struct l_rusage * rusage; char rusage_r_[PADR_(struct l_rusage *)];
};
struct linux_add_key_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_request_key_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_keyctl_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_ioprio_set_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_ioprio_get_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_inotify_init_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_inotify_add_watch_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_inotify_rm_watch_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_migrate_pages_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_openat_args {
char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
@@ -1075,7 +1075,7 @@ struct linux_ppoll_args {
char ssize_l_[PADL_(l_size_t)]; l_size_t ssize; char ssize_r_[PADR_(l_size_t)];
};
struct linux_unshare_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_set_robust_list_args {
char head_l_[PADL_(struct linux_robust_list_head *)]; struct linux_robust_list_head * head; char head_r_[PADR_(struct linux_robust_list_head *)];
@@ -1103,13 +1103,13 @@ struct linux_sync_file_range_args {
char flags_l_[PADL_(unsigned int)]; unsigned int flags; char flags_r_[PADR_(unsigned int)];
};
struct linux_tee_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_vmsplice_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_move_pages_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_getcpu_args {
char cpu_l_[PADL_(l_uint *)]; l_uint * cpu; char cpu_r_[PADR_(l_uint *)];
@@ -1131,7 +1131,7 @@ struct linux_utimensat_args {
char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_signalfd_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_timerfd_create_args {
char clockid_l_[PADL_(l_int)]; l_int clockid; char clockid_r_[PADR_(l_int)];
@@ -1159,7 +1159,7 @@ struct linux_timerfd_gettime_args {
char old_value_l_[PADL_(struct l_itimerspec *)]; struct l_itimerspec * old_value; char old_value_r_[PADR_(struct l_itimerspec *)];
};
struct linux_signalfd4_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_eventfd2_args {
char initval_l_[PADL_(l_uint)]; l_uint initval; char initval_r_[PADR_(l_uint)];
@@ -1178,7 +1178,7 @@ struct linux_pipe2_args {
char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_inotify_init1_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_preadv_args {
char fd_l_[PADL_(l_ulong)]; l_ulong fd; char fd_r_[PADR_(l_ulong)];
@@ -1201,7 +1201,7 @@ struct linux_rt_tgsigqueueinfo_args {
char uinfo_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * uinfo; char uinfo_r_[PADR_(l_siginfo_t *)];
};
struct linux_perf_event_open_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_recvmmsg_args {
char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
@@ -1211,10 +1211,10 @@ struct linux_recvmmsg_args {
char timeout_l_[PADL_(struct l_timespec *)]; struct l_timespec * timeout; char timeout_r_[PADR_(struct l_timespec *)];
};
struct linux_fanotify_init_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_fanotify_mark_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_prlimit64_args {
char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
@@ -1235,7 +1235,7 @@ struct linux_open_by_handle_at_args {
char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_clock_adjtime_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_syncfs_args {
char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
@@ -1247,7 +1247,7 @@ struct linux_sendmmsg_args {
char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
};
struct linux_setns_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_process_vm_readv_args {
char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
@@ -1467,10 +1467,13 @@ struct linux_arch_prctl_args {
char arg2_l_[PADL_(l_ulong)]; l_ulong arg2; char arg2_r_[PADR_(l_ulong)];
};
struct linux_io_pgetevents_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_rseq_args {
- register_t dummy;
+ char rseq_l_[PADL_(struct linux_rseq *)]; struct linux_rseq * rseq; char rseq_r_[PADR_(struct linux_rseq *)];
+ char rseq_len_l_[PADL_(uint32_t)]; uint32_t rseq_len; char rseq_len_r_[PADR_(uint32_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+ char sig_l_[PADL_(uint32_t)]; uint32_t sig; char sig_r_[PADR_(uint32_t)];
};
struct linux_semget_args {
char key_l_[PADL_(l_key_t)]; l_key_t key; char key_r_[PADR_(l_key_t)];
@@ -1532,7 +1535,7 @@ struct linux_clock_settime64_args {
char tp_l_[PADL_(struct l_timespec64 *)]; struct l_timespec64 * tp; char tp_r_[PADR_(struct l_timespec64 *)];
};
struct linux_clock_adjtime64_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_clock_getres_time64_args {
char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)];
@@ -1545,16 +1548,24 @@ struct linux_clock_nanosleep_time64_args {
char rmtp_l_[PADL_(struct l_timespec64 *)]; struct l_timespec64 * rmtp; char rmtp_r_[PADR_(struct l_timespec64 *)];
};
struct linux_timer_gettime64_args {
- register_t dummy;
+ char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)];
+ char setting_l_[PADL_(struct l_itimerspec64 *)]; struct l_itimerspec64 * setting; char setting_r_[PADR_(struct l_itimerspec64 *)];
};
struct linux_timer_settime64_args {
- register_t dummy;
+ char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+ char new_l_[PADL_(const struct l_itimerspec64 *)]; const struct l_itimerspec64 * new; char new_r_[PADR_(const struct l_itimerspec64 *)];
+ char old_l_[PADL_(struct l_itimerspec64 *)]; struct l_itimerspec64 * old; char old_r_[PADR_(struct l_itimerspec64 *)];
};
struct linux_timerfd_gettime64_args {
- register_t dummy;
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
+ char old_value_l_[PADL_(struct l_itimerspec64 *)]; struct l_itimerspec64 * old_value; char old_value_r_[PADR_(struct l_itimerspec64 *)];
};
struct linux_timerfd_settime64_args {
- register_t dummy;
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+ char new_value_l_[PADL_(const struct l_itimerspec64 *)]; const struct l_itimerspec64 * new_value; char new_value_r_[PADR_(const struct l_itimerspec64 *)];
+ char old_value_l_[PADL_(struct l_itimerspec64 *)]; struct l_itimerspec64 * old_value; char old_value_r_[PADR_(struct l_itimerspec64 *)];
};
struct linux_utimensat_time64_args {
char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
@@ -1573,24 +1584,31 @@ struct linux_pselect6_time64_args {
struct linux_ppoll_time64_args {
char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)];
char nfds_l_[PADL_(uint32_t)]; uint32_t nfds; char nfds_r_[PADR_(uint32_t)];
- char tsp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tsp; char tsp_r_[PADR_(struct l_timespec *)];
+ char tsp_l_[PADL_(struct l_timespec64 *)]; struct l_timespec64 * tsp; char tsp_r_[PADR_(struct l_timespec64 *)];
char sset_l_[PADL_(l_sigset_t *)]; l_sigset_t * sset; char sset_r_[PADR_(l_sigset_t *)];
char ssize_l_[PADL_(l_size_t)]; l_size_t ssize; char ssize_r_[PADR_(l_size_t)];
};
struct linux_io_pgetevents_time64_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_recvmmsg_time64_args {
- register_t dummy;
+ char s_l_[PADL_(l_int)]; l_int s; char s_r_[PADR_(l_int)];
+ char msg_l_[PADL_(struct l_mmsghdr *)]; struct l_mmsghdr * msg; char msg_r_[PADR_(struct l_mmsghdr *)];
+ char vlen_l_[PADL_(l_uint)]; l_uint vlen; char vlen_r_[PADR_(l_uint)];
+ char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
+ char timeout_l_[PADL_(struct l_timespec64 *)]; struct l_timespec64 * timeout; char timeout_r_[PADR_(struct l_timespec64 *)];
};
struct linux_mq_timedsend_time64_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_mq_timedreceive_time64_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_semtimedop_time64_args {
- register_t dummy;
+ char semid_l_[PADL_(l_int)]; l_int semid; char semid_r_[PADR_(l_int)];
+ char tsops_l_[PADL_(struct sembuf *)]; struct sembuf * tsops; char tsops_r_[PADR_(struct sembuf *)];
+ char nsops_l_[PADL_(l_size_t)]; l_size_t nsops; char nsops_r_[PADR_(l_size_t)];
+ char timeout_l_[PADL_(struct l_timespec64 *)]; struct l_timespec64 * timeout; char timeout_r_[PADR_(struct l_timespec64 *)];
};
struct linux_rt_sigtimedwait_time64_args {
char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)];
@@ -1607,7 +1625,8 @@ struct linux_sys_futex_time64_args {
char val3_l_[PADL_(uint32_t)]; uint32_t val3; char val3_r_[PADR_(uint32_t)];
};
struct linux_sched_rr_get_interval_time64_args {
- register_t dummy;
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char interval_l_[PADL_(struct l_timespec64 *)]; struct l_timespec64 * interval; char interval_r_[PADR_(struct l_timespec64 *)];
};
struct linux_pidfd_send_signal_args {
char pidfd_l_[PADL_(l_int)]; l_int pidfd; char pidfd_r_[PADR_(l_int)];
@@ -1616,47 +1635,47 @@ struct linux_pidfd_send_signal_args {
char flags_l_[PADL_(l_uint)]; l_uint flags; char flags_r_[PADR_(l_uint)];
};
struct linux_io_uring_setup_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_io_uring_enter_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_io_uring_register_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_open_tree_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_move_mount_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_fsopen_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_fsconfig_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_fsmount_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_fspick_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_pidfd_open_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_clone3_args {
char uargs_l_[PADL_(struct l_user_clone_args *)]; struct l_user_clone_args * uargs; char uargs_r_[PADR_(struct l_user_clone_args *)];
char usize_l_[PADL_(l_size_t)]; l_size_t usize; char usize_r_[PADR_(l_size_t)];
};
struct linux_close_range_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_openat2_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_pidfd_getfd_args {
- register_t dummy;
+ syscallarg_t dummy;
};
struct linux_faccessat2_args {
char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)];
@@ -1665,13 +1684,18 @@ struct linux_faccessat2_args {
char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
};
struct linux_process_madvise_args {
- register_t dummy;
+ syscallarg_t dummy;
};
-struct linux_epoll_pwait2_args {
- register_t dummy;
+struct linux_epoll_pwait2_64_args {
+ char epfd_l_[PADL_(l_int)]; l_int epfd; char epfd_r_[PADR_(l_int)];
+ char events_l_[PADL_(struct epoll_event *)]; struct epoll_event * events; char events_r_[PADR_(struct epoll_event *)];
+ char maxevents_l_[PADL_(l_int)]; l_int maxevents; char maxevents_r_[PADR_(l_int)];
+ char timeout_l_[PADL_(struct l_timespec64 *)]; struct l_timespec64 * timeout; char timeout_r_[PADR_(struct l_timespec64 *)];
+ char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)];
+ char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
};
struct linux_mount_setattr_args {
- register_t dummy;
+ syscallarg_t dummy;
};
#define nosys linux_nosys
int linux_exit(struct thread *, struct linux_exit_args *);
@@ -2035,57 +2059,8 @@ int linux_openat2(struct thread *, struct linux_openat2_args *);
int linux_pidfd_getfd(struct thread *, struct linux_pidfd_getfd_args *);
int linux_faccessat2(struct thread *, struct linux_faccessat2_args *);
int linux_process_madvise(struct thread *, struct linux_process_madvise_args *);
-int linux_epoll_pwait2(struct thread *, struct linux_epoll_pwait2_args *);
+int linux_epoll_pwait2_64(struct thread *, struct linux_epoll_pwait2_64_args *);
int linux_mount_setattr(struct thread *, struct linux_mount_setattr_args *);
-
-#ifdef COMPAT_43
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_43 */
-
-
-#ifdef COMPAT_FREEBSD4
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD4 */
-
-
-#ifdef COMPAT_FREEBSD6
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD6 */
-
-
-#ifdef COMPAT_FREEBSD7
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD7 */
-
-
-#ifdef COMPAT_FREEBSD10
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD10 */
-
-
-#ifdef COMPAT_FREEBSD11
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD11 */
-
-
-#ifdef COMPAT_FREEBSD12
-
-#define nosys linux_nosys
-
-#endif /* COMPAT_FREEBSD12 */
-
#define LINUX32_SYS_AUE_linux_exit AUE_EXIT
#define LINUX32_SYS_AUE_linux_fork AUE_FORK
#define LINUX32_SYS_AUE_linux_open AUE_OPEN_RWTC
@@ -2429,7 +2404,7 @@ int linux_mount_setattr(struct thread *, struct linux_mount_setattr_args *);
#define LINUX32_SYS_AUE_linux_semtimedop_time64 AUE_NULL
#define LINUX32_SYS_AUE_linux_rt_sigtimedwait_time64 AUE_NULL
#define LINUX32_SYS_AUE_linux_sys_futex_time64 AUE_NULL
-#define LINUX32_SYS_AUE_linux_sched_rr_get_interval_time64 AUE_NULL
+#define LINUX32_SYS_AUE_linux_sched_rr_get_interval_time64 AUE_SCHED_RR_GET_INTERVAL
#define LINUX32_SYS_AUE_linux_pidfd_send_signal AUE_NULL
#define LINUX32_SYS_AUE_linux_io_uring_setup AUE_NULL
#define LINUX32_SYS_AUE_linux_io_uring_enter AUE_NULL
@@ -2447,7 +2422,7 @@ int linux_mount_setattr(struct thread *, struct linux_mount_setattr_args *);
#define LINUX32_SYS_AUE_linux_pidfd_getfd AUE_NULL
#define LINUX32_SYS_AUE_linux_faccessat2 AUE_NULL
#define LINUX32_SYS_AUE_linux_process_madvise AUE_NULL
-#define LINUX32_SYS_AUE_linux_epoll_pwait2 AUE_NULL
+#define LINUX32_SYS_AUE_linux_epoll_pwait2_64 AUE_NULL
#define LINUX32_SYS_AUE_linux_mount_setattr AUE_NULL
#undef PAD_
diff --git a/sys/amd64/linux32/linux32_support.s b/sys/amd64/linux32/linux32_support.s
index 2e2dbca4e24b..c92cb48e2d1a 100644
--- a/sys/amd64/linux32/linux32_support.s
+++ b/sys/amd64/linux32/linux32_support.s
@@ -39,7 +39,7 @@ futex_fault:
je 1f
clac
1: movq $0,PCB_ONFAULT(%r8)
- movl $-EFAULT,%eax
+ movl $EFAULT,%eax
ret
ENTRY(futex_xchgl_nosmap)
diff --git a/sys/amd64/linux32/linux32_syscall.h b/sys/amd64/linux32/linux32_syscall.h
index b2724c50d6a0..c8b497710470 100644
--- a/sys/amd64/linux32/linux32_syscall.h
+++ b/sys/amd64/linux32/linux32_syscall.h
@@ -402,6 +402,6 @@
#define LINUX32_SYS_linux_pidfd_getfd 438
#define LINUX32_SYS_linux_faccessat2 439
#define LINUX32_SYS_linux_process_madvise 440
-#define LINUX32_SYS_linux_epoll_pwait2 441
+#define LINUX32_SYS_linux_epoll_pwait2_64 441
#define LINUX32_SYS_linux_mount_setattr 442
#define LINUX32_SYS_MAXSYSCALL 444
diff --git a/sys/amd64/linux32/linux32_syscalls.c b/sys/amd64/linux32/linux32_syscalls.c
index 3ee1639b5971..f44eef1f589a 100644
--- a/sys/amd64/linux32/linux32_syscalls.c
+++ b/sys/amd64/linux32/linux32_syscalls.c
@@ -448,7 +448,7 @@ const char *linux32_syscallnames[] = {
"linux_pidfd_getfd", /* 438 = linux_pidfd_getfd */
"linux_faccessat2", /* 439 = linux_faccessat2 */
"linux_process_madvise", /* 440 = linux_process_madvise */
- "linux_epoll_pwait2", /* 441 = linux_epoll_pwait2 */
+ "linux_epoll_pwait2_64", /* 441 = linux_epoll_pwait2_64 */
"linux_mount_setattr", /* 442 = linux_mount_setattr */
"#443", /* 443 = nosys */
};
diff --git a/sys/amd64/linux32/linux32_sysent.c b/sys/amd64/linux32/linux32_sysent.c
index 46b74d6a8139..54a1c50807f2 100644
--- a/sys/amd64/linux32/linux32_sysent.c
+++ b/sys/amd64/linux32/linux32_sysent.c
@@ -12,7 +12,7 @@
#include <amd64/linux32/linux.h>
#include <amd64/linux32/linux32_proto.h>
-#define AS(name) (sizeof(struct name) / sizeof(register_t))
+#define AS(name) (sizeof(struct name) / sizeof(syscallarg_t))
/* The casts are bogus but will do for now. */
struct sysent linux32_sysent[] = {
@@ -403,7 +403,7 @@ struct sysent linux32_sysent[] = {
{ .sy_narg = AS(linux_statx_args), .sy_call = (sy_call_t *)linux_statx, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 383 = linux_statx */
{ .sy_narg = AS(linux_arch_prctl_args), .sy_call = (sy_call_t *)linux_arch_prctl, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 384 = linux_arch_prctl */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_io_pgetevents, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 385 = linux_io_pgetevents */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_rseq, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 386 = linux_rseq */
+ { .sy_narg = AS(linux_rseq_args), .sy_call = (sy_call_t *)linux_rseq, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 386 = linux_rseq */
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 387 = nosys */
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 388 = nosys */
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 389 = nosys */
@@ -425,22 +425,22 @@ struct sysent linux32_sysent[] = {
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_clock_adjtime64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 405 = linux_clock_adjtime64 */
{ .sy_narg = AS(linux_clock_getres_time64_args), .sy_call = (sy_call_t *)linux_clock_getres_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 406 = linux_clock_getres_time64 */
{ .sy_narg = AS(linux_clock_nanosleep_time64_args), .sy_call = (sy_call_t *)linux_clock_nanosleep_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 407 = linux_clock_nanosleep_time64 */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_timer_gettime64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 408 = linux_timer_gettime64 */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_timer_settime64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 409 = linux_timer_settime64 */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_timerfd_gettime64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 410 = linux_timerfd_gettime64 */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_timerfd_settime64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 411 = linux_timerfd_settime64 */
+ { .sy_narg = AS(linux_timer_gettime64_args), .sy_call = (sy_call_t *)linux_timer_gettime64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 408 = linux_timer_gettime64 */
+ { .sy_narg = AS(linux_timer_settime64_args), .sy_call = (sy_call_t *)linux_timer_settime64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 409 = linux_timer_settime64 */
+ { .sy_narg = AS(linux_timerfd_gettime64_args), .sy_call = (sy_call_t *)linux_timerfd_gettime64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 410 = linux_timerfd_gettime64 */
+ { .sy_narg = AS(linux_timerfd_settime64_args), .sy_call = (sy_call_t *)linux_timerfd_settime64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 411 = linux_timerfd_settime64 */
{ .sy_narg = AS(linux_utimensat_time64_args), .sy_call = (sy_call_t *)linux_utimensat_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 412 = linux_utimensat_time64 */
{ .sy_narg = AS(linux_pselect6_time64_args), .sy_call = (sy_call_t *)linux_pselect6_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 413 = linux_pselect6_time64 */
{ .sy_narg = AS(linux_ppoll_time64_args), .sy_call = (sy_call_t *)linux_ppoll_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 414 = linux_ppoll_time64 */
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 415 = nosys */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_io_pgetevents_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 416 = linux_io_pgetevents_time64 */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_recvmmsg_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 417 = linux_recvmmsg_time64 */
+ { .sy_narg = AS(linux_recvmmsg_time64_args), .sy_call = (sy_call_t *)linux_recvmmsg_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 417 = linux_recvmmsg_time64 */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_mq_timedsend_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 418 = linux_mq_timedsend_time64 */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_mq_timedreceive_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 419 = linux_mq_timedreceive_time64 */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_semtimedop_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 420 = linux_semtimedop_time64 */
+ { .sy_narg = AS(linux_semtimedop_time64_args), .sy_call = (sy_call_t *)linux_semtimedop_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 420 = linux_semtimedop_time64 */
{ .sy_narg = AS(linux_rt_sigtimedwait_time64_args), .sy_call = (sy_call_t *)linux_rt_sigtimedwait_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 421 = linux_rt_sigtimedwait_time64 */
{ .sy_narg = AS(linux_sys_futex_time64_args), .sy_call = (sy_call_t *)linux_sys_futex_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 422 = linux_sys_futex_time64 */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_sched_rr_get_interval_time64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 423 = linux_sched_rr_get_interval_time64 */
+ { .sy_narg = AS(linux_sched_rr_get_interval_time64_args), .sy_call = (sy_call_t *)linux_sched_rr_get_interval_time64, .sy_auevent = AUE_SCHED_RR_GET_INTERVAL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 423 = linux_sched_rr_get_interval_time64 */
{ .sy_narg = AS(linux_pidfd_send_signal_args), .sy_call = (sy_call_t *)linux_pidfd_send_signal, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 424 = linux_pidfd_send_signal */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_io_uring_setup, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 425 = linux_io_uring_setup */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_io_uring_enter, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 426 = linux_io_uring_enter */
@@ -458,7 +458,7 @@ struct sysent linux32_sysent[] = {
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_pidfd_getfd, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 438 = linux_pidfd_getfd */
{ .sy_narg = AS(linux_faccessat2_args), .sy_call = (sy_call_t *)linux_faccessat2, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 439 = linux_faccessat2 */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_process_madvise, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 440 = linux_process_madvise */
- { .sy_narg = 0, .sy_call = (sy_call_t *)linux_epoll_pwait2, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 441 = linux_epoll_pwait2 */
+ { .sy_narg = AS(linux_epoll_pwait2_64_args), .sy_call = (sy_call_t *)linux_epoll_pwait2_64, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 441 = linux_epoll_pwait2_64 */
{ .sy_narg = 0, .sy_call = (sy_call_t *)linux_mount_setattr, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 442 = linux_mount_setattr */
{ .sy_narg = 0, .sy_call = (sy_call_t *)nosys, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_ABSENT }, /* 443 = nosys */
};
diff --git a/sys/amd64/linux32/linux32_systrace_args.c b/sys/amd64/linux32/linux32_systrace_args.c
index c9c7914d01be..fee5cf2c2e2d 100644
--- a/sys/amd64/linux32/linux32_systrace_args.c
+++ b/sys/amd64/linux32/linux32_systrace_args.c
@@ -1161,10 +1161,10 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
case 172: {
struct linux_prctl_args *p = params;
iarg[a++] = p->option; /* l_int */
- iarg[a++] = p->arg2; /* l_int */
- iarg[a++] = p->arg3; /* l_int */
- iarg[a++] = p->arg4; /* l_int */
- iarg[a++] = p->arg5; /* l_int */
+ uarg[a++] = (intptr_t)p->arg2; /* l_uintptr_t */
+ uarg[a++] = (intptr_t)p->arg3; /* l_uintptr_t */
+ uarg[a++] = (intptr_t)p->arg4; /* l_uintptr_t */
+ uarg[a++] = (intptr_t)p->arg5; /* l_uintptr_t */
*n_args = 5;
break;
}
@@ -2867,7 +2867,12 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_rseq */
case 386: {
- *n_args = 0;
+ struct linux_rseq_args *p = params;
+ uarg[a++] = (intptr_t)p->rseq; /* struct linux_rseq * */
+ uarg[a++] = p->rseq_len; /* uint32_t */
+ iarg[a++] = p->flags; /* l_int */
+ uarg[a++] = p->sig; /* uint32_t */
+ *n_args = 4;
break;
}
/* linux_semget */
@@ -3002,22 +3007,38 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_timer_gettime64 */
case 408: {
- *n_args = 0;
+ struct linux_timer_gettime64_args *p = params;
+ iarg[a++] = p->timerid; /* l_timer_t */
+ uarg[a++] = (intptr_t)p->setting; /* struct l_itimerspec64 * */
+ *n_args = 2;
break;
}
/* linux_timer_settime64 */
case 409: {
- *n_args = 0;
+ struct linux_timer_settime64_args *p = params;
+ iarg[a++] = p->timerid; /* l_timer_t */
+ iarg[a++] = p->flags; /* l_int */
+ uarg[a++] = (intptr_t)p->new; /* const struct l_itimerspec64 * */
+ uarg[a++] = (intptr_t)p->old; /* struct l_itimerspec64 * */
+ *n_args = 4;
break;
}
/* linux_timerfd_gettime64 */
case 410: {
- *n_args = 0;
+ struct linux_timerfd_gettime64_args *p = params;
+ iarg[a++] = p->fd; /* l_int */
+ uarg[a++] = (intptr_t)p->old_value; /* struct l_itimerspec64 * */
+ *n_args = 2;
break;
}
/* linux_timerfd_settime64 */
case 411: {
- *n_args = 0;
+ struct linux_timerfd_settime64_args *p = params;
+ iarg[a++] = p->fd; /* l_int */
+ iarg[a++] = p->flags; /* l_int */
+ uarg[a++] = (intptr_t)p->new_value; /* const struct l_itimerspec64 * */
+ uarg[a++] = (intptr_t)p->old_value; /* struct l_itimerspec64 * */
+ *n_args = 4;
break;
}
/* linux_utimensat_time64 */
@@ -3047,7 +3068,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
struct linux_ppoll_time64_args *p = params;
uarg[a++] = (intptr_t)p->fds; /* struct pollfd * */
uarg[a++] = p->nfds; /* uint32_t */
- uarg[a++] = (intptr_t)p->tsp; /* struct l_timespec * */
+ uarg[a++] = (intptr_t)p->tsp; /* struct l_timespec64 * */
uarg[a++] = (intptr_t)p->sset; /* l_sigset_t * */
iarg[a++] = p->ssize; /* l_size_t */
*n_args = 5;
@@ -3060,7 +3081,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_recvmmsg_time64 */
case 417: {
- *n_args = 0;
+ struct linux_recvmmsg_time64_args *p = params;
+ iarg[a++] = p->s; /* l_int */
+ uarg[a++] = (intptr_t)p->msg; /* struct l_mmsghdr * */
+ iarg[a++] = p->vlen; /* l_uint */
+ iarg[a++] = p->flags; /* l_uint */
+ uarg[a++] = (intptr_t)p->timeout; /* struct l_timespec64 * */
+ *n_args = 5;
break;
}
/* linux_mq_timedsend_time64 */
@@ -3075,7 +3102,12 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_semtimedop_time64 */
case 420: {
- *n_args = 0;
+ struct linux_semtimedop_time64_args *p = params;
+ iarg[a++] = p->semid; /* l_int */
+ uarg[a++] = (intptr_t)p->tsops; /* struct sembuf * */
+ iarg[a++] = p->nsops; /* l_size_t */
+ uarg[a++] = (intptr_t)p->timeout; /* struct l_timespec64 * */
+ *n_args = 4;
break;
}
/* linux_rt_sigtimedwait_time64 */
@@ -3102,7 +3134,10 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
}
/* linux_sched_rr_get_interval_time64 */
case 423: {
- *n_args = 0;
+ struct linux_sched_rr_get_interval_time64_args *p = params;
+ iarg[a++] = p->pid; /* l_pid_t */
+ uarg[a++] = (intptr_t)p->interval; /* struct l_timespec64 * */
+ *n_args = 2;
break;
}
/* linux_pidfd_send_signal */
@@ -3203,9 +3238,16 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 0;
break;
}
- /* linux_epoll_pwait2 */
+ /* linux_epoll_pwait2_64 */
case 441: {
- *n_args = 0;
+ struct linux_epoll_pwait2_64_args *p = params;
+ iarg[a++] = p->epfd; /* l_int */
+ uarg[a++] = (intptr_t)p->events; /* struct epoll_event * */
+ iarg[a++] = p->maxevents; /* l_int */
+ uarg[a++] = (intptr_t)p->timeout; /* struct l_timespec64 * */
+ uarg[a++] = (intptr_t)p->mask; /* l_sigset_t * */
+ iarg[a++] = p->sigsetsize; /* l_size_t */
+ *n_args = 6;
break;
}
/* linux_mount_setattr */
@@ -4989,16 +5031,16 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
p = "l_int";
break;
case 1:
- p = "l_int";
+ p = "l_uintptr_t";
break;
case 2:
- p = "l_int";
+ p = "l_uintptr_t";
break;
case 3:
- p = "l_int";
+ p = "l_uintptr_t";
break;
case 4:
- p = "l_int";
+ p = "l_uintptr_t";
break;
default:
break;
@@ -7873,6 +7915,22 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_rseq */
case 386:
+ switch (ndx) {
+ case 0:
+ p = "userland struct linux_rseq *";
+ break;
+ case 1:
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "uint32_t";
+ break;
+ default:
+ break;
+ };
break;
/* linux_semget */
case 393:
@@ -8100,15 +8158,67 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_timer_gettime64 */
case 408:
+ switch (ndx) {
+ case 0:
+ p = "l_timer_t";
+ break;
+ case 1:
+ p = "userland struct l_itimerspec64 *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_timer_settime64 */
case 409:
+ switch (ndx) {
+ case 0:
+ p = "l_timer_t";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "userland const struct l_itimerspec64 *";
+ break;
+ case 3:
+ p = "userland struct l_itimerspec64 *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_timerfd_gettime64 */
case 410:
+ switch (ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "userland struct l_itimerspec64 *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_timerfd_settime64 */
case 411:
+ switch (ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "l_int";
+ break;
+ case 2:
+ p = "userland const struct l_itimerspec64 *";
+ break;
+ case 3:
+ p = "userland struct l_itimerspec64 *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_utimensat_time64 */
case 412:
@@ -8164,7 +8274,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
p = "uint32_t";
break;
case 2:
- p = "userland struct l_timespec *";
+ p = "userland struct l_timespec64 *";
break;
case 3:
p = "userland l_sigset_t *";
@@ -8181,6 +8291,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_recvmmsg_time64 */
case 417:
+ switch (ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "userland struct l_mmsghdr *";
+ break;
+ case 2:
+ p = "l_uint";
+ break;
+ case 3:
+ p = "l_uint";
+ break;
+ case 4:
+ p = "userland struct l_timespec64 *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_mq_timedsend_time64 */
case 418:
@@ -8190,6 +8319,22 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_semtimedop_time64 */
case 420:
+ switch (ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "userland struct sembuf *";
+ break;
+ case 2:
+ p = "l_size_t";
+ break;
+ case 3:
+ p = "userland struct l_timespec64 *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_rt_sigtimedwait_time64 */
case 421:
@@ -8237,6 +8382,16 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_sched_rr_get_interval_time64 */
case 423:
+ switch (ndx) {
+ case 0:
+ p = "l_pid_t";
+ break;
+ case 1:
+ p = "userland struct l_timespec64 *";
+ break;
+ default:
+ break;
+ };
break;
/* linux_pidfd_send_signal */
case 424:
@@ -8331,8 +8486,30 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
/* linux_process_madvise */
case 440:
break;
- /* linux_epoll_pwait2 */
+ /* linux_epoll_pwait2_64 */
case 441:
+ switch (ndx) {
+ case 0:
+ p = "l_int";
+ break;
+ case 1:
+ p = "userland struct epoll_event *";
+ break;
+ case 2:
+ p = "l_int";
+ break;
+ case 3:
+ p = "userland struct l_timespec64 *";
+ break;
+ case 4:
+ p = "userland l_sigset_t *";
+ break;
+ case 5:
+ p = "l_size_t";
+ break;
+ default:
+ break;
+ };
break;
/* linux_mount_setattr */
case 442:
@@ -9924,6 +10101,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 385:
/* linux_rseq */
case 386:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_semget */
case 393:
if (ndx == 0 || ndx == 1)
@@ -9998,12 +10178,24 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_timer_gettime64 */
case 408:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_timer_settime64 */
case 409:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_timerfd_gettime64 */
case 410:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_timerfd_settime64 */
case 411:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_utimensat_time64 */
case 412:
if (ndx == 0 || ndx == 1)
@@ -10023,12 +10215,18 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
case 416:
/* linux_recvmmsg_time64 */
case 417:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_mq_timedsend_time64 */
case 418:
/* linux_mq_timedreceive_time64 */
case 419:
/* linux_semtimedop_time64 */
case 420:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_rt_sigtimedwait_time64 */
case 421:
if (ndx == 0 || ndx == 1)
@@ -10041,6 +10239,9 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_sched_rr_get_interval_time64 */
case 423:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_pidfd_send_signal */
case 424:
if (ndx == 0 || ndx == 1)
@@ -10084,8 +10285,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
/* linux_process_madvise */
case 440:
- /* linux_epoll_pwait2 */
+ /* linux_epoll_pwait2_64 */
case 441:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
/* linux_mount_setattr */
case 442:
default:
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index b9d2d7aaf7cd..ff16822a352b 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -91,6 +91,8 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_util.h>
#include <compat/linux/linux_vdso.h>
+#include <x86/linux/linux_x86_sigframe.h>
+
MODULE_VERSION(linux, 1);
#define LINUX32_MAXUSER ((1ul << 32) - PAGE_SIZE)
@@ -132,45 +134,6 @@ static void linux_vdso_reloc(char *mapping, Elf_Addr offset);
static void linux32_set_fork_retval(struct thread *td);
static void linux32_set_syscall_retval(struct thread *td, int error);
-#define LINUX_T_UNKNOWN 255
-static int _bsd_to_linux_trapcode[] = {
- LINUX_T_UNKNOWN, /* 0 */
- 6, /* 1 T_PRIVINFLT */
- LINUX_T_UNKNOWN, /* 2 */
- 3, /* 3 T_BPTFLT */
- LINUX_T_UNKNOWN, /* 4 */
- LINUX_T_UNKNOWN, /* 5 */
- 16, /* 6 T_ARITHTRAP */
- 254, /* 7 T_ASTFLT */
- LINUX_T_UNKNOWN, /* 8 */
- 13, /* 9 T_PROTFLT */
- 1, /* 10 T_TRCTRAP */
- LINUX_T_UNKNOWN, /* 11 */
- 14, /* 12 T_PAGEFLT */
- LINUX_T_UNKNOWN, /* 13 */
- 17, /* 14 T_ALIGNFLT */
- LINUX_T_UNKNOWN, /* 15 */
- LINUX_T_UNKNOWN, /* 16 */
- LINUX_T_UNKNOWN, /* 17 */
- 0, /* 18 T_DIVIDE */
- 2, /* 19 T_NMI */
- 4, /* 20 T_OFLOW */
- 5, /* 21 T_BOUND */
- 7, /* 22 T_DNA */
- 8, /* 23 T_DOUBLEFLT */
- 9, /* 24 T_FPOPFLT */
- 10, /* 25 T_TSSFLT */
- 11, /* 26 T_SEGNPFLT */
- 12, /* 27 T_STKFLT */
- 18, /* 28 T_MCHK */
- 19, /* 29 T_XMMFLT */
- 15 /* 30 T_RESERVED */
-};
-#define bsd_to_linux_trapcode(code) \
- ((code)<nitems(_bsd_to_linux_trapcode)? \
- _bsd_to_linux_trapcode[(code)]: \
- LINUX_T_UNKNOWN)
-
struct linux32_ps_strings {
u_int32_t ps_argvstr; /* first of 0 or more argument strings */
u_int ps_nargvstr; /* the number of argument strings */
@@ -181,34 +144,13 @@ struct linux32_ps_strings {
sizeof(struct linux32_ps_strings))
LINUX_VDSO_SYM_INTPTR(__kernel_vsyscall);
-LINUX_VDSO_SYM_INTPTR(__kernel_sigreturn);
-LINUX_VDSO_SYM_INTPTR(__kernel_rt_sigreturn);
+LINUX_VDSO_SYM_INTPTR(linux32_vdso_sigcode);
+LINUX_VDSO_SYM_INTPTR(linux32_vdso_rt_sigcode);
LINUX_VDSO_SYM_INTPTR(kern_timekeep_base);
LINUX_VDSO_SYM_INTPTR(kern_tsc_selector);
+LINUX_VDSO_SYM_INTPTR(kern_cpu_selector);
LINUX_VDSO_SYM_CHAR(linux_platform);
-/*
- * If FreeBSD & Linux have a difference of opinion about what a trap
- * means, deal with it here.
- *
- * MPSAFE
- */
-static int
-linux_translate_traps(int signal, int trap_code)
-{
- if (signal != SIGBUS)
- return (signal);
- switch (trap_code) {
- case T_PROTFLT:
- case T_TSSFLT:
- case T_DOUBLEFLT:
- case T_PAGEFLT:
- return (SIGSEGV);
- default:
- return (signal);
- }
-}
-
static int
linux_copyout_auxargs(struct image_params *imgp, uintptr_t base)
{
@@ -291,7 +233,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
int sig;
int code;
- sig = ksi->ksi_signo;
+ sig = linux_translate_traps(ksi->ksi_signo, ksi->ksi_trapno);
code = ksi->ksi_code;
PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts;
@@ -313,10 +255,9 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
bzero(&frame, sizeof(frame));
- frame.sf_handler = PTROUT(catcher);
frame.sf_sig = sig;
frame.sf_siginfo = PTROUT(&fp->sf_si);
- frame.sf_ucontext = PTROUT(&fp->sf_sc);
+ frame.sf_ucontext = PTROUT(&fp->sf_uc);
/* Fill in POSIX parts. */
siginfo_to_lsiginfo(&ksi->ksi_info, &frame.sf_si, sig);
@@ -324,38 +265,35 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/*
* Build the signal context to be used by sigreturn and libgcc unwind.
*/
- frame.sf_sc.uc_flags = 0; /* XXX ??? */
- frame.sf_sc.uc_link = 0; /* XXX ??? */
-
- frame.sf_sc.uc_stack.ss_sp = PTROUT(td->td_sigstk.ss_sp);
- frame.sf_sc.uc_stack.ss_size = td->td_sigstk.ss_size;
- frame.sf_sc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
+ frame.sf_uc.uc_stack.ss_sp = PTROUT(td->td_sigstk.ss_sp);
+ frame.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size;
+ frame.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
PROC_UNLOCK(p);
- bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
-
- frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__mask;
- frame.sf_sc.uc_mcontext.sc_edi = regs->tf_rdi;
- frame.sf_sc.uc_mcontext.sc_esi = regs->tf_rsi;
- frame.sf_sc.uc_mcontext.sc_ebp = regs->tf_rbp;
- frame.sf_sc.uc_mcontext.sc_ebx = regs->tf_rbx;
- frame.sf_sc.uc_mcontext.sc_esp = regs->tf_rsp;
- frame.sf_sc.uc_mcontext.sc_edx = regs->tf_rdx;
- frame.sf_sc.uc_mcontext.sc_ecx = regs->tf_rcx;
- frame.sf_sc.uc_mcontext.sc_eax = regs->tf_rax;
- frame.sf_sc.uc_mcontext.sc_eip = regs->tf_rip;
- frame.sf_sc.uc_mcontext.sc_cs = regs->tf_cs;
- frame.sf_sc.uc_mcontext.sc_gs = regs->tf_gs;
- frame.sf_sc.uc_mcontext.sc_fs = regs->tf_fs;
- frame.sf_sc.uc_mcontext.sc_es = regs->tf_es;
- frame.sf_sc.uc_mcontext.sc_ds = regs->tf_ds;
- frame.sf_sc.uc_mcontext.sc_eflags = regs->tf_rflags;
- frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_rsp;
- frame.sf_sc.uc_mcontext.sc_ss = regs->tf_ss;
- frame.sf_sc.uc_mcontext.sc_err = regs->tf_err;
- frame.sf_sc.uc_mcontext.sc_cr2 = (u_int32_t)(uintptr_t)ksi->ksi_addr;
- frame.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
+ bsd_to_linux_sigset(mask, &frame.sf_uc.uc_sigmask);
+
+ frame.sf_uc.uc_mcontext.sc_mask = frame.sf_uc.uc_sigmask.__mask;
+ frame.sf_uc.uc_mcontext.sc_edi = regs->tf_rdi;
+ frame.sf_uc.uc_mcontext.sc_esi = regs->tf_rsi;
+ frame.sf_uc.uc_mcontext.sc_ebp = regs->tf_rbp;
+ frame.sf_uc.uc_mcontext.sc_ebx = regs->tf_rbx;
+ frame.sf_uc.uc_mcontext.sc_esp = regs->tf_rsp;
+ frame.sf_uc.uc_mcontext.sc_edx = regs->tf_rdx;
+ frame.sf_uc.uc_mcontext.sc_ecx = regs->tf_rcx;
+ frame.sf_uc.uc_mcontext.sc_eax = regs->tf_rax;
+ frame.sf_uc.uc_mcontext.sc_eip = regs->tf_rip;
+ frame.sf_uc.uc_mcontext.sc_cs = regs->tf_cs;
+ frame.sf_uc.uc_mcontext.sc_gs = regs->tf_gs;
+ frame.sf_uc.uc_mcontext.sc_fs = regs->tf_fs;
+ frame.sf_uc.uc_mcontext.sc_es = regs->tf_es;
+ frame.sf_uc.uc_mcontext.sc_ds = regs->tf_ds;
+ frame.sf_uc.uc_mcontext.sc_eflags = regs->tf_rflags;
+ frame.sf_uc.uc_mcontext.sc_esp_at_signal = regs->tf_rsp;
+ frame.sf_uc.uc_mcontext.sc_ss = regs->tf_ss;
+ frame.sf_uc.uc_mcontext.sc_err = regs->tf_err;
+ frame.sf_uc.uc_mcontext.sc_cr2 = (u_int32_t)(uintptr_t)ksi->ksi_addr;
+ frame.sf_uc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
if (copyout(&frame, fp, sizeof(frame)) != 0) {
/*
@@ -368,7 +306,8 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/* Build context to run handler in. */
regs->tf_rsp = PTROUT(fp);
- regs->tf_rip = __kernel_rt_sigreturn;
+ regs->tf_rip = linux32_vdso_rt_sigcode;
+ regs->tf_rdi = PTROUT(catcher);
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ss = _udatasel;
@@ -404,7 +343,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
int oonstack;
int sig, code;
- sig = ksi->ksi_signo;
+ sig = linux_translate_traps(ksi->ksi_signo, ksi->ksi_trapno);
code = ksi->ksi_code;
PROC_LOCK_ASSERT(p, MA_OWNED);
psp = p->p_sigacts;
@@ -433,7 +372,6 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
bzero(&frame, sizeof(frame));
- frame.sf_handler = PTROUT(catcher);
frame.sf_sig = sig;
bsd_to_linux_sigset(mask, &lmask);
@@ -474,7 +412,8 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
/* Build context to run handler in. */
regs->tf_rsp = PTROUT(fp);
- regs->tf_rip = __kernel_sigreturn;
+ regs->tf_rip = linux32_vdso_sigcode;
+ regs->tf_rdi = PTROUT(catcher);
regs->tf_rflags &= ~(PSL_T | PSL_D);
regs->tf_cs = _ucode32sel;
regs->tf_ss = _udatasel;
@@ -771,16 +710,11 @@ linux_copyout_strings(struct image_params *imgp, uintptr_t *stack_base)
char canary[LINUX_AT_RANDOM_LEN];
size_t execpath_len;
- /* Calculate string base and vector table pointers. */
- if (imgp->execpath != NULL && imgp->auxargs != NULL)
- execpath_len = strlen(imgp->execpath) + 1;
- else
- execpath_len = 0;
-
- arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS;
+ arginfo = (struct linux32_ps_strings *)PROC_PS_STRINGS(imgp->proc);
destp = (uintptr_t)arginfo;
- if (execpath_len != 0) {
+ if (imgp->execpath != NULL && imgp->auxargs != NULL) {
+ execpath_len = strlen(imgp->execpath) + 1;
destp -= execpath_len;
destp = rounddown2(destp, sizeof(uint32_t));
imgp->execpathp = (void *)destp;
@@ -890,6 +824,9 @@ SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxssiz, CTLFLAG_RW,
static u_long linux32_maxvmem = LINUX32_MAXVMEM;
SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxvmem, CTLFLAG_RW,
&linux32_maxvmem, 0, "");
+bool linux32_emulate_i386 = false;
+SYSCTL_BOOL(_compat_linux32, OID_AUTO, emulate_i386, CTLFLAG_RWTUN,
+ &linux32_emulate_i386, 0, "Emulate the real i386");
static void
linux32_fixlimit(struct rlimit *rl, int which)
@@ -926,7 +863,6 @@ linux32_fixlimit(struct rlimit *rl, int which)
struct sysentvec elf_linux_sysvec = {
.sv_size = LINUX32_SYS_MAXSYSCALL,
.sv_table = linux32_sysent,
- .sv_transtrap = linux_translate_traps,
.sv_fixup = linux_fixup_elf,
.sv_sendsig = linux_sendsig,
.sv_sigcode = &_binary_linux32_vdso_so_o_start,
@@ -942,6 +878,7 @@ struct sysentvec elf_linux_sysvec = {
.sv_maxuser = LINUX32_MAXUSER,
.sv_usrstack = LINUX32_USRSTACK,
.sv_psstrings = LINUX32_PS_STRINGS,
+ .sv_psstringssz = sizeof(struct linux32_ps_strings),
.sv_stackprot = VM_PROT_ALL,
.sv_copyout_auxargs = linux_copyout_auxargs,
.sv_copyout_strings = linux_copyout_strings,
@@ -1001,6 +938,12 @@ linux_exec_sysvec_init(void *param)
*ktsc_selector = linux_vdso_tsc_selector_idx();
if (bootverbose)
printf("Linux i386 vDSO tsc_selector: %u\n", *ktsc_selector);
+
+ tkoff = kern_cpu_selector - linux_vdso_base;
+ ktsc_selector = (l_uintptr_t *)(linux_vdso_mapping + tkoff);
+ *ktsc_selector = linux_vdso_cpu_selector_idx();
+ if (bootverbose)
+ printf("Linux i386 vDSO cpu_selector: %u\n", *ktsc_selector);
}
SYSINIT(elf_linux_exec_sysvec_init, SI_SUB_EXEC + 1, SI_ORDER_ANY,
linux_exec_sysvec_init, &elf_linux_sysvec);
diff --git a/sys/amd64/linux32/linux32_vdso.lds.s b/sys/amd64/linux32/linux32_vdso.lds.s
index 0a392e6380b6..6b47a120847e 100644
--- a/sys/amd64/linux32/linux32_vdso.lds.s
+++ b/sys/amd64/linux32/linux32_vdso.lds.s
@@ -58,6 +58,7 @@ VERSION
__vdso_clock_gettime;
__vdso_gettimeofday;
__vdso_time;
+ __vdso_getcpu;
__vdso_clock_getres;
__vdso_clock_gettime64;
};
@@ -75,6 +76,9 @@ VERSION
linux_platform;
kern_timekeep_base;
kern_tsc_selector;
+ kern_cpu_selector;
+ linux32_vdso_sigcode;
+ linux32_vdso_rt_sigcode;
local: *;
};
}
diff --git a/sys/amd64/linux32/linux32_vdso_gtod.c b/sys/amd64/linux32/linux32_vdso_gtod.c
index 0caf787c9503..4f9892af3fa5 100644
--- a/sys/amd64/linux32/linux32_vdso_gtod.c
+++ b/sys/amd64/linux32/linux32_vdso_gtod.c
@@ -38,8 +38,9 @@ __FBSDID("$FreeBSD$");
#undef _KERNEL
#include <stdbool.h>
-#include <machine/atomic.h>
-#include <machine/stdarg.h>
+#include <i386/include/atomic.h>
+#include <i386/include/cpufunc.h>
+#include <i386/include/stdarg.h>
#include <amd64/linux32/linux.h>
#include <amd64/linux32/linux32_syscall.h>
@@ -49,8 +50,10 @@ __FBSDID("$FreeBSD$");
/* The kernel fixup this at vDSO install */
uintptr_t *kern_timekeep_base = NULL;
uint32_t kern_tsc_selector = 0;
+uint32_t kern_cpu_selector = 0;
#include <x86/linux/linux_vdso_gettc_x86.inc>
+#include <x86/linux/linux_vdso_getcpu_x86.inc>
static int
write(int fd, const void *buf, size_t size)
@@ -128,6 +131,21 @@ __vdso_clock_getres_fallback(clockid_t clock_id, struct l_timespec *ts)
}
static int
+__vdso_getcpu_fallback(uint32_t *cpu, uint32_t *node, void *cache)
+{
+ int res;
+
+ __asm__ __volatile__
+ (
+ "int $0x80"
+ : "=a"(res)
+ : "a"(LINUX32_SYS_linux_getcpu), "D"(cpu), "S"(node), "d"(cache)
+ : "cc", "memory"
+ );
+ return (res);
+}
+
+static int
__vdso_time_fallback(long *tm)
{
int res;
diff --git a/sys/amd64/linux32/syscalls.conf b/sys/amd64/linux32/syscalls.conf
index 7d096b5a9c64..ce9a437e82e3 100644
--- a/sys/amd64/linux32/syscalls.conf
+++ b/sys/amd64/linux32/syscalls.conf
@@ -9,3 +9,4 @@ syscallprefix="LINUX32_SYS_"
switchname="linux32_sysent"
namesname="linux32_syscallnames"
systrace="linux32_systrace_args.c"
+compat_set=""
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
index 9d55fb1ade48..935f44d5b34f 100644
--- a/sys/amd64/linux32/syscalls.master
+++ b/sys/amd64/linux32/syscalls.master
@@ -912,10 +912,10 @@
172 AUE_PRCTL STD {
int linux_prctl(
l_int option,
- l_int arg2,
- l_int arg3,
- l_int arg4,
- l_int arg5
+ l_uintptr_t arg2,
+ l_uintptr_t arg3,
+ l_uintptr_t arg4,
+ l_uintptr_t arg5
);
}
173 AUE_NULL STD {
@@ -2265,7 +2265,12 @@
int linux_io_pgetevents(void);
}
386 AUE_NULL STD {
- int linux_rseq(void);
+ int linux_rseq(
+ struct linux_rseq *rseq,
+ uint32_t rseq_len,
+ l_int flags,
+ uint32_t sig
+ );
}
387-392 AUE_NULL UNIMPL nosys
393 AUE_NULL STD {
@@ -2370,16 +2375,32 @@
);
}
408 AUE_NULL STD {
- int linux_timer_gettime64(void);
+ int linux_timer_gettime64(
+ l_timer_t timerid,
+ struct l_itimerspec64 *setting
+ );
}
409 AUE_NULL STD {
- int linux_timer_settime64(void);
+ int linux_timer_settime64(
+ l_timer_t timerid,
+ l_int flags,
+ const struct l_itimerspec64 *new,
+ struct l_itimerspec64 *old
+ );
}
410 AUE_NULL STD {
- int linux_timerfd_gettime64(void);
+ int linux_timerfd_gettime64(
+ l_int fd,
+ struct l_itimerspec64 *old_value
+ );
}
411 AUE_NULL STD {
- int linux_timerfd_settime64(void);
+ int linux_timerfd_settime64(
+ l_int fd,
+ l_int flags,
+ const struct l_itimerspec64 *new_value,
+ struct l_itimerspec64 *old_value
+ );
}
412 AUE_NULL STD {
int linux_utimensat_time64(
@@ -2403,7 +2424,7 @@
int linux_ppoll_time64(
struct pollfd *fds,
uint32_t nfds,
- struct l_timespec *tsp,
+ struct l_timespec64 *tsp,
l_sigset_t *sset,
l_size_t ssize
);
@@ -2413,7 +2434,13 @@
int linux_io_pgetevents_time64(void);
}
417 AUE_NULL STD {
- int linux_recvmmsg_time64(void);
+ int linux_recvmmsg_time64(
+ l_int s,
+ struct l_mmsghdr *msg,
+ l_uint vlen,
+ l_uint flags,
+ struct l_timespec64 *timeout
+ );
}
418 AUE_NULL STD {
int linux_mq_timedsend_time64(void);
@@ -2422,7 +2449,12 @@
int linux_mq_timedreceive_time64(void);
}
420 AUE_NULL STD {
- int linux_semtimedop_time64(void);
+ int linux_semtimedop_time64(
+ l_int semid,
+ struct sembuf *tsops,
+ l_size_t nsops,
+ struct l_timespec64 *timeout
+ );
}
421 AUE_NULL STD {
int linux_rt_sigtimedwait_time64(
@@ -2442,8 +2474,11 @@
uint32_t val3
);
}
-423 AUE_NULL STD {
- int linux_sched_rr_get_interval_time64(void);
+423 AUE_SCHED_RR_GET_INTERVAL STD {
+ int linux_sched_rr_get_interval_time64(
+ l_pid_t pid,
+ struct l_timespec64 *interval
+ );
}
424 AUE_NULL STD {
int linux_pidfd_send_signal(
@@ -2510,7 +2545,14 @@
int linux_process_madvise(void);
}
441 AUE_NULL STD {
- int linux_epoll_pwait2(void);
+ int linux_epoll_pwait2_64(
+ l_int epfd,
+ struct epoll_event *events,
+ l_int maxevents,
+ struct l_timespec64 *timeout,
+ l_sigset_t *mask,
+ l_size_t sigsetsize
+ );
}
442 AUE_NULL STD {
int linux_mount_setattr(void);
diff --git a/sys/amd64/sgx/sgx.c b/sys/amd64/sgx/sgx.c
index 283e13bd0e7c..1c0d9a051990 100644
--- a/sys/amd64/sgx/sgx.c
+++ b/sys/amd64/sgx/sgx.c
@@ -236,7 +236,6 @@ sgx_va_slot_init(struct sgx_softc *sc,
uint64_t va_page_idx;
uint64_t idx;
vm_object_t object;
- int va_slot;
int ret;
object = enclave->object;
@@ -245,7 +244,6 @@ sgx_va_slot_init(struct sgx_softc *sc,
pidx = OFF_TO_IDX(addr);
- va_slot = pidx % SGX_VA_PAGE_SLOTS;
va_page_idx = pidx / SGX_VA_PAGE_SLOTS;
idx = - SGX_VA_PAGES_OFFS - va_page_idx;
diff --git a/sys/amd64/vmm/amd/amdiommu.c b/sys/amd64/vmm/amd/amdiommu.c
index 8dceb1aa241b..6b4349d1c160 100644
--- a/sys/amd64/vmm/amd/amdiommu.c
+++ b/sys/amd64/vmm/amd/amdiommu.c
@@ -178,8 +178,6 @@ ivhd_teardown_intr(device_t dev)
return (0);
}
-static devclass_t amdiommu_devclass;
-
/* This driver has to be loaded before ivhd */
-DRIVER_MODULE(amdiommu, pci, amdiommu_driver, amdiommu_devclass, 0, 0);
+DRIVER_MODULE(amdiommu, pci, amdiommu_driver, 0, 0);
MODULE_DEPEND(amdiommu, pci, 1, 1, 1);
diff --git a/sys/amd64/vmm/amd/amdvi_hw.c b/sys/amd64/vmm/amd/amdvi_hw.c
index 57386b6bea88..87270b24c9f6 100644
--- a/sys/amd64/vmm/amd/amdvi_hw.c
+++ b/sys/amd64/vmm/amd/amdvi_hw.c
@@ -423,7 +423,7 @@ amdvi_cmd_inv_intr_map(struct amdvi_softc *softc,
static void
amdvi_inv_domain(struct amdvi_softc *softc, uint16_t domain_id)
{
- struct amdvi_cmd *cmd;
+ struct amdvi_cmd *cmd __diagused;
cmd = amdvi_get_cmd_tail(softc);
KASSERT(cmd != NULL, ("Cmd is NULL"));
@@ -444,13 +444,14 @@ amdvi_inv_domain(struct amdvi_softc *softc, uint16_t domain_id)
static bool
amdvi_cmp_wait(struct amdvi_softc *softc)
{
- struct amdvi_ctrl *ctrl;
+#ifdef AMDVI_DEBUG_CMD
+ struct amdvi_ctrl *ctrl = softc->ctrl;
+#endif
const uint64_t VERIFY = 0xA5A5;
volatile uint64_t *read;
int i;
bool status;
- ctrl = softc->ctrl;
read = &softc->cmp_data;
*read = 0;
amdvi_cmd_cmp(softc, VERIFY);
diff --git a/sys/amd64/vmm/amd/ivrs_drv.c b/sys/amd64/vmm/amd/ivrs_drv.c
index a0b332e297b1..574c70cad383 100644
--- a/sys/amd64/vmm/amd/ivrs_drv.c
+++ b/sys/amd64/vmm/amd/ivrs_drv.c
@@ -754,12 +754,9 @@ static driver_t ivhd_driver = {
sizeof(struct amdvi_softc),
};
-static devclass_t ivhd_devclass;
-
/*
* Load this module at the end after PCI re-probing to configure interrupt.
*/
-DRIVER_MODULE_ORDERED(ivhd, acpi, ivhd_driver, ivhd_devclass, 0, 0,
- SI_ORDER_ANY);
+DRIVER_MODULE_ORDERED(ivhd, acpi, ivhd_driver, 0, 0, SI_ORDER_ANY);
MODULE_DEPEND(ivhd, acpi, 1, 1, 1);
MODULE_DEPEND(ivhd, pci, 1, 1, 1);
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index fbf11ec84084..57e941fc6145 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -351,7 +351,7 @@ svm_msr_index(uint64_t msr, int *index, int *bit)
static void
svm_msr_perm(uint8_t *perm_bitmap, uint64_t msr, bool read, bool write)
{
- int index, bit, error;
+ int index, bit, error __diagused;
error = svm_msr_index(msr, &index, &bit);
KASSERT(error == 0, ("%s: invalid msr %#lx", __func__, msr));
@@ -654,7 +654,7 @@ svm_vcpu_mode(struct vmcb *vmcb)
{
struct vmcb_segment seg;
struct vmcb_state *state;
- int error;
+ int error __diagused;
state = &vmcb->state;
@@ -719,7 +719,7 @@ static void
svm_inout_str_seginfo(struct svm_softc *svm_sc, int vcpu, int64_t info1,
int in, struct vm_inout_str *vis)
{
- int error, s;
+ int error __diagused, s;
if (in) {
vis->seg_name = VM_REG_GUEST_ES;
@@ -858,7 +858,7 @@ svm_handle_inst_emul(struct vmcb *vmcb, uint64_t gpa, struct vm_exit *vmexit)
struct vmcb_segment seg;
struct vmcb_ctrl *ctrl;
char *inst_bytes;
- int error, inst_len;
+ int error __diagused, inst_len;
ctrl = &vmcb->ctrl;
paging = &vmexit->u.inst_emul.paging;
@@ -1113,7 +1113,7 @@ enable_nmi_blocking(struct svm_softc *sc, int vcpu)
static void
clear_nmi_blocking(struct svm_softc *sc, int vcpu)
{
- int error;
+ int error __diagused;
KASSERT(nmi_blocked(sc, vcpu), ("vNMI already unblocked"));
VCPU_CTR0(sc->vm, vcpu, "vNMI blocking cleared");
@@ -1146,7 +1146,7 @@ svm_write_efer(struct svm_softc *sc, int vcpu, uint64_t newval, bool *retu)
struct vm_exit *vme;
struct vmcb_state *state;
uint64_t changed, lma, oldval;
- int error;
+ int error __diagused;
state = svm_get_vmcb_state(sc, vcpu);
@@ -1328,7 +1328,7 @@ svm_vmexit(struct svm_softc *svm_sc, int vcpu, struct vm_exit *vmexit)
struct svm_regctx *ctx;
uint64_t code, info1, info2, val;
uint32_t eax, ecx, edx;
- int error, errcode_valid, handled, idtvec, reflect;
+ int error __diagused, errcode_valid, handled, idtvec, reflect;
bool retu;
ctx = svm_get_guest_regctx(svm_sc, vcpu);
@@ -2554,7 +2554,6 @@ done:
static int
svm_vmcx_snapshot(void *arg, struct vm_snapshot_meta *meta, int vcpu)
{
- struct vmcb *vmcb;
struct svm_softc *sc;
int err, running, hostcpu;
@@ -2562,7 +2561,6 @@ svm_vmcx_snapshot(void *arg, struct vm_snapshot_meta *meta, int vcpu)
err = 0;
KASSERT(arg != NULL, ("%s: arg was NULL", __func__));
- vmcb = svm_get_vmcb(sc, vcpu);
running = vcpu_is_running(sc->vm, vcpu, &hostcpu);
if (running && hostcpu !=curcpu) {
diff --git a/sys/amd64/vmm/amd/svm_msr.c b/sys/amd64/vmm/amd/svm_msr.c
index 12046de4dbb9..1a22f16cf48e 100644
--- a/sys/amd64/vmm/amd/svm_msr.c
+++ b/sys/amd64/vmm/amd/svm_msr.c
@@ -120,9 +120,14 @@ svm_rdmsr(struct svm_softc *sc, int vcpu, u_int num, uint64_t *result,
break;
case MSR_MTRRcap:
case MSR_MTRRdefType:
- case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
case MSR_MTRR64kBase:
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1:
+ if (vm_rdmtrr(&sc->mtrr[vcpu], num, result) != 0) {
+ vm_inject_gp(sc->vm, vcpu);
+ }
+ break;
case MSR_SYSCFG:
case MSR_AMDK8_IPM:
case MSR_EXTFEATURES:
@@ -146,12 +151,15 @@ svm_wrmsr(struct svm_softc *sc, int vcpu, u_int num, uint64_t val, bool *retu)
case MSR_MCG_STATUS:
break; /* ignore writes */
case MSR_MTRRcap:
- vm_inject_gp(sc->vm, vcpu);
- break;
case MSR_MTRRdefType:
- case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
case MSR_MTRR64kBase:
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1:
+ if (vm_wrmtrr(&sc->mtrr[vcpu], num, val) != 0) {
+ vm_inject_gp(sc->vm, vcpu);
+ }
+ break;
case MSR_SYSCFG:
break; /* Ignore writes */
case MSR_AMDK8_IPM:
diff --git a/sys/amd64/vmm/amd/svm_softc.h b/sys/amd64/vmm/amd/svm_softc.h
index 8735353bb472..5f6a267617d2 100644
--- a/sys/amd64/vmm/amd/svm_softc.h
+++ b/sys/amd64/vmm/amd/svm_softc.h
@@ -31,6 +31,8 @@
#ifndef _SVM_SOFTC_H_
#define _SVM_SOFTC_H_
+#include "x86.h"
+
#define SVM_IO_BITMAP_SIZE (3 * PAGE_SIZE)
#define SVM_MSR_BITMAP_SIZE (2 * PAGE_SIZE)
@@ -64,6 +66,7 @@ struct svm_softc {
uint8_t *iopm_bitmap; /* shared by all vcpus */
uint8_t *msr_bitmap; /* shared by all vcpus */
struct vm *vm;
+ struct vm_mtrr mtrr[VM_MAXCPU];
};
CTASSERT((offsetof(struct svm_softc, nptp) & PAGE_MASK) == 0);
diff --git a/sys/amd64/vmm/intel/vmcs.h b/sys/amd64/vmm/intel/vmcs.h
index 8aa7b1e8fc08..5c5214c65609 100644
--- a/sys/amd64/vmm/intel/vmcs.h
+++ b/sys/amd64/vmm/intel/vmcs.h
@@ -76,7 +76,7 @@ int vmcs_snapshot_any(struct vmcs *vmcs, int running, int ident,
static __inline uint64_t
vmcs_read(uint32_t encoding)
{
- int error;
+ int error __diagused;
uint64_t val;
error = vmread(encoding, &val);
@@ -87,7 +87,7 @@ vmcs_read(uint32_t encoding)
static __inline void
vmcs_write(uint32_t encoding, uint64_t val)
{
- int error;
+ int error __diagused;
error = vmwrite(encoding, val);
KASSERT(error == 0, ("vmcs_write(%u) error %d", encoding, error));
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index e7ced1b2c3fa..72ff227587aa 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -1389,7 +1389,7 @@ vmx_set_tsc_offset(struct vmx *vmx, int vcpu, uint64_t offset)
static void
vmx_inject_nmi(struct vmx *vmx, int vcpu)
{
- uint32_t gi, info;
+ uint32_t gi __diagused, info;
gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
KASSERT((gi & NMI_BLOCKING) == 0, ("vmx_inject_nmi: invalid guest "
@@ -1634,7 +1634,7 @@ vmx_clear_nmi_blocking(struct vmx *vmx, int vcpuid)
static void
vmx_assert_nmi_blocking(struct vmx *vmx, int vcpuid)
{
- uint32_t gi;
+ uint32_t gi __diagused;
gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
KASSERT(gi & VMCS_INTERRUPTIBILITY_NMI_BLOCKING,
@@ -1958,7 +1958,7 @@ static uint64_t
inout_str_index(struct vmx *vmx, int vcpuid, int in)
{
uint64_t val;
- int error;
+ int error __diagused;
enum vm_reg_name reg;
reg = in ? VM_REG_GUEST_RDI : VM_REG_GUEST_RSI;
@@ -1971,7 +1971,7 @@ static uint64_t
inout_str_count(struct vmx *vmx, int vcpuid, int rep)
{
uint64_t val;
- int error;
+ int error __diagused;
if (rep) {
error = vmx_getreg(vmx, vcpuid, VM_REG_GUEST_RCX, &val);
@@ -2004,7 +2004,7 @@ static void
inout_str_seginfo(struct vmx *vmx, int vcpuid, uint32_t inst_info, int in,
struct vm_inout_str *vis)
{
- int error, s;
+ int error __diagused, s;
if (in) {
vis->seg_name = VM_REG_GUEST_ES;
@@ -3860,7 +3860,7 @@ vmx_enable_x2apic_mode_vid(struct vlapic *vlapic)
struct vmx *vmx;
struct vmcs *vmcs;
uint32_t proc_ctls2;
- int vcpuid, error;
+ int vcpuid, error __diagused;
vcpuid = vlapic->vcpuid;
vmx = ((struct vlapic_vtx *)vlapic)->vmx;
diff --git a/sys/amd64/vmm/intel/vmx.h b/sys/amd64/vmm/intel/vmx.h
index 57499a3a6869..81e508e30d3d 100644
--- a/sys/amd64/vmm/intel/vmx.h
+++ b/sys/amd64/vmm/intel/vmx.h
@@ -32,6 +32,7 @@
#define _VMX_H_
#include "vmcs.h"
+#include "x86.h"
struct pmap;
@@ -134,6 +135,7 @@ struct vmx {
uint64_t eptp;
struct vm *vm;
long eptgen[MAXCPU]; /* cached pmap->pm_eptgen */
+ struct vm_mtrr mtrr[VM_MAXCPU];
};
CTASSERT((offsetof(struct vmx, vmcs) & PAGE_MASK) == 0);
CTASSERT((offsetof(struct vmx, msr_bitmap) & PAGE_MASK) == 0);
diff --git a/sys/amd64/vmm/intel/vmx_msr.c b/sys/amd64/vmm/intel/vmx_msr.c
index db9e659bab5b..a135518cb1c3 100644
--- a/sys/amd64/vmm/intel/vmx_msr.c
+++ b/sys/amd64/vmm/intel/vmx_msr.c
@@ -425,10 +425,13 @@ vmx_rdmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t *val, bool *retu)
break;
case MSR_MTRRcap:
case MSR_MTRRdefType:
- case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
case MSR_MTRR64kBase:
- *val = 0;
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1:
+ if (vm_rdmtrr(&vmx->mtrr[vcpuid], num, val) != 0) {
+ vm_inject_gp(vmx->vm, vcpuid);
+ }
break;
case MSR_IA32_MISC_ENABLE:
*val = misc_enable;
@@ -465,13 +468,15 @@ vmx_wrmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t val, bool *retu)
case MSR_MCG_STATUS:
break; /* ignore writes */
case MSR_MTRRcap:
- vm_inject_gp(vmx->vm, vcpuid);
- break;
case MSR_MTRRdefType:
- case MSR_MTRR4kBase ... MSR_MTRR4kBase + 8:
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
case MSR_MTRR64kBase:
- break; /* Ignore writes */
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1:
+ if (vm_wrmtrr(&vmx->mtrr[vcpuid], num, val) != 0) {
+ vm_inject_gp(vmx->vm, vcpuid);
+ }
+ break;
case MSR_IA32_MISC_ENABLE:
changed = val ^ misc_enable;
/*
diff --git a/sys/amd64/vmm/io/ppt.c b/sys/amd64/vmm/io/ppt.c
index a936326e8df3..6bcd8f78bbab 100644
--- a/sys/amd64/vmm/io/ppt.c
+++ b/sys/amd64/vmm/io/ppt.c
@@ -195,9 +195,8 @@ static device_method_t ppt_methods[] = {
{0, 0}
};
-static devclass_t ppt_devclass;
DEFINE_CLASS_0(ppt, ppt_driver, ppt_methods, sizeof(struct pptdev));
-DRIVER_MODULE(ppt, pci, ppt_driver, ppt_devclass, NULL, NULL);
+DRIVER_MODULE(ppt, pci, ppt_driver, NULL, NULL);
static int
ppt_find(struct vm *vm, int bus, int slot, int func, struct pptdev **pptp)
diff --git a/sys/amd64/vmm/io/vlapic.c b/sys/amd64/vmm/io/vlapic.c
index 940e45cce458..9599b4b4e62c 100644
--- a/sys/amd64/vmm/io/vlapic.c
+++ b/sys/amd64/vmm/io/vlapic.c
@@ -201,7 +201,7 @@ static uint32_t
vlapic_get_ccr(struct vlapic *vlapic)
{
struct bintime bt_now, bt_rem;
- struct LAPIC *lapic;
+ struct LAPIC *lapic __diagused;
uint32_t ccr;
ccr = 0;
@@ -1740,10 +1740,13 @@ vlapic_snapshot(struct vm *vm, struct vm_snapshot_meta *meta)
SNAPSHOT_VAR_OR_LEAVE(ccr, meta, ret, done);
- if (meta->op == VM_SNAPSHOT_RESTORE) {
+ if (meta->op == VM_SNAPSHOT_RESTORE &&
+ vlapic_enabled(vlapic) && lapic->icr_timer != 0) {
/* Reset the value of the 'timer_fire_bt' and the vlapic
* callout based on the value of the current count
- * register saved when the VM snapshot was created
+ * register saved when the VM snapshot was created.
+ * If initial count register is 0, timer is not used.
+ * Look at "10.5.4 APIC Timer" in Software Developer Manual.
*/
vlapic_reset_callout(vlapic, ccr);
}
diff --git a/sys/amd64/vmm/io/vrtc.c b/sys/amd64/vmm/io/vrtc.c
index 5d6968e3583e..65b2cd2cb39f 100644
--- a/sys/amd64/vmm/io/vrtc.c
+++ b/sys/amd64/vmm/io/vrtc.c
@@ -285,12 +285,13 @@ rtc_to_secs(struct vrtc *vrtc)
struct clocktime ct;
struct timespec ts;
struct rtcdev *rtc;
- struct vm *vm;
+#ifdef KTR
+ struct vm *vm = vrtc->vm;
+#endif
int century, error, hour, pm, year;
KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
- vm = vrtc->vm;
rtc = &vrtc->rtcdev;
bzero(&ct, sizeof(struct clocktime));
@@ -401,7 +402,6 @@ static int
vrtc_time_update(struct vrtc *vrtc, time_t newtime, sbintime_t newbase)
{
struct rtcdev *rtc;
- sbintime_t oldbase;
time_t oldtime;
uint8_t alarm_sec, alarm_min, alarm_hour;
@@ -416,9 +416,8 @@ vrtc_time_update(struct vrtc *vrtc, time_t newtime, sbintime_t newbase)
VM_CTR2(vrtc->vm, "Updating RTC secs from %#lx to %#lx",
oldtime, newtime);
- oldbase = vrtc->base_uptime;
VM_CTR2(vrtc->vm, "Updating RTC base uptime from %#lx to %#lx",
- oldbase, newbase);
+ vrtc->base_uptime, newbase);
vrtc->base_uptime = newbase;
if (newtime == oldtime)
@@ -545,7 +544,7 @@ vrtc_callout_handler(void *arg)
struct vrtc *vrtc = arg;
sbintime_t freqsbt, basetime;
time_t rtctime;
- int error;
+ int error __diagused;
VM_CTR0(vrtc->vm, "vrtc callout fired");
@@ -581,7 +580,7 @@ done:
static __inline void
vrtc_callout_check(struct vrtc *vrtc, sbintime_t freq)
{
- int active;
+ int active __diagused;
active = callout_active(&vrtc->callout) ? 1 : 0;
KASSERT((freq == 0 && !active) || (freq != 0 && active),
@@ -633,7 +632,7 @@ vrtc_set_reg_b(struct vrtc *vrtc, uint8_t newval)
struct rtcdev *rtc;
sbintime_t oldfreq, newfreq, basetime;
time_t curtime, rtctime;
- int error;
+ int error __diagused;
uint8_t oldval, changed;
KASSERT(VRTC_LOCKED(vrtc), ("%s: vrtc not locked", __func__));
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index 80fcde8d80fa..45125cb92a7e 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -134,7 +134,7 @@ struct mem_seg {
bool sysmem;
struct vm_object *object;
};
-#define VM_MAX_MEMSEGS 3
+#define VM_MAX_MEMSEGS 4
struct mem_map {
vm_paddr_t gpa;
@@ -854,7 +854,7 @@ static void
vm_free_memmap(struct vm *vm, int ident)
{
struct mem_map *mm;
- int error;
+ int error __diagused;
mm = &vm->mem_maps[ident];
if (mm->len) {
@@ -938,10 +938,8 @@ vm_iommu_modify(struct vm *vm, bool map)
hpa = DMAP_TO_PHYS((uintptr_t)vp);
if (map) {
iommu_create_mapping(vm->iommu, gpa, hpa, sz);
- iommu_remove_mapping(host_domain, hpa, sz);
} else {
iommu_remove_mapping(vm->iommu, gpa, sz);
- iommu_create_mapping(host_domain, hpa, hpa, sz);
}
gpa += PAGE_SIZE;
@@ -1304,7 +1302,7 @@ vm_handle_rendezvous(struct vm *vm, int vcpuid)
mtx_lock(&vm->rendezvous_mtx);
while (vm->rendezvous_func != NULL) {
/* 'rendezvous_req_cpus' must be a subset of 'active_cpus' */
- CPU_AND(&vm->rendezvous_req_cpus, &vm->active_cpus);
+ CPU_AND(&vm->rendezvous_req_cpus, &vm->rendezvous_req_cpus, &vm->active_cpus);
if (vcpuid != -1 &&
CPU_ISSET(vcpuid, &vm->rendezvous_req_cpus) &&
@@ -1827,7 +1825,7 @@ vm_restart_instruction(void *arg, int vcpuid)
struct vcpu *vcpu;
enum vcpu_state state;
uint64_t rip;
- int error;
+ int error __diagused;
vm = arg;
if (vcpuid < 0 || vcpuid >= vm->maxcpus)
@@ -2066,7 +2064,7 @@ vm_inject_exception(struct vm *vm, int vcpuid, int vector, int errcode_valid,
{
struct vcpu *vcpu;
uint64_t regval;
- int error;
+ int error __diagused;
if (vcpuid < 0 || vcpuid >= vm->maxcpus)
return (EINVAL);
@@ -2126,7 +2124,7 @@ vm_inject_fault(void *vmarg, int vcpuid, int vector, int errcode_valid,
int errcode)
{
struct vm *vm;
- int error, restart_instruction;
+ int error __diagused, restart_instruction;
vm = vmarg;
restart_instruction = 1;
@@ -2140,7 +2138,7 @@ void
vm_inject_pf(void *vmarg, int vcpuid, int error_code, uint64_t cr2)
{
struct vm *vm;
- int error;
+ int error __diagused;
vm = vmarg;
VCPU_CTR2(vm, vcpuid, "Injecting page fault: error_code %#x, cr2 %#lx",
diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
index 2ce9470cf6dd..db8563c91830 100644
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -69,6 +69,18 @@ __FBSDID("$FreeBSD$");
#include "io/vhpet.h"
#include "io/vrtc.h"
+#ifdef COMPAT_FREEBSD13
+struct vm_stats_old {
+ int cpuid; /* in */
+ int num_entries; /* out */
+ struct timeval tv;
+ uint64_t statbuf[MAX_VM_STATS];
+};
+
+#define VM_STATS_OLD \
+ _IOWR('v', IOCNUM_VM_STATS, struct vm_stats_old)
+#endif
+
struct devmem_softc {
int segid;
char *name;
@@ -376,6 +388,9 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
struct vm_pptdev_msi *pptmsi;
struct vm_pptdev_msix *pptmsix;
struct vm_nmi *vmnmi;
+#ifdef COMPAT_FREEBSD13
+ struct vm_stats_old *vmstats_old;
+#endif
struct vm_stats *vmstats;
struct vm_stat_desc *statdesc;
struct vm_x2apic *x2apic;
@@ -501,11 +516,21 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
statdesc->desc, sizeof(statdesc->desc));
break;
}
+#ifdef COMPAT_FREEBSD13
+ case VM_STATS_OLD:
+ vmstats_old = (struct vm_stats_old *)data;
+ getmicrotime(&vmstats_old->tv);
+ error = vmm_stat_copy(sc->vm, vmstats_old->cpuid, 0,
+ nitems(vmstats_old->statbuf),
+ &vmstats_old->num_entries,
+ vmstats_old->statbuf);
+ break;
+#endif
case VM_STATS: {
- CTASSERT(MAX_VM_STATS >= MAX_VMM_STAT_ELEMS);
vmstats = (struct vm_stats *)data;
getmicrotime(&vmstats->tv);
- error = vmm_stat_copy(sc->vm, vmstats->cpuid,
+ error = vmm_stat_copy(sc->vm, vmstats->cpuid, vmstats->index,
+ nitems(vmstats->statbuf),
&vmstats->num_entries, vmstats->statbuf);
break;
}
@@ -968,7 +993,7 @@ vmmdev_destroy(void *arg)
{
struct vmmdev_softc *sc = arg;
struct devmem_softc *dsc;
- int error;
+ int error __diagused;
error = vcpu_lock_all(sc);
KASSERT(error == 0, ("%s: error %d freezing vcpus", __func__, error));
@@ -1027,10 +1052,7 @@ sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
}
/*
- * The 'cdev' will be destroyed asynchronously when 'si_threadcount'
- * goes down to 0 so we should not do it again in the callback.
- *
- * Setting 'sc->cdev' to NULL is also used to indicate that the VM
+ * Setting 'sc->cdev' to NULL is used to indicate that the VM
* is scheduled for destruction.
*/
cdev = sc->cdev;
@@ -1038,21 +1060,19 @@ sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
mtx_unlock(&vmmdev_mtx);
/*
- * Schedule all cdevs to be destroyed:
+ * Destroy all cdevs:
*
* - any new operations on the 'cdev' will return an error (ENXIO).
*
- * - when the 'si_threadcount' dwindles down to zero the 'cdev' will
- * be destroyed and the callback will be invoked in a taskqueue
- * context.
- *
* - the 'devmem' cdevs are destroyed before the virtual machine 'cdev'
*/
SLIST_FOREACH(dsc, &sc->devmem, link) {
KASSERT(dsc->cdev != NULL, ("devmem cdev already destroyed"));
- destroy_dev_sched_cb(dsc->cdev, devmem_destroy, dsc);
+ destroy_dev(dsc->cdev);
+ devmem_destroy(dsc);
}
- destroy_dev_sched_cb(cdev, vmmdev_destroy, sc);
+ destroy_dev(cdev);
+ vmmdev_destroy(sc);
error = 0;
out:
diff --git a/sys/amd64/vmm/vmm_instruction_emul.c b/sys/amd64/vmm/vmm_instruction_emul.c
index ae022210893c..06dffe6a80b9 100644
--- a/sys/amd64/vmm/vmm_instruction_emul.c
+++ b/sys/amd64/vmm/vmm_instruction_emul.c
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <strings.h>
#include <vmmapi.h>
+#define __diagused
#define KASSERT(exp,msg) assert((exp))
#define panic(...) errx(4, __VA_ARGS__)
#endif /* _KERNEL */
@@ -717,7 +718,7 @@ get_gla(void *vm, int vcpuid, struct vie *vie, struct vm_guest_paging *paging,
{
struct seg_desc desc;
uint64_t cr0, val, rflags;
- int error;
+ int error __diagused;
error = vie_read_register(vm, vcpuid, VM_REG_GUEST_CR0, &cr0);
KASSERT(error == 0, ("%s: error %d getting cr0", __func__, error));
diff --git a/sys/amd64/vmm/vmm_ioport.c b/sys/amd64/vmm/vmm_ioport.c
index e494bac46f23..e30f796d598c 100644
--- a/sys/amd64/vmm/vmm_ioport.c
+++ b/sys/amd64/vmm/vmm_ioport.c
@@ -157,7 +157,7 @@ emulate_inout_str(struct vm *vm, int vcpuid, struct vm_exit *vmexit, bool *retu)
int
vm_handle_inout(struct vm *vm, int vcpuid, struct vm_exit *vmexit, bool *retu)
{
- int bytes, error;
+ int bytes __diagused, error;
bytes = vmexit->u.inout.bytes;
KASSERT(bytes == 1 || bytes == 2 || bytes == 4,
diff --git a/sys/amd64/vmm/vmm_stat.c b/sys/amd64/vmm/vmm_stat.c
index 89133d4b3868..497db4452f3b 100644
--- a/sys/amd64/vmm/vmm_stat.c
+++ b/sys/amd64/vmm/vmm_stat.c
@@ -82,15 +82,29 @@ vmm_stat_register(void *arg)
}
int
-vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf)
+vmm_stat_copy(struct vm *vm, int vcpu, int index, int count, int *num_stats,
+ uint64_t *buf)
{
struct vmm_stat_type *vst;
uint64_t *stats;
- int i;
+ int i, tocopy;
if (vcpu < 0 || vcpu >= vm_get_maxcpus(vm))
return (EINVAL);
+ if (index < 0 || count < 0)
+ return (EINVAL);
+
+ if (index > vst_num_elems)
+ return (ENOENT);
+
+ if (index == vst_num_elems) {
+ *num_stats = 0;
+ return (0);
+ }
+
+ tocopy = min(vst_num_elems - index, count);
+
/* Let stats functions update their counters */
for (i = 0; i < vst_num_types; i++) {
vst = vsttab[i];
@@ -100,9 +114,8 @@ vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf)
/* Copy over the stats */
stats = vcpu_stats(vm, vcpu);
- for (i = 0; i < vst_num_elems; i++)
- buf[i] = stats[i];
- *num_stats = vst_num_elems;
+ memcpy(buf, stats + index, tocopy * sizeof(stats[0]));
+ *num_stats = tocopy;
return (0);
}
diff --git a/sys/amd64/vmm/vmm_stat.h b/sys/amd64/vmm/vmm_stat.h
index f97743e77fe7..0e9c8db8429d 100644
--- a/sys/amd64/vmm/vmm_stat.h
+++ b/sys/amd64/vmm/vmm_stat.h
@@ -87,10 +87,8 @@ void *vmm_stat_alloc(void);
void vmm_stat_init(void *vp);
void vmm_stat_free(void *vp);
-/*
- * 'buf' should be at least fit 'MAX_VMM_STAT_TYPES' entries
- */
-int vmm_stat_copy(struct vm *vm, int vcpu, int *num_stats, uint64_t *buf);
+int vmm_stat_copy(struct vm *vm, int vcpu, int index, int count,
+ int *num_stats, uint64_t *buf);
int vmm_stat_desc_copy(int index, char *buf, int buflen);
static void __inline
diff --git a/sys/amd64/vmm/x86.c b/sys/amd64/vmm/x86.c
index c43a3c870211..c97cb91af4f6 100644
--- a/sys/amd64/vmm/x86.c
+++ b/sys/amd64/vmm/x86.c
@@ -648,3 +648,85 @@ vm_cpuid_capability(struct vm *vm, int vcpuid, enum vm_cpuid_capability cap)
}
return (rv);
}
+
+int
+vm_rdmtrr(struct vm_mtrr *mtrr, u_int num, uint64_t *val)
+{
+ switch (num) {
+ case MSR_MTRRcap:
+ *val = MTRR_CAP_WC | MTRR_CAP_FIXED | VMM_MTRR_VAR_MAX;
+ break;
+ case MSR_MTRRdefType:
+ *val = mtrr->def_type;
+ break;
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
+ *val = mtrr->fixed4k[num - MSR_MTRR4kBase];
+ break;
+ case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
+ *val = mtrr->fixed16k[num - MSR_MTRR16kBase];
+ break;
+ case MSR_MTRR64kBase:
+ *val = mtrr->fixed64k;
+ break;
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1: {
+ u_int offset = num - MSR_MTRRVarBase;
+ if (offset % 2 == 0) {
+ *val = mtrr->var[offset / 2].base;
+ } else {
+ *val = mtrr->var[offset / 2].mask;
+ }
+ break;
+ }
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
+
+int
+vm_wrmtrr(struct vm_mtrr *mtrr, u_int num, uint64_t val)
+{
+ switch (num) {
+ case MSR_MTRRcap:
+ /* MTRRCAP is read only */
+ return (-1);
+ case MSR_MTRRdefType:
+ if (val & ~VMM_MTRR_DEF_MASK) {
+ /* generate #GP on writes to reserved fields */
+ return (-1);
+ }
+ mtrr->def_type = val;
+ break;
+ case MSR_MTRR4kBase ... MSR_MTRR4kBase + 7:
+ mtrr->fixed4k[num - MSR_MTRR4kBase] = val;
+ break;
+ case MSR_MTRR16kBase ... MSR_MTRR16kBase + 1:
+ mtrr->fixed16k[num - MSR_MTRR16kBase] = val;
+ break;
+ case MSR_MTRR64kBase:
+ mtrr->fixed64k = val;
+ break;
+ case MSR_MTRRVarBase ... MSR_MTRRVarBase + (VMM_MTRR_VAR_MAX * 2) - 1: {
+ u_int offset = num - MSR_MTRRVarBase;
+ if (offset % 2 == 0) {
+ if (val & ~VMM_MTRR_PHYSBASE_MASK) {
+ /* generate #GP on writes to reserved fields */
+ return (-1);
+ }
+ mtrr->var[offset / 2].base = val;
+ } else {
+ if (val & ~VMM_MTRR_PHYSMASK_MASK) {
+ /* generate #GP on writes to reserved fields */
+ return (-1);
+ }
+ mtrr->var[offset / 2].mask = val;
+ }
+ break;
+ }
+ default:
+ return (-1);
+ }
+
+ return (0);
+}
diff --git a/sys/amd64/vmm/x86.h b/sys/amd64/vmm/x86.h
index 7c8fccf78f28..318f0b5cf871 100644
--- a/sys/amd64/vmm/x86.h
+++ b/sys/amd64/vmm/x86.h
@@ -80,4 +80,24 @@ enum vm_cpuid_capability {
* and 'false' otherwise.
*/
bool vm_cpuid_capability(struct vm *vm, int vcpuid, enum vm_cpuid_capability);
+
+#define VMM_MTRR_VAR_MAX 10
+#define VMM_MTRR_DEF_MASK \
+ (MTRR_DEF_ENABLE | MTRR_DEF_FIXED_ENABLE | MTRR_DEF_TYPE)
+#define VMM_MTRR_PHYSBASE_MASK (MTRR_PHYSBASE_PHYSBASE | MTRR_PHYSBASE_TYPE)
+#define VMM_MTRR_PHYSMASK_MASK (MTRR_PHYSMASK_PHYSMASK | MTRR_PHYSMASK_VALID)
+struct vm_mtrr {
+ uint64_t def_type;
+ uint64_t fixed4k[8];
+ uint64_t fixed16k[2];
+ uint64_t fixed64k;
+ struct {
+ uint64_t base;
+ uint64_t mask;
+ } var[VMM_MTRR_VAR_MAX];
+};
+
+int vm_rdmtrr(struct vm_mtrr *mtrr, u_int num, uint64_t *val);
+int vm_wrmtrr(struct vm_mtrr *mtrr, u_int num, uint64_t val);
+
#endif