From: Andrew Cooper Date: Mon, 17 Feb 2020 09:48:26 +0000 (+0000) Subject: Fix asm constraints for push/pop instructions X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=a82affd0be75d25ac2578d0de5199c21fe8bd62c;p=xtf.git Fix asm constraints for push/pop instructions There are several issues with 64bit builds. Correct the types/constraints to prohibit encoding 32bit registers, and immediates which can't be represented as a 32bit signed extended number. Introduce asm_checks() in selftest as a build-time check for constraint corner cases, to be extended as needed. Signed-off-by: Andrew Cooper --- diff --git a/arch/x86/include/arch/lib.h b/arch/x86/include/arch/lib.h index 0259c2e..4046b9c 100644 --- a/arch/x86/include/arch/lib.h +++ b/arch/x86/include/arch/lib.h @@ -175,7 +175,7 @@ static inline unsigned int read_ss(void) return ss; } -static inline void write_cs(unsigned int cs) +static inline void write_cs(unsigned long cs) { asm volatile ("push %0;" "push $1f;" @@ -183,7 +183,7 @@ static inline void write_cs(unsigned int cs) "rex64 " #endif "lret; 1:" - :: "qI" (cs)); + :: "rme" (cs)); } static inline void write_ds(unsigned int ds) @@ -211,18 +211,18 @@ static inline void write_ss(unsigned int ss) asm volatile ("mov %0, %%ss" :: "rm" (ss)); } -static inline unsigned int read_flags(void) +static inline unsigned long read_flags(void) { - unsigned int flags; + unsigned long flags; asm volatile ("pushf; pop %0" : "=rm" (flags)); return flags; } -static inline void write_flags(unsigned int flags) +static inline void write_flags(unsigned long flags) { - asm volatile ("push %0; popf" :: "irm" (flags)); + asm volatile ("push %0; popf" :: "rme" (flags)); } static inline unsigned long read_cr0(void) diff --git a/tests/selftest/main.c b/tests/selftest/main.c index a376df3..c2f6e72 100644 --- a/tests/selftest/main.c +++ b/tests/selftest/main.c @@ -375,6 +375,28 @@ void test_main(void) xtf_success(NULL); } +/* + * Inline assembly checks. + * + * Needs to be written out into an object file to cause build failures. + * Nothing executes the resulting code. + * + * - push/pop %reg need to use unsigned long types to avoid trying to allocate + * 32bit registers, which aren't encodable in 64bit. + * - push $imm can't encode 64bit integers (only 32bit sign extended) + */ +static void __used asm_checks(void) +{ + read_flags(); + +#ifdef __x86_64__ + unsigned long tmp = 0xdead0000c0deULL; + + write_flags(tmp); + write_cs(tmp); +#endif +} + /* * Local variables: * mode: C