Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
{sysutils,emulators}/xen-{tools,kernel}: update to latest stable hash
Update the kernel and tools packages and also include a fix for a clang code generation bug. Sponsored by: Cloud Software Group Approved by: bapt (implicit)
- Loading branch information
Roger Pau Monné
authored and
Roger Pau Monné
committed
Feb 22, 2024
1 parent
e86f4ac
commit 1094417
Showing
5 changed files
with
150 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
TIMESTAMP = 1702977481 | ||
SHA256 (xen-project-xen-1792d1723b7fb45a20b145d2de4d233913b22c09_GL0.tar.gz) = cd999c5c715190cffa80e51d2099423039aca535d478d0090c31bacdf33a3401 | ||
SIZE (xen-project-xen-1792d1723b7fb45a20b145d2de4d233913b22c09_GL0.tar.gz) = 6825501 | ||
TIMESTAMP = 1708622887 | ||
SHA256 (xen-project-xen-b1fdd7d0e47e0831ac7a99d0417385fc10d3068c_GL0.tar.gz) = 4cb7ef37b51d9d1ff58272fafebfa91d48aadacdb5cc4ee6f046488234be8c1b | ||
SIZE (xen-project-xen-b1fdd7d0e47e0831ac7a99d0417385fc10d3068c_GL0.tar.gz) = 6826601 |
137 changes: 137 additions & 0 deletions
137
emulators/xen-kernel/files/v2-0001-x86-altcall-use-an-union-as-register-type-for-fun.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
From e0d563ca60b16dfab45956f60a6c1b7b1e218ba4 Mon Sep 17 00:00:00 2001 | ||
From: Roger Pau Monne <roger.pau@citrix.com> | ||
To: xen-devel@lists.xenproject.org | ||
Cc: Jan Beulich <jbeulich@suse.com> | ||
Cc: Andrew Cooper <andrew.cooper3@citrix.com> | ||
Cc: "Roger Pau Monné" <roger.pau@citrix.com> | ||
Cc: Wei Liu <wl@xen.org> | ||
Date: Wed, 21 Feb 2024 16:55:12 +0100 | ||
Subject: [PATCH v2] x86/altcall: use an union as register type for function | ||
parameters | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain; charset=UTF-8 | ||
Content-Transfer-Encoding: 8bit | ||
|
||
The current code for alternative calls uses the caller parameter types as the | ||
types for the register variables that serve as function parameters: | ||
|
||
uint8_t foo; | ||
[...] | ||
alternative_call(myfunc, foo); | ||
|
||
Would expand roughly into: | ||
|
||
register unint8_t a1_ asm("rdi") = foo; | ||
register unsigned long a2_ asm("rsi"); | ||
[...] | ||
asm volatile ("call *%c[addr](%%rip)"...); | ||
|
||
However under certain circumstances clang >= 16.0.0 with -O2 can generate | ||
incorrect code, given the following example: | ||
|
||
unsigned int func(uint8_t t) | ||
{ | ||
return t; | ||
} | ||
|
||
static void bar(uint8_t b) | ||
{ | ||
int ret_; | ||
register uint8_t di asm("rdi") = b; | ||
register unsigned long si asm("rsi"); | ||
register unsigned long dx asm("rdx"); | ||
register unsigned long cx asm("rcx"); | ||
register unsigned long r8 asm("r8"); | ||
register unsigned long r9 asm("r9"); | ||
register unsigned long r10 asm("r10"); | ||
register unsigned long r11 asm("r11"); | ||
|
||
asm volatile ( "call %c[addr]" | ||
: "+r" (di), "=r" (si), "=r" (dx), | ||
"=r" (cx), "=r" (r8), "=r" (r9), | ||
"=r" (r10), "=r" (r11), "=a" (ret_) | ||
: [addr] "i" (&(func)), "g" (func) | ||
: "memory" ); | ||
} | ||
|
||
void foo(unsigned int a) | ||
{ | ||
bar(a); | ||
} | ||
|
||
Clang generates the following code: | ||
|
||
func: # @func | ||
movl %edi, %eax | ||
retq | ||
foo: # @foo | ||
callq func | ||
retq | ||
|
||
Note the truncation of the unsigned int parameter 'a' of foo() to uint8_t when | ||
passed into bar() is lost. | ||
|
||
The above can be worked around by using an union when defining the register | ||
variables, so that `di` becomes: | ||
|
||
register union { | ||
uint8_t e; | ||
unsigned long r; | ||
} di asm("rdi") = { .e = b }; | ||
|
||
Which results in following code generated for `foo()`: | ||
|
||
foo: # @foo | ||
movzbl %dil, %edi | ||
callq func | ||
retq | ||
|
||
So the truncation is not longer lost. Apply such workaround only when built | ||
with clang. | ||
|
||
Reported-by: Matthew Grooms <mgrooms@shrew.net> | ||
Link: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=277200 | ||
Link: https://github.com/llvm/llvm-project/issues/82598 | ||
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> | ||
--- | ||
Changes since v1: | ||
- Only apply the union workaround with clang. | ||
|
||
Seems like all gitlab build tests are OK with this approach. | ||
--- | ||
xen/arch/x86/include/asm/alternative.h | 16 ++++++++++++++++ | ||
1 file changed, 16 insertions(+) | ||
|
||
diff --git a/xen/arch/x86/include/asm/alternative.h b/xen/arch/x86/include/asm/alternative.h | ||
index a1cd6a9fe5b8..3fe27ea791bf 100644 | ||
--- a/xen/arch/x86/include/asm/alternative.h | ||
+++ b/xen/arch/x86/include/asm/alternative.h | ||
@@ -167,9 +167,25 @@ extern void alternative_branches(void); | ||
#define ALT_CALL_arg5 "r8" | ||
#define ALT_CALL_arg6 "r9" | ||
|
||
+#ifdef CONFIG_CC_IS_CLANG | ||
+/* | ||
+ * Use an union with an unsigned long in order to prevent clang from skipping a | ||
+ * possible truncation of the value. By using the union any truncation is | ||
+ * carried before the call instruction. | ||
+ * https://github.com/llvm/llvm-project/issues/82598 | ||
+ */ | ||
+#define ALT_CALL_ARG(arg, n) \ | ||
+ register union { \ | ||
+ typeof(arg) e; \ | ||
+ unsigned long r; \ | ||
+ } a ## n ## _ asm ( ALT_CALL_arg ## n ) = { \ | ||
+ .e = ({ BUILD_BUG_ON(sizeof(arg) > sizeof(void *)); (arg); }) \ | ||
+ } | ||
+#else | ||
#define ALT_CALL_ARG(arg, n) \ | ||
register typeof(arg) a ## n ## _ asm ( ALT_CALL_arg ## n ) = \ | ||
({ BUILD_BUG_ON(sizeof(arg) > sizeof(void *)); (arg); }) | ||
+#endif | ||
#define ALT_CALL_NO_ARG(n) \ | ||
register unsigned long a ## n ## _ asm ( ALT_CALL_arg ## n ) | ||
|
||
-- | ||
2.43.0 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters