DF-5123 / fix.diff
--- 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); } |