在KVM中实现自定义超级调用 [英] Implementing a custom hypercall in kvm
问题描述
我对虚拟化非常陌生,最近我一直在尝试使自己熟悉VMM的操作方式以及如何进行超级调用.
I am very new to Virtualization and of late I have been trying to familiarize myself with the way VMMs operate and how hypercalls are made.
讨论要在KVM上实现哪些新的超级调用,该超级调用已安装在Ubuntu桌面上,并且可以在来宾环境中调用.通过此超级调用,我计划仅返回一个字符串"Hello World".在这一点上,我对如何实现它一无所知.如果您能指导我如何实现这样的超级调用,那将非常有帮助.谢谢!
Talking about which I plan to implement a new hypercall in KVM which is installed on my Ubuntu desktop, and in turn can be callable from the guest environment.With this hypercall I plan to just return a string saying "Hello World". At this point,I am clueless about how to make it happen.It would be really helpful if you could please guide me as to how do I go about implementing such a hypercall.Thank you!
推荐答案
下面的补丁实现了一个超级调用,该调用将trace_printk
"Hello World"发送到主机的
The patches below implement a hypercall that will trace_printk
"Hello World" to the host's ftrace. (The base code is Linux 4.10.)
- (在来宾内核源代码中)添加调用hypercall的系统调用:
diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl
index e93ef0b..2ff3b3f 100644
--- a/arch/x86/entry/syscalls/syscall_64.tbl
+++ b/arch/x86/entry/syscalls/syscall_64.tbl
@@ -338,6 +338,7 @@
329 common pkey_mprotect sys_pkey_mprotect
330 common pkey_alloc sys_pkey_alloc
331 common pkey_free sys_pkey_free
+332 common hello_hypercall sys_hello_hypercall
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 91a740f..19208d5 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -902,5 +902,6 @@ asmlinkage long sys_pkey_mprotect(unsigned long start, size_t len,
unsigned long prot, int pkey);
asmlinkage long sys_pkey_alloc(unsigned long flags, unsigned long init_val);
asmlinkage long sys_pkey_free(int pkey);
+asmlinkage long sys_hello_hypercall(void);
#endif
diff --git a/hello_hypercall/hello_hypercall.h b/hello_hypercall/hello_hypercall.h
new file mode 100644
index 0000000..cc727ee8
--- /dev/null
+++ b/hello_hypercall/hello_hypercall.h
@@ -0,0 +1 @@
+asmlinkage long sys_hello_hypercall(void);
diff --git a/hello_hypercall/Makefile b/hello_hypercall/Makefile
new file mode 100644
index 0000000..6247351
--- /dev/null
+++ b/hello_hypercall/Makefile
@@ -0,0 +1 @@
+obj-y:=hello_hypercall.o
diff --git a/Makefile b/Makefile
index f1e6a02..6a84315 100644
--- a/Makefile
+++ b/Makefile
@@ -910,7 +910,7 @@ export mod_sign_cmd
ifeq ($(KBUILD_EXTMOD),)
-core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/
+core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ hello_hypercall/
vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
$(core-y) $(core-m) $(drivers-y) $(drivers-m) \
- (在来宾内核源代码中)实现syscall来调用超级调用
diff --git a/hello_hypercall/hello_hypercall.c b/hello_hypercall/hello_hypercall.c
new file mode 100644
index 0000000..aa333f8
--- /dev/null
+++ b/hello_hypercall/hello_hypercall.c
@@ -0,0 +1,17 @@
+#include<linux/kernel.h>
+#include<linux/syscalls.h>
+#include<linux/init.h>
+#include<linux/linkage.h>
+#include "hello_hypercall.h"
+#include<uapi/linux/kvm_para.h>
+#include<linux/cpumask.h>
+
+asmlinkage long sys_hello_hypercall(void)
+{
+ kvm_hypercall0(KVM_HC_HELLO_HYPERCALL);
+ return 0;
+}
kvm_hypercall0
用零个参数调用X86_FEATURE_VMMCALL
(其他kvm_hypercall
函数最多处理四个参数).号码KVM_HC_HELLO_HYPERCALL
(在include/uapi/linux/kvm_para.h
中定义)作为超级呼叫号码传入.用超级调用号和可能的参数调用X86_FEATURE_VMMCALL
后,执行将跳转到arch/x86/kvm/x86.c
中主机内核的函数kvm_emulate_hypercall
.
kvm_hypercall0
calls X86_FEATURE_VMMCALL
with zero arguments (the other kvm_hypercall
functions handle up to four arguments). The number KVM_HC_HELLO_HYPERCALL
(defined in include/uapi/linux/kvm_para.h
) is passed in as the hypercall number. After calling X86_FEATURE_VMMCALL
with the hypercall number and possibly arguments, execution will jump to the host kernel's function kvm_emulate_hypercall
in arch/x86/kvm/x86.c
.
请参见 https://有关更多信息,请访问elixir.bootlin.com/linux/latest/source/arch/x86/include/asm/kvm_para.h#L21 .
- (在主机内核源代码中)定义超级调用号(
include/uapi/linux/kvm_para.h
)并打印"Hello World"作为超级调用代码(arch/x86/kvm/x86.c
)
- (In host kernel source code) Define the hypercall number (
include/uapi/linux/kvm_para.h
) and print "Hello World" as the hypercall code (arch/x86/kvm/x86.c
)
diff --git a/include/uapi/linux/kvm_para.h b/include/uapi/linux/kvm_para.h
index bf6cd7d..67304a17 100644
--- a/include/uapi/linux/kvm_para.h
+++ b/include/uapi/linux/kvm_para.h
@@ -23,6 +23,7 @@
#define KVM_HC_MIPS_GET_CLOCK_FREQ 6
#define KVM_HC_MIPS_EXIT_VM 7
#define KVM_HC_MIPS_CONSOLE_OUTPUT 8
+#define KVM_HC_HELLO_HYPERCALL 9
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index e52c908..b755ccf 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6151,6 +6209,9 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
kvm_pv_kick_cpu_op(vcpu->kvm, a0, a1);
ret = 0;
break;
+ case KVM_HC_HELLO_HYPERCALL:
+ trace_printk("Hello World");
+ break;
default:
ret = -KVM_ENOSYS;
break;
KVM_HC_HELLO_HYPERCALL
存储超级呼叫的号码9(请参见此处(用于现有的超级呼叫号码).在arch/x86/kvm/x86.c
的kvm_emulate_hypercall
函数中,添加超级呼叫号码与KVM_HC_HELLO_HYPERCALL
匹配的情况.
KVM_HC_HELLO_HYPERCALL
stores the hypercall's number, 9 (see here for existing hypercall numbers). In arch/x86/kvm/x86.c
, in the kvm_emulate_hypercall
function, add the case where the the hypercall number matches KVM_HC_HELLO_HYPERCALL
.
在来宾内核中调用超级调用,以在主机的ftrace上查看其输出.
Invoke the hypercall in the guest kernel to see its output on the host's ftrace.
这篇关于在KVM中实现自定义超级调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!