1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 19:37:36 +00:00

Kernel: Properly propagate errors in VirtIOGPU 3D device initialization

This commit is contained in:
Liav A 2022-12-16 13:22:00 +02:00 committed by Sam Atkins
parent 1a85539741
commit bb491a681d
4 changed files with 15 additions and 13 deletions

View file

@ -21,25 +21,24 @@ VirtIOGPU3DDevice::PerContextState::PerContextState(Graphics::VirtIOGPU::Context
{ {
} }
NonnullLockRefPtr<VirtIOGPU3DDevice> VirtIOGPU3DDevice::must_create(VirtIOGraphicsAdapter const& adapter) ErrorOr<NonnullLockRefPtr<VirtIOGPU3DDevice>> VirtIOGPU3DDevice::try_create(VirtIOGraphicsAdapter& adapter)
{ {
// Setup memory transfer region // Setup memory transfer region
auto region_result = MM.allocate_kernel_region( auto region_result = TRY(MM.allocate_kernel_region(
NUM_TRANSFER_REGION_PAGES * PAGE_SIZE, NUM_TRANSFER_REGION_PAGES * PAGE_SIZE,
"VIRGL3D kernel upload buffer"sv, "VIRGL3D kernel upload buffer"sv,
Memory::Region::Access::ReadWrite, Memory::Region::Access::ReadWrite,
AllocationStrategy::AllocateNow); AllocationStrategy::AllocateNow));
VERIFY(!region_result.is_error()); auto kernel_context_id = TRY(adapter.create_context());
auto device = MUST(DeviceManagement::try_create_device<VirtIOGPU3DDevice>(adapter, region_result.release_value())); return TRY(DeviceManagement::try_create_device<VirtIOGPU3DDevice>(adapter, move(region_result), kernel_context_id));
return device;
} }
VirtIOGPU3DDevice::VirtIOGPU3DDevice(VirtIOGraphicsAdapter const& graphics_adapter, NonnullOwnPtr<Memory::Region> transfer_buffer_region) VirtIOGPU3DDevice::VirtIOGPU3DDevice(VirtIOGraphicsAdapter const& graphics_adapter, NonnullOwnPtr<Memory::Region> transfer_buffer_region, Graphics::VirtIOGPU::ContextID kernel_context_id)
: CharacterDevice(28, 0) : CharacterDevice(28, 0)
, m_graphics_adapter(graphics_adapter) , m_graphics_adapter(graphics_adapter)
, m_kernel_context_id(kernel_context_id)
, m_transfer_buffer_region(move(transfer_buffer_region)) , m_transfer_buffer_region(move(transfer_buffer_region))
{ {
m_kernel_context_id = MUST(m_graphics_adapter->create_context());
} }
void VirtIOGPU3DDevice::detach(OpenFileDescription& description) void VirtIOGPU3DDevice::detach(OpenFileDescription& description)

View file

@ -95,10 +95,10 @@ class VirtIOGPU3DDevice : public CharacterDevice {
friend class DeviceManagement; friend class DeviceManagement;
public: public:
static NonnullLockRefPtr<VirtIOGPU3DDevice> must_create(VirtIOGraphicsAdapter const&); static ErrorOr<NonnullLockRefPtr<VirtIOGPU3DDevice>> try_create(VirtIOGraphicsAdapter&);
private: private:
VirtIOGPU3DDevice(VirtIOGraphicsAdapter const& graphics_adapter, NonnullOwnPtr<Memory::Region> transfer_buffer_region); VirtIOGPU3DDevice(VirtIOGraphicsAdapter const& graphics_adapter, NonnullOwnPtr<Memory::Region> transfer_buffer_region, Graphics::VirtIOGPU::ContextID kernel_context_id);
class PerContextState final : public AtomicRefCounted<PerContextState> { class PerContextState final : public AtomicRefCounted<PerContextState> {
public: public:

View file

@ -40,6 +40,7 @@ NonnullLockRefPtr<VirtIOGraphicsAdapter> VirtIOGraphicsAdapter::initialize(PCI::
ErrorOr<void> VirtIOGraphicsAdapter::initialize_adapter() ErrorOr<void> VirtIOGraphicsAdapter::initialize_adapter()
{ {
VERIFY(m_num_scanouts <= VIRTIO_GPU_MAX_SCANOUTS); VERIFY(m_num_scanouts <= VIRTIO_GPU_MAX_SCANOUTS);
TRY(initialize_3d_device());
for (size_t index = 0; index < m_num_scanouts; index++) { for (size_t index = 0; index < m_num_scanouts; index++) {
auto display_connector = VirtIODisplayConnector::must_create(*this, index); auto display_connector = VirtIODisplayConnector::must_create(*this, index);
m_scanouts[index].display_connector = display_connector; m_scanouts[index].display_connector = display_connector;
@ -450,12 +451,13 @@ void VirtIOGraphicsAdapter::delete_resource(Graphics::VirtIOGPU::ResourceID reso
VERIFY(response.type == to_underlying(Graphics::VirtIOGPU::Protocol::CommandType::VIRTIO_GPU_RESP_OK_NODATA)); VERIFY(response.type == to_underlying(Graphics::VirtIOGPU::Protocol::CommandType::VIRTIO_GPU_RESP_OK_NODATA));
} }
void VirtIOGraphicsAdapter::initialize_3d_device() ErrorOr<void> VirtIOGraphicsAdapter::initialize_3d_device()
{ {
if (m_has_virgl_support) { if (m_has_virgl_support) {
SpinlockLocker locker(m_operation_lock); SpinlockLocker locker(m_operation_lock);
m_3d_device = VirtIOGPU3DDevice::must_create(*this); m_3d_device = TRY(VirtIOGPU3DDevice::try_create(*this));
} }
return {};
} }
ErrorOr<Graphics::VirtIOGPU::ContextID> VirtIOGraphicsAdapter::create_context() ErrorOr<Graphics::VirtIOGPU::ContextID> VirtIOGraphicsAdapter::create_context()

View file

@ -40,7 +40,6 @@ public:
static NonnullLockRefPtr<VirtIOGraphicsAdapter> initialize(PCI::DeviceIdentifier const&); static NonnullLockRefPtr<VirtIOGraphicsAdapter> initialize(PCI::DeviceIdentifier const&);
virtual void initialize() override; virtual void initialize() override;
void initialize_3d_device();
ErrorOr<void> mode_set_resolution(Badge<VirtIODisplayConnector>, VirtIODisplayConnector&, size_t width, size_t height); ErrorOr<void> mode_set_resolution(Badge<VirtIODisplayConnector>, VirtIODisplayConnector&, size_t width, size_t height);
void set_dirty_displayed_rect(Badge<VirtIODisplayConnector>, VirtIODisplayConnector&, Graphics::VirtIOGPU::Protocol::Rect const& dirty_rect, bool main_buffer); void set_dirty_displayed_rect(Badge<VirtIODisplayConnector>, VirtIODisplayConnector&, Graphics::VirtIOGPU::Protocol::Rect const& dirty_rect, bool main_buffer);
@ -50,6 +49,8 @@ public:
private: private:
ErrorOr<void> attach_physical_range_to_framebuffer(VirtIODisplayConnector& connector, bool main_buffer, size_t framebuffer_offset, size_t framebuffer_size); ErrorOr<void> attach_physical_range_to_framebuffer(VirtIODisplayConnector& connector, bool main_buffer, size_t framebuffer_offset, size_t framebuffer_size);
ErrorOr<void> initialize_3d_device();
void flush_dirty_rectangle(Graphics::VirtIOGPU::ScanoutID, Graphics::VirtIOGPU::ResourceID, Graphics::VirtIOGPU::Protocol::Rect const& dirty_rect); void flush_dirty_rectangle(Graphics::VirtIOGPU::ScanoutID, Graphics::VirtIOGPU::ResourceID, Graphics::VirtIOGPU::Protocol::Rect const& dirty_rect);
struct Scanout { struct Scanout {
struct PhysicalBuffer { struct PhysicalBuffer {