platform_drv: transfer of quota to device_pd

Issue #2507
This commit is contained in:
Alexander Boettcher 2017-09-15 12:59:57 +02:00 committed by Christian Helmuth
parent c66c23b7f1
commit 1cc09ac786
2 changed files with 32 additions and 19 deletions

View File

@ -15,6 +15,7 @@
/* base */ /* base */
#include <base/env.h> #include <base/env.h>
#include <os/ram_session_guard.h>
#include <region_map/client.h> #include <region_map/client.h>
#include <pd_session/connection.h> #include <pd_session/connection.h>
@ -41,11 +42,15 @@ class Platform::Device_pd
struct Expanding_region_map_client : Genode::Region_map_client struct Expanding_region_map_client : Genode::Region_map_client
{ {
Genode::Env &_env; Genode::Env &_env;
Genode::Pd_connection &_pd;
Genode::Ram_session_guard &ram_guard;
Expanding_region_map_client(Genode::Env &env, Expanding_region_map_client(Genode::Env &env,
Genode::Capability<Genode::Region_map> address_space) Genode::Pd_connection &pd,
Genode::Ram_session_guard &ram_guard)
: :
Region_map_client(address_space), _env(env) Region_map_client(pd.address_space()), _env(env), _pd(pd),
ram_guard(ram_guard)
{ } { }
Local_addr attach(Genode::Dataspace_capability ds, Local_addr attach(Genode::Dataspace_capability ds,
@ -64,35 +69,46 @@ class Platform::Device_pd
executable); }, executable); },
[&] () { [&] () {
enum { UPGRADE_CAP_QUOTA = 2 }; enum { UPGRADE_CAP_QUOTA = 2 };
/* XXX actually we would need here a ram_cap
* guard per session, not the process global
* cap env to check for enough caps */
if (_env.pd().avail_caps().value < UPGRADE_CAP_QUOTA) if (_env.pd().avail_caps().value < UPGRADE_CAP_QUOTA)
throw; throw;
Genode::String<32> arg("cap_quota=", (unsigned)UPGRADE_CAP_QUOTA); _env.pd().transfer_quota(_pd, Genode::Cap_quota{UPGRADE_CAP_QUOTA});
_env.upgrade(Genode::Parent::Env::pd(), arg.string());
} }
); );
}, },
[&] () { [&] () {
enum { UPGRADE_RAM_QUOTA = 4096 }; enum { UPGRADE_RAM_QUOTA = 4096 };
if (_env.ram().avail_ram().value < UPGRADE_RAM_QUOTA) if (!ram_guard.withdraw(UPGRADE_RAM_QUOTA))
throw; throw;
Genode::String<32> arg("ram_quota=", (unsigned)UPGRADE_RAM_QUOTA); _env.pd().transfer_quota(_pd, Genode::Ram_quota{UPGRADE_RAM_QUOTA});
_env.upgrade(Genode::Parent::Env::pd(), arg.string());
} }
); );
} }
Local_addr attach_at(Genode::Dataspace_capability ds,
Genode::addr_t local_addr,
Genode::size_t size = 0,
Genode::off_t offset = 0) {
return attach(ds, size, offset, true, local_addr); };
} _address_space; } _address_space;
public: public:
Device_pd(Genode::Env &env, Device_pd(Genode::Env &env,
Genode::Session_label const &label) Genode::Session_label const &label,
Genode::Ram_session_guard &ram_guard)
: :
_pd(env, label.string(), Genode::Pd_connection::Virt_space::UNCONSTRAIN), _pd(env, label.string(), Genode::Pd_connection::Virt_space::UNCONSTRAIN),
_label(label), _label(label),
_address_space(env, _pd.address_space()) _address_space(env, _pd, ram_guard)
{ } {
_pd.ref_account(env.pd_session_cap());
}
void attach_dma_mem(Genode::Dataspace_capability); void attach_dma_mem(Genode::Dataspace_capability);
void assign_pci(Genode::Io_mem_dataspace_capability, Genode::uint16_t); void assign_pci(Genode::Io_mem_dataspace_capability, Genode::uint16_t);

View File

@ -232,7 +232,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
return false; return false;
} }
Platform::Device_pd _device_pd { _env, _label }; Platform::Device_pd _device_pd { _env, _label, _env_ram };
enum { MAX_PCI_DEVICES = Device_config::MAX_BUSES * enum { MAX_PCI_DEVICES = Device_config::MAX_BUSES *
Device_config::MAX_DEVICES * Device_config::MAX_DEVICES *
@ -684,10 +684,8 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
if (bdf_in_use.get(Device_config::MAX_BUSES * bus + if (bdf_in_use.get(Device_config::MAX_BUSES * bus +
Device_config::MAX_DEVICES * device + Device_config::MAX_DEVICES * device +
function, 1)) function, 1))
Genode::error("Device ", Genode::error("Device ", config,
Genode::Hex(bus), ":", " is used by more than one driver - "
Genode::Hex(device), ".", function, " "
"is used by more than one driver - "
"session '", _label, "'."); "session '", _label, "'.");
else else
bdf_in_use.set(Device_config::MAX_BUSES * bus + bdf_in_use.set(Device_config::MAX_BUSES * bus +
@ -794,16 +792,15 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
return ram_cap; return ram_cap;
try { _device_pd.attach_dma_mem(ram_cap); } try { _device_pd.attach_dma_mem(ram_cap); }
catch (Out_of_ram) { _rollback(size, ram_cap);; } catch (Out_of_ram) { _rollback(size, ram_cap); }
catch (Out_of_caps) { catch (Out_of_caps) {
Genode::warning("Out_of_caps while attaching DMA memory"); Genode::warning("Out_of_caps while attaching DMA memory");
_rollback(size, ram_cap);; _rollback(size, ram_cap);
} }
try { _insert(ram_cap); } try { _insert(ram_cap); }
catch (Genode::Out_of_ram) { catch (Genode::Out_of_ram) {
_rollback(size, ram_cap); _rollback(size, ram_cap);
throw;
} }
return ram_cap; return ram_cap;