x86/altcall: allow compound types to be passed
authorJan Beulich <jbeulich@suse.com>
Thu, 4 Nov 2021 16:04:05 +0000 (17:04 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 29 Nov 2021 13:53:05 +0000 (13:53 +0000)
Replace the conditional operator in ALT_CALL_ARG(), which was intended
to limit usable types to scalar ones, by a size check. Some restriction
here is necessary to make sure we don't violate the ABI's calling
conventions, but limiting to scalar types was both too restrictive
(disallowing e.g. guest handles) and too permissive (allowing e.g.
__int128_t).

Note that there was some anomaly with that conditional operator anyway:
Something - I don't recall what - made it impossible to omit the middle
operand.

Code-generation-wise this has the effect of removing certain zero- or
sign-extending in some altcall invocations. This ought to be fine as the
ABI doesn't require sub-sizeof(int) values to be extended, except when
passed through an ellipsis. No functions subject to altcall patching has
a variable number of arguments, though.

Requested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
Unfortunately this triggers -Werror=sizeof-array-argument on some versions of
GCC, so alter xsm_{alloc,free}_security_evtchns() to use a pointer rather than
array parameter.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Daniel P. Smith <dpsmith@apertussolutions.com>
xen/include/asm-x86/alternative.h
xen/include/xsm/xsm.h

index 8e78cc91c35b944c4e8a64dbd512b6b032b88360..8bc59b02afd76c4b7566b29d59664a8011741041 100644 (file)
@@ -168,8 +168,8 @@ extern void alternative_branches(void);
 #define ALT_CALL_arg6 "r9"
 
 #define ALT_CALL_ARG(arg, n) \
-    register typeof((arg) ? (arg) : 0) a ## n ## _ \
-    asm ( ALT_CALL_arg ## n ) = (arg)
+    register typeof(arg) a ## n ## _ asm ( ALT_CALL_arg ## n ) = \
+        ({ BUILD_BUG_ON(sizeof(arg) > sizeof(void *)); (arg); })
 #define ALT_CALL_NO_ARG(n) \
     register unsigned long a ## n ## _ asm ( ALT_CALL_arg ## n )
 
index c101e653f6d74c804621a8a2913062d1e2c21009..0b360e1a35530e710cd29abf51c47beac1ef135f 100644 (file)
@@ -332,13 +332,13 @@ static inline void xsm_free_security_domain(struct domain *d)
 }
 
 static inline int xsm_alloc_security_evtchns(
-    struct evtchn chn[], unsigned int nr)
+    struct evtchn *chn, unsigned int nr)
 {
     return alternative_call(xsm_ops.alloc_security_evtchns, chn, nr);
 }
 
 static inline void xsm_free_security_evtchns(
-    struct evtchn chn[], unsigned int nr)
+    struct evtchn *chn, unsigned int nr)
 {
     alternative_vcall(xsm_ops.free_security_evtchns, chn, nr);
 }