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)