summaryrefslogtreecommitdiff
path: root/Kernel/Bus/PCI
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2021-12-12 16:33:08 +0200
committerAndreas Kling <kling@serenityos.org>2021-12-14 09:01:33 +0100
commit478f54389903d34a0a5b670d6606c5cc0db1dd4d (patch)
tree854c0afe4bb7ec267a592f8039db33ff2eb9f4d4 /Kernel/Bus/PCI
parent4daf07e69fe8ef641bcb39909f17df7cbfe88a01 (diff)
downloadserenity-478f54389903d34a0a5b670d6606c5cc0db1dd4d.zip
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.
Diffstat (limited to 'Kernel/Bus/PCI')
-rw-r--r--Kernel/Bus/PCI/SysFSPCI.cpp59
-rw-r--r--Kernel/Bus/PCI/SysFSPCI.h13
2 files changed, 53 insertions, 19 deletions
diff --git a/Kernel/Bus/PCI/SysFSPCI.cpp b/Kernel/Bus/PCI/SysFSPCI.cpp
index a2980b2972..dfcc7b52f2 100644
--- a/Kernel/Bus/PCI/SysFSPCI.cpp
+++ b/Kernel/Bus/PCI/SysFSPCI.cpp
@@ -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();
+ }
+}
+
+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(StringView name, const PCIDeviceSysFSDirectory& device, PCI::RegisterOffset offset, size_t field_bytes_width)
- : SysFSComponent(name)
+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)
diff --git a/Kernel/Bus/PCI/SysFSPCI.h b/Kernel/Bus/PCI/SysFSPCI.h
index f7c9a7e967..4f549c45c3 100644
--- a/Kernel/Bus/PCI/SysFSPCI.h
+++ b/Kernel/Bus/PCI/SysFSPCI.h
@@ -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;