mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
platform: pass reserved memory update to IOMMU
Only add default mappings on IOMMU construction and on reserved-memory updates. Issue #5232
This commit is contained in:
parent
6912dd62fa
commit
0aafec038d
@ -90,6 +90,28 @@ class Driver::Common : Device_reporter,
|
||||
|
||||
void Driver::Common::acquire_io_mmu_devices()
|
||||
{
|
||||
auto init_default_mappings = [&] (Io_mmu & io_mmu_dev) {
|
||||
_devices.for_each([&] (Device const & device) {
|
||||
device.with_optional_io_mmu(io_mmu_dev.name(), [&] () {
|
||||
bool has_reserved_mem = false;
|
||||
device.for_each_reserved_memory([&] (unsigned,
|
||||
Io_mmu::Range range) {
|
||||
io_mmu_dev.add_default_range(range, range.start);
|
||||
has_reserved_mem = true;
|
||||
});
|
||||
|
||||
if (!has_reserved_mem)
|
||||
return;
|
||||
|
||||
/* enable default mappings for corresponding pci devices */
|
||||
device.for_pci_config([&] (Device::Pci_config const & cfg) {
|
||||
io_mmu_dev.enable_default_mappings(
|
||||
{cfg.bus_num, cfg.dev_num, cfg.func_num});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
_io_mmu_factories.for_each([&] (Io_mmu_factory & factory) {
|
||||
|
||||
_devices.for_each([&] (Device & dev) {
|
||||
@ -99,6 +121,11 @@ void Driver::Common::acquire_io_mmu_devices()
|
||||
if (factory.matches(dev)) {
|
||||
dev.acquire(*this);
|
||||
factory.create(_heap, _io_mmu_devices, dev);
|
||||
|
||||
_io_mmu_devices.for_each([&] (Io_mmu & io_mmu_dev) {
|
||||
if (io_mmu_dev.name() == dev.name())
|
||||
init_default_mappings(io_mmu_dev);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -117,31 +144,6 @@ void Driver::Common::acquire_io_mmu_devices()
|
||||
if (device_present && !mpu_present)
|
||||
_root.enable_dma_remapping();
|
||||
|
||||
/* iterate devices and add default mappings */
|
||||
_devices.for_each([&] (Device & device) {
|
||||
device.for_each_io_mmu([&] (Device::Io_mmu const & io_mmu) {
|
||||
_io_mmu_devices.for_each([&] (Io_mmu & io_mmu_dev) {
|
||||
if (io_mmu_dev.name() == io_mmu.name) {
|
||||
bool has_reserved_mem = false;
|
||||
device.for_each_reserved_memory([&] (unsigned,
|
||||
Io_mmu::Range range) {
|
||||
io_mmu_dev.add_default_range(range, range.start);
|
||||
has_reserved_mem = true;
|
||||
});
|
||||
|
||||
if (!has_reserved_mem)
|
||||
return;
|
||||
|
||||
/* enable default mappings for corresponding pci devices */
|
||||
device.for_pci_config([&] (Device::Pci_config const & cfg) {
|
||||
io_mmu_dev.enable_default_mappings(
|
||||
{cfg.bus_num, cfg.dev_num, cfg.func_num});
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [&] () { /* empty list fn */ });
|
||||
});
|
||||
|
||||
bool kernel_iommu_present { false };
|
||||
_io_mmu_devices.for_each([&] (Io_mmu & io_mmu_dev) {
|
||||
io_mmu_dev.default_mappings_complete();
|
||||
|
@ -417,6 +417,15 @@ class Driver::Device : private List_model<Device>::Element
|
||||
empty_fn();
|
||||
}
|
||||
|
||||
template <typename FN>
|
||||
void with_optional_io_mmu(Io_mmu::Name const & name, FN && fn) const
|
||||
{
|
||||
_io_mmu_list.for_each([&] (Io_mmu const & io_mmu) {
|
||||
if (io_mmu.name == name)
|
||||
fn();
|
||||
});
|
||||
}
|
||||
|
||||
void generate(Xml_generator &, bool) const;
|
||||
|
||||
void update(Allocator &, Xml_node const &, Reserved_memory_handler &);
|
||||
|
@ -76,6 +76,18 @@ void Driver::Root::add_range(Device const & dev, Range const & range)
|
||||
sc._dma_allocator.reserve(range.start, range.size);
|
||||
});
|
||||
|
||||
/* add default mapping and enable for corresponding pci device */
|
||||
_io_mmu_devices.for_each([&] (Io_mmu & io_mmu_dev) {
|
||||
dev.with_optional_io_mmu(io_mmu_dev.name(), [&] () {
|
||||
|
||||
io_mmu_dev.add_default_range(range, range.start);
|
||||
dev.for_pci_config([&] (Device::Pci_config const & cfg) {
|
||||
io_mmu_dev.enable_default_mappings(
|
||||
{cfg.bus_num, cfg.dev_num, cfg.func_num});
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -85,6 +97,12 @@ void Driver::Root::remove_range(Device const & dev, Range const & range)
|
||||
if (!sc.matches(dev)) return;
|
||||
sc._dma_allocator.unreserve(range.start, range.size);
|
||||
});
|
||||
|
||||
/*
|
||||
* remark: There is no need to remove default mappings since once known
|
||||
* default mappings should be preserved. Double-insertion in case
|
||||
* mapping are re-added at a later point in time is taken care of.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -132,12 +132,8 @@ void Session_component::update_io_mmu_devices()
|
||||
if (used_by_owned_device)
|
||||
return;
|
||||
|
||||
dev.for_each_io_mmu(
|
||||
[&] (Device::Io_mmu const & io_mmu) {
|
||||
if (io_mmu.name == io_mmu_dev.name())
|
||||
used_by_owned_device = true;
|
||||
},
|
||||
[&] () { });
|
||||
dev.with_optional_io_mmu(io_mmu_dev.name(), [&] () {
|
||||
used_by_owned_device = true; });
|
||||
});
|
||||
|
||||
/* synchronise with IOMMU domains */
|
||||
|
Loading…
x
Reference in New Issue
Block a user