1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 13:07:46 +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
auto region_result = MM.allocate_kernel_region(
auto region_result = TRY(MM.allocate_kernel_region(
NUM_TRANSFER_REGION_PAGES * PAGE_SIZE,
"VIRGL3D kernel upload buffer"sv,
Memory::Region::Access::ReadWrite,
AllocationStrategy::AllocateNow);
VERIFY(!region_result.is_error());
auto device = MUST(DeviceManagement::try_create_device<VirtIOGPU3DDevice>(adapter, region_result.release_value()));
return device;
AllocationStrategy::AllocateNow));
auto kernel_context_id = TRY(adapter.create_context());
return TRY(DeviceManagement::try_create_device<VirtIOGPU3DDevice>(adapter, move(region_result), kernel_context_id));
}
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)
, m_graphics_adapter(graphics_adapter)
, m_kernel_context_id(kernel_context_id)
, m_transfer_buffer_region(move(transfer_buffer_region))
{
m_kernel_context_id = MUST(m_graphics_adapter->create_context());
}
void VirtIOGPU3DDevice::detach(OpenFileDescription& description)

View file

@ -95,10 +95,10 @@ class VirtIOGPU3DDevice : public CharacterDevice {
friend class DeviceManagement;
public:
static NonnullLockRefPtr<VirtIOGPU3DDevice> must_create(VirtIOGraphicsAdapter const&);
static ErrorOr<NonnullLockRefPtr<VirtIOGPU3DDevice>> try_create(VirtIOGraphicsAdapter&);
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> {
public:

View file

@ -40,6 +40,7 @@ NonnullLockRefPtr<VirtIOGraphicsAdapter> VirtIOGraphicsAdapter::initialize(PCI::
ErrorOr<void> VirtIOGraphicsAdapter::initialize_adapter()
{
VERIFY(m_num_scanouts <= VIRTIO_GPU_MAX_SCANOUTS);
TRY(initialize_3d_device());
for (size_t index = 0; index < m_num_scanouts; index++) {
auto display_connector = VirtIODisplayConnector::must_create(*this, index);
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));
}
void VirtIOGraphicsAdapter::initialize_3d_device()
ErrorOr<void> VirtIOGraphicsAdapter::initialize_3d_device()
{
if (m_has_virgl_support) {
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()

View file

@ -40,7 +40,6 @@ public:
static NonnullLockRefPtr<VirtIOGraphicsAdapter> initialize(PCI::DeviceIdentifier const&);
virtual void initialize() override;
void initialize_3d_device();
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);
@ -50,6 +49,8 @@ public:
private:
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);
struct Scanout {
struct PhysicalBuffer {