kvm_cpu__arch_init
vcpuの準備
ioctl KVM_CREATE_VCPU
ioctl KVM_GET_ONE_REG (ISA)
ioctl KVM_GET_ONE_REG (timebase)
ioctl KVM_GET_VCPU_MMAP_SIZE #TODO mmap はなにを示している? vcpu->kvm_run = mmap_size
ioctl KVM_CHECK_EXTENSION #TODO ? coalesced mmio
ioctl KVM_SET_ONE_REG (ISA)
code:kvm/kvm-cpu.c
struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
{
struct kvm_cpu *vcpu;
unsigned long timebase = 0, isa = 0;
int coalesced_offset, mmap_size;
struct kvm_one_reg reg;
vcpu = calloc(1, sizeof(struct kvm_cpu));
if (!vcpu)
return NULL;
vcpu->vcpu_fd = ioctl(kvm->vm_fd, KVM_CREATE_VCPU, cpu_id);
if (vcpu->vcpu_fd < 0)
die_perror("KVM_CREATE_VCPU ioctl");
reg.id = RISCV_CONFIG_REG(isa);
reg.addr = (unsigned long)&isa;
if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
die("KVM_GET_ONE_REG failed (config.isa)");
reg.id = RISCV_CONFIG_REG(tbfreq);
reg.addr = (unsigned long)&timebase;
if (ioctl(vcpu->vcpu_fd, KVM_GET_ONE_REG, ®) < 0)
die("KVM_GET_ONE_REG failed (config.timebase)");
mmap_size = ioctl(kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
if (mmap_size < 0)
die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl");
vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED,
vcpu->vcpu_fd, 0);
if (vcpu->kvm_run == MAP_FAILED)
die("unable to mmap vcpu fd");
coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION,
KVM_CAP_COALESCED_MMIO);
if (coalesced_offset)
vcpu->ring = (void *)vcpu->kvm_run +
(coalesced_offset * PAGE_SIZE);
reg.id = RISCV_CONFIG_REG(isa);
reg.addr = (unsigned long)&isa;
if (ioctl(vcpu->vcpu_fd, KVM_SET_ONE_REG, ®) < 0)
die("KVM_SET_ONE_REG failed (config.isa)");
/* Populate the vcpu structure. */
vcpu->kvm = kvm;
vcpu->cpu_id = cpu_id;
vcpu->riscv_isa = isa;
vcpu->riscv_xlen = __riscv_xlen;
vcpu->riscv_timebase = timebase;
vcpu->is_running = true;
return vcpu;
}