From 4b653fbac12ef9af3e1fd2750f1ab7ccf7ec8348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Tue, 5 Sep 2017 14:03:36 +0200 Subject: [PATCH] gpu/intel: handle double insertion in PPGTT As the PPGTT is populated by the client, the client has to account for guard pages and so forth. Issue #4148 #4233 --- repos/os/include/gpu_session/connection.h | 3 ++- repos/os/include/gpu_session/gpu_session.h | 10 ++++++++-- repos/os/src/drivers/gpu/intel/main.cc | 20 ++++++++++---------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/repos/os/include/gpu_session/connection.h b/repos/os/include/gpu_session/connection.h index 80b2d09fde..214db59426 100644 --- a/repos/os/include/gpu_session/connection.h +++ b/repos/os/include/gpu_session/connection.h @@ -30,7 +30,8 @@ struct Gpu::Connection : Genode::Connection, Session_client Genode::Capability _session(Genode::Parent &parent, char const *label, Genode::size_t quota) { - return session(parent, "ram_quota=%ld, label=\"%s\"", quota, label); + return session(parent, "ram_quota=%ld, cap_quota=%ld, label=\"%s\"", + quota, CAP_QUOTA, label); } /** diff --git a/repos/os/include/gpu_session/gpu_session.h b/repos/os/include/gpu_session/gpu_session.h index 9a801116fc..bd2fc9490b 100644 --- a/repos/os/include/gpu_session/gpu_session.h +++ b/repos/os/include/gpu_session/gpu_session.h @@ -65,6 +65,7 @@ struct Gpu::Session : public Genode::Session struct Out_of_ram : Genode::Exception { }; struct Out_of_caps : Genode::Exception { }; struct Invalid_state : Genode::Exception { }; + struct Mapping_buffer_failed : Genode::Exception { }; enum { REQUIRED_QUOTA = 1024 * 1024, CAP_QUOTA = 8, }; @@ -124,6 +125,8 @@ struct Gpu::Session : public Genode::Session * \param ds dataspace capability for buffer * \param aperture if true create CPU accessible mapping through * GGTT window, otherwise create PPGTT mapping + * + * \throw Mapping_buffer_failed */ virtual Genode::Dataspace_capability map_buffer(Genode::Dataspace_capability ds, bool aperture) = 0; @@ -140,6 +143,9 @@ struct Gpu::Session : public Genode::Session * * \param ds dataspace capability for buffer * \param va virtual address + * + * \throw Mapping_buffer_failed + * \throw Out_of_ram */ virtual bool map_buffer_ppgtt(Genode::Dataspace_capability ds, Gpu::addr_t va) = 0; @@ -174,12 +180,12 @@ struct Gpu::Session : public Genode::Session Genode::size_t); GENODE_RPC(Rpc_free_buffer, void, free_buffer, Genode::Dataspace_capability); GENODE_RPC_THROW(Rpc_map_buffer, Genode::Dataspace_capability, map_buffer, - GENODE_TYPE_LIST(Out_of_ram), + GENODE_TYPE_LIST(Mapping_buffer_failed, Out_of_ram), Genode::Dataspace_capability, bool); GENODE_RPC(Rpc_unmap_buffer, void, unmap_buffer, Genode::Dataspace_capability); GENODE_RPC_THROW(Rpc_map_buffer_ppgtt, bool, map_buffer_ppgtt, - GENODE_TYPE_LIST(Out_of_ram), + GENODE_TYPE_LIST(Mapping_buffer_failed, Out_of_ram), Genode::Dataspace_capability, Gpu::addr_t); GENODE_RPC(Rpc_unmap_buffer_ppgtt, void, unmap_buffer_ppgtt, Genode::Dataspace_capability, Gpu::addr_t); diff --git a/repos/os/src/drivers/gpu/intel/main.cc b/repos/os/src/drivers/gpu/intel/main.cc index 9b2e318ae8..d4613efd36 100644 --- a/repos/os/src/drivers/gpu/intel/main.cc +++ b/repos/os/src/drivers/gpu/intel/main.cc @@ -796,8 +796,8 @@ struct Igd::Device } catch (Igd::Ppgtt_allocator::Out_of_memory) { throw Igd::Device::Out_of_ram(); } catch (...) { - Genode::log(__func__, ": unknown exception"); - throw; + /* Double_insertion and the like */ + throw Igd::Device::Could_not_map_buffer(); } } @@ -1560,21 +1560,21 @@ class Gpu::Session_component : public Genode::Session_object buffer.ppgtt_va_valid = true; result = OK; } catch (Igd::Device::Could_not_map_buffer) { - /* FIXME do not result in Out_of_ram */ - Genode::error("could not map buffer object into PPGTT"); + Genode::error("could not map buffer object (", Genode::Hex(va), ") into PPGTT"); result = MAP_FAILED; return; } - /* will throw below */ - catch (Igd::Device::Out_of_ram) { return; } + catch (Igd::Device::Out_of_ram) { + result = ALLOC_FAILED; + return; + } }; _buffer_registry.for_each(lookup_and_map); switch (result) { - case ALLOC_FAILED: - throw Gpu::Session::Out_of_ram(); - case OK: - return true; + case ALLOC_FAILED: throw Gpu::Session::Out_of_ram(); + case MAP_FAILED: throw Gpu::Session::Mapping_buffer_failed(); + case OK: return true; default: return false; }