1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 16:37:47 +00:00

Kernel/SysFS: Prevent allocation for component name during construction

Instead, allocate before constructing the object and pass NonnullOwnPtr
of KString to the object if needed. Some classes can determine their
names as they have a known attribute to look for or have a static name.
This commit is contained in:
Liav A 2021-12-12 16:33:08 +02:00 committed by Andreas Kling
parent 4daf07e69f
commit 478f543899
17 changed files with 116 additions and 65 deletions

View file

@ -15,21 +15,24 @@ namespace Kernel::PCI {
UNMAP_AFTER_INIT NonnullRefPtr<PCIDeviceSysFSDirectory> PCIDeviceSysFSDirectory::create(const SysFSDirectory& parent_directory, Address address)
{
return adopt_ref(*new (nothrow) PCIDeviceSysFSDirectory(parent_directory, address));
// FIXME: Handle allocation failure gracefully
auto device_name = MUST(KString::try_create(String::formatted("{:04x}:{:02x}:{:02x}.{}", address.domain(), address.bus(), address.device(), address.function())));
return adopt_ref(*new (nothrow) PCIDeviceSysFSDirectory(move(device_name), parent_directory, address));
}
UNMAP_AFTER_INIT PCIDeviceSysFSDirectory::PCIDeviceSysFSDirectory(const SysFSDirectory& parent_directory, Address address)
: SysFSDirectory(String::formatted("{:04x}:{:02x}:{:02x}.{}", address.domain(), address.bus(), address.device(), address.function()), parent_directory)
UNMAP_AFTER_INIT PCIDeviceSysFSDirectory::PCIDeviceSysFSDirectory(NonnullOwnPtr<KString> device_directory_name, const SysFSDirectory& parent_directory, Address address)
: SysFSDirectory(parent_directory)
, m_address(address)
, m_device_directory_name(move(device_directory_name))
{
m_components.append(PCIDeviceAttributeSysFSComponent::create("vendor"sv, *this, PCI::RegisterOffset::VENDOR_ID, 2));
m_components.append(PCIDeviceAttributeSysFSComponent::create("device_id"sv, *this, PCI::RegisterOffset::DEVICE_ID, 2));
m_components.append(PCIDeviceAttributeSysFSComponent::create("class"sv, *this, PCI::RegisterOffset::CLASS, 1));
m_components.append(PCIDeviceAttributeSysFSComponent::create("subclass"sv, *this, PCI::RegisterOffset::SUBCLASS, 1));
m_components.append(PCIDeviceAttributeSysFSComponent::create("revision"sv, *this, PCI::RegisterOffset::REVISION_ID, 1));
m_components.append(PCIDeviceAttributeSysFSComponent::create("progif"sv, *this, PCI::RegisterOffset::PROG_IF, 1));
m_components.append(PCIDeviceAttributeSysFSComponent::create("subsystem_vendor"sv, *this, PCI::RegisterOffset::SUBSYSTEM_VENDOR_ID, 2));
m_components.append(PCIDeviceAttributeSysFSComponent::create("subsystem_id"sv, *this, PCI::RegisterOffset::SUBSYSTEM_ID, 2));
m_components.append(PCIDeviceAttributeSysFSComponent::create(*this, PCI::RegisterOffset::VENDOR_ID, 2));
m_components.append(PCIDeviceAttributeSysFSComponent::create(*this, PCI::RegisterOffset::DEVICE_ID, 2));
m_components.append(PCIDeviceAttributeSysFSComponent::create(*this, PCI::RegisterOffset::CLASS, 1));
m_components.append(PCIDeviceAttributeSysFSComponent::create(*this, PCI::RegisterOffset::SUBCLASS, 1));
m_components.append(PCIDeviceAttributeSysFSComponent::create(*this, PCI::RegisterOffset::REVISION_ID, 1));
m_components.append(PCIDeviceAttributeSysFSComponent::create(*this, PCI::RegisterOffset::PROG_IF, 1));
m_components.append(PCIDeviceAttributeSysFSComponent::create(*this, PCI::RegisterOffset::SUBSYSTEM_VENDOR_ID, 2));
m_components.append(PCIDeviceAttributeSysFSComponent::create(*this, PCI::RegisterOffset::SUBSYSTEM_ID, 2));
}
UNMAP_AFTER_INIT void PCIBusSysFSDirectory::initialize()
@ -39,7 +42,7 @@ UNMAP_AFTER_INIT void PCIBusSysFSDirectory::initialize()
}
UNMAP_AFTER_INIT PCIBusSysFSDirectory::PCIBusSysFSDirectory()
: SysFSDirectory("pci", SysFSComponentRegistry::the().buses_directory())
: SysFSDirectory(SysFSComponentRegistry::the().buses_directory())
{
PCI::enumerate([&](DeviceIdentifier const& device_identifier) {
auto pci_device = PCI::PCIDeviceSysFSDirectory::create(*this, device_identifier.address());
@ -47,13 +50,37 @@ UNMAP_AFTER_INIT PCIBusSysFSDirectory::PCIBusSysFSDirectory()
});
}
NonnullRefPtr<PCIDeviceAttributeSysFSComponent> PCIDeviceAttributeSysFSComponent::create(StringView name, const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width)
StringView PCIDeviceAttributeSysFSComponent::name() const
{
return adopt_ref(*new (nothrow) PCIDeviceAttributeSysFSComponent(name, device, offset, field_bytes_width));
switch (m_offset) {
case PCI::RegisterOffset::VENDOR_ID:
return "vendor"sv;
case PCI::RegisterOffset::DEVICE_ID:
return "device_id"sv;
case PCI::RegisterOffset::CLASS:
return "class"sv;
case PCI::RegisterOffset::SUBCLASS:
return "subclass"sv;
case PCI::RegisterOffset::REVISION_ID:
return "revision"sv;
case PCI::RegisterOffset::PROG_IF:
return "progif"sv;
case PCI::RegisterOffset::SUBSYSTEM_VENDOR_ID:
return "subsystem_vendor"sv;
case PCI::RegisterOffset::SUBSYSTEM_ID:
return "subsystem_id"sv;
default:
VERIFY_NOT_REACHED();
}
}
PCIDeviceAttributeSysFSComponent::PCIDeviceAttributeSysFSComponent(StringView name, const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width)
: SysFSComponent(name)
NonnullRefPtr<PCIDeviceAttributeSysFSComponent> PCIDeviceAttributeSysFSComponent::create(const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width)
{
return adopt_ref(*new (nothrow) PCIDeviceAttributeSysFSComponent(device, offset, field_bytes_width));
}
PCIDeviceAttributeSysFSComponent::PCIDeviceAttributeSysFSComponent(const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width)
: SysFSComponent()
, m_device(device)
, m_offset(offset)
, m_field_bytes_width(field_bytes_width)

