KVM: arm64: pkvm_proxy: add helpers needed to run a VCPU

Change-Id: Ifbfd0721773147cc54613c7455b78d9c02f119b7
diff --git a/arch/arm64/include/uapi/asm/pkvm_proxy.h b/arch/arm64/include/uapi/asm/pkvm_proxy.h
index b977d10..51c39a4 100644
--- a/arch/arm64/include/uapi/asm/pkvm_proxy.h
+++ b/arch/arm64/include/uapi/asm/pkvm_proxy.h
@@ -2,7 +2,8 @@
 #ifndef __ASM_PKVM_PROXY_H
 #define __ASM_PKVM_PROXY_H
 
-#include <linux/kvm_host.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
 
 #define HPROX_HVC_TYPE 0
 #define HPROX_STRUCTS_TYPE 1
@@ -31,17 +32,29 @@
 };
 
 enum struct_kvm_vcpu_fields {
-	HPROX_VCPU_ID,
-	HPROX_VCPU_IDX,
-	HPROX_ARCH_CFLAGS,
-	HPROX_ARCH_FEATURES,
-	HPROX_ARCH_HCR_EL2,
+	HPROX_VCPU_ID, /* int */
+	HPROX_VCPU_IDX, /* int */
+	HPROX_VCPU_CFLAGS,
+	HPROX_VCPU_IFLAGS,
+	HPROX_VCPU_FEATURES,
+	HPROX_VCPU_HCR_EL2, /* u64 */
+	HPROX_VCPU_FAULT, /* struct hprox_vcpu_fault_info */
+	HPROX_VCPU_REGS, /* struct user_pt_regs */
+	HPROX_VCPU_FP_REGS, /* struct user_fpsimd_state */
+	HPROX_VCPU_MEMCACHE, /* struct hprox_memcache */
 	// TODO add SVE state, for now SVE-less guests only
 };
 
+struct hprox_vcpu_fault_info {
+	__u64 esr_el2; /* Hyp Syndrom Register */
+	__u64 far_el2; /* Hyp Fault Address Register */
+	__u64 hpfar_el2; /* Hyp IPA Fault Address Register */
+	__u64 disr_el1; /* Deferred [SError] Status Register */
+};
+
 // Need to match up kvm_hyp_memcache
