|
| 1 | +#include <sys/types.h> |
| 2 | +#include <linux/types.h> |
| 3 | +#include <linux/kvm.h> |
| 4 | +#include <sys/sysinfo.h> |
| 5 | + |
| 6 | + |
| 7 | +/* XXX |
| 8 | + * This comes from linux/kvm.h, but only for aarch64. Mirrored here simply |
| 9 | + * to make it compile for x86_64. |
| 10 | + */ |
| 11 | +#ifdef __x86_64__ |
| 12 | +struct user_pt_regs { |
| 13 | + __u64 regs[31]; |
| 14 | + __u64 sp; |
| 15 | + __u64 pc; |
| 16 | + __u64 pstate; |
| 17 | +}; |
| 18 | +#endif |
| 19 | + |
| 20 | +#define __KVM_HOST_SMCCC_FUNC___kvm_hyp_init 0 |
| 21 | + |
| 22 | +enum __kvm_host_smccc_func { |
| 23 | + /* Hypercalls available only prior to pKVM finalisation */ |
| 24 | + /* __KVM_HOST_SMCCC_FUNC___kvm_hyp_init */ |
| 25 | + __KVM_HOST_SMCCC_FUNC___kvm_get_mdcr_el2 = |
| 26 | + __KVM_HOST_SMCCC_FUNC___kvm_hyp_init + 1, |
| 27 | + __KVM_HOST_SMCCC_FUNC___pkvm_init, |
| 28 | + __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping, |
| 29 | + __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector, |
| 30 | + __KVM_HOST_SMCCC_FUNC___kvm_enable_ssbs, |
| 31 | + __KVM_HOST_SMCCC_FUNC___vgic_v3_init_lrs, |
| 32 | + __KVM_HOST_SMCCC_FUNC___vgic_v3_get_gic_config, |
| 33 | + __KVM_HOST_SMCCC_FUNC___kvm_flush_vm_context, |
| 34 | + __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid_ipa, |
| 35 | + __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_vmid, /* 10 */ |
| 36 | + __KVM_HOST_SMCCC_FUNC___kvm_flush_cpu_context, |
| 37 | + __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize, |
| 38 | + |
| 39 | + /* Hypercalls available after pKVM finalisation */ |
| 40 | + __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp, |
| 41 | + __KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp, |
| 42 | + __KVM_HOST_SMCCC_FUNC___pkvm_host_reclaim_page, |
| 43 | + __KVM_HOST_SMCCC_FUNC___pkvm_host_map_guest, |
| 44 | + __KVM_HOST_SMCCC_FUNC___kvm_adjust_pc, |
| 45 | + __KVM_HOST_SMCCC_FUNC___kvm_vcpu_run, |
| 46 | + __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff, |
| 47 | + __KVM_HOST_SMCCC_FUNC___vgic_v3_save_vmcr_aprs, /* 20 */ |
| 48 | + __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs, |
| 49 | + __KVM_HOST_SMCCC_FUNC___pkvm_init_vm, |
| 50 | + __KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu, |
| 51 | + __KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm, |
| 52 | + __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_load, |
| 53 | + __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_put, |
| 54 | + __KVM_HOST_SMCCC_FUNC___pkvm_vcpu_sync_state, |
| 55 | +}; |
| 56 | + |
| 57 | +#define HPROX_HVC_TYPE 'h' |
| 58 | +#define HPROX_STRUCTS_TYPE 's' |
| 59 | +#define HPROX_ALLOC_TYPE 'a' |
| 60 | +#define HPROX_MEMCACHE_TYPE 'm' |
| 61 | + |
| 62 | + |
| 63 | +// Perform the HVC numbered hvcnum, with this number of arguments. |
| 64 | +// The ioctl parameter is an array containing the arguments |
| 65 | +#define HVC_PROXY_IOCTL(hvcnum, numarg) \ |
| 66 | + _IOC(_IOC_WRITE, HPROX_HVC_TYPE, hvcnum, 8 * numarg) |
| 67 | + |
| 68 | +// All those ioctl return a size or an offset as return value. |
| 69 | +#define HPROX_STRUCT_KVM_GET_SIZE _IO(HPROX_STRUCTS_TYPE, 0) |
| 70 | +// The argument must be a: enum struct_kvm_fields |
| 71 | +#define HPROX_STRUCT_KVM_GET_OFFSET _IO(HPROX_STRUCTS_TYPE, 1) |
| 72 | +#define HPROX_HYP_VM_GET_SIZE _IO(HPROX_STRUCTS_TYPE, 2) |
| 73 | +#define HPROX_PGD_GET_SIZE _IO(HPROX_STRUCTS_TYPE, 3) |
| 74 | +#define HPROX_STRUCT_KVM_VCPU_GET_SIZE _IO(HPROX_STRUCTS_TYPE, 4) |
| 75 | +// The argument must be a: enum struct_kvm_vcpu_fields |
| 76 | +#define HPROX_STRUCT_KVM_VCPU_GET_OFFSET _IO(HPROX_STRUCTS_TYPE, 5) |
| 77 | +#define HPROX_HYP_VCPU_GET_SIZE _IO(HPROX_STRUCTS_TYPE, 6) |
| 78 | + |
| 79 | +enum struct_kvm_fields { |
| 80 | + HPROX_NR_MEM_SLOT_PAGES, /* unsigned long */ |
| 81 | + HPROX_VCPU_ARRAY, /* xarray */ |
| 82 | + HPROX_MAX_VCPUS, /* int */ |
| 83 | + HPROX_CREATED_VCPUS, /* int */ |
| 84 | + HPROX_ARCH_PKVM_ENABLED, /* bool */ |
| 85 | + HPROX_ARCH_PKVM_TEARDOWN_MC, /* struct hprox_memcache */ |
| 86 | +}; |
| 87 | + |
| 88 | +enum struct_kvm_vcpu_fields { |
| 89 | + HPROX_VCPU_ID, /* int */ |
| 90 | + HPROX_VCPU_IDX, /* int */ |
| 91 | + HPROX_VCPU_CFLAGS, /* 8 bits bitfield */ |
| 92 | + HPROX_VCPU_IFLAGS, /* 8 bits bitfield */ |
| 93 | + HPROX_VCPU_FEATURES, /* KVM_VCPU_MAX_FEATURES bits bitfield */ |
| 94 | + HPROX_VCPU_HCR_EL2, /* u64 */ |
| 95 | + HPROX_VCPU_FAULT, /* struct hprox_vcpu_fault_info */ |
| 96 | + HPROX_VCPU_REGS, /* struct user_pt_regs */ |
| 97 | + HPROX_VCPU_FP_REGS, /* struct user_fpsimd_state */ |
| 98 | + HPROX_VCPU_MEMCACHE, /* struct hprox_memcache */ |
| 99 | + // TODO add SVE state, for now SVE-less guests only |
| 100 | +}; |
| 101 | + |
| 102 | +struct hprox_vcpu_fault_info { |
| 103 | + __u64 esr_el2; /* Hyp Syndrom Register */ |
| 104 | + __u64 far_el2; /* Hyp Fault Address Register */ |
| 105 | + __u64 hpfar_el2; /* Hyp IPA Fault Address Register */ |
| 106 | + __u64 disr_el1; /* Deferred [SError] Status Register */ |
| 107 | +}; |
| 108 | + |
| 109 | +// Need to match up kvm_hyp_memcache |
| 110 | +struct hprox_memcache { |
| 111 | + __u64 head; // kernel address, might not be accessible, if not |
| 112 | + // donated from a hprox_alloc region. |
| 113 | + unsigned long nr_pages; |
| 114 | +}; |
| 115 | +enum hprox_alloc_type { HPROX_VMALLOC, HPROX_PAGES_EXACT }; |
| 116 | + |
| 117 | +// the ioctl parameter is the size of the allocation |
| 118 | +#define HPROX_ALLOC(alloc) _IO(HPROX_ALLOC_TYPE, alloc) |
| 119 | +#define HPROX_ALLOC_PAGES HPROX_ALLOC(HPROX_PAGES_EXACT) |
| 120 | + |
| 121 | +// ioctl on the mmapable fd from the HPROX_ALLOC ioctl |
| 122 | +#define HPROX_ALLOC_KADDR _IOR('A',0, __u64) |
| 123 | +#define HPROX_ALLOC_PHYS _IOR('A', 1, __u64) |
| 124 | +#define HPROX_ALLOC_RELEASE _IO('A', 2) |
| 125 | +#define HPROX_ALLOC_FREE _IO('A', 3) |
| 126 | + |
| 127 | +// memcache ioctl, free is encoded as topup 0 |
| 128 | +#define HPROX_MEMCACHE_FREE \ |
| 129 | + _IOWR(HPROX_MEMCACHE_TYPE, 0, struct hprox_memcache) |
| 130 | +#define HPROX_MEMCACHE_TOPUP(n) \ |
| 131 | + _IOWR(HPROX_MEMCACHE_TYPE, (n), struct hprox_memcache) |
0 commit comments