hw & imx53: IRQ injection via Vm::proceed
Enhance the VM state, that can be accessed by a VMM, by a member 'unsigned irq_injection'. In Kernel::Vm::proceed check, whether irq_injection is set. If so, check whether irq_injection is a non-secure IRQ. If so, let the PIC raise this IRQ in the VM and reset irq_injection. Ref #1497
This commit is contained in:
parent
0b39b22e14
commit
85ba3259f8
|
@ -31,6 +31,7 @@ struct Genode::Vm_state : Genode::Cpu_state_modes
|
||||||
Genode::addr_t dfar;
|
Genode::addr_t dfar;
|
||||||
Genode::addr_t ttbr[2];
|
Genode::addr_t ttbr[2];
|
||||||
Genode::addr_t ttbrc;
|
Genode::addr_t ttbrc;
|
||||||
|
Genode::addr_t irq_injection;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _INCLUDE__SPEC__IMX53__VM_STATE_H_ */
|
#endif /* _INCLUDE__SPEC__IMX53__VM_STATE_H_ */
|
||||||
|
|
|
@ -43,6 +43,12 @@ class Genode::Pic : public Mmio
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Software Interrupt Trigger Register
|
||||||
|
*/
|
||||||
|
struct Swint : Register<0xf00, 32> {
|
||||||
|
struct Intid : Bitfield<0,10> { }; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interrupt control register
|
* Interrupt control register
|
||||||
*/
|
*/
|
||||||
|
@ -154,6 +160,13 @@ class Genode::Pic : public Mmio
|
||||||
if (valid(i)) { write<Enclear::Clear_enable>(1, i); } }
|
if (valid(i)) { write<Enclear::Clear_enable>(1, i); } }
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trigger interrupt 'i' from software if possible
|
||||||
|
*/
|
||||||
|
void trigger(unsigned const i) {
|
||||||
|
write<Swint>(Swint::Intid::bits(i)); }
|
||||||
|
|
||||||
|
|
||||||
/*************
|
/*************
|
||||||
** Dummies **
|
** Dummies **
|
||||||
*************/
|
*************/
|
||||||
|
|
|
@ -56,8 +56,19 @@ void Vm::exception(unsigned const cpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool secure_irq(unsigned const i);
|
||||||
|
|
||||||
void Vm::proceed(unsigned const cpu)
|
void Vm::proceed(unsigned const cpu)
|
||||||
{
|
{
|
||||||
|
unsigned const irq = _state->irq_injection;
|
||||||
|
if (irq) {
|
||||||
|
if (secure_irq(irq)) {
|
||||||
|
PWRN("Refuse to inject secure IRQ into VM");
|
||||||
|
} else {
|
||||||
|
pic()->trigger(irq);
|
||||||
|
_state->irq_injection = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
mtc()->switch_to(reinterpret_cast<Cpu::Context*>(_state), cpu,
|
mtc()->switch_to(reinterpret_cast<Cpu::Context*>(_state), cpu,
|
||||||
(addr_t)&_mt_nonsecure_entry_pic,
|
(addr_t)&_mt_nonsecure_entry_pic,
|
||||||
(addr_t)&_tz_client_context);
|
(addr_t)&_tz_client_context);
|
||||||
|
|
|
@ -26,6 +26,17 @@ using namespace Genode;
|
||||||
/* monitor exception vector address */
|
/* monitor exception vector address */
|
||||||
extern int _mon_kernel_entry;
|
extern int _mon_kernel_entry;
|
||||||
|
|
||||||
|
bool secure_irq(unsigned const i)
|
||||||
|
{
|
||||||
|
if (i == Board::EPIT_1_IRQ) return true;
|
||||||
|
if (i == Board::EPIT_2_IRQ) return true;
|
||||||
|
if (i == Board::I2C_2_IRQ) return true;
|
||||||
|
if (i == Board::I2C_3_IRQ) return true;
|
||||||
|
if (i >= Board::GPIO1_IRQL && i <= Board::GPIO4_IRQH) return true;
|
||||||
|
if (i >= Board::GPIO5_IRQL && i <= Board::GPIO7_IRQH) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Kernel::init_trustzone(Pic * pic)
|
void Kernel::init_trustzone(Pic * pic)
|
||||||
{
|
{
|
||||||
|
@ -47,14 +58,7 @@ void Kernel::init_trustzone(Pic * pic)
|
||||||
|
|
||||||
/* configure non-secure interrupts */
|
/* configure non-secure interrupts */
|
||||||
for (unsigned i = 0; i < Pic::NR_OF_IRQ; i++) {
|
for (unsigned i = 0; i < Pic::NR_OF_IRQ; i++) {
|
||||||
if ((i != Board::EPIT_1_IRQ) &&
|
if (!secure_irq(i)) { pic->unsecure(i); } }
|
||||||
(i != Board::EPIT_2_IRQ) &&
|
|
||||||
(i != Board::I2C_2_IRQ) &&
|
|
||||||
(i != Board::I2C_3_IRQ) &&
|
|
||||||
(i < Board::GPIO1_IRQL || i > Board::GPIO4_IRQH) &&
|
|
||||||
(i < Board::GPIO5_IRQL || i > Board::GPIO7_IRQH))
|
|
||||||
pic->unsecure(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* configure central security unit */
|
/* configure central security unit */
|
||||||
Genode::Csu csu(Board::CSU_BASE);
|
Genode::Csu csu(Board::CSU_BASE);
|
||||||
|
|
Loading…
Reference in New Issue