Trap secondary VM access to floating point state and phys timer.
Change-Id: I8bb5ef366fa58e50e7ab29f57c15b27ba0d6b7e5
diff --git a/src/arch/aarch64/exceptions.S b/src/arch/aarch64/exceptions.S
index 54e3882..a143361 100644
--- a/src/arch/aarch64/exceptions.S
+++ b/src/arch/aarch64/exceptions.S
@@ -269,9 +269,8 @@
msr sp_el0, x20
msr sp_el1, x21
- ldp x22, x23, [x0, #16 * 11]
+ ldr x22, [x0, #16 * 11]
msr par_el1, x22
- msr hcr_el2, x23
/* Restore non-volatile registers. */
add x0, x0, #(VCPU_REGS - VCPU_LAZY)
diff --git a/src/arch/aarch64/inc/arch_cpu.h b/src/arch/aarch64/inc/arch_cpu.h
index 6acee6e..6aa7bc4 100644
--- a/src/arch/aarch64/inc/arch_cpu.h
+++ b/src/arch/aarch64/inc/arch_cpu.h
@@ -12,6 +12,7 @@
uint64_t pc;
uint64_t spsr;
+ /* TODO: We need to save virtual timer state. */
struct {
uint64_t vmpidr_el2;
uint64_t csselr_el1;
@@ -36,7 +37,6 @@
uint64_t sp_el0;
uint64_t sp_el1;
uint64_t par_el1;
- uint64_t hcr_el2;
} lazy;
};
@@ -57,6 +57,40 @@
__asm volatile("msr DAIFClr, #0xf");
}
+static inline void arch_cpu_update(bool is_primary)
+{
+ uint64_t hcr;
+ uint64_t cptr;
+ uint64_t cnthctl;
+
+ /* TODO: Determine if we need to set TSW. */
+ hcr = (1u << 31) | /* RW bit. */
+ (1u << 21) | /* TACR, trap access to ACTRL_EL1. */
+ (1u << 19) | /* TSC, trap SMC instructions. */
+ (1u << 20) | /* TIDCP, trap impl-defined funct. */
+ (1u << 2) | /* PTW, Protected Table Walk. */
+ (1u << 0); /* VM: enable stage-2 translation. */
+
+ cptr = 0;
+ cnthctl = 0;
+
+ if (!is_primary) {
+ hcr |= (7u << 3) | /* AMO, IMO, FMO bits. */
+ (1u << 9) | /* FB bit. */
+ (1u << 10) | /* BSU bits set to inner-sh. */
+ (3u << 13); /* TWI, TWE bits. */
+
+ cptr |= (1u << 10); /* TFP, trap fp access. */
+
+ cnthctl |= (1u << 0) | /* EL1PCTEN, trap phys cnt access. */
+ (1u << 1); /* EL1PCEN, trap phys timer access. */
+ }
+
+ __asm__ volatile("msr hcr_el2, %0" :: "r"(hcr));
+ __asm__ volatile("msr cptr_el2, %0" :: "r"(cptr));
+ __asm__ volatile("msr cnthctl_el2, %0" :: "r"(cnthctl));
+}
+
static inline void arch_regs_init(struct arch_regs *r, size_t pc, size_t arg,
bool is_primary)
{
@@ -65,20 +99,6 @@
(0xf << 6); /* DAIF bits set; disable interrupts. */
r->pc = pc;
r->r[0] = arg;
- /* TODO: Determine if we need to set TSW. */
- r->lazy.hcr_el2 = (1u << 31) | /* RW bit. */
- (1u << 21) | /* TACR, trap access to ACTRL_EL1. */
- (1u << 19) | /* TSC, trap SMC instructions. */
- (1u << 20) | /* TIDCP, trap impl-defined funct. */
- (1u << 2) | /* PTW, Protected Table Walk. */
- (1u << 0); /* VM: enable stage-2 translation. */
-
- if (!is_primary) {
- r->lazy.hcr_el2 |= (7u << 3) | /* AMO, IMO, FMO bits. */
- (1u << 9) | /* FB bit. */
- (1u << 10) | /* BSU bits set to inner-sh. */
- (3u << 13); /* TWI, TWE bits. */
- }
}
static inline void arch_regs_set_retval(struct arch_regs *r, size_t v)
@@ -86,16 +106,4 @@
r->r[0] = v;
}
-static inline void arch_regs_set_irq(struct arch_regs *r)
-{
- /* Set the VI bit. */
- r->lazy.hcr_el2 |= (1u << 7);
-}
-
-static inline void arch_regs_clear_irq(struct arch_regs *r)
-{
- /* Clear the VI bit. */
- r->lazy.hcr_el2 &= ~(1u << 7);
-}
-
#endif /* _ARCH_CPU_H */
diff --git a/src/vm.c b/src/vm.c
index cadda86..3c4fd4d 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1,5 +1,6 @@
#include "vm.h"
+#include "api.h"
#include "cpu.h"
#include "std.h"
@@ -33,5 +34,6 @@
void vm_set_current(struct vm *vm)
{
+ arch_cpu_update(vm == &primary_vm);
arch_mm_set_vm(vm->ptable.id, (paddr_t)vm->ptable.table);
}