|
1093 | 1093 | __emit_inst(0xd5000000|(\sreg)|(.L__gpr_num_\rt)) |
1094 | 1094 | .endm |
1095 | 1095 |
|
| 1096 | + .macro msr_hcr_el2, reg |
| 1097 | +#if IS_ENABLED(CONFIG_AMPERE_ERRATUM_AC04_CPU_23) |
| 1098 | + dsb nsh |
| 1099 | + msr hcr_el2, \reg |
| 1100 | + isb |
| 1101 | +#else |
| 1102 | + msr hcr_el2, \reg |
| 1103 | +#endif |
| 1104 | + .endm |
1096 | 1105 | #else |
1097 | 1106 |
|
1098 | 1107 | #include <linux/bitfield.h> |
|
1180 | 1189 | write_sysreg(__scs_new, sysreg); \ |
1181 | 1190 | } while (0) |
1182 | 1191 |
|
| 1192 | +#define sysreg_clear_set_hcr(clear, set) do { \ |
| 1193 | + u64 __scs_val = read_sysreg(hcr_el2); \ |
| 1194 | + u64 __scs_new = (__scs_val & ~(u64)(clear)) | (set); \ |
| 1195 | + if (__scs_new != __scs_val) \ |
| 1196 | + write_sysreg_hcr(__scs_new); \ |
| 1197 | +} while (0) |
| 1198 | + |
1183 | 1199 | #define sysreg_clear_set_s(sysreg, clear, set) do { \ |
1184 | 1200 | u64 __scs_val = read_sysreg_s(sysreg); \ |
1185 | 1201 | u64 __scs_new = (__scs_val & ~(u64)(clear)) | (set); \ |
1186 | 1202 | if (__scs_new != __scs_val) \ |
1187 | 1203 | write_sysreg_s(__scs_new, sysreg); \ |
1188 | 1204 | } while (0) |
1189 | 1205 |
|
| 1206 | +#define write_sysreg_hcr(__val) do { \ |
| 1207 | + if (IS_ENABLED(CONFIG_AMPERE_ERRATUM_AC04_CPU_23) && \ |
| 1208 | + (!system_capabilities_finalized() || \ |
| 1209 | + alternative_has_cap_unlikely(ARM64_WORKAROUND_AMPERE_AC04_CPU_23))) \ |
| 1210 | + asm volatile("dsb nsh; msr hcr_el2, %x0; isb" \ |
| 1211 | + : : "rZ" (__val)); \ |
| 1212 | + else \ |
| 1213 | + asm volatile("msr hcr_el2, %x0" \ |
| 1214 | + : : "rZ" (__val)); \ |
| 1215 | +} while (0) |
| 1216 | + |
1190 | 1217 | #define read_sysreg_par() ({ \ |
1191 | 1218 | u64 par; \ |
1192 | 1219 | asm(ALTERNATIVE("nop", "dmb sy", ARM64_WORKAROUND_1508412)); \ |
|
0 commit comments