View file

@ -15,6 +15,7 @@ namespace Kernel::PCI {
class PCIBusSysFSDirectory final : public SysFSDirectory {
public:
static void initialize();
virtual StringView name() const override { return "pci"sv; }
private:
PCIBusSysFSDirectory();
@ -25,22 +26,28 @@ public:
static NonnullRefPtr<PCIDeviceSysFSDirectory> create(const SysFSDirectory&, Address);
const Address& address() const { return m_address; }
virtual StringView name() const override { return m_device_directory_name->view(); }
private:
PCIDeviceSysFSDirectory(const SysFSDirectory&, Address);
PCIDeviceSysFSDirectory(NonnullOwnPtr<KString> device_directory_name, const SysFSDirectory&, Address);
Address m_address;
NonnullOwnPtr<KString> m_device_directory_name;
};
class PCIDeviceAttributeSysFSComponent : public SysFSComponent {
public:
static NonnullRefPtr<PCIDeviceAttributeSysFSComponent> create(StringView name, const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width);
static NonnullRefPtr<PCIDeviceAttributeSysFSComponent> create(const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width);
virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer&, OpenFileDescription*) const override;
virtual ~PCIDeviceAttributeSysFSComponent() {};
virtual StringView name() const override;
protected:
ErrorOr<NonnullOwnPtr<KBuffer>> try_to_generate_buffer() const;
PCIDeviceAttributeSysFSComponent(StringView name, const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width);
PCIDeviceAttributeSysFSComponent(const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width);
NonnullRefPtr<PCIDeviceSysFSDirectory> m_device;
PCI::RegisterOffset m_offset;
size_t m_field_bytes_width;

View file

@ -13,9 +13,10 @@ namespace Kernel::USB {
static SysFSUSBBusDirectory* s_procfs_usb_bus_directory;
SysFSUSBDeviceInformation::SysFSUSBDeviceInformation(USB::Device& device)
: SysFSComponent(String::number(device.address()))
SysFSUSBDeviceInformation::SysFSUSBDeviceInformation(NonnullOwnPtr<KString> device_name, USB::Device& device)
: SysFSComponent()
, m_device(device)
, m_device_name(move(device_name))
{
}
@ -150,7 +151,7 @@ SysFSUSBBusDirectory& SysFSUSBBusDirectory::the()
}
UNMAP_AFTER_INIT SysFSUSBBusDirectory::SysFSUSBBusDirectory(SysFSBusDirectory& buses_directory)
: SysFSDirectory("usb"sv, buses_directory)
: SysFSDirectory(buses_directory)
{
}
@ -163,7 +164,8 @@ UNMAP_AFTER_INIT void SysFSUSBBusDirectory::initialize()
NonnullRefPtr<SysFSUSBDeviceInformation> SysFSUSBDeviceInformation::create(USB::Device& device)
{
return adopt_ref(*new SysFSUSBDeviceInformation(device));
auto device_name = KString::must_create(String::number(device.address()));
return adopt_ref(*new SysFSUSBDeviceInformation(move(device_name), device));
}
}

View file

@ -20,11 +20,12 @@ public:
virtual ~SysFSUSBDeviceInformation() override;
static NonnullRefPtr<SysFSUSBDeviceInformation> create(USB::Device&);
virtual StringView name() const override { return m_device_name->view(); }
RefPtr<USB::Device> device() const { return m_device; }
protected:
explicit SysFSUSBDeviceInformation(USB::Device& device);
SysFSUSBDeviceInformation(NonnullOwnPtr<KString> device_name, USB::Device& device);
virtual ErrorOr<size_t> read_bytes(off_t offset, size_t count, UserOrKernelBuffer& buffer, OpenFileDescription*) const override;
@ -36,6 +37,7 @@ private:
ErrorOr<void> try_generate(KBufferBuilder&);
virtual ErrorOr<void> refresh_data(OpenFileDescription& description) const override;
mutable Mutex m_lock { "SysFSUSBDeviceInformation" };
NonnullOwnPtr<KString> m_device_name;
};
class SysFSUSBBusDirectory final : public SysFSDirectory {
@ -43,6 +45,8 @@ public:
static void initialize();
static SysFSUSBBusDirectory& the();
virtual StringView name() const override { return "usb"sv; }
void plug(USB::Device&);
void unplug(USB::Device&);