Stack Overflow ã®ãã®æ稿 https://stackoverflow.com/questions/33590843/implementing-a-custom-hypercall-in-kvm ã®ã»ã¼ãã®ã¾ã¾ã§ã。
ãã¤ãã°ã°ãã grep ã§ã³ã¼ãã®å ´æãæ¢ãã¦ãã¾ãã®ã§åå¿é²。
ãã®ãã¤ãã¼ã³ã¼ã«ã®å¼ã³ããã¯ã¢ã¼ããã¯ãã£ã«ãã£ã¦ç°ãªãã,x86 ã§ã¯ç°¡åã§
ãããã¾ãã ã,
ã¨ããã§,kvm ã® VM exit ãã³ãã©ã®é åãªã®ã ããã©ã,
追è¨:ãã£ã±ãããããæ¡å¼µãã£ã https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
diff --git a/include/uapi/linux/kvm_para.h b/include/uapi/linux/kvm_para.h
index dcf629dd2889..e0f8b786a62a 100644
--- a/include/uapi/linux/kvm_para.h
+++ b/include/uapi/linux/kvm_para.h
@@ -26,6 +26,7 @@
#define KVM_HC_MIPS_EXIT_VM 7
#define KVM_HC_MIPS_CONSOLE_OUTPUT 8
#define KVM_HC_CLOCK_PAIRING 9
+#define KVM_HC_TEST 100
/*
* hypercalls use architecture specific
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b7618b30b7d6..5c82ac8f4b38 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6714,6 +6714,9 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
ret = kvm_pv_clock_pairing(vcpu, a0, a1);
break;
#endif
+ case KVM_HC_TEST:
+ some_process();
+ break;
default:
ret = -KVM_ENOSYS;
break;
ãã®ããã«,ãã¤ãã¼ã³ã¼ã«ã®çªå·ã追å ã,ã¢ã¼ããã¯ãã£åºæã®ã³ã¼ãã«ãã¤ãã¼ã³ã¼ã«ã®çªå·ã§ switch ãã¦ããç®æãããã®ã§ããã«å¦çã追å ããã°è¯ã。
ã¡ãªã¿ã«ãã®ãã¤ãã¼ã³ã¼ã«ã®å¦çã追å ãã¦ããç®æã®é¢æ° kvm_emulate_hypercall
㯠x86 ã§ã¯ arch/x86/kvm/vmx.c
ã® handle_vmcall()
ããå¼ã°ãã¦ãã,ãã®é¢æ°ã¯åã½ã¼ã¹å
ã«ãã kvm_vmx_exit_handlers
ã¨ããé¢æ°ãã¤ã³ã¿ã®é
å㧠[EXIT_REASON_VMCALL]
ã«ç»é²ããã¦ãã。ã¤ã¾ã, VM exit ã®çç±ã vmcall ã ã£ãå ´åã«å¼ã°ããé¢æ°ã 。ãã®ãã¤ãã¼ã³ã¼ã«ã®å¼ã³ããã¯ã¢ã¼ããã¯ãã£ã«ãã£ã¦ç°ãªãã,x86 ã§ã¯ç°¡åã§
eax
ã¬ã¸ã¹ã¿ã«ãã¤ãã¼ã³ã¼ã«çªå·ãç©ãã§ãã vmcall
çªå·ãçºè¡ããã°è¯ãã®ã§,
asm volatile ("vmcall" : "eax"(100));
ã¨ããã°è¯ã。
ãã ,arch/x86/include/asm/kvm_para.h
ã§ã¯ä¾¿å©ãªé¢æ°ã次ã®ããã«å®ç¾©ããã¦ãã,
static inline long kvm_hypercall0(unsigned int nr)
{
long ret;
asm volatile(KVM_HYPERCALL
: "=a"(ret)
: "a"(nr)
: "memory");
return ret;
}
ãã㯠#include <uapi/linux/kvm_para.h>
ã¨ããã°èªã¿è¾¼ããããã¢ã¼ããã¯ãã£ã«ä¾åãããã¤ãã¼ã³ã¼ã«ãå¼ã¹ãããç´æ¥ã¢ã»ã³ããªå½ä»¤ãçºè¡ãããããè³¢æãã¨æããã。
å¼æ°ãå¢ãããããã° kvm_hypercall0()
ã¨ãªã£ã¦ããé¨åã® 0 ãå¥ã®æ°åã«ããã°è¯ã。4 ã¾ã§å¢ããã。ãããã¾ãã ã,
kvm_para.h
ãã¤ã³ã¯ã«ã¼ãããã«ãã¦ã vmcall
å½ä»¤ãçºè¡ããã«ãã¦ã Linux ã«ã¼ãã«ã®ä¸ã§ãããªããã°ãããªã。ã¨ããã§,kvm ã® VM exit ãã³ãã©ã®é åãªã®ã ããã©ã,
static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
[EXIT_REASON_EXCEPTION_NMI] = handle_exception,
[EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt,
[EXIT_REASON_TRIPLE_FAULT] = handle_triple_fault,
[EXIT_REASON_NMI_WINDOW] = handle_nmi_window,
[EXIT_REASON_IO_INSTRUCTION] = handle_io,
...
};
ããªãã§ã³ã³ãã¤ã«ãéããããããã£ã¦ã¾ãã。GNU æ¡å¼µã§é
åã®ç¹å®ã®æ·»åã®å ´æã«è¦ç´ ãå
¥ãã¦åæåã§ããè¨æ³ã§ãããã®ããª,ã¨ã¯æãã¾ãã。
ã©ãªããæãã¦ãã ããã¨ãããããã§ã。追è¨:ãã£ã±ãããããæ¡å¼µãã£ã https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html