fix: kernel concurrency, interrupt context, and user VA safety

This commit is contained in:
daniel committed 2026-08-01 15:43:38 +02:00
1 parent f222bf1f04
commit b1c55073c7
71 files changed
+2654 -1092

No files matched your search

+7 -64
View File
@@ -13,8 +13,6 @@
#include <Memory/Paging.hpp>
#include <Memory/PageFrameAllocator.hpp>
#include <Libraries/Memory.hpp>
#include <Hal/Apic/Interrupts.hpp>
#include <Hal/Apic/IoApic.hpp>
#include <Timekeeping/ApicTimer.hpp>
using namespace Kt;
@@ -511,9 +509,9 @@ namespace Drivers::Storage::Nvme {
cmd.Prp1 = g_ioCqPhys;
// CDW10: bits 31:16 = queue size (0-based), bits 15:0 = queue ID
cmd.Cdw10 = ((uint32_t)(g_ioCqDepth - 1) << 16) | 1;
// CDW11: bit 0 = physically contiguous, bit 1 = interrupts enabled
// bits 31:16 = interrupt vector
cmd.Cdw11 = (1u << 0) | (1u << 1) | (0u << 16);
// Physically contiguous, with completion interrupts disabled. The
// queue is consumed synchronously by WaitCompletion().
cmd.Cdw11 = (1u << 0);
CqEntry cqe;
if (!AdminCommand(cmd, cqe)) {
@@ -549,54 +547,6 @@ namespace Drivers::Storage::Nvme {
return true;
}
// -------------------------------------------------------------------------
// Interrupt handler
// -------------------------------------------------------------------------
static void HandleInterrupt(uint8_t irq) {
(void)irq;
// NVMe uses polling-based completion in this driver.
// The interrupt handler just acknowledges the interrupt.
// Completions are consumed in the polling loops above.
}
// -------------------------------------------------------------------------
// MSI setup
// -------------------------------------------------------------------------
static bool SetupMsi(uint8_t bus, uint8_t dev, uint8_t func) {
uint8_t cap = Pci::FindCapability(bus, dev, func, Pci::PCI_CAP_MSI);
if (cap == 0) {
KernelLogStream(INFO, "NVMe") << "MSI capability not found";
return false;
}
uint16_t msgCtrl = Pci::LegacyRead16(bus, dev, func, cap + 2);
bool is64bit = (msgCtrl & (1 << 7)) != 0;
Pci::LegacyWrite32(bus, dev, func, cap + 4, MSI_ADDR_BASE);
if (is64bit) {
Pci::LegacyWrite32(bus, dev, func, cap + 8, 0);
Pci::LegacyWrite16(bus, dev, func, cap + 12, MSI_VECTOR);
} else {
Pci::LegacyWrite16(bus, dev, func, cap + 8, MSI_VECTOR);
}
msgCtrl &= ~(0x70); // Single message
msgCtrl |= (1 << 0); // MSI Enable
Pci::LegacyWrite16(bus, dev, func, cap + 2, msgCtrl);
uint16_t pciCmd = Pci::LegacyRead16(bus, dev, func, (uint8_t)Pci::PCI_REG_COMMAND);
pciCmd |= Pci::PCI_CMD_INTX_DISABLE;
Pci::LegacyWrite16(bus, dev, func, (uint8_t)Pci::PCI_REG_COMMAND, pciCmd);
Hal::RegisterIrqHandler(MSI_IRQ, HandleInterrupt);
KernelLogStream(OK, "NVMe") << "MSI enabled: vector " << base::dec << (uint64_t)MSI_VECTOR;
return true;
}
// -------------------------------------------------------------------------
// Probe (PCI driver entry point)
// -------------------------------------------------------------------------
@@ -629,6 +579,7 @@ namespace Drivers::Storage::Nvme {
// Enable bus mastering and memory space
Pci::EnableBusMaster(dev.Bus, dev.Device, dev.Function);
Pci::DisableInterruptDelivery(dev.Bus, dev.Device, dev.Function);
// Read capabilities
uint64_t cap = ReadReg64(REG_CAP);
@@ -653,17 +604,9 @@ namespace Drivers::Storage::Nvme {
return false;
}
// Step 2: Set up MSI
bool hasMsi = SetupMsi(dev.Bus, dev.Device, dev.Function);
if (!hasMsi) {
uint8_t irqLine = Pci::LegacyRead8(dev.Bus, dev.Device, dev.Function,
(uint8_t)Pci::PCI_REG_INTERRUPT);
if (irqLine != 0xFF) {
KernelLogStream(INFO, "NVMe") << "Using legacy IRQ " << base::dec << (uint64_t)irqLine;
Hal::RegisterIrqHandler(irqLine, HandleInterrupt);
Hal::IoApic::UnmaskIrq(Hal::IoApic::GetGsiForIrq(irqLine));
}
}
// Step 2: keep PCI interrupt delivery disabled. Admin and I/O queues
// are polled synchronously, so completion interrupts add latency and
// can starve the lower-vector scheduler timer under sustained I/O.
// Step 3: Set up admin queues
if (!SetupAdminQueues()) {