xref: /openbmc/linux/arch/riscv/kvm/vm.c (revision fd7bb4a251dfc1da3496bf59a4793937c13e8c1f)
199cdc6c1SAnup Patel // SPDX-License-Identifier: GPL-2.0
299cdc6c1SAnup Patel /*
399cdc6c1SAnup Patel  * Copyright (C) 2019 Western Digital Corporation or its affiliates.
499cdc6c1SAnup Patel  *
599cdc6c1SAnup Patel  * Authors:
699cdc6c1SAnup Patel  *     Anup Patel <anup.patel@wdc.com>
799cdc6c1SAnup Patel  */
899cdc6c1SAnup Patel 
999cdc6c1SAnup Patel #include <linux/errno.h>
1099cdc6c1SAnup Patel #include <linux/err.h>
1199cdc6c1SAnup Patel #include <linux/module.h>
1299cdc6c1SAnup Patel #include <linux/uaccess.h>
1399cdc6c1SAnup Patel #include <linux/kvm_host.h>
1499cdc6c1SAnup Patel 
1599cdc6c1SAnup Patel const struct _kvm_stats_desc kvm_vm_stats_desc[] = {
1699cdc6c1SAnup Patel 	KVM_GENERIC_VM_STATS()
1799cdc6c1SAnup Patel };
1899cdc6c1SAnup Patel static_assert(ARRAY_SIZE(kvm_vm_stats_desc) ==
1999cdc6c1SAnup Patel 		sizeof(struct kvm_vm_stat) / sizeof(u64));
2099cdc6c1SAnup Patel 
2199cdc6c1SAnup Patel const struct kvm_stats_header kvm_vm_stats_header = {
2299cdc6c1SAnup Patel 	.name_size = KVM_STATS_NAME_SIZE,
2399cdc6c1SAnup Patel 	.num_desc = ARRAY_SIZE(kvm_vm_stats_desc),
2499cdc6c1SAnup Patel 	.id_offset =  sizeof(struct kvm_stats_header),
2599cdc6c1SAnup Patel 	.desc_offset = sizeof(struct kvm_stats_header) + KVM_STATS_NAME_SIZE,
2699cdc6c1SAnup Patel 	.data_offset = sizeof(struct kvm_stats_header) + KVM_STATS_NAME_SIZE +
2799cdc6c1SAnup Patel 		       sizeof(kvm_vm_stats_desc),
2899cdc6c1SAnup Patel };
2999cdc6c1SAnup Patel 
3099cdc6c1SAnup Patel int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
3199cdc6c1SAnup Patel {
3299cdc6c1SAnup Patel 	/* TODO: To be added later. */
3399cdc6c1SAnup Patel 	return -EOPNOTSUPP;
3499cdc6c1SAnup Patel }
3599cdc6c1SAnup Patel 
3699cdc6c1SAnup Patel int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
3799cdc6c1SAnup Patel {
3899cdc6c1SAnup Patel 	int r;
3999cdc6c1SAnup Patel 
4099cdc6c1SAnup Patel 	r = kvm_riscv_stage2_alloc_pgd(kvm);
4199cdc6c1SAnup Patel 	if (r)
4299cdc6c1SAnup Patel 		return r;
4399cdc6c1SAnup Patel 
44*fd7bb4a2SAnup Patel 	r = kvm_riscv_stage2_vmid_init(kvm);
45*fd7bb4a2SAnup Patel 	if (r) {
46*fd7bb4a2SAnup Patel 		kvm_riscv_stage2_free_pgd(kvm);
47*fd7bb4a2SAnup Patel 		return r;
48*fd7bb4a2SAnup Patel 	}
49*fd7bb4a2SAnup Patel 
5099cdc6c1SAnup Patel 	return 0;
5199cdc6c1SAnup Patel }
5299cdc6c1SAnup Patel 
5399cdc6c1SAnup Patel void kvm_arch_destroy_vm(struct kvm *kvm)
5499cdc6c1SAnup Patel {
5599cdc6c1SAnup Patel 	int i;
5699cdc6c1SAnup Patel 
5799cdc6c1SAnup Patel 	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
5899cdc6c1SAnup Patel 		if (kvm->vcpus[i]) {
5999cdc6c1SAnup Patel 			kvm_vcpu_destroy(kvm->vcpus[i]);
6099cdc6c1SAnup Patel 			kvm->vcpus[i] = NULL;
6199cdc6c1SAnup Patel 		}
6299cdc6c1SAnup Patel 	}
6399cdc6c1SAnup Patel 	atomic_set(&kvm->online_vcpus, 0);
6499cdc6c1SAnup Patel }
6599cdc6c1SAnup Patel 
6699cdc6c1SAnup Patel int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
6799cdc6c1SAnup Patel {
6899cdc6c1SAnup Patel 	int r;
6999cdc6c1SAnup Patel 
7099cdc6c1SAnup Patel 	switch (ext) {
719f701326SAnup Patel 	case KVM_CAP_IOEVENTFD:
7299cdc6c1SAnup Patel 	case KVM_CAP_DEVICE_CTRL:
7399cdc6c1SAnup Patel 	case KVM_CAP_USER_MEMORY:
7499cdc6c1SAnup Patel 	case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
7599cdc6c1SAnup Patel 	case KVM_CAP_ONE_REG:
7699cdc6c1SAnup Patel 	case KVM_CAP_READONLY_MEM:
7799cdc6c1SAnup Patel 	case KVM_CAP_MP_STATE:
7899cdc6c1SAnup Patel 	case KVM_CAP_IMMEDIATE_EXIT:
7999cdc6c1SAnup Patel 		r = 1;
8099cdc6c1SAnup Patel 		break;
8199cdc6c1SAnup Patel 	case KVM_CAP_NR_VCPUS:
8299cdc6c1SAnup Patel 		r = num_online_cpus();
8399cdc6c1SAnup Patel 		break;
8499cdc6c1SAnup Patel 	case KVM_CAP_MAX_VCPUS:
8599cdc6c1SAnup Patel 		r = KVM_MAX_VCPUS;
8699cdc6c1SAnup Patel 		break;
8799cdc6c1SAnup Patel 	case KVM_CAP_NR_MEMSLOTS:
8899cdc6c1SAnup Patel 		r = KVM_USER_MEM_SLOTS;
8999cdc6c1SAnup Patel 		break;
9099cdc6c1SAnup Patel 	default:
9199cdc6c1SAnup Patel 		r = 0;
9299cdc6c1SAnup Patel 		break;
9399cdc6c1SAnup Patel 	}
9499cdc6c1SAnup Patel 
9599cdc6c1SAnup Patel 	return r;
9699cdc6c1SAnup Patel }
9799cdc6c1SAnup Patel 
9899cdc6c1SAnup Patel long kvm_arch_vm_ioctl(struct file *filp,
9999cdc6c1SAnup Patel 		       unsigned int ioctl, unsigned long arg)
10099cdc6c1SAnup Patel {
10199cdc6c1SAnup Patel 	return -EINVAL;
10299cdc6c1SAnup Patel }
103