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:
Martin Stein 2015-11-02 14:36:01 +01:00 committed by Christian Helmuth
parent 0b39b22e14
commit 85ba3259f8
4 changed files with 37 additions and 8 deletions

View File

@ -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_ */

View File

@ -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 **
*************/ *************/

View File

@ -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);

View File

@ -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);