Eliminate vm_set_current.

It is a potential source of bugs if we forget to call it, and is
leftover from when hafnium had a scheduler.

Change-Id: I1ce07302ea4c40578fde43a4277b628abf3e4918
diff --git a/inc/hf/vm.h b/inc/hf/vm.h
index dc72e4a..6bc4882 100644
--- a/inc/hf/vm.h
+++ b/inc/hf/vm.h
@@ -52,4 +52,3 @@
 uint32_t vm_get_count(void);
 struct vm *vm_get(uint32_t id);
 void vm_start_vcpu(struct vm *vm, size_t index, ipaddr_t entry, uintreg_t arg);
-void vm_set_current(struct vm *vm);
diff --git a/src/api.c b/src/api.c
index 8761e61..16df0d9 100644
--- a/src/api.c
+++ b/src/api.c
@@ -41,9 +41,6 @@
 	struct vm *primary = vm_get(HF_PRIMARY_VM_ID);
 	struct vcpu *next = &primary->vcpus[cpu_index(current->cpu)];
 
-	/* Switch back to primary VM. */
-	vm_set_current(primary);
-
 	/* Set the return value for the primary VM's call to HF_VCPU_RUN. */
 	arch_regs_set_retval(&next->regs,
 			     hf_vcpu_run_return_encode(primary_ret));
@@ -151,7 +148,6 @@
 	} else {
 		vcpu->cpu = current->cpu;
 		vcpu->state = vcpu_state_running;
-		vm_set_current(vm);
 		*next = vcpu;
 		ret.code = HF_VCPU_RUN_YIELD;
 	}
