From b97e549dc4cf95fdd1814d7c7fcd85f37ed6b82f Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Wed, 17 Apr 2024 09:05:04 +0200 Subject: [PATCH] intel/gpu: reset framebuffer part of ggtt on display client close (intel_fb). The former code constructed a temporary object on the stack, which sets up the scratch pages for the closed client. However, the scratch page backing store (dma_buffer) gets freed on destruction of the temporary stack object, which leads to DMA faults with visual noise on the screen. Instead, use the already in use ggtt object and add the scratch pages explicitly. Issue #5180 --- repos/os/src/drivers/gpu/intel/ggtt.h | 10 ++++++++++ repos/os/src/drivers/gpu/intel/main.cc | 19 +++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/repos/os/src/drivers/gpu/intel/ggtt.h b/repos/os/src/drivers/gpu/intel/ggtt.h index 816f43966d..772bcdda58 100644 --- a/repos/os/src/drivers/gpu/intel/ggtt.h +++ b/repos/os/src/drivers/gpu/intel/ggtt.h @@ -165,6 +165,16 @@ class Igd::Ggtt for (size_t i = fb_entries; i < _num_entries; i++) { _insert_pte(mmio, _scratch_page.dma_addr(), i); } + + } + + void fill_fb_with_scratch_pages(Mmio &mmio, size_t const fb_size) + { + auto const entries = Genode::min(fb_size / PAGE_SIZE, _num_entries); + + for (size_t i = 0; i < entries; i++) { + _insert_pte(mmio, _scratch_page.dma_addr(), i); + } } /** diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc index 171bac8e53..cc19c60d8f 100644 --- a/repos/os/src/drivers/gpu/intel/main.cc +++ b/repos/os/src/drivers/gpu/intel/main.cc @@ -285,6 +285,15 @@ struct Igd::Device fn_error(); } + void reset_reserved_fb_ggtt() + { + with_ggtt([&](auto &ggtt, auto &mmio) { + ggtt.fill_fb_with_scratch_pages(mmio, _resources.aperture_reserved()); + }, []() { + Genode::error(__func__, " failed"); + }); + } + /************ ** MEMORY ** ************/ @@ -2677,14 +2686,8 @@ struct Main : Irq_ack_handler, Gpu_reset_handler void reset() override { - _dev.with_mmio([&](auto &mmio) { - _dev.with_platform([&](auto &plat_con) { - auto const base = mmio.base() + (mmio.size() / 2); - Igd::Ggtt(plat_con, mmio, base, _dev.gtt_reserved(), 0, 0); - }); - }, []() { - error("reset failed"); - }); + if (_igd_device.constructed()) + _igd_device->reset_reserved_fb_ggtt(); } };