xref: /openbmc/linux/arch/riscv/kvm/vm.c (revision 27592ae8dbe41033261b6fdf27d78998aabd2665)
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_arch_init_vm(struct kvm *kvm, unsigned long type)
3199cdc6c1SAnup Patel {
3299cdc6c1SAnup Patel 	int r;
3399cdc6c1SAnup Patel 
3499cdc6c1SAnup Patel 	r = kvm_riscv_stage2_alloc_pgd(kvm);
3599cdc6c1SAnup Patel 	if (r)
3699cdc6c1SAnup Patel 		return r;
3799cdc6c1SAnup Patel 
38fd7bb4a2SAnup Patel 	r = kvm_riscv_stage2_vmid_init(kvm);
39fd7bb4a2SAnup Patel 	if (r) {
40fd7bb4a2SAnup Patel 		kvm_riscv_stage2_free_pgd(kvm);
41fd7bb4a2SAnup Patel 		return r;
42fd7bb4a2SAnup Patel 	}
43fd7bb4a2SAnup Patel 
443a9f66cbSAtish Patra 	return kvm_riscv_guest_timer_init(kvm);
4599cdc6c1SAnup Patel }
4699cdc6c1SAnup Patel 
4799cdc6c1SAnup Patel void kvm_arch_destroy_vm(struct kvm *kvm)
4899cdc6c1SAnup Patel {
49*27592ae8SMarc Zyngier 	kvm_destroy_vcpus(kvm);
5099cdc6c1SAnup Patel }
5199cdc6c1SAnup Patel 
5299cdc6c1SAnup Patel int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
5399cdc6c1SAnup Patel {
5499cdc6c1SAnup Patel 	int r;
5599cdc6c1SAnup Patel 
5699cdc6c1SAnup Patel 	switch (ext) {
579f701326SAnup Patel 	case KVM_CAP_IOEVENTFD:
5899cdc6c1SAnup Patel 	case KVM_CAP_DEVICE_CTRL:
5999cdc6c1SAnup Patel 	case KVM_CAP_USER_MEMORY:
609955371cSAnup Patel 	case KVM_CAP_SYNC_MMU:
6199cdc6c1SAnup Patel 	case KVM_CAP_DESTROY_MEMORY_REGION_WORKS:
6299cdc6c1SAnup Patel 	case KVM_CAP_ONE_REG:
6399cdc6c1SAnup Patel 	case KVM_CAP_READONLY_MEM:
6499cdc6c1SAnup Patel 	case KVM_CAP_MP_STATE:
6599cdc6c1SAnup Patel 	case KVM_CAP_IMMEDIATE_EXIT:
6699cdc6c1SAnup Patel 		r = 1;
6799cdc6c1SAnup Patel 		break;
6899cdc6c1SAnup Patel 	case KVM_CAP_NR_VCPUS:
6937fd3ce1SVitaly Kuznetsov 		r = min_t(unsigned int, num_online_cpus(), KVM_MAX_VCPUS);
7099cdc6c1SAnup Patel 		break;
7199cdc6c1SAnup Patel 	case KVM_CAP_MAX_VCPUS:
7299cdc6c1SAnup Patel 		r = KVM_MAX_VCPUS;
7399cdc6c1SAnup Patel 		break;
7499cdc6c1SAnup Patel 	case KVM_CAP_NR_MEMSLOTS:
7599cdc6c1SAnup Patel 		r = KVM_USER_MEM_SLOTS;
7699cdc6c1SAnup Patel 		break;
7799cdc6c1SAnup Patel 	default:
7899cdc6c1SAnup Patel 		r = 0;
7999cdc6c1SAnup Patel 		break;
8099cdc6c1SAnup Patel 	}
8199cdc6c1SAnup Patel 
8299cdc6c1SAnup Patel 	return r;
8399cdc6c1SAnup Patel }
8499cdc6c1SAnup Patel 
8599cdc6c1SAnup Patel long kvm_arch_vm_ioctl(struct file *filp,
8699cdc6c1SAnup Patel 		       unsigned int ioctl, unsigned long arg)
8799cdc6c1SAnup Patel {
8899cdc6c1SAnup Patel 	return -EINVAL;
8999cdc6c1SAnup Patel }
90