c - 具有多个参数的 kvm 超级调用
问题描述
我目前正在尝试使用 kvm 构建一个小型虚拟机管理程序和内核,但我很难让具有多个 args 的超级调用正常工作。
这是我尝试过的:
// guest.c
#define KVM_HYPERCALL vmcall
// #define KVM_HYPERCALL vmmcall
// #define KVM_HYPERCALL ".byte 0x0f,0x01,0xd9"
// #define KVM_HYPERCALL .byte 0x0f,0x01,0xc1"
static inline long kvm_hypercall4(int nr, unsigned long p1,
unsigned long p2, unsigned long p3,
unsigned long p4) {
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
: "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4)
: "memory");
return ret;
}
这些超级调用中的任何一个都会导致vcpu->kvm_run->exit_reason
等于 6,这让我感到惊讶KVM_EXIT_MMIO
,而不是KVM_EXIT_HYPERCALL
switch (vcpu->kvm_run->exit_reason) {
case KVM_EXIT_MMIO:
printf("syscall: %lld\n", vcpu->kvm_run->hypercall.nr); // prints 0
printf("arg 1: %lld\n", vcpu->kvm_run->hypercall.args[1]); // prints 0
printf("arg 2: %lld\n", vcpu->kvm_run->hypercall.args[2]); // prints 0
printf("arg 3: %lld\n", vcpu->kvm_run->hypercall.args[3]); // prints 0
if(ioctl(vcpu->fd, KVM_GET_REGS, ®s)<0) exit 1;
printf("rax: %lld\n", regs.rax); // prints 0
printf("rbx: %lld\n", regs.rbx); // prints 0
printf("rcx: %lld\n", regs.rcx); // prints 0
除了退出原因是KVM_EXIT_MMIO
为什么没有设置规则?使用多个参数触发 KVM_EXIT_HYPERCALL 的正确方法是什么?
提前致谢
编辑:以防万一:我使用的是第 9 代英特尔 i7 cpu,运行带有 linux 内核 5.4 的 debian
解决方案
KVM_EXIT_HYPERCALL
根据文档,不再使用:
/* KVM_EXIT_HYPERCALL */ struct { __u64 nr; __u64 args[6]; __u64 ret; __u32 longmode; __u32 pad; } hypercall;
没用过。这曾经被用于“对用户空间的超级调用”。要实现此类功能,请使用 KVM_EXIT_IO (x86) 或 KVM_EXIT_MMIO(除 s390 之外的所有)。注意 KVM_EXIT_IO 比 KVM_EXIT_MMIO 快得多。
在我看来,这KVM_EXIT_HYPERCALL
也没有实施。使用grep进行快速而肮脏的搜索。它已定义,但永远不会分配为exit_reason
:
user@host:~/Linux/src> grep -R KVM_EXIT_HYPERCALL
include/uapi/linux/kvm.h:#define KVM_EXIT_HYPERCALL 3
include/uapi/linux/kvm.h: /* KVM_EXIT_HYPERCALL */
Documentation/virt/kvm/api.rst: /* KVM_EXIT_HYPERCALL */
tools/include/uapi/linux/kvm.h:#define KVM_EXIT_HYPERCALL 3
tools/include/uapi/linux/kvm.h: /* KVM_EXIT_HYPERCALL */
tools/testing/selftests/kvm/lib/kvm_util.c: {KVM_EXIT_HYPERCALL, "HYPERCALL"},
user@host:~/Linux/src>
Linux 版本:
user@host:~/Linux/src> git-describe --tags
v5.6-10895-g4c205c84e249
user@host:~/Linux/src>
有一个较旧的问题,如何在此站点上实现自定义 VMCALL,并提供两个答案。你试过了吗?
推荐阅读
- css - 将自定义 CSS 文件添加到 AdminBro 组件中
- python - Python - 从“for循环”获取单个浮点类型输出并组合成一个列表
- listview - 在 KivyMD 中,如何在每个条目的左侧创建一个带有文本的 MDList,在每个条目的右侧创建一个进度条?
- f# - 反转列表中的F#值限制问题
- python - 应该使用什么 tkinter 小部件来显示和存储数据?可以用标签吗?我正在使用 sqlite3 作为数据库
- java - 获取用户的存在 - discord JDA 库
- vba - 如何浏览不同级别的链接 selenium vba
- python - 如何使用字符串作为 python 函数语法?
- python - Python 的模式匹配性能如何?是 O(1) 吗?
- javascript - 使用 Web 服务并使用 Node.js 将 CLOB 插入 Oracle 数据库表