diff --git a/src/arch/aarch64/exceptions.S b/src/arch/aarch64/exceptions.S
index 4e3219f..de349a1 100644
--- a/src/arch/aarch64/exceptions.S
+++ b/src/arch/aarch64/exceptions.S
@@ -279,7 +279,15 @@
 	stp x20, x21, [x1, #16 * 10]
 
 	mrs x22, par_el1
-	str x22, [x1, #16 * 11]
+	mrs x23, hcr_el2
+	stp x22, x23, [x1, #16 * 11]
+
+	mrs x24, cptr_el2
+	mrs x25, cnthctl_el2
+	stp x24, x25, [x1, #16 * 12]
+
+	mrs x26, vttbr_el2
+	str x26, [x1, #16 * 13]
 
 	/* Intentional fallthrough. */
 
@@ -335,8 +343,16 @@
 	msr sp_el0, x20
 	msr sp_el1, x21
 
-	ldr x22, [x0, #16 * 11]
+	ldp x22, x23, [x0, #16 * 11]
 	msr par_el1, x22
+	msr hcr_el2, x23
+
+	ldp x24, x25, [x0, #16 * 12]
+	msr cptr_el2, x22
+	msr cnthctl_el2, x23
+
+	ldr x26, [x0, #16 * 13]
+	msr vttbr_el2, x26
 
 	/* Restore non-volatile registers. */
 	add x0, x0, #(VCPU_REGS - VCPU_LAZY)
diff --git a/src/arch/aarch64/inc/hf/arch/cpu.h b/src/arch/aarch64/inc/hf/arch/cpu.h
index 78f3cf2..efbad6e 100644
--- a/src/arch/aarch64/inc/hf/arch/cpu.h
+++ b/src/arch/aarch64/inc/hf/arch/cpu.h
@@ -55,6 +55,10 @@
 		uintreg_t sp_el0;
 		uintreg_t sp_el1;
 		uintreg_t par_el1;
+		uintreg_t hcr_el2;
+		uintreg_t cptr_el2;
+		uintreg_t cnthctl_el2;
+		uintreg_t vttbr_el2;
 	} lazy;
 };
 
@@ -68,7 +72,9 @@
 	__asm__ volatile("msr DAIFClr, #0xf");
 }
 
-static inline void arch_cpu_update(bool is_primary)
+static inline void arch_regs_init(struct arch_regs *r, bool is_primary,
+				  uint64_t vmid, paddr_t table, ipaddr_t pc,
+				  uintreg_t arg)
 {
 	uintreg_t hcr;
 	uintreg_t cptr;
@@ -97,14 +103,10 @@
 			   (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, ipaddr_t pc,
-				  uintreg_t arg)
-{
+	r->lazy.hcr_el2 = hcr;
+	r->lazy.cptr_el2 = cptr;
+	r->lazy.cnthctl_el2 = cnthctl;
+	r->lazy.vttbr_el2 = pa_addr(table) | (vmid << 48);
 	/* TODO: Use constant here. */
 	r->spsr = 5 |	 /* M bits, set to EL1h. */
 		  (0xf << 6); /* DAIF bits set; disable interrupts. */
diff --git a/src/arch/aarch64/inc/hf/arch/mm.h b/src/arch/aarch64/inc/hf/arch/mm.h
index 7ee6d68..35278ca 100644
--- a/src/arch/aarch64/inc/hf/arch/mm.h
+++ b/src/arch/aarch64/inc/hf/arch/mm.h
@@ -193,13 +193,6 @@
 		"dsb ish\n");
 }
 
-static inline void arch_mm_set_vm(uint64_t vmid, paddr_t table)
-{
-	__asm__ volatile("msr vttbr_el2, %0"
-			 :
-			 : "r"(pa_addr(table) | (vmid << 48)));
-}
-
 uint64_t arch_mm_mode_to_attrs(int mode);
 bool arch_mm_init(paddr_t table, bool first);
 uint8_t arch_mm_max_level(int mode);
diff --git a/src/arch/fake/inc/hf/arch/cpu.h b/src/arch/fake/inc/hf/arch/cpu.h
index d374bcb..d8ede27 100644
--- a/src/arch/fake/inc/hf/arch/cpu.h
+++ b/src/arch/fake/inc/hf/arch/cpu.h
@@ -37,16 +37,14 @@
 	/* TODO */
 }
 
-static inline void arch_cpu_update(bool is_primary)
-{
-	/* TODO */
-	(void)is_primary;
-}
-
-static inline void arch_regs_init(struct arch_regs *r, ipaddr_t pc,
+static inline void arch_regs_init(struct arch_regs *r, bool is_primary,
+				  uint64_t vmid, paddr_t table, ipaddr_t pc,
 				  uintreg_t arg)
 {
 	/* TODO */
+	(void)is_primary;
+	(void)vmid;
+	(void)table;
 	(void)pc;
 	r->r[0] = arg;
 }
diff --git a/src/arch/fake/inc/hf/arch/mm.h b/src/arch/fake/inc/hf/arch/mm.h
index 98c73c7..c99bf92 100644
--- a/src/arch/fake/inc/hf/arch/mm.h
+++ b/src/arch/fake/inc/hf/arch/mm.h
@@ -203,10 +203,3 @@
 	(void)first;
 	return true;
 }
-
-static inline void arch_mm_set_vm(uint64_t vmid, paddr_t table)
-{
-	/* TODO */
-	(void)vmid;
-	(void)table;
-}
diff --git a/src/cpu.c b/src/cpu.c
index 9c7484b..4c6a18b 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -92,9 +92,10 @@
 	sl_unlock(&c->lock);
 
 	if (!prev) {
-		struct vcpu *vcpu =
-			&vm_get(HF_PRIMARY_VM_ID)->vcpus[cpu_index(c)];
-		arch_regs_init(&vcpu->regs, entry, arg);
+		struct vm *vm = vm_get(HF_PRIMARY_VM_ID);
+		struct vcpu *vcpu = &vm->vcpus[cpu_index(c)];
+		arch_regs_init(&vcpu->regs, true, vm->id, vm->ptable.table,
+			       entry, arg);
 		vcpu_on(vcpu);
 	}
 
diff --git a/src/main.c b/src/main.c
index db191a8..eb233d9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -130,7 +130,6 @@
  */
 struct vcpu *cpu_main(struct cpu *c)
 {
-	struct vm *primary;
 	struct vcpu *vcpu;
 
 	/*
@@ -149,10 +148,7 @@
 		panic("mm_cpu_init failed");
 	}
 
-	primary = vm_get(HF_PRIMARY_VM_ID);
-	vm_set_current(primary);
-
-	vcpu = &primary->vcpus[cpu_index(c)];
+	vcpu = &vm_get(HF_PRIMARY_VM_ID)->vcpus[cpu_index(c)];
 	vcpu->cpu = c;
 	return vcpu;
 }
diff --git a/src/vm.c b/src/vm.c
index 02b60ff..7387f20 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -73,13 +73,8 @@
 {
 	struct vcpu *vcpu = &vm->vcpus[index];
 	if (index < vm->vcpu_count) {
-		arch_regs_init(&vcpu->regs, entry, arg);
+		arch_regs_init(&vcpu->regs, vm->id == HF_PRIMARY_VM_ID, vm->id,
+			       vm->ptable.table, entry, arg);
 		vcpu_on(vcpu);
 	}
 }
-
-void vm_set_current(struct vm *vm)
-{
-	arch_cpu_update(vm->id == HF_PRIMARY_VM_ID);
-	arch_mm_set_vm(vm->id, vm->ptable.table);
-}