diff --git a/arch/arm64/include/asm/alternative-macros.h b/arch/arm64/include/asm/alternative-macros.h index 3622e9f4fb44..c7842fd06ad6 100644 --- a/arch/arm64/include/asm/alternative-macros.h +++ b/arch/arm64/include/asm/alternative-macros.h @@ -19,6 +19,7 @@ #error "cpucaps have overflown ARM64_CB_BIT" #endif +#ifndef BUILD_FIPS140_KO #ifndef __ASSEMBLY__ #include @@ -261,4 +262,50 @@ l_yes: #endif /* __ASSEMBLY__ */ +#else + +/* + * The FIPS140 module does not support alternatives patching, as this + * invalidates the HMAC digest of the .text section. However, some alternatives + * are known to be irrelevant so we can tolerate them in the FIPS140 module, as + * they will never be applied in the first place in the use cases that the + * FIPS140 module targets (Android running on a production phone). Any other + * uses of alternatives should be avoided, as it is not safe in the general + * case to simply use the default sequence in one place (the fips module) and + * the alternative sequence everywhere else. + * + * Below is an allowlist of features that we can ignore, by simply taking the + * safe default instruction sequence. Note that this implies that the FIPS140 + * module is not compatible with VHE, or with pseudo-NMI support. + */ + +#define __ALT_ARM64_HAS_LDAPR 0, +#define __ALT_ARM64_HAS_VIRT_HOST_EXTN 0, +#define __ALT_ARM64_HAS_IRQ_PRIO_MASKING 0, + +#define ALTERNATIVE(oldinstr, newinstr, feature, ...) \ + _ALTERNATIVE(oldinstr, __ALT_ ## feature, #feature) + +#define _ALTERNATIVE(oldinstr, feature, feature_str) \ + __take_second_arg(feature oldinstr, \ + ".err Feature " feature_str " not supported in fips140 module") + +#ifndef __ASSEMBLY__ + +#include + +static __always_inline bool +alternative_has_feature_likely(unsigned long feature) +{ + return feature == ARM64_HAS_LDAPR || + feature == ARM64_HAS_VIRT_HOST_EXTN || + feature == ARM64_HAS_IRQ_PRIO_MASKING; +} + +#define alternative_has_feature_unlikely alternative_has_feature_likely + +#endif /* !__ASSEMBLY__ */ + +#endif /* BUILD_FIPS140_KO */ + #endif /* __ASM_ALTERNATIVE_MACROS_H */