fix: kernel concurrency, interrupt context, and user VA safety
This commit is contained in:
1 parent
f222bf1f04
commit
b1c55073c7
71 files changed
+2654
-1092
No files matched your search
@@ -36,8 +36,17 @@ namespace montauk::abi {
|
||||
if (fbBase == nullptr) return 0;
|
||||
|
||||
uint64_t fbPhys = Memory::SubHHDM((uint64_t)fbBase);
|
||||
uint64_t fbSize = Graphics::Framebuffer::GetHeight()
|
||||
* Graphics::Framebuffer::GetPitch();
|
||||
uint64_t width = Graphics::Framebuffer::GetWidth();
|
||||
uint64_t height = Graphics::Framebuffer::GetHeight();
|
||||
uint64_t pitch = Graphics::Framebuffer::GetPitch();
|
||||
if (width == 0 || height == 0 || pitch == 0
|
||||
|| width > (~0ULL / 4) || pitch < width * 4
|
||||
|| height > (~0ULL / pitch)) {
|
||||
Kt::KernelLogStream(Kt::ERROR, "FbMap")
|
||||
<< "Invalid or overflowing framebuffer geometry";
|
||||
return 0;
|
||||
}
|
||||
uint64_t fbSize = height * pitch;
|
||||
uint64_t numPages = (fbSize + 0xFFF) / 0x1000;
|
||||
|
||||
Kt::KernelLogStream(Kt::INFO, "FbMap") << "fbPhys=" << kcp::hex << fbPhys
|
||||
@@ -47,8 +56,28 @@ namespace montauk::abi {
|
||||
<< "x" << Graphics::Framebuffer::GetHeight()
|
||||
<< " pitch=" << Graphics::Framebuffer::GetPitch() << ")";
|
||||
|
||||
// Map at a fixed user VA
|
||||
constexpr uint64_t userVa = 0x50000000ULL;
|
||||
// Map in the dedicated framebuffer arena, away from the heap,
|
||||
// shared libraries, reusable IPC surfaces, and the user stack.
|
||||
constexpr uint64_t userVa = Sched::UserFramebufferBase;
|
||||
uint64_t mappedBytes = numPages * 0x1000ULL;
|
||||
bool flipSupported = Drivers::Graphics::IntelGPU::FlipSupported();
|
||||
uint64_t buffers = flipSupported ? 2 : 1;
|
||||
if (mappedBytes > (Sched::UserFramebufferLimit - userVa) / buffers) {
|
||||
Kt::KernelLogStream(Kt::ERROR, "FbMap")
|
||||
<< "Framebuffer mappings exceed reserved user VA range";
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Never expose more of buffer 1 than the GPU driver allocated. This
|
||||
// independently contains a future geometry-contract regression before
|
||||
// any partial framebuffer mapping is installed in the process.
|
||||
if (flipSupported
|
||||
&& (Drivers::Graphics::IntelGPU::GetBufferPhys(1) == 0
|
||||
|| Drivers::Graphics::IntelGPU::GetBufferPageCount(1) < numPages)) {
|
||||
Kt::KernelLogStream(Kt::ERROR, "FbMap")
|
||||
<< "Page-flip buffer is smaller than firmware framebuffer";
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (uint64_t i = 0; i < numPages; i++) {
|
||||
if (!Memory::VMM::Paging::MapUserInWC(
|
||||
@@ -63,7 +92,7 @@ namespace montauk::abi {
|
||||
// When page flipping is available, map the second scanout buffer
|
||||
// immediately after the first so a double-buffered client can reach
|
||||
// both. Single-buffer clients never touch the extra pages.
|
||||
if (Drivers::Graphics::IntelGPU::FlipSupported()) {
|
||||
if (flipSupported) {
|
||||
uint64_t buf1Phys = Drivers::Graphics::IntelGPU::GetBufferPhys(1);
|
||||
for (uint64_t i = 0; i < numPages; i++) {
|
||||
if (!Memory::VMM::Paging::MapUserInWC(
|
||||
@@ -82,6 +111,7 @@ namespace montauk::abi {
|
||||
// SYS_FBFLIP: point scanout at buffer `index` (0 or 1). The hardware
|
||||
// latches the new surface at vblank, so the flip is tear-free.
|
||||
// index == -1 queries support without side effects.
|
||||
// index == -2 acquires flip ownership and returns the live front buffer.
|
||||
static int64_t Sys_FbFlip(uint64_t index, uint64_t flags) {
|
||||
namespace GPU = Drivers::Graphics::IntelGPU;
|
||||
|
||||
@@ -91,9 +121,11 @@ namespace montauk::abi {
|
||||
if (!GPU::FlipSupported()) return -1;
|
||||
|
||||
auto* proc = Sched::GetCurrentProcessPtr();
|
||||
if (proc != nullptr) GPU::SetFlipOwner(proc->pid);
|
||||
|
||||
return GPU::Flip((int)index, (flags & 1) != 0);
|
||||
if ((int64_t)index == -2) {
|
||||
return proc != nullptr ? GPU::AcquireFlip(proc->pid) : -1;
|
||||
}
|
||||
if (proc == nullptr) return -1;
|
||||
return GPU::Flip((int)index, (flags & 1) != 0, proc->pid);
|
||||
}
|
||||
|
||||
static int64_t Sys_DisplayInfo(DisplayInfo* out) {
|
||||
|
||||
Reference in new issue
Block a user