[PATCH] x86/acrn: Improve ACRN hypercalls

From: Uros Bizjak
Date: Thu Aug 04 2022 - 14:04:17 EST


As explained in section 6.47.5.2, "Specifying Registers for Local Variables"
of the GCC info documentation, the correct way to specify register for
input operands when calling Extended 'asm' is to define a local register
variable and associate it with a specified register:

register unsigned long r8 asm ("r8") = hcall_id;

Use the above approach instead of explicit MOV to R8 at the beginning
of the asm. The relaxed assignment allows compiler to optimize and
shrink drivers/virt/acrn.o for 181 bytes:

text data bss dec hex filename
4284 208 0 4492 118c hsm-new.o
4465 208 0 4673 1241 hsm-old.o

Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Borislav Petkov <bp@xxxxxxxxx>
Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>
Cc: "H. Peter Anvin" <hpa@xxxxxxxxx>
Signed-off-by: Uros Bizjak <ubizjak@xxxxxxxxx>
---
arch/x86/include/asm/acrn.h | 27 ++++++++++++---------------
1 file changed, 12 insertions(+), 15 deletions(-)

diff --git a/arch/x86/include/asm/acrn.h b/arch/x86/include/asm/acrn.h
index e003a01b7c67..601867085b95 100644
--- a/arch/x86/include/asm/acrn.h
+++ b/arch/x86/include/asm/acrn.h
@@ -29,19 +29,16 @@ static inline u32 acrn_cpuid_base(void)
* - Hypercall number is passed in R8 register.
* - Up to 2 arguments are passed in RDI, RSI.
* - Return value will be placed in RAX.
- *
- * Because GCC doesn't support R8 register as direct register constraints, use
- * supported constraint as input with a explicit MOV to R8 in beginning of asm.
*/
static inline long acrn_hypercall0(unsigned long hcall_id)
{
long result;

- asm volatile("movl %1, %%r8d\n\t"
- "vmcall\n\t"
+ register unsigned long r8 asm ("r8") = hcall_id;
+ asm volatile("vmcall"
: "=a" (result)
- : "g" (hcall_id)
- : "r8", "memory");
+ : "r" (r8)
+ : "memory");

return result;
}
@@ -51,11 +48,11 @@ static inline long acrn_hypercall1(unsigned long hcall_id,
{
long result;

- asm volatile("movl %1, %%r8d\n\t"
- "vmcall\n\t"
+ register unsigned long r8 asm ("r8") = hcall_id;
+ asm volatile("vmcall"
: "=a" (result)
- : "g" (hcall_id), "D" (param1)
- : "r8", "memory");
+ : "r" (r8), "D" (param1)
+ : "memory");

return result;
}
@@ -66,11 +63,11 @@ static inline long acrn_hypercall2(unsigned long hcall_id,
{
long result;

- asm volatile("movl %1, %%r8d\n\t"
- "vmcall\n\t"
+ register unsigned long r8 asm ("r8") = hcall_id;
+ asm volatile("vmcall"
: "=a" (result)
- : "g" (hcall_id), "D" (param1), "S" (param2)
- : "r8", "memory");
+ : "r" (r8), "D" (param1), "S" (param2)
+ : "memory");

return result;
}
--
2.37.1