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