Commit e57b7575 authored by hanliyang's avatar hanliyang
Browse files

KVM: SVM: CSV: Provide KVM_CSV3_SET_GUEST_PRIVATE_MEMORY ioctl interface

hygon inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IBGDLQ


CVE: NA

---------------------------

For newer CSV1/2/3 firmware, multiple LAUNCH_ENCRYPT_DATA commands are
allowed to be issued. However, SET_GUEST_PRIVATE_MEMORY command can only
be issued once.

Provide a separate ioctl interface KVM_CSV3_SET_GUEST_PRIVATE_MEMORY
here. The user space VMM can negotiate with KVM on whether to enable the
capability KVM_CAP_HYGON_COCO_EXT_CSV3_SET_PRIV_MEM. When this
capability is enabled, the user space VMM should explicitly request the
KVM_CSV3_SET_GUEST_PRIVATE_MEMORY ioctl interface, and the
KVM_CSV3_LAUNCH_ENCRYPT_DATA ioctl handler will skip the process of
issuing the SET_GUEST_PRIVATE_MEMORY command, in addition, the user
space VMM will have the chance to request KVM_CSV3_LAUNCH_ENCRYPT_DATA
ioctl interface more than once. When this capability is disabled, the
user space will not request the KVM_CSV3_SET_GUEST_PRIVATE_MEMORY ioctl
interface, and the KVM_CSV3_LAUNCH_ENCRYPT_DATA ioctl handler will still
issue the SET_GUEST_PRIVATE_MEMORY command.

Signed-off-by: default avatarhanliyang <hanliyang@hygon.cn>
parent 1fa7a0d5
Loading
Loading
Loading
Loading
+24 −11
Original line number Diff line number Diff line
@@ -1042,7 +1042,7 @@ static bool csv3_is_mmio_pfn(kvm_pfn_t pfn)
				     E820_TYPE_RAM);
}

static int csv3_set_guest_private_memory(struct kvm *kvm)
static int csv3_set_guest_private_memory(struct kvm *kvm, struct kvm_sev_cmd *argp)
{
	struct kvm_memslots *slots = kvm_memslots(kvm);
	struct kvm_memory_slot *memslot;
@@ -1057,7 +1057,7 @@ static int csv3_set_guest_private_memory(struct kvm *kvm)
	LIST_HEAD(tmp_list);
	struct list_head *pos, *q;
	u32 i = 0, count = 0, remainder;
	int ret = 0, error;
	int ret = 0;
	u64 size = 0, nr_smr = 0, nr_pages = 0;
	u32 smr_entry_shift;
	int bkt;
@@ -1069,6 +1069,10 @@ static int csv3_set_guest_private_memory(struct kvm *kvm)
	if (!csv3_guest(kvm))
		return -ENOTTY;

	/* The smr_list should be initialized only once */
	if (!list_empty(&csv->smr_list))
		return -EFAULT;

	nodes_clear(nodemask);
	for_each_set_bit(i, &csv->nodemask, BITS_PER_LONG)
		if (i < MAX_NUMNODES)
@@ -1151,7 +1155,7 @@ static int csv3_set_guest_private_memory(struct kvm *kvm)
			/* set secury memory region for launch enrypt data */
			ret = hygon_kvm_hooks.sev_issue_cmd(kvm,
						CSV3_CMD_SET_GUEST_PRIVATE_MEMORY,
						set_guest_private_memory, &error);
						set_guest_private_memory, &argp->error);
			if (ret)
				goto e_free_smr;

@@ -1211,10 +1215,17 @@ static int csv3_launch_encrypt_data(struct kvm *kvm, struct kvm_sev_cmd *argp)
		goto exit;
	}

	/*
	 * If userspace request to invoke CSV3_CMD_SET_GUEST_PRIVATE_MEMORY
	 * explicitly, we should not calls to csv3_set_guest_private_memory()
	 * here.
	 */
	if (!(csv->inuse_ext & KVM_CAP_HYGON_COCO_EXT_CSV3_SET_PRIV_MEM)) {
		/* Allocate all the guest memory from CMA */
	ret = csv3_set_guest_private_memory(kvm);
		ret = csv3_set_guest_private_memory(kvm, argp);
		if (ret)
			goto exit;
	}

	num_entries = params.len / PAGE_SIZE;
	num_entries_in_block = ARRAY_SIZE(blocks->entry);
@@ -1675,7 +1686,7 @@ static int csv3_receive_encrypt_data(struct kvm *kvm, struct kvm_sev_cmd *argp)

	if (unlikely(list_empty(&csv->smr_list))) {
		/* Allocate all the guest memory from CMA */
		ret = csv3_set_guest_private_memory(kvm);
		ret = csv3_set_guest_private_memory(kvm, argp);
		if (ret)
			goto exit;
	}
@@ -2435,6 +2446,9 @@ static int csv_mem_enc_ioctl(struct kvm *kvm, void __user *argp)
	case KVM_CSV3_HANDLE_MEMORY:
		r = csv3_handle_memory(kvm, &sev_cmd);
		break;
	case KVM_CSV3_SET_GUEST_PRIVATE_MEMORY:
		r = csv3_set_guest_private_memory(kvm, &sev_cmd);
		break;
	default:
		/*
		 * If the command is compatible between CSV and SEV, the
@@ -2731,9 +2745,8 @@ static int csv_get_hygon_coco_extension(struct kvm *kvm)
	 * field of kvm_csv_info is valid.
	 */
	if (csv->kvm_ext_valid == false) {
		/* Currently, KVM doesn't support any extensions, we don't need
		 * to fill in kvm_ext field of kvm_csv_info here.
		 */
		if (csv3_guest(kvm))
			csv->kvm_ext |= KVM_CAP_HYGON_COCO_EXT_CSV3_SET_PRIV_MEM;
		csv->kvm_ext_valid = true;
	}

+2 −0
Original line number Diff line number Diff line
@@ -2384,6 +2384,8 @@ enum csv3_cmd_id {
	KVM_CSV3_RECEIVE_ENCRYPT_CONTEXT,
	KVM_CSV3_HANDLE_MEMORY,

	KVM_CSV3_SET_GUEST_PRIVATE_MEMORY = 0xc8,

	KVM_CSV3_NR_MAX,
};