[kvm-unit-tests PATCH v2 08/16] x86/run_in_user: Relax register constraints of inline asm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The code doesn't clobber all the registers it states it would. It
explicitly preserves the values of rcx, rdi and rsi. With a minor code
change rdx can be preserved as well. The code does, however, needlessly
save and restore rbx around the function call.

Change the code to not clobber rdx and drop all the register clobbers
from the asm constraints, as these registers are, in fact, preserved.
The function call either returns without throwing an exception (and
restoring all call clobbered registers itself) or via longjmp() (doing
the same, basically, but with special handling in the compiler as well).

Signed-off-by: Mathias Krause <minipli@xxxxxxxxxxxxxx>
---
 lib/x86/usermode.c | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/lib/x86/usermode.c b/lib/x86/usermode.c
index 10fcea288a62..fd19551a7a2d 100644
--- a/lib/x86/usermode.c
+++ b/lib/x86/usermode.c
@@ -63,21 +63,20 @@ uint64_t run_in_user(usermode_func func, unsigned int fault_vector,
 			"pushq %[user_stack_top]\n\t"
 			"pushfq\n\t"
 			"pushq %[user_cs]\n\t"
-			"lea user_mode(%%rip), %%rdx\n\t"
-			"pushq %%rdx\n\t"
+			"lea user_mode(%%rip), %%rax\n\t"
+			"pushq %%rax\n\t"
 			"iretq\n"
 
 			"user_mode:\n\t"
-			/* Back up registers before invoking func */
-			"push %%rbx\n\t"
+			/* Back up volatile registers before invoking func */
 			"push %%rcx\n\t"
 			"push %%rdx\n\t"
+			"push %%rdi\n\t"
+			"push %%rsi\n\t"
 			"push %%r8\n\t"
 			"push %%r9\n\t"
 			"push %%r10\n\t"
 			"push %%r11\n\t"
-			"push %%rdi\n\t"
-			"push %%rsi\n\t"
 			/* Call user mode function */
 			"mov %[arg1], %%rdi\n\t"
 			"mov %[arg2], %%rsi\n\t"
@@ -85,15 +84,14 @@ uint64_t run_in_user(usermode_func func, unsigned int fault_vector,
 			"mov %[arg4], %%rcx\n\t"
 			"call *%[func]\n\t"
 			/* Restore registers */
-			"pop %%rsi\n\t"
-			"pop %%rdi\n\t"
 			"pop %%r11\n\t"
 			"pop %%r10\n\t"
 			"pop %%r9\n\t"
 			"pop %%r8\n\t"
+			"pop %%rsi\n\t"
+			"pop %%rdi\n\t"
 			"pop %%rdx\n\t"
 			"pop %%rcx\n\t"
-			"pop %%rbx\n\t"
 			/* Return to kernel via system call */
 			"int %[kernel_entry_vector]\n\t"
 			/* Kernel Mode */
@@ -112,9 +110,7 @@ uint64_t run_in_user(usermode_func func, unsigned int fault_vector,
 			[user_cs]"i"(USER_CS),
 			[user_stack_top]"r"(user_stack +
 					sizeof(user_stack)),
-			[kernel_entry_vector]"i"(RET_TO_KERNEL_IRQ)
-			:
-			"rsi", "rdi", "rcx", "rdx");
+			[kernel_entry_vector]"i"(RET_TO_KERNEL_IRQ));
 
 	handle_exception(fault_vector, old_ex);
 
-- 
2.39.2




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux