Support psp virtualization
Signed-off-by: niuyongwen <niuyongwen@hygon.cn>
This commit is contained in:
parent
d94139184b
commit
d1a84dd07d
|
@ -2149,6 +2149,8 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event);
|
||||||
int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
|
int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low,
|
||||||
unsigned long ipi_bitmap_high, u32 min,
|
unsigned long ipi_bitmap_high, u32 min,
|
||||||
unsigned long icr, int op_64_bit);
|
unsigned long icr, int op_64_bit);
|
||||||
|
int kvm_pv_psp_op(struct kvm *kvm, int cmd, gpa_t data_gpa,
|
||||||
|
gpa_t psp_ret_gpa, gpa_t table_gpa);
|
||||||
|
|
||||||
int kvm_add_user_return_msr(u32 msr);
|
int kvm_add_user_return_msr(u32 msr);
|
||||||
int kvm_find_user_return_msr(u32 msr);
|
int kvm_find_user_return_msr(u32 msr);
|
||||||
|
|
|
@ -12,7 +12,7 @@ include $(srctree)/virt/kvm/Makefile.kvm
|
||||||
kvm-y += x86.o emulate.o i8259.o irq.o lapic.o \
|
kvm-y += x86.o emulate.o i8259.o irq.o lapic.o \
|
||||||
i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
|
i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
|
||||||
hyperv.o debugfs.o mmu/mmu.o mmu/page_track.o \
|
hyperv.o debugfs.o mmu/mmu.o mmu/page_track.o \
|
||||||
mmu/spte.o
|
mmu/spte.o psp.o
|
||||||
|
|
||||||
ifdef CONFIG_HYPERV
|
ifdef CONFIG_HYPERV
|
||||||
kvm-y += kvm_onhyperv.o
|
kvm-y += kvm_onhyperv.o
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* PSP virtualization
|
||||||
|
*
|
||||||
|
* Copyright (c) 2023, HYGON CORPORATION. All rights reserved.
|
||||||
|
* Author: Ge Yang <yangge@hygon.cn>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kvm_types.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/kvm_host.h>
|
||||||
|
#include <linux/psp-sev.h>
|
||||||
|
#include <linux/psp-hygon.h>
|
||||||
|
|
||||||
|
struct psp_cmdresp_head {
|
||||||
|
uint32_t buf_size;
|
||||||
|
uint32_t cmdresp_size;
|
||||||
|
uint32_t cmdresp_code;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
int guest_addr_map_table_op(void *data_hva, gpa_t data_gpa, gpa_t table_gpa,
|
||||||
|
int op)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int kvm_pv_psp_op(struct kvm *kvm, int cmd, gpa_t data_gpa, gpa_t psp_ret_gpa,
|
||||||
|
gpa_t table_gpa)
|
||||||
|
{
|
||||||
|
void *data;
|
||||||
|
struct psp_cmdresp_head psp_head;
|
||||||
|
uint32_t data_size;
|
||||||
|
int psp_ret = 0;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (unlikely(kvm_read_guest(kvm, data_gpa, &psp_head,
|
||||||
|
sizeof(struct psp_cmdresp_head))))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
data_size = psp_head.buf_size;
|
||||||
|
data = kzalloc(data_size, GFP_KERNEL);
|
||||||
|
if (!data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (unlikely(kvm_read_guest(kvm, data_gpa, data, data_size))) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
goto e_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (guest_addr_map_table_op(data, data_gpa, table_gpa, 0)) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
goto e_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = psp_do_cmd(cmd, data, &psp_ret);
|
||||||
|
if (ret) {
|
||||||
|
pr_err("%s: psp do cmd error, %d\n", __func__, psp_ret);
|
||||||
|
ret = -EIO;
|
||||||
|
goto e_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (guest_addr_map_table_op(data, data_gpa, table_gpa, 1)) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
goto e_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(kvm_write_guest(kvm, data_gpa, data, data_size))) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
goto e_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlikely(kvm_write_guest(kvm, psp_ret_gpa, &psp_ret,
|
||||||
|
sizeof(psp_ret)))) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
goto e_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
e_free:
|
||||||
|
kfree(data);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -9891,7 +9891,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (static_call(kvm_x86_get_cpl)(vcpu) != 0 &&
|
if (static_call(kvm_x86_get_cpl)(vcpu) != 0 &&
|
||||||
!(is_x86_vendor_hygon() && nr == KVM_HC_VM_ATTESTATION)) {
|
!(is_x86_vendor_hygon() && (nr == KVM_HC_VM_ATTESTATION || nr == KVM_HC_PSP_OP))) {
|
||||||
ret = -KVM_EPERM;
|
ret = -KVM_EPERM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -9928,6 +9928,9 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
|
||||||
kvm_sched_yield(vcpu, a0);
|
kvm_sched_yield(vcpu, a0);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
case KVM_HC_PSP_OP:
|
||||||
|
ret = kvm_pv_psp_op(vcpu->kvm, a0, a1, a2, a3);
|
||||||
|
break;
|
||||||
case KVM_HC_MAP_GPA_RANGE: {
|
case KVM_HC_MAP_GPA_RANGE: {
|
||||||
u64 gpa = a0, npages = a1, attrs = a2;
|
u64 gpa = a0, npages = a1, attrs = a2;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#define KVM_HC_SCHED_YIELD 11
|
#define KVM_HC_SCHED_YIELD 11
|
||||||
#define KVM_HC_MAP_GPA_RANGE 12
|
#define KVM_HC_MAP_GPA_RANGE 12
|
||||||
#define KVM_HC_VM_ATTESTATION 100 /* Specific to Hygon CPU */
|
#define KVM_HC_VM_ATTESTATION 100 /* Specific to Hygon CPU */
|
||||||
|
#define KVM_HC_PSP_OP 101 /* Specific to Hygon platform */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hypercalls use architecture specific
|
* hypercalls use architecture specific
|
||||||
|
|
Loading…
Reference in New Issue