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

@ -19,6 +19,7 @@
#include "fs/fs.h"
#include "fs/file.h"
#include "dev/input.h"
#include "dev/kbd.h"
#include "core/uaccess.h"
#include "gfx/gfx.h"
#include "uapi/errno.h"
@ -230,6 +231,9 @@ input_grab(int dev, int on)
// accident unless the kernel says which it was.
cprintf("input: event%d %s by pid %d\n", dev,
on ? "grabbed" : "released", myproc() ? myproc()->pid : -1);
// The holder kept its own lights; the console's come back with it.
if(!on && dev == INPUT_KBD)
kbd_set_leds(kbd_lock_state());
}
return 0;
}
@ -433,11 +437,31 @@ inputread(struct inode *ip, uint64 off, char *dst, int n)
return got;
}
// evdev accepts writes to set keyboard LEDs. There are no LEDs to set here,
// and a program that writes one should not see an error for it.
// evdev accepts writes to set keyboard LEDs, and X sets them this way: it
// keeps its own lock state while it holds the keyboard. Each write is
// struct input_event -- a 16-byte time, type, code, value -- and EV_LED's
// codes 0, 1 and 2 are Num, Caps and Scroll Lock. Anything else is accepted
// and ignored.
int
inputwrite(struct inode *ip, uint64 off, char *src, int n)
{
static uint xleds;
int changed = 0;
for (int k = 0; k + 24 <= n; k += 24) {
uint16 type, code;
int32 value;
memmove(&type, src + k + 16, 2);
memmove(&code, src + k + 18, 2);
memmove(&value, src + k + 20, 4);
if (type != 0x11 || code > 2) // EV_LED
continue;
uint bit = code == 0 ? NUMLOCK : code == 1 ? CAPSLOCK : SCROLLLOCK;
xleds = value ? (xleds | bit) : (xleds & ~bit);
changed = 1;
}
if (changed)
kbd_set_leds(xleds);
return n;
}