180708Sjake/*- 281899Sjake * Copyright (c) 2001, Jake Burkholder 381185Sjake * Copyright (C) 1994, David Greenman 481185Sjake * Copyright (c) 1990, 1993 581185Sjake * The Regents of the University of California. All rights reserved. 681185Sjake * 781185Sjake * This code is derived from software contributed to Berkeley by 881185Sjake * the University of Utah, and William Jolitz. 981185Sjake * 1081185Sjake * Redistribution and use in source and binary forms, with or without 1181185Sjake * modification, are permitted provided that the following conditions 1281185Sjake * are met: 1381185Sjake * 1. Redistributions of source code must retain the above copyright 1481185Sjake * notice, this list of conditions and the following disclaimer. 1581185Sjake * 2. Redistributions in binary form must reproduce the above copyright 1681185Sjake * notice, this list of conditions and the following disclaimer in the 1781185Sjake * documentation and/or other materials provided with the distribution. 1881185Sjake * 4. Neither the name of the University nor the names of its contributors 1981185Sjake * may be used to endorse or promote products derived from this software 2081185Sjake * without specific prior written permission. 2181185Sjake * 2281337Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2381185Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2481185Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2581337Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2681185Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2781185Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2881185Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2981185Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3081185Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3181185Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3281185Sjake * SUCH DAMAGE. 3381185Sjake * 34181701Smarius * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 35181701Smarius * from: FreeBSD: src/sys/i386/i386/trap.c,v 1.197 2001/07/19 3680708Sjake */ 3780708Sjake 38157445Smarius#include <sys/cdefs.h> 39157445Smarius__FBSDID("$FreeBSD: stable/11/sys/sparc64/sparc64/trap.c 337061 2018-08-01 20:38:01Z jhb $"); 40157445Smarius 4180709Sjake#include "opt_ddb.h" 4282903Sjake#include "opt_ktr.h" 4380709Sjake 4480708Sjake#include <sys/param.h> 45131950Smarcel#include <sys/kdb.h> 4698037Sjake#include <sys/kernel.h> 4784849Stmm#include <sys/bus.h> 4884849Stmm#include <sys/interrupt.h> 4982903Sjake#include <sys/ktr.h> 5081135Stmm#include <sys/lock.h> 5180709Sjake#include <sys/mutex.h> 5280709Sjake#include <sys/systm.h> 53204152Smarius#include <sys/pcpu.h> 5482006Sjake#include <sys/pioctl.h> 55120965Srobert#include <sys/ptrace.h> 5680708Sjake#include <sys/proc.h> 5791783Sjake#include <sys/smp.h> 58120937Srobert#include <sys/signalvar.h> 5982006Sjake#include <sys/syscall.h> 6098037Sjake#include <sys/sysctl.h> 6181135Stmm#include <sys/sysent.h> 6282006Sjake#include <sys/vmmeter.h> 63155814Srwatson#include <security/audit/audit.h> 6480708Sjake 65182773Smarius#include <dev/ofw/openfirm.h> 66182773Smarius 6780709Sjake#include <vm/vm.h> 6881185Sjake#include <vm/pmap.h> 6981185Sjake#include <vm/vm_extern.h> 7080709Sjake#include <vm/vm_param.h> 7180709Sjake#include <vm/vm_kern.h> 7281185Sjake#include <vm/vm_map.h> 7380709Sjake#include <vm/vm_page.h> 7480709Sjake 75105939Sjake#include <machine/cpu.h> 7680708Sjake#include <machine/frame.h> 7781387Sjake#include <machine/intr_machdep.h> 78190107Smarius#include <machine/ofw_machdep.h> 79200215Smarius#include <machine/pcb.h> 8091783Sjake#include <machine/smp.h> 8180709Sjake#include <machine/trap.h> 8282006Sjake#include <machine/tstate.h> 8380709Sjake#include <machine/tte.h> 8480709Sjake#include <machine/tlb.h> 8580709Sjake#include <machine/tsb.h> 8682006Sjake#include <machine/watch.h> 8780708Sjake 8880709Sjakevoid trap(struct trapframe *tf); 8984186Sjakevoid syscall(struct trapframe *tf); 9080708Sjake 91206086Smariusstatic int trap_cecc(void); 9288642Sjakestatic int trap_pfault(struct thread *td, struct trapframe *tf); 9382903Sjake 94101955Sjakeextern char copy_fault[]; 95101955Sjakeextern char copy_nofault_begin[]; 96101955Sjakeextern char copy_nofault_end[]; 9784186Sjake 98101955Sjakeextern char fs_fault[]; 99101955Sjakeextern char fs_nofault_begin[]; 100101955Sjakeextern char fs_nofault_end[]; 101101955Sjakeextern char fs_nofault_intr_begin[]; 102101955Sjakeextern char fs_nofault_intr_end[]; 103101955Sjake 104116659Sjmgextern char fas_fault[]; 105116659Sjmgextern char fas_nofault_begin[]; 106116659Sjmgextern char fas_nofault_end[]; 107116659Sjmg 108190107Smariusconst char *const trap_msg[] = { 10980709Sjake "reserved", 11080709Sjake "instruction access exception", 11180709Sjake "instruction access error", 11288642Sjake "instruction access protection", 11388642Sjake "illtrap instruction", 11480709Sjake "illegal instruction", 11580709Sjake "privileged opcode", 11680709Sjake "floating point disabled", 11780709Sjake "floating point exception ieee 754", 11880709Sjake "floating point exception other", 11980709Sjake "tag overflow", 12080709Sjake "division by zero", 12180709Sjake "data access exception", 12280709Sjake "data access error", 12388642Sjake "data access protection", 12480709Sjake "memory address not aligned", 12580709Sjake "privileged action", 12688642Sjake "async data error", 12788642Sjake "trap instruction 16", 12888642Sjake "trap instruction 17", 12988642Sjake "trap instruction 18", 13088642Sjake "trap instruction 19", 13188642Sjake "trap instruction 20", 13288642Sjake "trap instruction 21", 13388642Sjake "trap instruction 22", 13488642Sjake "trap instruction 23", 13588642Sjake "trap instruction 24", 13688642Sjake "trap instruction 25", 13788642Sjake "trap instruction 26", 13888642Sjake "trap instruction 27", 13988642Sjake "trap instruction 28", 14088642Sjake "trap instruction 29", 14188642Sjake "trap instruction 30", 14288642Sjake "trap instruction 31", 143114650Sjake "fast instruction access mmu miss", 144114650Sjake "fast data access mmu miss", 14588642Sjake "interrupt", 14680709Sjake "physical address watchpoint", 14780709Sjake "virtual address watchpoint", 14880709Sjake "corrected ecc error", 14982903Sjake "spill", 15082903Sjake "fill", 15182903Sjake "fill", 15280709Sjake "breakpoint", 15388642Sjake "clean window", 15488642Sjake "range check", 15588642Sjake "fix alignment", 15688642Sjake "integer overflow", 15782006Sjake "syscall", 15885236Sjake "restore physical watchpoint", 15985236Sjake "restore virtual watchpoint", 16088781Sjake "kernel stack fault", 16180709Sjake}; 16280709Sjake 163157445Smariusstatic const int trap_sig[] = { 164105939Sjake SIGILL, /* reserved */ 165105939Sjake SIGILL, /* instruction access exception */ 166105939Sjake SIGILL, /* instruction access error */ 167105939Sjake SIGILL, /* instruction access protection */ 168105939Sjake SIGILL, /* illtrap instruction */ 169105939Sjake SIGILL, /* illegal instruction */ 170105939Sjake SIGBUS, /* privileged opcode */ 171105939Sjake SIGFPE, /* floating point disabled */ 172105939Sjake SIGFPE, /* floating point exception ieee 754 */ 173105939Sjake SIGFPE, /* floating point exception other */ 174105939Sjake SIGEMT, /* tag overflow */ 175105939Sjake SIGFPE, /* division by zero */ 176105939Sjake SIGILL, /* data access exception */ 177105939Sjake SIGILL, /* data access error */ 178105939Sjake SIGBUS, /* data access protection */ 179105939Sjake SIGBUS, /* memory address not aligned */ 180105939Sjake SIGBUS, /* privileged action */ 181105939Sjake SIGBUS, /* async data error */ 182105939Sjake SIGILL, /* trap instruction 16 */ 183105939Sjake SIGILL, /* trap instruction 17 */ 184105939Sjake SIGILL, /* trap instruction 18 */ 185105939Sjake SIGILL, /* trap instruction 19 */ 186105939Sjake SIGILL, /* trap instruction 20 */ 187105939Sjake SIGILL, /* trap instruction 21 */ 188105939Sjake SIGILL, /* trap instruction 22 */ 189105939Sjake SIGILL, /* trap instruction 23 */ 190105939Sjake SIGILL, /* trap instruction 24 */ 191105939Sjake SIGILL, /* trap instruction 25 */ 192105939Sjake SIGILL, /* trap instruction 26 */ 193105939Sjake SIGILL, /* trap instruction 27 */ 194105939Sjake SIGILL, /* trap instruction 28 */ 195105939Sjake SIGILL, /* trap instruction 29 */ 196105939Sjake SIGILL, /* trap instruction 30 */ 197105939Sjake SIGILL, /* trap instruction 31 */ 198114650Sjake SIGSEGV, /* fast instruction access mmu miss */ 199114650Sjake SIGSEGV, /* fast data access mmu miss */ 200105939Sjake -1, /* interrupt */ 201105939Sjake -1, /* physical address watchpoint */ 202105939Sjake -1, /* virtual address watchpoint */ 203105939Sjake -1, /* corrected ecc error */ 204105939Sjake SIGILL, /* spill */ 205105939Sjake SIGILL, /* fill */ 206105939Sjake SIGILL, /* fill */ 207105939Sjake SIGTRAP, /* breakpoint */ 208105939Sjake SIGILL, /* clean window */ 209105939Sjake SIGILL, /* range check */ 210105939Sjake SIGILL, /* fix alignment */ 211105939Sjake SIGILL, /* integer overflow */ 212105996Sjake SIGSYS, /* syscall */ 213105939Sjake -1, /* restore physical watchpoint */ 214105939Sjake -1, /* restore virtual watchpoint */ 215105939Sjake -1, /* kernel stack fault */ 216105939Sjake}; 217105939Sjake 218298352SpfgCTASSERT(nitems(trap_msg) == T_MAX); 219298352SpfgCTASSERT(nitems(trap_sig) == T_MAX); 220233747Smarius 221105733SjakeCTASSERT(sizeof(struct trapframe) == 256); 222105733Sjake 22398037Sjakeint debugger_on_signal = 0; 22498037SjakeSYSCTL_INT(_debug, OID_AUTO, debugger_on_signal, CTLFLAG_RW, 22598037Sjake &debugger_on_signal, 0, ""); 22698037Sjake 227206086Smariusu_int corrected_ecc = 0; 228206086SmariusSYSCTL_UINT(_machdep, OID_AUTO, corrected_ecc, CTLFLAG_RD, &corrected_ecc, 0, 229206086Smarius "corrected ECC errors"); 230206086Smarius 231182773Smarius/* 232182773Smarius * SUNW,set-trap-table allows to take over %tba from the PROM, which 233182773Smarius * will turn off interrupts and handle outstanding ones while doing so, 234182773Smarius * in a safe way. 235182773Smarius */ 23680708Sjakevoid 237182773Smariussun4u_set_traptable(void *tba_addr) 238182773Smarius{ 239182773Smarius static struct { 240182773Smarius cell_t name; 241182773Smarius cell_t nargs; 242182773Smarius cell_t nreturns; 243182773Smarius cell_t tba_addr; 244182773Smarius } args = { 245182773Smarius (cell_t)"SUNW,set-trap-table", 246206449Smarius 1, 247206449Smarius 0, 248182773Smarius }; 249182773Smarius 250182773Smarius args.tba_addr = (cell_t)tba_addr; 251186347Snwhitehorn ofw_entry(&args); 252182773Smarius} 253182773Smarius 254182773Smariusvoid 25580709Sjaketrap(struct trapframe *tf) 25680708Sjake{ 25783366Sjulian struct thread *td; 25881135Stmm struct proc *p; 25981387Sjake int error; 260337061Sjhb int sig, ucode; 261157445Smarius register_t addr; 262151316Sdavidxu ksiginfo_t ksi; 26380709Sjake 264181701Smarius td = curthread; 26581185Sjake 266105939Sjake CTR4(KTR_TRAP, "trap: %p type=%s (%s) pil=%#lx", td, 267105939Sjake trap_msg[tf->tf_type & ~T_KERNEL], 268105939Sjake (TRAPF_USERMODE(tf) ? "user" : "kernel"), rdpr(pil)); 269105939Sjake 270170291Sattilio PCPU_INC(cnt.v_trap); 27184186Sjake 272105939Sjake if ((tf->tf_tstate & TSTATE_PRIV) == 0) { 273105939Sjake KASSERT(td != NULL, ("trap: curthread NULL")); 274105939Sjake KASSERT(td->td_proc != NULL, ("trap: curproc NULL")); 27584186Sjake 276105939Sjake p = td->td_proc; 277155455Sphk td->td_pticks = 0; 27883366Sjulian td->td_frame = tf; 279157445Smarius addr = tf->tf_tpc; 280337061Sjhb ucode = (int)tf->tf_type; /* XXX not POSIX */ 281284214Smjg if (td->td_cowgen != p->p_cowgen) 282284214Smjg thread_cow_update(td); 28381135Stmm 284105939Sjake switch (tf->tf_type) { 285105939Sjake case T_DATA_MISS: 286105939Sjake case T_DATA_PROTECTION: 287157445Smarius addr = tf->tf_sfar; 288157445Smarius /* FALLTHROUGH */ 289105939Sjake case T_INSTRUCTION_MISS: 290105939Sjake sig = trap_pfault(td, tf); 291105939Sjake break; 292105939Sjake case T_FILL: 293105939Sjake sig = rwindow_load(td, tf, 2); 294105939Sjake break; 295105939Sjake case T_FILL_RET: 296105939Sjake sig = rwindow_load(td, tf, 1); 297105939Sjake break; 298105939Sjake case T_SPILL: 299105939Sjake sig = rwindow_save(td); 300105939Sjake break; 301206086Smarius case T_CORRECTED_ECC_ERROR: 302206086Smarius sig = trap_cecc(); 303206086Smarius break; 304337061Sjhb case T_BREAKPOINT: 305337061Sjhb sig = SIGTRAP; 306337061Sjhb ucode = TRAP_BRKPT; 307337061Sjhb break; 308105939Sjake default: 309233748Smarius if (tf->tf_type > T_MAX) 310206086Smarius panic("trap: bad trap type %#lx (user)", 311206086Smarius tf->tf_type); 312206086Smarius else if (trap_sig[tf->tf_type] == -1) 313206086Smarius panic("trap: %s (user)", 314206086Smarius trap_msg[tf->tf_type]); 315105939Sjake sig = trap_sig[tf->tf_type]; 316105939Sjake break; 317105939Sjake } 31884186Sjake 319105939Sjake if (sig != 0) { 320105939Sjake /* Translate fault for emulators. */ 321105939Sjake if (p->p_sysent->sv_transtrap != NULL) { 322105939Sjake sig = p->p_sysent->sv_transtrap(sig, 323105939Sjake tf->tf_type); 324105939Sjake } 325105939Sjake if (debugger_on_signal && 326105939Sjake (sig == 4 || sig == 10 || sig == 11)) 327174898Srwatson kdb_enter(KDB_WHY_TRAPSIG, "trapsig"); 328151316Sdavidxu ksiginfo_init_trap(&ksi); 329151316Sdavidxu ksi.ksi_signo = sig; 330337061Sjhb ksi.ksi_code = ucode; 331157445Smarius ksi.ksi_addr = (void *)addr; 332151354Sdavidxu ksi.ksi_trapno = (int)tf->tf_type; 333151316Sdavidxu trapsignal(td, &ksi); 33484186Sjake } 33584186Sjake 336155455Sphk userret(td, tf); 337181701Smarius } else { 338105939Sjake KASSERT((tf->tf_type & T_KERNEL) != 0, 339105939Sjake ("trap: kernel trap isn't")); 340105939Sjake 341131950Smarcel if (kdb_active) { 342131950Smarcel kdb_reenter(); 343131950Smarcel return; 344131950Smarcel } 345131950Smarcel 346105939Sjake switch (tf->tf_type & ~T_KERNEL) { 347105939Sjake case T_BREAKPOINT: 348105939Sjake case T_KSTACK_FAULT: 349131950Smarcel error = (kdb_trap(tf->tf_type, 0, tf) == 0); 350131950Smarcel TF_DONE(tf); 351105939Sjake break; 352105939Sjake#ifdef notyet 353105939Sjake case T_PA_WATCHPOINT: 354105939Sjake case T_VA_WATCHPOINT: 355105939Sjake error = db_watch_trap(tf); 356105939Sjake break; 35780709Sjake#endif 358105939Sjake case T_DATA_MISS: 359105939Sjake case T_DATA_PROTECTION: 360105939Sjake case T_INSTRUCTION_MISS: 361105939Sjake error = trap_pfault(td, tf); 362101955Sjake break; 363105939Sjake case T_DATA_EXCEPTION: 364105939Sjake case T_MEM_ADDRESS_NOT_ALIGNED: 365105939Sjake if ((tf->tf_sfsr & MMU_SFSR_FV) != 0 && 366105939Sjake MMU_SFSR_GET_ASI(tf->tf_sfsr) == ASI_AIUP) { 367105939Sjake if (tf->tf_tpc >= (u_long)copy_nofault_begin && 368105939Sjake tf->tf_tpc <= (u_long)copy_nofault_end) { 369105939Sjake tf->tf_tpc = (u_long)copy_fault; 370105939Sjake tf->tf_tnpc = tf->tf_tpc + 4; 371105939Sjake error = 0; 372105939Sjake break; 373105939Sjake } 374105939Sjake if (tf->tf_tpc >= (u_long)fs_nofault_begin && 375105939Sjake tf->tf_tpc <= (u_long)fs_nofault_end) { 376105939Sjake tf->tf_tpc = (u_long)fs_fault; 377105939Sjake tf->tf_tnpc = tf->tf_tpc + 4; 378105939Sjake error = 0; 379105939Sjake break; 380105939Sjake } 381105939Sjake } 382181701Smarius error = 1; 383105939Sjake break; 384116659Sjmg case T_DATA_ERROR: 385116659Sjmg /* 386157513Smarius * Handle PCI poke/peek as per UltraSPARC IIi 387157513Smarius * User's Manual 16.2.1, modulo checking the 388157513Smarius * TPC as USIII CPUs generate a precise trap 389157513Smarius * instead of a special deferred one. 390116659Sjmg */ 391116659Sjmg if (tf->tf_tpc > (u_long)fas_nofault_begin && 392157513Smarius tf->tf_tpc < (u_long)fas_nofault_end) { 393122464Sjake cache_flush(); 394204152Smarius cache_enable(PCPU_GET(impl)); 395116659Sjmg tf->tf_tpc = (u_long)fas_fault; 396116659Sjmg tf->tf_tnpc = tf->tf_tpc + 4; 397116659Sjmg error = 0; 398116659Sjmg break; 399116659Sjmg } 400116659Sjmg error = 1; 401116659Sjmg break; 402206086Smarius case T_CORRECTED_ECC_ERROR: 403206086Smarius error = trap_cecc(); 404206086Smarius break; 405105939Sjake default: 406105939Sjake error = 1; 407105939Sjake break; 408101955Sjake } 409105939Sjake 410206086Smarius if (error != 0) { 411206086Smarius tf->tf_type &= ~T_KERNEL; 412233748Smarius if (tf->tf_type > T_MAX) 413206086Smarius panic("trap: bad trap type %#lx (kernel)", 414206086Smarius tf->tf_type); 415233747Smarius panic("trap: %s (kernel)", trap_msg[tf->tf_type]); 416206086Smarius } 41780709Sjake } 41884186Sjake CTR1(KTR_TRAP, "trap: td=%p return", td); 41980708Sjake} 42081185Sjake 42188642Sjakestatic int 422206086Smariustrap_cecc(void) 423206086Smarius{ 424206086Smarius u_long eee; 425206086Smarius 426206086Smarius /* 427206086Smarius * Turn off (non-)correctable error reporting while we're dealing 428206086Smarius * with the error. 429206086Smarius */ 430206086Smarius eee = ldxa(0, ASI_ESTATE_ERROR_EN_REG); 431206086Smarius stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee & ~(AA_ESTATE_NCEEN | 432206086Smarius AA_ESTATE_CEEN)); 433206086Smarius /* Flush the caches in order ensure no corrupt data got installed. */ 434206086Smarius cache_flush(); 435206086Smarius /* Ensure the caches are still turned on (should be). */ 436206086Smarius cache_enable(PCPU_GET(impl)); 437218909Sbrucec /* Clear the error from the AFSR. */ 438206086Smarius stxa_sync(0, ASI_AFSR, ldxa(0, ASI_AFSR)); 439206086Smarius corrected_ecc++; 440206086Smarius printf("corrected ECC error\n"); 441206086Smarius /* Turn (non-)correctable error reporting back on. */ 442206086Smarius stxa_sync(0, ASI_ESTATE_ERROR_EN_REG, eee); 443206086Smarius return (0); 444206086Smarius} 445206086Smarius 446206086Smariusstatic int 44788642Sjaketrap_pfault(struct thread *td, struct trapframe *tf) 44881185Sjake{ 449287625Skib vm_map_t map; 45083366Sjulian struct proc *p; 45181185Sjake vm_offset_t va; 45282903Sjake vm_prot_t prot; 453182122Smarius vm_map_entry_t entry; 45482903Sjake u_long ctx; 45582903Sjake int type; 45681185Sjake int rv; 45781185Sjake 458105939Sjake if (td == NULL) 459105939Sjake return (-1); 46088642Sjake KASSERT(td->td_pcb != NULL, ("trap_pfault: pcb NULL")); 461105939Sjake KASSERT(td->td_proc != NULL, ("trap_pfault: curproc NULL")); 462105939Sjake KASSERT(td->td_proc->p_vmspace != NULL, ("trap_pfault: vmspace NULL")); 46381185Sjake 464105939Sjake p = td->td_proc; 465105939Sjake 46682903Sjake rv = KERN_SUCCESS; 46788642Sjake ctx = TLB_TAR_CTX(tf->tf_tar); 46882903Sjake type = tf->tf_type & ~T_KERNEL; 46988642Sjake va = TLB_TAR_VA(tf->tf_tar); 47081185Sjake 47188642Sjake CTR4(KTR_TRAP, "trap_pfault: td=%p pm_ctx=%#lx va=%#lx ctx=%#lx", 472181701Smarius td, p->p_vmspace->vm_pmap.pm_context[curcpu], va, ctx); 47381185Sjake 474199868Salc if (type == T_DATA_PROTECTION) 47582903Sjake prot = VM_PROT_WRITE; 476199868Salc else { 47788642Sjake if (type == T_DATA_MISS) 47882903Sjake prot = VM_PROT_READ; 47981387Sjake else 48082903Sjake prot = VM_PROT_READ | VM_PROT_EXECUTE; 48182903Sjake } 48281185Sjake 48388642Sjake if (ctx != TLB_CTX_KERNEL) { 48488642Sjake if ((tf->tf_tstate & TSTATE_PRIV) != 0 && 485101955Sjake (tf->tf_tpc >= (u_long)fs_nofault_intr_begin && 486181701Smarius tf->tf_tpc <= (u_long)fs_nofault_intr_end)) { 487101955Sjake tf->tf_tpc = (u_long)fs_fault; 488101955Sjake tf->tf_tnpc = tf->tf_tpc + 4; 489101955Sjake return (0); 490101955Sjake } 49188642Sjake 492287625Skib /* This is a fault on non-kernel virtual memory. */ 493287625Skib map = &p->p_vmspace->vm_map; 49482903Sjake } else { 49588642Sjake /* 496101955Sjake * This is a fault on kernel virtual memory. Attempts to 497101955Sjake * access kernel memory from user mode cause privileged 498101955Sjake * action traps, not page fault. 49988642Sjake */ 50088642Sjake KASSERT(tf->tf_tstate & TSTATE_PRIV, 50188642Sjake ("trap_pfault: fault on nucleus context from user mode")); 50288642Sjake 503182122Smarius if (tf->tf_tpc >= (u_long)copy_nofault_begin && 504182122Smarius tf->tf_tpc <= (u_long)copy_nofault_end) { 505182122Smarius vm_map_lock_read(kernel_map); 506182122Smarius if (vm_map_lookup_entry(kernel_map, va, &entry) && 507182122Smarius (entry->eflags & MAP_ENTRY_NOFAULT) != 0) { 508182122Smarius tf->tf_tpc = (u_long)copy_fault; 509182122Smarius tf->tf_tnpc = tf->tf_tpc + 4; 510182122Smarius vm_map_unlock_read(kernel_map); 511182122Smarius return (0); 512182122Smarius } 513182122Smarius vm_map_unlock_read(kernel_map); 514182122Smarius } 515287625Skib map = kernel_map; 51681185Sjake } 51788642Sjake 518287625Skib /* Fault in the page. */ 519287625Skib rv = vm_fault(map, va, prot, VM_FAULT_NORMAL); 520287625Skib 52188642Sjake CTR3(KTR_TRAP, "trap_pfault: return td=%p va=%#lx rv=%d", 52288642Sjake td, va, rv); 52381185Sjake if (rv == KERN_SUCCESS) 52481185Sjake return (0); 525101955Sjake if (ctx != TLB_CTX_KERNEL && (tf->tf_tstate & TSTATE_PRIV) != 0) { 526101955Sjake if (tf->tf_tpc >= (u_long)fs_nofault_begin && 527101955Sjake tf->tf_tpc <= (u_long)fs_nofault_end) { 528101955Sjake tf->tf_tpc = (u_long)fs_fault; 52981185Sjake tf->tf_tnpc = tf->tf_tpc + 4; 53081185Sjake return (0); 53181185Sjake } 532101955Sjake if (tf->tf_tpc >= (u_long)copy_nofault_begin && 533101955Sjake tf->tf_tpc <= (u_long)copy_nofault_end) { 534101955Sjake tf->tf_tpc = (u_long)copy_fault; 535101955Sjake tf->tf_tnpc = tf->tf_tpc + 4; 536101955Sjake return (0); 537101955Sjake } 53881185Sjake } 53988642Sjake return ((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV); 54081185Sjake} 54182006Sjake 54282006Sjake/* Maximum number of arguments that can be passed via the out registers. */ 54382006Sjake#define REG_MAXARGS 6 54482006Sjake 545208453Skibint 546321343Skibcpu_fetch_syscall_args(struct thread *td) 547202900Smarius{ 548202900Smarius struct trapframe *tf; 549202900Smarius struct proc *p; 550208453Skib register_t *argp; 551321343Skib struct syscall_args *sa; 552202900Smarius int reg; 553202900Smarius int regcnt; 554202900Smarius int error; 555202900Smarius 556202900Smarius p = td->td_proc; 557202900Smarius tf = td->td_frame; 558321343Skib sa = &td->td_sa; 559202900Smarius reg = 0; 560202900Smarius regcnt = REG_MAXARGS; 561202900Smarius 562202900Smarius sa->code = tf->tf_global[1]; 563202900Smarius 564208453Skib if (sa->code == SYS_syscall || sa->code == SYS___syscall) { 565202900Smarius sa->code = tf->tf_out[reg++]; 566202900Smarius regcnt--; 567202900Smarius } 568202900Smarius 569202900Smarius if (p->p_sysent->sv_mask) 570202900Smarius sa->code &= p->p_sysent->sv_mask; 571202900Smarius if (sa->code >= p->p_sysent->sv_size) 572202900Smarius sa->callp = &p->p_sysent->sv_table[0]; 573202900Smarius else 574202900Smarius sa->callp = &p->p_sysent->sv_table[sa->code]; 575202900Smarius 576202900Smarius sa->narg = sa->callp->sy_narg; 577202900Smarius KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]), 578202900Smarius ("Too many syscall arguments!")); 579202900Smarius error = 0; 580208453Skib argp = sa->args; 581202900Smarius bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt); 582202900Smarius if (sa->narg > regcnt) 583202900Smarius error = copyin((void *)(tf->tf_out[6] + SPOFF + 584202900Smarius offsetof(struct frame, fr_pad[6])), &sa->args[regcnt], 585202900Smarius (sa->narg - regcnt) * sizeof(sa->args[0])); 586208453Skib if (error == 0) { 587208453Skib td->td_retval[0] = 0; 588208453Skib td->td_retval[1] = 0; 589208453Skib } 590202900Smarius 591202900Smarius return (error); 592202900Smarius} 593202900Smarius 594225474Skib#include "../../kern/subr_syscall.c" 595225474Skib 59682006Sjake/* 597202900Smarius * Syscall handler 598202900Smarius * The arguments to the syscall are passed in the out registers by the caller, 599202900Smarius * and are saved in the trap frame. The syscall number is passed in %g1 (and 600202900Smarius * also saved in the trap frame). 60182006Sjake */ 60282006Sjakevoid 60384186Sjakesyscall(struct trapframe *tf) 60482006Sjake{ 605208453Skib struct thread *td; 60682006Sjake int error; 60782006Sjake 608181701Smarius td = curthread; 609208453Skib td->td_frame = tf; 610208453Skib 611105939Sjake KASSERT(td != NULL, ("trap: curthread NULL")); 612105939Sjake KASSERT(td->td_proc != NULL, ("trap: curproc NULL")); 61384186Sjake 61482006Sjake /* 61582006Sjake * For syscalls, we don't want to retry the faulting instruction 61682006Sjake * (usually), instead we need to advance one instruction. 61782006Sjake */ 618199135Skib td->td_pcb->pcb_tpc = tf->tf_tpc; 61986146Stmm TF_DONE(tf); 62082006Sjake 621321343Skib error = syscallenter(td); 622321343Skib syscallret(td, error); 62382006Sjake} 624