Keyboard lights, TLB shootdowns, battery in sysfs, /proc/pid/maps

Caps, Num and Scroll Lock now light their LEDs on PS/2 and USB keyboards,
share one state between keyboards, and stop toggling on key repeat. X sets
them through evdev writes while it holds the keyboard.

Unmapping memory in a process with threads on other CPUs now flushes their
TLBs with an IPI. Without it a freed page stayed reachable through stale
translations, which corrupted Epiphany's heap on SMP.

ACPI batteries and AC adapters appear under /sys/class/power_supply.
/proc/<pid>/maps lists file mappings, and a process killed by a fault
names the file and offset it died in. r8169 gets a 256-entry RX ring.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-25 13:43:27 +01:00
commit 438e7af141
18 changed files with 945 additions and 9 deletions

View file

@ -334,6 +334,7 @@ mm_put(struct mm *m)
if (!last)
return;
mm_release_shared(m);
mapname_free(m);
if (m->pgdir)
freevm(m->pgdir);
m->pgdir = 0;
@ -720,6 +721,7 @@ fork(void)
shm_ref(np->mm->vma[i].shmid);
}
np->mm->mmap_next = myproc()->mm->mmap_next;
mapname_copy(np->mm, pm);
mm_unlock(pm);
memmove(np->tf, myproc()->tf, sizeof(struct trapframe));
@ -1360,6 +1362,17 @@ exit(int status)
struct proc *p;
int fd;
// Killed by a fault of its own -- the trapframe holds an exception, not a
// syscall -- so say which file it was executing. The register dump from
// trap() gives addresses; this gives the library they are in.
{
int sig = status & 0x7f;
struct trapframe *tf = myproc()->tf;
if ((sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || sig == SIGFPE) &&
tf && (tf->cs & 3) == DPL_USER && tf->trapno < 32)
mapname_report(myproc());
}
if(myproc() == initproc) {
// Returning from exit() is the *success* path here. exec() does not fail
// to return -- it returns 0 having replaced the address space, and the new
@ -3006,3 +3019,24 @@ proc_cputime(uint64 *user, uint64 *sys)
*user = u;
*sys = s;
}
// /proc/<pid>/maps: see mapname_gen(). 0 bytes for a pid that is gone.
int
proc_maps(int pid, char *buf, int cap)
{
struct mm *m = 0;
acquire(&ptable.lock);
for (struct proc *p = ptable.proc; p < &ptable.proc[NPROC]; p++)
if (p->pid == pid && p->state != UNUSED && p->state != ZOMBIE && p->mm) {
m = p->mm;
mm_get(m);
break;
}
release(&ptable.lock);
if (!m)
return 0;
int n = mapname_gen(m, buf, cap);
mm_put(m);
return n;
}