linux kernel KVM

本文介绍KVM虚拟机的创建过程及ioctl命令的处理机制,详细解析了KVM内核模块中用于创建虚拟机的数据结构及ioctl命令的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kvm 的linux内核描述:

include/linux/kvm_host.h struct kvm {  spinlock_t mmu_lock;  struct mutex slots_lock;  struct mm_struct *mm; /*进程地址空间描述*/ struct kvm_memslots *memslots[KVM_ADDRESS_SPACE_NUM];KVM使用的内存描述  struct srcu_struct srcu;  struct srcu_struct irq_srcu;  struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];支持的最大虚拟CPU个数

 /*   * created_vcpus is protected by kvm->lock, and is incremented   * at the beginning of KVM_CREATE_VCPU.  online_vcpus is only   * incremented after storing the kvm_vcpu pointer in vcpus,   * and is accessed atomically.   */  atomic_t online_vcpus;  int created_vcpus;  int last_boosted_vcpu;  struct list_head vm_list;  struct mutex lock;  struct kvm_io_bus *buses[KVM_NR_BUSES]; #ifdef CONFIG_HAVE_KVM_EVENTFD  struct {   spinlock_t        lock;   struct list_head  items;   struct list_head  resampler_list;   struct mutex      resampler_lock;  } irqfds;  struct list_head ioeventfds; #endif  struct kvm_vm_stat stat;  struct kvm_arch arch;  atomic_t users_count; #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET  struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;  spinlock_t ring_lock;  struct list_head coalesced_zones; #endif

 struct mutex irq_lock; #ifdef CONFIG_HAVE_KVM_IRQCHIP  struct kvm_irq_routing_table __rcu *irq_routing; #endif #ifdef CONFIG_HAVE_KVM_IRQFD  struct hlist_head irq_ack_notifier_list; #endif

#if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)  struct mmu_notifier mmu_notifier;  unsigned long mmu_notifier_seq;  long mmu_notifier_count; #endif  long tlbs_dirty;  struct list_head devices;  struct dentry *debugfs_dentry;  struct kvm_stat_data **debugfs_stat_data; };

相关的结构:

static struct file_operations kvm_chardev_ops = {  .unlocked_ioctl = kvm_dev_ioctl,  .compat_ioctl   = kvm_dev_ioctl,  .llseek  = noop_llseek, };

static struct miscdevice kvm_dev = {  KVM_MINOR,  "kvm",  &kvm_chardev_ops, };

用户空间工具通过ioctl与内核空间的kvm模块通信,kvm_dev_ioctl主要功能是创建虚拟机数据结构。

static long kvm_dev_ioctl(struct file *filp,      unsigned int ioctl, unsigned long arg) {  long r = -EINVAL;

 switch (ioctl) {  case KVM_GET_API_VERSION:   if (arg)    goto out;   r = KVM_API_VERSION;   break;  case KVM_CREATE_VM:   r = kvm_dev_ioctl_create_vm(arg);   break;  case KVM_CHECK_EXTENSION:   r = kvm_vm_ioctl_check_extension_generic(NULL, arg);   break;  case KVM_GET_VCPU_MMAP_SIZE:   if (arg)    goto out;   r = PAGE_SIZE;     /* struct kvm_run */ #ifdef CONFIG_X86   r += PAGE_SIZE;    /* pio data page */ #endif #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET   r += PAGE_SIZE;    /* coalesced mmio ring page */ #endif   break;  case KVM_TRACE_ENABLE:  case KVM_TRACE_PAUSE:  case KVM_TRACE_DISABLE:   r = -EOPNOTSUPP;   break;  default:   return kvm_arch_dev_ioctl(filp, ioctl, arg);  } out:  return r; } 上面函数需要注意三点,一是支持的case类别,二是创建虚拟机的cmd类别为KVM_CREATE_VM

三是体系结构可以对kvm_dev_ioctl支持的case增强,即实现kvm_arch_dev_ioctl函数,以达到更强的控制。

显然,KVM框架层支持的case以在上面函数给出,主要有:

#define KVM_GET_API_VERSION       _IO(KVMIO,   0x00) #define KVM_CREATE_VM             _IO(KVMIO,   0x01) /* returns a VM fd */ #define KVM_GET_MSR_INDEX_LIST    _IOWR(KVMIO, 0x02, struct kvm_msr_list)

/*  * Check if a kvm extension is available.  Argument is extension number,  * return is 1 (yes) or 0 (no, sorry).  */ #define KVM_CHECK_EXTENSION       _IO(KVMIO,   0x03) /*  * Get size for mmap(vcpu_fd)  */ #define KVM_GET_VCPU_MMAP_SIZE    _IO(KVMIO,   0x04) /* in bytes */ #define KVM_GET_SUPPORTED_CPUID   _IOWR(KVMIO, 0x05, struct kvm_cpuid2) #define KVM_TRACE_ENABLE          __KVM_DEPRECATED_MAIN_W_0x06 #define KVM_TRACE_PAUSE           __KVM_DEPRECATED_MAIN_0x07 #define KVM_TRACE_DISABLE         __KVM_DEPRECATED_MAIN_0x08 #define KVM_GET_EMULATED_CPUID   _IOWR(KVMIO, 0x09, struct kvm_cpuid2)

创建虚拟机的函数为kvm_dev_ioctl_create_vm()。

对于X86体系架构来说,其实现了kvm_arch_dev_ioctl()函数:

arch/x86/kvm/x86.c

long kvm_arch_dev_ioctl(struct file *filp,    unsigned int ioctl, unsigned long arg) {  void __user *argp = (void __user *)arg;  long r;

 switch (ioctl) {  case KVM_GET_MSR_INDEX_LIST: {   struct kvm_msr_list __user *user_msr_list = argp;   struct kvm_msr_list msr_list;   unsigned n;

  r = -EFAULT;   if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list))    goto out;   n = msr_list.nmsrs;   msr_list.nmsrs = num_msrs_to_save + num_emulated_msrs;   if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list))    goto out;   r = -E2BIG;   if (n < msr_list.nmsrs)    goto out;   r = -EFAULT;   if (copy_to_user(user_msr_list->indices, &msrs_to_save,      num_msrs_to_save * sizeof(u32)))    goto out;   if (copy_to_user(user_msr_list->indices + num_msrs_to_save,      &emulated_msrs,      num_emulated_msrs * sizeof(u32)))    goto out;   r = 0;   break;  }  case KVM_GET_SUPPORTED_CPUID:  case KVM_GET_EMULATED_CPUID: {   struct kvm_cpuid2 __user *cpuid_arg = argp;   struct kvm_cpuid2 cpuid;

  r = -EFAULT;   if (copy_from_user(&cpuid, cpuid_arg, sizeof cpuid))    goto out;

  r = kvm_dev_ioctl_get_cpuid(&cpuid, cpuid_arg->entries,          ioctl);   if (r)    goto out;

  r = -EFAULT;   if (copy_to_user(cpuid_arg, &cpuid, sizeof cpuid))    goto out;   r = 0;   break;  }  case KVM_X86_GET_MCE_CAP_SUPPORTED: {   r = -EFAULT;   if (copy_to_user(argp, &kvm_mce_cap_supported,      sizeof(kvm_mce_cap_supported)))    goto out;   r = 0;   break;  }  default:   r = -EINVAL;  } out:  return r; }

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值