diff options
Diffstat (limited to 'sys/amd64')
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 |