Skip to content

Commit dda3117

Browse files
kelleymhtyhicks
authored andcommitted
smccc: Add HVC call variant with result registers other than 0 thru 3
Hypercalls to Hyper-V on ARM64 may return results in registers other than X0 thru X3, as permitted by the SMCCC spec version 1.2 and later. Accommodate this by adding a variant of arm_smccc_1_1_hvc that allows the caller to specify which 3 registers are returned in addition to X0. Signed-off-by: Michael Kelley <mikelley@microsoft.com>
1 parent 2b445a7 commit dda3117

1 file changed

Lines changed: 23 additions & 6 deletions

File tree

include/linux/arm-smccc.h

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,12 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
300300
* entitled to optimise the whole sequence away. "volatile" is what
301301
* makes it stick.
302302
*/
303-
#define __arm_smccc_1_1(inst, ...) \
303+
#define __arm_smccc_1_1(inst, reg1, reg2, reg3, ...) \
304304
do { \
305305
register unsigned long r0 asm("r0"); \
306-
register unsigned long r1 asm("r1"); \
307-
register unsigned long r2 asm("r2"); \
308-
register unsigned long r3 asm("r3"); \
306+
register unsigned long r1 asm(reg1); \
307+
register unsigned long r2 asm(reg2); \
308+
register unsigned long r3 asm(reg3); \
309309
__declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \
310310
asm volatile(inst "\n" : \
311311
"=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \
@@ -328,7 +328,8 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
328328
* to the SMC instruction. The return values are updated with the content
329329
* from register 0 to 3 on return from the SMC instruction if not NULL.
330330
*/
331-
#define arm_smccc_1_1_smc(...) __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
331+
#define arm_smccc_1_1_smc(...)\
332+
__arm_smccc_1_1(SMCCC_SMC_INST, "r1", "r2", "r3", __VA_ARGS__)
332333

333334
/*
334335
* arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
@@ -344,7 +345,23 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
344345
* to the HVC instruction. The return values are updated with the content
345346
* from register 0 to 3 on return from the HVC instruction if not NULL.
346347
*/
347-
#define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
348+
#define arm_smccc_1_1_hvc(...) \
349+
__arm_smccc_1_1(SMCCC_HVC_INST, "r1", "r2", "r3", __VA_ARGS__)
350+
351+
/*
352+
* arm_smccc_1_1_hvc_reg() - make an SMCCC v1.1 compliant HVC call
353+
* specifying output registers
354+
*
355+
* This is a variant of arm_smccc_1_1_hvc() that allows specifying
356+
* three registers from which result values will be returned in
357+
* addition to r0.
358+
*
359+
* @a0-a2: register specifications for 3 return registers (e.g., "r5")
360+
* @a3-a10: arguments passed in registers 0 to 7
361+
* @res: result values from register 0 and the three registers specified
362+
* in a0-a2.
363+
*/
364+
#define arm_smccc_1_1_hvc_reg(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
348365

349366
/*
350367
* Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.

0 commit comments

Comments
 (0)