summaryrefslogtreecommitdiff
path: root/sys/src/9/pc64/trap.c
AgeCommit message (Collapse)Author
2022-08-17kernel: allocate notes in heapcinap_lenrek
de-bloat the proc structure by allocating notes with on the heap instead of embedding them in the proc structure. This saves around 640 bytes per process.
2022-08-17kernel: simplify notify() adding common popnote() functioncinap_lenrek
Handlin notes is common for all architectures except how the note has to be pushed on the user stack. This change adds a popnote() function that returns only the note string or nil if the process should not be notified (no notes or user notes hold off). Popnote() also handles common errors like notify during note handling or missing note handler and will suicide the process in that case.
2025-05-14kernel: get rid of Proc.kstackglenda
The kernel stack is now above the Proc structure, so the explicit kstack pointer can be eliminated.
2020-12-20kernel: handle tos and per process pcycle counters in port/cinap_lenrek
we might as well handle the per process cycle counter in the portable part instead of duplicating the code in every arch and have inconsistent implementations. we now have a portable kenter() and kexit() function, that is ment to be used in trap/syscall from user, which updates the counters. some kernels missed initializing Mach.cyclefreq.
2020-11-29pc, pc64, xen: rewrite interrupt handling codecinap_lenrek
This implements proper intrdisable() support for all interrupt controllers. For enable, (*arch->intrassign)(Vctl*) fills in the Vctl.enable and Vctl.disable pointers with the appropriate routines and returns the assigned vector number. Once the Vctl struct has been linked to its vector chain, Vctl.enable(Vctl*, shared) gets called with a flag if the vector has been already enabled (shared). This order is important here as enabling the interrupt on the controller before we have linked the chain can cause spurious interrupts, expecially on mp system where the interrupt can target a different cpu than the caller of intrenable(). The intrdisable() case is the other way around. We first disable the interrupt on the controller and after that unlink the Vctl from the chain. On a multiprocessor, the xfree() of the Vctl struct is delayed to avoid freeing it while it is still in use by another cpu. The xen port now also uses pc/irq.c which has been made generic enougth to handle xen's irq scheme. Also, archgeneric is now a separate file to avoid pulling in dependencies from the 8259 interrupt controller code.
2020-11-22pc, pc64: move common irq handling code out of trap.ccinap_lenrek
Move the common irq handling code out of trap.c into pc/irq.c so that it can be shared between 386 and amd64 ports.
2020-11-21pc, pc64: implement disabling of msi interruptscinap_lenrek
2020-11-17pc, pc64: load idt early in trapinit0()cinap_lenrek
loading the interrupt vector table early allows us to handle traps during bootup before mmuinit() which gives better diagnostics for debugging. we also can handle general protection fault on rdmsr() and wrmsr() which helps during cpuidentify() and archinit() when probing for cpu features.
2020-04-09pc, pc64: remove "got unassigned irq" printscinap_lenrek
most pc's are multiprocessors these days, that use apic or msi interrupts, then the irq does not matter anymore. and uefi does not even assign irq to pci devices anymore. if we have a problem enabling an interrupt, we will print.
2020-01-26kernel: implement portable userinit() and simplify process creationcinap_lenrek
replace machine specific userinit() by a portable implemntation that uses kproc() to create the first process. the initcode text is mapped using kmap(), so there is no need for machine specific tmpmap() functions. initcode stack preparation should be done in init0() where the stack is mapped and can be accessed directly. replacing the machine specific userinit() allows some big simplifications as sysrfork() and kproc() are now the only callers of newproc() and we can avoid initializing fields that we know are being initialized by these callers. rename autogenerated init.h and reboot.h headers. the initcode[] and rebootcode[] blobs are now in *.i files and hex generation was moved to portmkfile. the machine specific mkfile only needs to specify how to build rebootcode.out and initcode.out.
2019-09-08kernel: clear FPillegal in pexit() and before pprint()cinap_lenrek
pexit() and pprint() can get called outside of a syscall (from procctl()) with a process that is in active note handling and require floating point in the kernel on amd64 for aesni (devtls).
2019-08-27kernel: catch execution read fault on SG_NOEXEC segmentcinap_lenrek
fault() now has an additional pc argument that is used to detect fault on a non-executable segment. that is, we check on read fault if the segment has the SG_NOEXEC attribute and the program counter is within faulting page.
2019-01-22pc64: properly handle faulterror in faultamd64()cinap_lenrek
replicate what faulterror() would have done with up->nerrlab == 0, that is, terminate the process.
2018-12-11kernel: change peek to return number of characters left rather than 0/-1aiju
2018-12-11dtracy: catch page faultsaiju
2018-02-11kernel: move devether and wifi to port/cinap_lenrek
the only architecture dependence of devether was enabling interrupts, which is now done at the end of the driver's reset() function now. the wifi stack and dummy ethersink also go to port/. do the IRQ2->IRQ9 hack for pc kernels in intrenabale(), so not every caller of intrenable() has to be aware of it.
2017-11-12pc64: allow using the FPU in syscall and pagefault handlerscinap_lenrek
The aim is to take advantage of SSE instructions such as AES-NI in the kernel by lazily saving and restoring FPU state across system calls and pagefaults. (everything can can do I/O) This is accomplished by the functions fpusave() and fpurestore(). fpusave() remembers the current state and disables the FPU if it was active by setting the TS flag. In case the FPU gets used, the current state gets saved and a new PFPU.fpslot is allocated by mathemu(). fpurestore() restores the previous FPU state, reenabling the FPU if fpusave() disabled it. In the most common case, when userspace is not using the FPU, then fpusave()/fpurestore() just toggle the FPpush bit in up->fpstate. When the FPU was active, but we do not use the FPU, then nothing needs to be saved or restored. We just switched the TS flag on and off agaian. Note, this is done for the amd64 kernel only.
2017-11-04kernel: introduce per process FPU struct (PFPU) for more flexible machine ↵cinap_lenrek
specific fpu handling introducing the PFPU structue which allows the machine specific code some flexibility on how to handle the FPU process state. for example, in the pc and pc64 kernel, the FPsave structure is arround 512 bytes. with avx512, it could grow up to 2K. instead of embedding that into the Proc strucutre, it is more effective to allocate it on first use of the fpu, as most processes do not use simd or floating point in the first place. also, the FPsave structure has special 16 byte alignment constraint, which further favours dynamic allocation. this gets rid of the memmoves in pc/pc64 kernels for the aligment. there is also devproc, which is now checking if the fpsave area is actually valid before reading it, avoiding debuggers to see garbage data. the Notsave structure is gone now, as it was not used on any machine.
2017-06-12pc/pc64: debugexc: ignore exception if in kernel mode and can't get hold of ↵aiju
up->debug
2017-06-12kernel: add support for hardware watchpointsaiju
2016-11-17pc64: check if vmap() range fits in VMAPLEN window, remove unneeded ↵cinap_lenrek
vmapsync(), rename fault386() to faultamd64()
2016-01-05kernel: change active.machs from bitmap to char array to support up to 64 ↵cinap_lenrek
cpus on pc64
2015-06-28pc, pc64: toggle bit 2 in port 0x61 to reset and enable PCI SERR# nmi's, ↵cinap_lenrek
print nmi status
2015-02-20pc, pc64: simplify intrdisable()cinap_lenrek
2015-02-18pc, pc64: fix intrdisable() MaxIrqLAPIC -> MaxVectorAPIC (thanks mischief)cinap_lenrek
2014-12-22pc, pc64, xen: change return type of intrdisable() to voidcinap_lenrek
intrdisable() will always be able to unregister the interrupt now, so there is no reason to have it return an error value. all drivers except uart8250 already assumed it to never fail and theres no need to maintain that complexity.
2014-12-22pc, pc64: fix intrdisable() to remove the Vctl entry even tho we can't ↵cinap_lenrek
disable the interrupt on apic
2014-12-22pc, pc64, xen: simplify #P/irqalloccinap_lenrek
2014-11-09kernel: remove implicit Proc* argument from procctl()cinap_lenrek
procctl() is always called with up and it would not work correctly if passed a different process, so remove the Proc* argument and use up directly.
2014-08-07pc64: fix wrong Ureg* argument on note handler (thanks _sl!)cinap_lenrek
_sl reported crash: stats 593: suicide: sys: trap: fault write addr=0xffffffff8258d1b0 pc=0x204cc7 ; acid 593 /proc/593/text:amd64 plan 9 executable /sys/lib/acid/port /sys/lib/acid/amd64 acid: lstk() notejmp(ret=0x1,j=0x40ac90)+0x13 /sys/src/libc/amd64/notejmp.c:10 alarmed(a=0xffffffff8258d1b0,s=0x7ffffeffea58)+0x3f /sys/src/cmd/stats.c:718 notifier+0x3e /sys/src/libc/port/atnotify.c:15 acid: note how a in alarmed is a kernel address! the first Ureg* argument is passed to the note handler in the RARG (BX) register, which was not loaded when returning to userspace from syscall() thru forkret(). fix by returning thru noteret() from syscall().
2014-07-20pc64: dont save/restore DS/ES/FS/GS segment registers on syscall or ↵cinap_lenrek
interrupt, they are ignored in long mode. we do not support 32 bit processes and DS, ES, FS and GS segment registers are ignored in long mode, so theres no point in saving and restoring them.
2014-07-20pc64: preserve user extern registers R14 and R15 across syscalls, use ↵cinap_lenrek
Ureg.bp (RARG) for syscall number the 6c compiler reserves R14 and R15 for extern register variables, which is used by the kernel to hold the m and up pointers. until now, the meaning of R14 and R15 was undefined for userspace and extern register would not work as the kernel trashes R14 and R15 on syscalls. with this change, user extern registers R14 and R15 are zeroed on exec and otherwise preserved across syscalls. so userspace *could* use them for per process variables like the kernel does. use Ureg.bp (RARG) for syscall number instead of Ureg.ax. this is less confusing and mirrors the amd64 calling convention.
2014-07-09pc, pc64: initial machine check architecture supportcinap_lenrek
2014-05-11pc, pc64: add simd error exception name in trap.ccinap_lenrek
2014-03-16pc64: fix swaped error/flags in dumpregs(), remove misleading comment in ↵cinap_lenrek
apbootstrap
2014-03-15pc64: add R8-R15 in dumpregs()cinap_lenrek
2014-02-10pc64: return up in RUSER (BP) for devproc kregs filecinap_lenrek
2014-02-09pc64: pass Ureg* argument in BP to userspace note handlercinap_lenrek
2014-02-06pc64: ensure user pc is never set to a non-canonical address through ↵mischief
setregisters on intel processors, a general protection exception is fired if a non-canonical address is loaded into PC during SYSRET. this will cause the kernel to panic. see http://www.kb.cert.org/vuls/id/649219 and the intel software developer manual for more information.
2014-02-06pc64: fix note handlingcinap_lenrek
2014-02-04pc64: remove cinaps cga screen interrupt debugger, was experiment...cinap_lenrek
2014-02-04pc64: dont dump user registers on exception, was experiment...cinap_lenrek
2014-02-02pc64: dont dump registers for user process on pagefault error, was experimentcinap_lenrek
2014-02-02pc64: print only 8 hex chars dumpstack sp/pccinap_lenrek
kernel addresses are sign extended to 64 bit. upper bits are not really helpfull.
2014-02-01add experimental pc64 kernelcinap_lenrek