mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-09 04:15:52 +00:00
os: enable smp support for ARM vmm
* Fix GIC model to support priority and cpu target settings correspondingly * Fix semantic of SGIR register for GICv2 * Minor GIC model IRQ state fix * Introduce synchronization for VirtIO and GIC models * Enable multiple CPUs in test run-script for ARMv8 Fix #3926
This commit is contained in:
parent
6be09a27ca
commit
429cd8d37a
@ -150,7 +150,7 @@ if { [have_spec arm_64] } {
|
||||
|
||||
if {![file exists bin/dtb]} {
|
||||
puts "Download device tree blob ..."
|
||||
exec >& /dev/null wget -c -O bin/dtb http://genode.org/files/release-20.02/dtb-arm64-virt
|
||||
exec >& /dev/null wget -c -O bin/dtb http://genode.org/files/release-20.11/dtb-arm64-virt-smp
|
||||
}
|
||||
|
||||
if {![file exists bin/initrd]} {
|
||||
@ -216,4 +216,4 @@ build_boot_image $boot_modules
|
||||
#
|
||||
append qemu_args " -nographic "
|
||||
run_genode_until "\[init -> vm\] .*sbin.*" 220
|
||||
exec rm bin/linux bin/dtb
|
||||
exec rm bin/linux bin/dtb bin/initrd
|
||||
|
@ -90,6 +90,7 @@ void Cpu_base::_handle_sync()
|
||||
{
|
||||
/* check device number*/
|
||||
switch (Esr::Ec::get(_state.esr_el2)) {
|
||||
case Esr::Ec::HVC_32: [[fallthrough]];
|
||||
case Esr::Ec::HVC:
|
||||
_handle_hyper_call();
|
||||
break;
|
||||
@ -137,6 +138,7 @@ void Cpu_base::_handle_hyper_call()
|
||||
case Psci::PSCI_FEATURES:
|
||||
_state.reg(0, Psci::NOT_SUPPORTED);
|
||||
return;
|
||||
case Psci::CPU_ON_32: [[fallthrough]];
|
||||
case Psci::CPU_ON:
|
||||
_vm.cpu((unsigned)_state.reg(1), [&] (Cpu & cpu) {
|
||||
cpu.state().ip = _state.reg(2);
|
||||
|
@ -45,6 +45,7 @@ class Vmm::Cpu_base
|
||||
enum {
|
||||
WFI = 0x1,
|
||||
MRC_MCR = 0x3,
|
||||
HVC_32 = 0x12,
|
||||
HVC = 0x16,
|
||||
MRS_MSR = 0x18,
|
||||
DA = 0x24,
|
||||
@ -219,6 +220,10 @@ class Vmm::Cpu_base
|
||||
void _handle_data_abort();
|
||||
void _handle_hyper_call();
|
||||
void _update_state();
|
||||
|
||||
public:
|
||||
|
||||
Vm & vm() { return _vm; }
|
||||
};
|
||||
|
||||
#endif /* _SRC__SERVER__VMM__CPU_BASE_H_ */
|
||||
|
@ -58,8 +58,9 @@ void Generic_timer::schedule_timeout()
|
||||
}
|
||||
|
||||
if (_enabled()) {
|
||||
if (_usecs_left()) {
|
||||
_timeout.schedule(Genode::Microseconds(_usecs_left()));
|
||||
Genode::uint64_t usecs = _usecs_left();
|
||||
if (usecs) {
|
||||
_timeout.schedule(Genode::Microseconds(usecs));
|
||||
} else _handle_timeout(Genode::Duration(Genode::Microseconds(0)));
|
||||
}
|
||||
}
|
||||
@ -67,7 +68,7 @@ void Generic_timer::schedule_timeout()
|
||||
|
||||
void Generic_timer::cancel_timeout()
|
||||
{
|
||||
if (_timeout.scheduled()) _timeout.discard();
|
||||
if (_timeout.scheduled()) { _timeout.discard(); }
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,6 +18,13 @@
|
||||
using Vmm::Gic;
|
||||
using Register = Vmm::Mmio_register::Register;
|
||||
|
||||
static Genode::Mutex & big_gic_lock()
|
||||
{
|
||||
static Genode::Mutex mutex;
|
||||
return mutex;
|
||||
}
|
||||
|
||||
|
||||
bool Gic::Irq::enabled() const { return _enabled; }
|
||||
|
||||
bool Gic::Irq::active() const {
|
||||
@ -52,10 +59,10 @@ void Gic::Irq::disable()
|
||||
void Gic::Irq::activate()
|
||||
{
|
||||
switch (_state) {
|
||||
case INACTIVE: return;
|
||||
case PENDING: return;
|
||||
case ACTIVE_PENDING: _state = PENDING; return;
|
||||
case ACTIVE: _state = INACTIVE; return;
|
||||
case INACTIVE: _state = ACTIVE; return;
|
||||
case PENDING: _state = ACTIVE_PENDING; return;
|
||||
case ACTIVE_PENDING: return;
|
||||
case ACTIVE: return;
|
||||
};
|
||||
}
|
||||
|
||||
@ -75,6 +82,8 @@ void Gic::Irq::assert()
|
||||
{
|
||||
if (pending()) return;
|
||||
|
||||
Genode::Mutex::Guard guard(big_gic_lock());
|
||||
|
||||
_state = PENDING;
|
||||
_pending_list.insert(*this);
|
||||
}
|
||||
@ -84,6 +93,8 @@ void Gic::Irq::deassert()
|
||||
{
|
||||
if (_state == INACTIVE) return;
|
||||
|
||||
Genode::Mutex::Guard guard(big_gic_lock());
|
||||
|
||||
_state = INACTIVE;
|
||||
_pending_list.remove(this);
|
||||
if (_handler) _handler->eoi();
|
||||
@ -124,17 +135,17 @@ Gic::Irq::Irq(unsigned num, Type t, Irq::List & l)
|
||||
void Gic::Irq::List::insert(Irq & irq)
|
||||
{
|
||||
Irq * i = first();
|
||||
while (i && i->priority() < irq.priority() && i->next()) i = i->next();
|
||||
while (i && i->priority() <= irq.priority() && i->next()) i = i->next();
|
||||
Genode::List<Irq>::insert(&irq, i);
|
||||
}
|
||||
|
||||
|
||||
Gic::Irq * Gic::Irq::List::highest_enabled()
|
||||
Gic::Irq * Gic::Irq::List::highest_enabled(unsigned cpu_id)
|
||||
{
|
||||
Irq * i = first();
|
||||
while(i) {
|
||||
if (i->enabled()) return i;
|
||||
i = i->next();
|
||||
for (Irq * i = first(); i; i = i->next()) {
|
||||
if (!i->enabled() || i->active()) { continue; }
|
||||
if (cpu_id < ~0U && (i->target() != cpu_id)) { continue; }
|
||||
return i;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -165,6 +176,8 @@ void Gic::Gicd_banked::handle_irq()
|
||||
|
||||
bool Gic::Gicd_banked::pending_irq()
|
||||
{
|
||||
Genode::Mutex::Guard guard(big_gic_lock());
|
||||
|
||||
if (_cpu.state().irqs.virtual_irq != SPURIOUS) return true;
|
||||
|
||||
Irq * i = _gic._pending_list.highest_enabled();
|
||||
@ -202,6 +215,8 @@ Gic::Gicd_banked::Gicd_banked(Cpu_base & cpu, Gic & gic, Mmio_bus & bus)
|
||||
|
||||
Register Gic::Irq_reg::read(Address_range & access, Cpu & cpu)
|
||||
{
|
||||
Genode::Mutex::Guard guard(big_gic_lock());
|
||||
|
||||
Register ret = 0;
|
||||
|
||||
Register bits_per_irq = size * 8 / irq_count;
|
||||
@ -214,6 +229,8 @@ Register Gic::Irq_reg::read(Address_range & access, Cpu & cpu)
|
||||
|
||||
void Gic::Irq_reg::write(Address_range & access, Cpu & cpu, Register value)
|
||||
{
|
||||
Genode::Mutex::Guard guard(big_gic_lock());
|
||||
|
||||
Register bits_per_irq = size * 8 / irq_count;
|
||||
Register irq_value_mask = (1<<bits_per_irq) - 1;
|
||||
for (unsigned i = (access.start * 8) / bits_per_irq;
|
||||
@ -226,6 +243,50 @@ void Gic::Irq_reg::write(Address_range & access, Cpu & cpu, Register value)
|
||||
unsigned Gic::version() { return _version; }
|
||||
|
||||
|
||||
void Gic::Gicd_sgir::write(Address_range &, Cpu & cpu,
|
||||
Mmio_register::Register value)
|
||||
{
|
||||
Target_filter::Target_type type =
|
||||
(Target_filter::Target_type) Target_filter::get(value);
|
||||
unsigned target_list = Target_list::get(value);
|
||||
unsigned irq = Int_id::get(value);
|
||||
|
||||
for (unsigned i = 0; i <= Vm::last_cpu(); i++) {
|
||||
switch (type) {
|
||||
case Target_filter::MYSELF:
|
||||
if (i != cpu.cpu_id()) { continue; }
|
||||
break;
|
||||
case Target_filter::ALL:
|
||||
if (i == cpu.cpu_id()) { continue; }
|
||||
break;
|
||||
case Target_filter::LIST:
|
||||
if (!(target_list & (1<<i))) { continue; }
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
};
|
||||
|
||||
cpu.vm().cpu(i, [&] (Cpu & c) {
|
||||
c.gic().irq(irq).assert();
|
||||
if (cpu.cpu_id() != c.cpu_id()) { cpu.recall(); }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Register Gic::Gicd_itargetr::read(Address_range & access, Cpu & cpu)
|
||||
{
|
||||
if (access.start < 0x20) { return (1 << cpu.cpu_id()) << 8; }
|
||||
return Irq_reg::read(access, cpu);
|
||||
}
|
||||
|
||||
|
||||
void Gic::Gicd_itargetr::write(Address_range & access, Cpu & cpu, Register value)
|
||||
{
|
||||
if (access.start >= 0x20) { Irq_reg::write(access, cpu, value); }
|
||||
}
|
||||
|
||||
|
||||
Gic::Gic(const char * const name,
|
||||
const Genode::uint64_t addr,
|
||||
const Genode::uint64_t size,
|
||||
|
@ -47,7 +47,7 @@ class Vmm::Gic : public Vmm::Mmio_device
|
||||
struct List : Genode::List<Irq>
|
||||
{
|
||||
void insert(Irq & irq);
|
||||
Irq * highest_enabled();
|
||||
Irq * highest_enabled(unsigned cpu_id = ~0U);
|
||||
};
|
||||
|
||||
struct Irq_handler {
|
||||
@ -92,7 +92,7 @@ class Vmm::Gic : public Vmm::Mmio_device
|
||||
Config _config { LEVEL };
|
||||
unsigned _num { 0 };
|
||||
Genode::uint8_t _prio { 0 };
|
||||
Genode::uint8_t _target { 1 };
|
||||
Genode::uint8_t _target { 0 };
|
||||
List & _pending_list;
|
||||
Irq_handler * _handler { nullptr };
|
||||
};
|
||||
@ -382,6 +382,9 @@ class Vmm::Gic : public Vmm::Mmio_device
|
||||
Register read(Irq & irq) { return irq.target(); }
|
||||
void write(Irq & irq, Register v) { irq.target(v); }
|
||||
|
||||
Register read(Address_range & access, Cpu&) override;
|
||||
void write(Address_range & access, Cpu&, Register value) override;
|
||||
|
||||
Gicd_itargetr()
|
||||
: Irq_reg("GICD_ITARGETSR", Mmio_register::RW, 0x800, 8, 1024) {}
|
||||
} _itargetr;
|
||||
@ -398,14 +401,14 @@ class Vmm::Gic : public Vmm::Mmio_device
|
||||
|
||||
struct Gicd_sgir : Genode::Register<32>, Mmio_register
|
||||
{
|
||||
struct Enable : Bitfield<0, 1> {};
|
||||
struct Disable : Bitfield<6, 1> {};
|
||||
struct Int_id : Bitfield<0, 4> {};
|
||||
struct Target_list : Bitfield<16, 8> {};
|
||||
struct Target_filter : Bitfield<24, 2> {
|
||||
enum Target_type { LIST, ALL, MYSELF, INVALID };
|
||||
};
|
||||
|
||||
void write(Address_range & access, Cpu & cpu,
|
||||
Mmio_register::Register value) override
|
||||
{
|
||||
Genode::error("SGIR WRITE ", value);
|
||||
}
|
||||
Mmio_register::Register value) override;
|
||||
|
||||
Gicd_sgir()
|
||||
: Mmio_register("GICD_SGIR", Mmio_register::WO, 0xf00, 4, 0) {}
|
||||
@ -414,8 +417,10 @@ class Vmm::Gic : public Vmm::Mmio_device
|
||||
|
||||
struct Gicd_irouter : Irq_reg
|
||||
{
|
||||
Register read(Irq &) { return 0x0; } // FIXME smp
|
||||
void write(Irq &, Register) { }
|
||||
Register read(Irq &) { return 0x0; } /* FIXME affinity routing support */
|
||||
|
||||
void write(Irq & i, Register v) {
|
||||
if (v) Genode::error("Affinity routing not supported ", i.number()); }
|
||||
|
||||
Gicd_irouter()
|
||||
: Irq_reg("GICD_IROUTER", Mmio_register::RW, 0x6100, 64, 1024) {}
|
||||
|
@ -21,6 +21,7 @@ namespace Vmm {
|
||||
PSCI_VERSION = 0x84000000,
|
||||
MIGRATE_INFO_TYPE = 0x84000006,
|
||||
PSCI_FEATURES = 0x8400000a,
|
||||
CPU_ON_32 = 0x84000003,
|
||||
CPU_ON = 0xc4000003,
|
||||
};
|
||||
|
||||
|
@ -186,4 +186,5 @@ Cpu::Cpu(Vm & vm,
|
||||
{
|
||||
_state.cpsr = 0x93; /* el1 mode and IRQs disabled */
|
||||
_state.sctrl = 0xc50078;
|
||||
_state.vmpidr = (1UL << 31) | cpu_id();
|
||||
}
|
||||
|
@ -14,9 +14,18 @@
|
||||
compatible = "arm,cortex-a15";
|
||||
reg = <0x00>;
|
||||
device_type = "cpu";
|
||||
enable-method = "psci";
|
||||
};
|
||||
};
|
||||
|
||||
psci {
|
||||
compatible = "arm,psci-1.0";
|
||||
method = "hvc";
|
||||
cpu_suspend = <0xc4000001>;
|
||||
cpu_off = <0xc4000002>;
|
||||
cpu_on = <0xc4000003>;
|
||||
};
|
||||
|
||||
timer {
|
||||
interrupts = <0x01 0x0d 0x04 0x01 0x0e 0x04 0x01 0x0b 0x04 0x01 0x0a 0x04>;
|
||||
compatible = "arm,armv7-timer";
|
||||
|
@ -46,7 +46,7 @@ namespace Vmm {
|
||||
|
||||
VTIMER_IRQ = 27,
|
||||
|
||||
MAX_CPUS = 1,
|
||||
MAX_CPUS = 4,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -4,39 +4,75 @@
|
||||
compatible = "linux,dummy-virt";
|
||||
#address-cells = <0x02>;
|
||||
#size-cells = <0x02>;
|
||||
interrupt-parent = <0x8001>;
|
||||
interrupt-parent = <&gic>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <0x01>;
|
||||
#size-cells = <0x00>;
|
||||
|
||||
cpu@0 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x00>;
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x00>;
|
||||
device_type = "cpu";
|
||||
enable-method = "psci";
|
||||
};
|
||||
|
||||
cpu@1 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x01>;
|
||||
device_type = "cpu";
|
||||
enable-method = "psci";
|
||||
};
|
||||
|
||||
cpu@2 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x02>;
|
||||
device_type = "cpu";
|
||||
enable-method = "psci";
|
||||
};
|
||||
|
||||
cpu@3 {
|
||||
compatible = "arm,cortex-a53";
|
||||
reg = <0x03>;
|
||||
device_type = "cpu";
|
||||
enable-method = "psci";
|
||||
};
|
||||
};
|
||||
|
||||
psci {
|
||||
compatible = "arm,psci-1.0";
|
||||
method = "hvc";
|
||||
cpu_suspend = <0xc4000001>;
|
||||
cpu_off = <0xc4000002>;
|
||||
cpu_on = <0xc4000003>;
|
||||
};
|
||||
|
||||
timer {
|
||||
interrupts = <0x01 0x0d 0x04 0x01 0x0e 0x04 0x01 0x0b 0x04 0x01 0x0a 0x04>;
|
||||
compatible = "arm,armv8-timer\0arm,armv7-timer";
|
||||
compatible = "arm,armv8-timer", "arm,armv7-timer";
|
||||
always-on;
|
||||
};
|
||||
|
||||
apb-pclk {
|
||||
compatible = "fixed-clock";
|
||||
phandle = <0x8000>;
|
||||
clock-output-names = "clk24mhz";
|
||||
clock-frequency = <0x16e3600>;
|
||||
#clock-cells = <0x00>;
|
||||
clocks {
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
clk_24mhz: clk@0 {
|
||||
compatible = "fixed-clock";
|
||||
clock-output-names = "clk24mhz";
|
||||
clock-frequency = <0x16e3600>;
|
||||
#clock-cells = <0x00>;
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
pl011@9000000 {
|
||||
interrupts = <0x00 0x01 0x04>;
|
||||
compatible = "arm,pl011\0arm,primecell";
|
||||
clock-names = "uartclk\0apb_pclk";
|
||||
compatible = "arm,pl011", "arm,primecell";
|
||||
clock-names = "uartclk", "apb_pclk";
|
||||
reg = <0x00 0x9000000 0x00 0x1000>;
|
||||
clocks = <0x8000 0x8000>;
|
||||
clocks = <&clk_24mhz>, <&clk_24mhz>;
|
||||
};
|
||||
|
||||
memory@40000000 {
|
||||
@ -45,17 +81,17 @@
|
||||
};
|
||||
|
||||
chosen {
|
||||
/* bootargs = "rdinit=/bin/sh console=hvc0 earlycon=pl011,0x9000000"; */
|
||||
/*bootargs = "rdinit=/bin/sh console=hvc0 earlycon=pl011,0x9000000";*/
|
||||
bootargs = "init=/sbin/init ip=dhcp console=hvc0";
|
||||
linux,initrd-start = <0x42000000>;
|
||||
linux,initrd-end = <0x420aa539>;
|
||||
stdout-path = "/pl011@9000000";
|
||||
};
|
||||
|
||||
intc@8000000 {
|
||||
gic: intc@8000000 {
|
||||
compatible = "arm,gic-v3";
|
||||
phandle = <0x8001>;
|
||||
reg = <0x00 0x8000000 0x00 0x10000 0x00 0x80a0000 0x00 0xf60000>;
|
||||
reg = <0x00 0x8000000 0x00 0x10000>,
|
||||
<0x00 0x80a0000 0x00 0xf60000>;
|
||||
ranges;
|
||||
#address-cells = <0x02>;
|
||||
#redistributor-regions = <0x01>;
|
||||
|
@ -32,6 +32,8 @@ class Vmm::Virtio_console : public Virtio_device
|
||||
|
||||
void _read()
|
||||
{
|
||||
Genode::Mutex::Guard guard(_mutex);
|
||||
|
||||
auto read = [&] (addr_t data, size_t size)
|
||||
{
|
||||
if (!_terminal.avail()) return 0ul;
|
||||
@ -61,6 +63,7 @@ class Vmm::Virtio_console : public Virtio_device
|
||||
}
|
||||
|
||||
Register _device_specific_features() { return 0; }
|
||||
|
||||
public:
|
||||
|
||||
Virtio_console(const char * const name,
|
||||
|
@ -225,6 +225,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
Genode::Constructible<Virtio_queue> _queue[NUM];
|
||||
Gic::Irq &_irq;
|
||||
Ram &_ram;
|
||||
Genode::Mutex _mutex;
|
||||
|
||||
struct Dummy {
|
||||
Mmio_register regs[7];
|
||||
@ -344,6 +345,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
|
||||
void write(Address_range&, Cpu&, Register reg) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
if (reg >= device.NUM) return;
|
||||
device._queue_select(reg);
|
||||
}
|
||||
@ -359,6 +361,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
|
||||
void write(Address_range&, Cpu&, Register reg) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
device._queue_data().num = Genode::min(reg,
|
||||
device._reg_container.regs[6].value());
|
||||
}
|
||||
@ -374,11 +377,13 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
|
||||
Register read(Address_range&, Cpu&) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
return device._queue_data().ready;
|
||||
}
|
||||
|
||||
void write(Address_range&, Cpu&, Register reg) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
bool construct = reg == 1 ? true : false;
|
||||
device._queue_data().ready = reg;
|
||||
device._queue_state(construct);
|
||||
@ -395,6 +400,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
|
||||
void write(Address_range&, Cpu&, Register reg) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
if (!device._queue[reg].constructed()) return;
|
||||
|
||||
device._notify(reg);
|
||||
@ -411,6 +417,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
|
||||
void write(Address_range&, Cpu&, Register reg) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
device._queue_data().descr_low = reg;
|
||||
}
|
||||
|
||||
@ -425,6 +432,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
|
||||
void write(Address_range&, Cpu&, Register reg) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
device._queue_data().descr_high = reg;
|
||||
}
|
||||
|
||||
@ -439,6 +447,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
|
||||
void write(Address_range&, Cpu&, Register reg) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
device._queue_data().driver_low = reg;
|
||||
}
|
||||
|
||||
@ -453,6 +462,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
|
||||
void write(Address_range&, Cpu&, Register reg) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
device._queue_data().driver_high = reg;
|
||||
}
|
||||
|
||||
@ -467,6 +477,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
|
||||
void write(Address_range&, Cpu&, Register reg) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
device._queue_data().device_low = reg;
|
||||
}
|
||||
|
||||
@ -481,6 +492,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
|
||||
void write(Address_range&, Cpu&, Register reg) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
device._queue_data().device_high = reg;
|
||||
}
|
||||
|
||||
@ -507,6 +519,7 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
|
||||
void write(Address_range&, Cpu&, Register reg) override
|
||||
{
|
||||
Genode::Mutex::Guard guard(device.mutex());
|
||||
device._deassert_irq();
|
||||
}
|
||||
|
||||
@ -525,6 +538,8 @@ class Vmm::Virtio_device : public Vmm::Mmio_device
|
||||
Mmio_bus &bus,
|
||||
Ram &ram,
|
||||
unsigned queue_size = 8);
|
||||
|
||||
Genode::Mutex & mutex() { return _mutex; }
|
||||
};
|
||||
|
||||
#endif /* _VIRTIO_DEVICE_H_ */
|
||||
|
@ -109,6 +109,8 @@ class Vmm::Virtio_net : public Virtio_device
|
||||
|
||||
void _handle()
|
||||
{
|
||||
Genode::Mutex::Guard guard(_mutex);
|
||||
|
||||
_rx();
|
||||
_tx();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user