⬢ DragonFlyBSD Kernel Audit
DF-5123 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/virtual/hyperv/x86_64/hyperv_machdep.c
+++ b/sys/dev/virtual/hyperv/x86_64/hyperv_machdep.c
@@ -74,11 +74,15 @@ static struct cpucounter hyperv_tsc_cpuc
 uint64_t
 hypercall_md(volatile void *hc_addr, uint64_t in_val,
     uint64_t in_paddr, uint64_t out_paddr)
 {
 	uint64_t status;
 
-	__asm__ __volatile__ ("mov %0, %%r8" : : "r" (out_paddr): "r8");
-	__asm__ __volatile__ ("call *%3" : "=a" (status) :
-	    "c" (in_val), "d" (in_paddr), "m" (hc_addr));
+	/*
+	 * Single asm: out_paddr must survive in %r8 until the call, and
+	 * the indirect call clobbers all caller-saved registers and
+	 * memory (hypercall input/output pages).
+	 */
+	__asm__ __volatile__ ("movq %3, %%r8\n\tcall *%4"
+	    : "=a" (status)
+	    : "c" (in_val), "d" (in_paddr), "r" (out_paddr), "m" (hc_addr)
+	    : "r8", "r9", "r10", "r11", "memory", "cc");
 	return (status);
 }