[Lguest] [PATCH resend v2] lguest: Change over to using KVM hypercalls mechanism

Rusty Russell rusty at rustcorp.com.au
Fri Oct 24 13:50:41 EST 2008


On Friday 24 October 2008 08:17:13 Matias Zabaljauregui wrote:
> This patch allows us to use KVM hypercalls.
>
> Signed-off-by: Matias Zabaljauregui <zabaljauregui at gmail.com>

Thanks, this is excellent!

I inserted some paragraph breaks in your prose, and expanded the wording a
little at the start and end.  I hope that's ok, here's the change.

Thanks!
Rusty.

diff -r 71fc5b444eea drivers/lguest/x86/core.c
--- a/drivers/lguest/x86/core.c	Fri Oct 24 13:35:43 2008 +1100
+++ b/drivers/lguest/x86/core.c	Fri Oct 24 13:49:38 2008 +1100
@@ -291,28 +291,36 @@ static int emulate_insn(struct lg_cpu *c
 }
 
 /* Our hypercalls mechanism used to be based on direct software interrupts.
- * After Anthony's "Refactor hypercall infrastructure" kvm patch,
- * we decided to change over to using kvm hypercalls.
- * KVM_HYPERCALL generates an invalid opcode fault (fault 6) on non-VT cpus, so
- * the easiest solution seemed to be an *emulation approach*: if the fault was
- * really produced by an hypercall (is_hypercall() does exactly this check), we
- * just call the corresponding hypercall host implementation function.
- * But invalid opcode faults are notably slower than software interrupts.
- * So we implemented the *patching (or rewriting) approach*: every time we find
- * the KVM_HYPERCALL opcode in guest code, we patch it to int 0x1f opcode, so
- * next time the guest calls this hypercall, it will use the faster
- * int mechanism. We made some tests to convince you. The benchmark shows the
- * average cycle cost of a hypercall. For each alternative solution
- * mentioned above we've made 5 runs of the benchmark:
- * 1) direct software interrupt:  2915, 2789, 2764, 2721, 2898
+ * After Anthony's "Refactor hypercall infrastructure" kvm patch, we decided to
+ * change over to using kvm hypercalls.
+ *
+ * KVM_HYPERCALL is actually a "vmcall" instruction, which generates an invalid
+ * opcode fault (fault 6) on non-VT cpus, so the easiest solution seemed to be
+ * an *emulation approach*: if the fault was really produced by an hypercall
+ * (is_hypercall() does exactly this check), we can just call the corresponding
+ * hypercall host implementation function.
+ *
+ * But these invalid opcode faults are notably slower than software interrupts.
+ * So we implemented the *patching (or rewriting) approach*: every time we hit
+ * the KVM_HYPERCALL opcode in Guest code, we patch it to the old "int 0x1f"
+ * opcode, so next time the Guest calls this hypercall it will use the
+ * faster trap mechanism.
+ *
+ * Matias even benchmarked it to convince you: this shows the average cycle
+ * cost of a hypercall.  For each alternative solution mentioned above we've
+ * made 5 runs of the benchmark:
+ *
+ * 1) direct software interrupt: 2915, 2789, 2764, 2721, 2898
  * 2) emulation technique: 3410, 3681, 3466, 3392, 3780
- * 3) patching (rewrite) technique: 2977, 2975, 2891, 2637, 2884 */
+ * 3) patching (rewrite) technique: 2977, 2975, 2891, 2637, 2884
+ *
+ * One two-line function is worth a 20% hypercall speed boost!
+ */
 static void rewrite_hypercall(struct lg_cpu *cpu)
 {
-	/* This are the opcodes we use to patch the guest.
-	 * The opcode for "int $0x1f"  is  0xcd 0x1f
-	 * but vmcall instruction is 3 bytes long, so we complete
-	 * the sequence with a NOP (0x90). */
+	/* This are the opcodes we use to patch the Guest.  The opcode for "int
+	 * $0x1f" is "0xcd 0x1f" but vmcall instruction is 3 bytes long, so we
+	 * complete the sequence with a NOP (0x90). */
 	u8 insn[3] = {0xcd, 0x1f, 0x90};
 
 	__lgwrite(cpu, guest_pa(cpu, cpu->regs->eip), insn, sizeof(insn));
@@ -326,7 +334,7 @@ static bool is_hypercall(struct lg_cpu *
 	 * The bottom two bits of the CS segment register are the privilege
 	 * level. */
 	if ((cpu->regs->cs & 3) != GUEST_PL)
-		return 0;
+		return false;
 
 	/* Is it a vmcall? */
 	__lgread(cpu, insn, guest_pa(cpu, cpu->regs->eip), sizeof(insn));



More information about the Lguest mailing list