-struct hprox_hyp_memcache {
-	unsigned long head; // kernel address, might not be accessible, if not
+struct hprox_memcache {
+        __u64 head; // kernel address, might not be accessible, if not
 			    // donated from a hprox_alloc region.
 	unsigned long nr_pages;
 };
@@ -53,5 +66,6 @@
 // ioctl on the mmapable fd from the HPROX_ALLOC ioctl
 #define HPROX_ALLOC_KADDR _IOR(0,0, void*)
 #define HPROX_ALLOC_PHYS _IOR(0, 1, void *)
+#define HPROX_ALLOC_RELEASE _IO(0, 2)
 
 #endif /* __ASM_PKVM_PROXY_H */
diff --git a/arch/arm64/kvm/pkvm_proxy.c b/arch/arm64/kvm/pkvm_proxy.c
index 6413f35..6b9560c 100644
--- a/arch/arm64/kvm/pkvm_proxy.c
+++ b/arch/arm64/kvm/pkvm_proxy.c
@@ -45,12 +45,14 @@
 	switch (cmd){
 	case HPROX_ALLOC_KADDR:
 		if(copy_to_user(res, &alloc->kaddr, sizeof(void*)))
-			return -EIO;
+			return -EFAULT;
 		return 0;
 	case HPROX_ALLOC_PHYS:
+		if(alloc->type != HPROX_PAGES_EXACT)
+			return -ENOTSUPP;
 		phys = virt_to_phys(alloc->kaddr);
 		if (copy_to_user(res, &phys, sizeof(void *)))
-			return -EIO;
+			return -EFAULT;
 		return 0;
 	default:
 		return -ENOSYS;
@@ -72,6 +74,8 @@
 static int pkvm_proxy_alloc_release(struct inode *inode, struct file *filep)
 {
 	struct pkvm_proxy_alloc *alloc = filep->private_data;
+	if(!alloc) return -EBADFD;
+	pr_warn("hprox releasing block at %lx of size %lx\n", alloc->kaddr, alloc->size);
 	pkvm_proxy_alloc_free(alloc);
 	kfree(alloc);
 	return 0;
@@ -94,6 +98,7 @@
 	if (vma->vm_pgoff != 0 || vma->vm_end - vma->vm_start != PAGE_ALIGN(alloc->size))
 		return -EINVAL;
 	BUG_ON(!alloc->kaddr);
+	pr_warn("mmaping hprox alloc of size %lx at %lx\n", alloc->size, alloc->kaddr);
 
 	switch (alloc->type) {
 	case HPROX_VMALLOC:
@@ -108,6 +113,7 @@
 
 	for (off = 0; off < alloc->size; off += PAGE_SIZE) {
 		page = vtop(alloc->kaddr + off);
+		pr_warn("mmap phys %lx\n", page_to_phys(page));
 		res = vm_insert_page(vma, vma->vm_start + off, page);
 		if (res)
 			return res;
@@ -173,6 +179,7 @@
 	}
 	BUG_ON(file->private_data != alloc);
 	fd_install(fd, file);
+	pr_warn("Returning fd %d for alloc at %lx\n", fd, alloc->kaddr);
 	return fd;
 
 put_fd:
@@ -208,8 +215,8 @@
 				offsetof(struct kvm_protected_vm, enabled);
 		case HPROX_ARCH_PKVM_TEARDOWN_MC:
 			return offsetof(struct kvm, arch) +
-			       offsetof(struct kvm_arch, pkvm) +
-			       offsetof(struct kvm_protected_vm, teardown_mc);
+				offsetof(struct kvm_arch, pkvm) +
+				offsetof(struct kvm_protected_vm, teardown_mc);
 		default:
 			return -EINVAL;
 		}
@@ -228,15 +235,22 @@
 			return offsetof(struct kvm_vcpu, vcpu_id);
 		case HPROX_VCPU_IDX:
 			return offsetof(struct kvm_vcpu, vcpu_idx);
-		case HPROX_ARCH_CFLAGS:
-			return offsetof(struct kvm_vcpu, arch) +
-				offsetof(struct kvm_vcpu_arch, cflags);
-		case HPROX_ARCH_FEATURES:
-			return offsetof(struct kvm_vcpu, arch) +
-				offsetof(struct kvm_vcpu_arch, features);
-		case HPROX_ARCH_HCR_EL2:
-			return offsetof(struct kvm_vcpu, arch) +
-				offsetof(struct kvm_vcpu_arch, hcr_el2);
+		case HPROX_VCPU_CFLAGS:
+			return offsetof(struct kvm_vcpu, arch.cflags);
+		case HPROX_VCPU_IFLAGS:
+			return offsetof(struct kvm_vcpu, arch.iflags);
+		case HPROX_VCPU_FEATURES:
+			return offsetof(struct kvm_vcpu, arch.features);
+		case HPROX_VCPU_HCR_EL2:
+			return offsetof(struct kvm_vcpu, arch.hcr_el2);
+		case HPROX_VCPU_FAULT:
+			return offsetof(struct kvm_vcpu, arch.fault);
+		case HPROX_VCPU_REGS:
+			return offsetof(struct kvm_vcpu, arch.ctxt.regs);
+		case HPROX_VCPU_FP_REGS:
+			return offsetof(struct kvm_vcpu, arch.ctxt.fp_regs);
+		case HPROX_VCPU_MEMCACHE:
+			return offsetof(struct kvm_vcpu, arch.pkvm_memcache);
 		default:
 			return -EINVAL;
 		}
@@ -255,12 +269,19 @@
 	u64 args[7] = {};
 	int id;
 	struct arm_smccc_res res;
+	pr_warn("Entering HVC ioctl\n");
 	id = _IOC_NR(cmd);
 	args_size = ALIGN(_IOC_SIZE(cmd), sizeof(u64));
 	if (args_size > 7 * sizeof(u64))
 		return -EINVAL;
-	if (copy_from_user(args, (void __user *)uarg, args_size))
+	if (args_size && copy_from_user(args, (void __user *)uarg, args_size))
 		return -EACCES;
+	if(id == __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp){
+		void* addr = pfn_to_kaddr(args[0]);
+		int* test = addr + 0x908;
+		pr_warn ("Content of test at 0x908 %d", *test);
+	}
+	pr_warn("Calling hvc %d\n", id);
 	arm_smccc_1_1_hvc(KVM_HOST_SMCCC_ID(id), args[0], args[1], args[2],
 			  args[3], args[4], args[5], args[6], &res);
 	if (res.a0 != SMCCC_RET_SUCCESS)