From 85ba3259f8f15166d178cfebbc1dac573eaed873 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Mon, 2 Nov 2015 14:36:01 +0100 Subject: [PATCH] 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 --- repos/base-hw/include/spec/imx53/vm_state.h | 1 + .../base-hw/src/core/include/spec/imx53/pic.h | 13 ++++++++++++ .../core/spec/arm_v7/trustzone/kernel/vm.cc | 11 ++++++++++ .../spec/imx53/trustzone/platform_support.cc | 20 +++++++++++-------- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/repos/base-hw/include/spec/imx53/vm_state.h b/repos/base-hw/include/spec/imx53/vm_state.h index 0dcc0506b..26dad041c 100644 --- a/repos/base-hw/include/spec/imx53/vm_state.h +++ b/repos/base-hw/include/spec/imx53/vm_state.h @@ -31,6 +31,7 @@ struct Genode::Vm_state : Genode::Cpu_state_modes Genode::addr_t dfar; Genode::addr_t ttbr[2]; Genode::addr_t ttbrc; + Genode::addr_t irq_injection; }; #endif /* _INCLUDE__SPEC__IMX53__VM_STATE_H_ */ diff --git a/repos/base-hw/src/core/include/spec/imx53/pic.h b/repos/base-hw/src/core/include/spec/imx53/pic.h index ff0035ac3..92894899a 100644 --- a/repos/base-hw/src/core/include/spec/imx53/pic.h +++ b/repos/base-hw/src/core/include/spec/imx53/pic.h @@ -43,6 +43,12 @@ class Genode::Pic : public Mmio protected: + /** + * Software Interrupt Trigger Register + */ + struct Swint : Register<0xf00, 32> { + struct Intid : Bitfield<0,10> { }; }; + /** * Interrupt control register */ @@ -154,6 +160,13 @@ class Genode::Pic : public Mmio if (valid(i)) { write(1, i); } } + /* + * Trigger interrupt 'i' from software if possible + */ + void trigger(unsigned const i) { + write(Swint::Intid::bits(i)); } + + /************* ** Dummies ** *************/ diff --git a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc index 41b57f554..2e7e0d898 100644 --- a/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc @@ -56,8 +56,19 @@ void Vm::exception(unsigned const cpu) } +bool secure_irq(unsigned const i); + 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(_state), cpu, (addr_t)&_mt_nonsecure_entry_pic, (addr_t)&_tz_client_context); diff --git a/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc b/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc index 846bf9bdb..fd87e7327 100644 --- a/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc +++ b/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc @@ -26,6 +26,17 @@ using namespace Genode; /* monitor exception vector address */ 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) { @@ -47,14 +58,7 @@ void Kernel::init_trustzone(Pic * pic) /* configure non-secure interrupts */ for (unsigned i = 0; i < Pic::NR_OF_IRQ; i++) { - if ((i != Board::EPIT_1_IRQ) && - (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); - } + if (!secure_irq(i)) { pic->unsecure(i); } } /* configure central security unit */ Genode::Csu csu(Board::CSU_BASE);