
一、Why LiKeX ?
| 项 | KVM | 指标意义 |
| 实现语言 | C | Rust |
| lapic/ioapic/pic 模拟 | 多种实现方式组合 | lapic 内核模拟,ioapic/pic用户态模拟 |
| PIT 模拟 | 内核或用户态都支持 | 不实现 |
| KVM 设备文件 vm/vcpu | 每个层面都是一个独立的文件句柄 | 共享一个文件句柄 |
| 指令模拟 | 内核态实现 | 用户态实现 |
| mmio 处理 | 用 ept misconfig,通过 mmu 页表追踪 mmio 区域 | 不使用 ept misconfig |
//Guest态运行的程序const unsigned char code[] = {0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */0x00, 0xd8, /* add %bl, %al */0x04, '0', /* add $'0', %al */0xee, /* out %al, (%dx) */0xb0, '\n', /* mov $'\n', %al */0xee, /* out %al, (%dx) */0xf4, /* hlt */};//Guest内存区域struct kvm_userspace_memory_region region = {.slot = 0,.flags = 0,.guest_phys_addr = 0,.memory_size = 0x1000,};struct kvm_regs regs = {.rip = 0,.rax = 2,.rbx = 2,.rflags = 0x2,};void main(void){fd = open("/dev/rust_kvm",O_RDWR); //打开rust_kvm设备ret = ioctl(fd, KVM_CREATE_VM, 0);//创建虚拟机mem = (unsigned long)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_ANONYMOUS, -1, 0);memset((char*)mem, 0, 4096);memcpy((char *)mem, code, sizeof(code));//拷贝Guest态代码到当前进程某段地址空间region.userspace_addr = (uint64_t)mem;ret = ioctl(fd, KVM_SET_USER_MEMORY_REGION, ®ion);//传递Guest地址空间到内核部分到rust_kvmret = ioctl(fd, KVM_CREATE_VCPU, 0); //创建VCPUrun = (struct kvm_run *)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);memset((char*)&sregs, 0, sizeof(sregs));ioctl(fd, KVM_GET_SREGS, &sregs);sregs.cs.base = 0;sregs.cs.selector = 0;ioctl(fd, KVM_SET_SREGS, &sregs);ioctl(fd, KVM_SET_REGS, ®s);ioctl(fd, KVM_GET_REGS, ®s);while (loop0 < 8) {ioctl(fd, KVM_RUN, NULL); //进入Guest态运行switch (run->exit_reason) {//从Guest态退出,根据退出原因在用户态调用对应处理函数/* Handle exit */case KVM_EXIT_HLT:return;case KVM_EXIT_IO:if (run->io.direction == KVM_EXIT_IO_OUT &&run->io.size == 1 &&run->io.port == 0x3f8 &&run->io.count == 1)printf("exit io:%c \n", (*(((char *)run) + run->io.data_offset)));break;case KVM_EXIT_FAIL_ENTRY:printf(" fail entry\n");memset((char*)®s, 0, sizeof(regs));ioctl(fd, KVM_GET_REGS, ®s);return;case KVM_EXIT_INTERNAL_ERROR:printf(" internal error\n");return;default:printf(" default:0x%x\n", run->exit_reason);return;}loop0++;}}
rust_kvm: Rust KVM Openrust_kvm: Rust kvm: vmcs=ffff888110f02000,revision=4rust_kvm: written new cr4 valuerust_kvm: Rust kvm: IOCTL_KVM_CREATE_VMrust_kvm: Rust kvm: IOCTL_KVM_SET_USER_MEMORY_REGIONrust_kvm: add_memory_region slot= 0,uaddr=7f531f3e5000, gpa = 0, npages=1rust_kvm: Rust kvm: IOCTL_KVM_CREATE_VCPUrust_kvm: RkvmMmu hpa(va) = ffff88811d6ed000rust_kvm: RkvmMmu hpa(phy) = 11d6ed000rust_kvm: ad_disabled = false, ecex_only = truerust_kvm: setup pin=17,cpu=a581e5f2, cpu2=82,exit=3fefff, entry=d1ffrust_kvm: pin_based = 17rust_kvm: cpu_based = a581e5f2rust_kvm: cpu_2nd_based = 82rust_kvm: vcpu_vmcs_initrust_kvm: init_mmu_rootrust_kvm: hpa= 11d6ed000, eptp = 11d6ed01erust_kvm: Rust kvm: IOCTL_KVM_CREATE_VCPU finishrust_kvm: Rust KVM mmaprust_kvm: Rust kvm: IOCTL_KVM_GET_SREGSrust_kvm: Rust kvm: IOCTL_KVM_VCPU_RUNrust_kvm: vcpu_run state guest rip = 0, read guest rip = 0rust_kvm: vmentry: launched = falserust_kvm: Enter handle EPT violationrust_kvm: pagefault: pfn=1999950rust_kvm: rkvm_tdp_map level=4, gfn=0, spte=14a55c907rust_kvm: rkvm_tdp_map level=3, gfn=0, spte=1567bf907rust_kvm: rkvm_tdp_map level=2, gfn=0, spte=11bcc5907rust_kvm: rkvm_tdp_map level=1, gfn=0, spte=6000001e844eb07rust_kvm: ret=Ok(1),after vcpu_exit_handlerrust_kvm: vmentry: launched = truerust_kvm: vmexit: guest_rip=7rust_kvm: handle_io port =3f8rust_kvm: ret=Ok(0), after vcpu_exit_handlerrust_kvm: vmentry: launched = truerust_kvm: vmexit: guest_rip=9rust_kvm: handle hltrust_kvm: ret=Ok(0), after vcpu_exit_handler

三、小结
欢迎扫描下方二维码,加入社区用户群,了解 OpenCloudOS 最新动态,获取技术相关的支持,分享交流使用体验。

文章转载自OpenCloudOS,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




