Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-next/ffa' into for-next/smccc

Merge in SMCCC update from Sudeep, which is a branch shared with arm-soc
for the FF-A driver work.

* for-next/ffa:
arm64: smccc: Add support for SMCCCv1.2 extended input/output registers

+121
+9
arch/arm64/kernel/asm-offsets.c
··· 138 138 DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); 139 139 DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id)); 140 140 DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state)); 141 + DEFINE(ARM_SMCCC_1_2_REGS_X0_OFFS, offsetof(struct arm_smccc_1_2_regs, a0)); 142 + DEFINE(ARM_SMCCC_1_2_REGS_X2_OFFS, offsetof(struct arm_smccc_1_2_regs, a2)); 143 + DEFINE(ARM_SMCCC_1_2_REGS_X4_OFFS, offsetof(struct arm_smccc_1_2_regs, a4)); 144 + DEFINE(ARM_SMCCC_1_2_REGS_X6_OFFS, offsetof(struct arm_smccc_1_2_regs, a6)); 145 + DEFINE(ARM_SMCCC_1_2_REGS_X8_OFFS, offsetof(struct arm_smccc_1_2_regs, a8)); 146 + DEFINE(ARM_SMCCC_1_2_REGS_X10_OFFS, offsetof(struct arm_smccc_1_2_regs, a10)); 147 + DEFINE(ARM_SMCCC_1_2_REGS_X12_OFFS, offsetof(struct arm_smccc_1_2_regs, a12)); 148 + DEFINE(ARM_SMCCC_1_2_REGS_X14_OFFS, offsetof(struct arm_smccc_1_2_regs, a14)); 149 + DEFINE(ARM_SMCCC_1_2_REGS_X16_OFFS, offsetof(struct arm_smccc_1_2_regs, a16)); 141 150 BLANK(); 142 151 DEFINE(HIBERN_PBE_ORIG, offsetof(struct pbe, orig_address)); 143 152 DEFINE(HIBERN_PBE_ADDR, offsetof(struct pbe, address));
+57
arch/arm64/kernel/smccc-call.S
··· 43 43 SMCCC hvc 44 44 SYM_FUNC_END(__arm_smccc_hvc) 45 45 EXPORT_SYMBOL(__arm_smccc_hvc) 46 + 47 + .macro SMCCC_1_2 instr 48 + /* Save `res` and free a GPR that won't be clobbered */ 49 + stp x1, x19, [sp, #-16]! 50 + 51 + /* Ensure `args` won't be clobbered while loading regs in next step */ 52 + mov x19, x0 53 + 54 + /* Load the registers x0 - x17 from the struct arm_smccc_1_2_regs */ 55 + ldp x0, x1, [x19, #ARM_SMCCC_1_2_REGS_X0_OFFS] 56 + ldp x2, x3, [x19, #ARM_SMCCC_1_2_REGS_X2_OFFS] 57 + ldp x4, x5, [x19, #ARM_SMCCC_1_2_REGS_X4_OFFS] 58 + ldp x6, x7, [x19, #ARM_SMCCC_1_2_REGS_X6_OFFS] 59 + ldp x8, x9, [x19, #ARM_SMCCC_1_2_REGS_X8_OFFS] 60 + ldp x10, x11, [x19, #ARM_SMCCC_1_2_REGS_X10_OFFS] 61 + ldp x12, x13, [x19, #ARM_SMCCC_1_2_REGS_X12_OFFS] 62 + ldp x14, x15, [x19, #ARM_SMCCC_1_2_REGS_X14_OFFS] 63 + ldp x16, x17, [x19, #ARM_SMCCC_1_2_REGS_X16_OFFS] 64 + 65 + \instr #0 66 + 67 + /* Load the `res` from the stack */ 68 + ldr x19, [sp] 69 + 70 + /* Store the registers x0 - x17 into the result structure */ 71 + stp x0, x1, [x19, #ARM_SMCCC_1_2_REGS_X0_OFFS] 72 + stp x2, x3, [x19, #ARM_SMCCC_1_2_REGS_X2_OFFS] 73 + stp x4, x5, [x19, #ARM_SMCCC_1_2_REGS_X4_OFFS] 74 + stp x6, x7, [x19, #ARM_SMCCC_1_2_REGS_X6_OFFS] 75 + stp x8, x9, [x19, #ARM_SMCCC_1_2_REGS_X8_OFFS] 76 + stp x10, x11, [x19, #ARM_SMCCC_1_2_REGS_X10_OFFS] 77 + stp x12, x13, [x19, #ARM_SMCCC_1_2_REGS_X12_OFFS] 78 + stp x14, x15, [x19, #ARM_SMCCC_1_2_REGS_X14_OFFS] 79 + stp x16, x17, [x19, #ARM_SMCCC_1_2_REGS_X16_OFFS] 80 + 81 + /* Restore original x19 */ 82 + ldp xzr, x19, [sp], #16 83 + ret 84 + .endm 85 + 86 + /* 87 + * void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args, 88 + * struct arm_smccc_1_2_regs *res); 89 + */ 90 + SYM_FUNC_START(arm_smccc_1_2_hvc) 91 + SMCCC_1_2 hvc 92 + SYM_FUNC_END(arm_smccc_1_2_hvc) 93 + EXPORT_SYMBOL(arm_smccc_1_2_hvc) 94 + 95 + /* 96 + * void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args, 97 + * struct arm_smccc_1_2_regs *res); 98 + */ 99 + SYM_FUNC_START(arm_smccc_1_2_smc) 100 + SMCCC_1_2 smc 101 + SYM_FUNC_END(arm_smccc_1_2_smc) 102 + EXPORT_SYMBOL(arm_smccc_1_2_smc)
+55
include/linux/arm-smccc.h
··· 227 227 unsigned long a3; 228 228 }; 229 229 230 + #ifdef CONFIG_ARM64 231 + /** 232 + * struct arm_smccc_1_2_regs - Arguments for or Results from SMC/HVC call 233 + * @a0-a17 argument values from registers 0 to 17 234 + */ 235 + struct arm_smccc_1_2_regs { 236 + unsigned long a0; 237 + unsigned long a1; 238 + unsigned long a2; 239 + unsigned long a3; 240 + unsigned long a4; 241 + unsigned long a5; 242 + unsigned long a6; 243 + unsigned long a7; 244 + unsigned long a8; 245 + unsigned long a9; 246 + unsigned long a10; 247 + unsigned long a11; 248 + unsigned long a12; 249 + unsigned long a13; 250 + unsigned long a14; 251 + unsigned long a15; 252 + unsigned long a16; 253 + unsigned long a17; 254 + }; 255 + 256 + /** 257 + * arm_smccc_1_2_hvc() - make HVC calls 258 + * @args: arguments passed via struct arm_smccc_1_2_regs 259 + * @res: result values via struct arm_smccc_1_2_regs 260 + * 261 + * This function is used to make HVC calls following SMC Calling Convention 262 + * v1.2 or above. The content of the supplied param are copied from the 263 + * structure to registers prior to the HVC instruction. The return values 264 + * are updated with the content from registers on return from the HVC 265 + * instruction. 266 + */ 267 + asmlinkage void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args, 268 + struct arm_smccc_1_2_regs *res); 269 + 270 + /** 271 + * arm_smccc_1_2_smc() - make SMC calls 272 + * @args: arguments passed via struct arm_smccc_1_2_regs 273 + * @res: result values via struct arm_smccc_1_2_regs 274 + * 275 + * This function is used to make SMC calls following SMC Calling Convention 276 + * v1.2 or above. The content of the supplied param are copied from the 277 + * structure to registers prior to the SMC instruction. The return values 278 + * are updated with the content from registers on return from the SMC 279 + * instruction. 280 + */ 281 + asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args, 282 + struct arm_smccc_1_2_regs *res); 283 + #endif 284 + 230 285 /** 231 286 * struct arm_smccc_quirk - Contains quirk information 232 287 * @id: quirk identification