@@ -440,6 +440,11 @@ unsigned long cpu_get_elf_hwcap2(void);
440440#define cpu_set_named_feature (name ) cpu_set_feature(cpu_feature(name))
441441#define cpu_have_named_feature (name ) cpu_have_feature(cpu_feature(name))
442442
443+ static __always_inline bool boot_capabilities_finalized (void )
444+ {
445+ return alternative_has_cap_likely (ARM64_ALWAYS_BOOT );
446+ }
447+
443448static __always_inline bool system_capabilities_finalized (void )
444449{
445450 return alternative_has_cap_likely (ARM64_ALWAYS_SYSTEM );
@@ -452,6 +457,8 @@ static __always_inline bool system_capabilities_finalized(void)
452457 */
453458static __always_inline bool cpus_have_cap (unsigned int num )
454459{
460+ if (__builtin_constant_p (num ) && !cpucap_is_possible (num ))
461+ return false;
455462 if (num >= ARM64_NCAPS )
456463 return false;
457464 return arch_test_bit (num , system_cpucaps );
@@ -460,55 +467,37 @@ static __always_inline bool cpus_have_cap(unsigned int num)
460467/*
461468 * Test for a capability without a runtime check.
462469 *
463- * Before capabilities are finalized, this returns false.
464- * After capabilities are finalized, this is patched to avoid a runtime check.
470+ * Before boot capabilities are finalized, this will BUG().
471+ * After boot capabilities are finalized, this is patched to avoid a runtime
472+ * check.
465473 *
466474 * @num must be a compile-time constant.
467475 */
468- static __always_inline bool __cpus_have_const_cap (int num )
476+ static __always_inline bool cpus_have_final_boot_cap (int num )
469477{
470- if (num >= ARM64_NCAPS )
471- return false;
472- return alternative_has_cap_unlikely (num );
478+ if (boot_capabilities_finalized ())
479+ return alternative_has_cap_unlikely (num );
480+ else
481+ BUG ();
473482}
474483
475484/*
476485 * Test for a capability without a runtime check.
477486 *
478- * Before capabilities are finalized, this will BUG().
479- * After capabilities are finalized, this is patched to avoid a runtime check.
487+ * Before system capabilities are finalized, this will BUG().
488+ * After system capabilities are finalized, this is patched to avoid a runtime
489+ * check.
480490 *
481491 * @num must be a compile-time constant.
482492 */
483493static __always_inline bool cpus_have_final_cap (int num )
484494{
485495 if (system_capabilities_finalized ())
486- return __cpus_have_const_cap (num );
496+ return alternative_has_cap_unlikely (num );
487497 else
488498 BUG ();
489499}
490500
491- /*
492- * Test for a capability, possibly with a runtime check for non-hyp code.
493- *
494- * For hyp code, this behaves the same as cpus_have_final_cap().
495- *
496- * For non-hyp code:
497- * Before capabilities are finalized, this behaves as cpus_have_cap().
498- * After capabilities are finalized, this is patched to avoid a runtime check.
499- *
500- * @num must be a compile-time constant.
501- */
502- static __always_inline bool cpus_have_const_cap (int num )
503- {
504- if (is_hyp_code ())
505- return cpus_have_final_cap (num );
506- else if (system_capabilities_finalized ())
507- return __cpus_have_const_cap (num );
508- else
509- return cpus_have_cap (num );
510- }
511-
512501static inline int __attribute_const__
513502cpuid_feature_extract_signed_field_width (u64 features , int field , int width )
514503{
@@ -628,7 +617,9 @@ static inline bool id_aa64pfr1_mte(u64 pfr1)
628617 return val >= ID_AA64PFR1_EL1_MTE_MTE2 ;
629618}
630619
631- void __init setup_cpu_features (void );
620+ void __init setup_system_features (void );
621+ void __init setup_user_features (void );
622+
632623void check_local_cpu_capabilities (void );
633624
634625u64 read_sanitised_ftr_reg (u32 id );
@@ -737,13 +728,12 @@ static inline bool system_supports_mixed_endian(void)
737728
738729static __always_inline bool system_supports_fpsimd (void )
739730{
740- return ! cpus_have_const_cap ( ARM64_HAS_NO_FPSIMD );
731+ return alternative_has_cap_likely ( ARM64_HAS_FPSIMD );
741732}
742733
743734static inline bool system_uses_hw_pan (void )
744735{
745- return IS_ENABLED (CONFIG_ARM64_PAN ) &&
746- cpus_have_const_cap (ARM64_HAS_PAN );
736+ return alternative_has_cap_unlikely (ARM64_HAS_PAN );
747737}
748738
749739static inline bool system_uses_ttbr0_pan (void )
@@ -754,26 +744,22 @@ static inline bool system_uses_ttbr0_pan(void)
754744
755745static __always_inline bool system_supports_sve (void )
756746{
757- return IS_ENABLED (CONFIG_ARM64_SVE ) &&
758- cpus_have_const_cap (ARM64_SVE );
747+ return alternative_has_cap_unlikely (ARM64_SVE );
759748}
760749
761750static __always_inline bool system_supports_sme (void )
762751{
763- return IS_ENABLED (CONFIG_ARM64_SME ) &&
764- cpus_have_const_cap (ARM64_SME );
752+ return alternative_has_cap_unlikely (ARM64_SME );
765753}
766754
767755static __always_inline bool system_supports_sme2 (void )
768756{
769- return IS_ENABLED (CONFIG_ARM64_SME ) &&
770- cpus_have_const_cap (ARM64_SME2 );
757+ return alternative_has_cap_unlikely (ARM64_SME2 );
771758}
772759
773760static __always_inline bool system_supports_fa64 (void )
774761{
775- return IS_ENABLED (CONFIG_ARM64_SME ) &&
776- cpus_have_const_cap (ARM64_SME_FA64 );
762+ return alternative_has_cap_unlikely (ARM64_SME_FA64 );
777763}
778764
779765static __always_inline bool system_supports_tpidr2 (void )
@@ -783,20 +769,17 @@ static __always_inline bool system_supports_tpidr2(void)
783769
784770static __always_inline bool system_supports_cnp (void )
785771{
786- return IS_ENABLED (CONFIG_ARM64_CNP ) &&
787- cpus_have_const_cap (ARM64_HAS_CNP );
772+ return alternative_has_cap_unlikely (ARM64_HAS_CNP );
788773}
789774
790775static inline bool system_supports_address_auth (void )
791776{
792- return IS_ENABLED (CONFIG_ARM64_PTR_AUTH ) &&
793- cpus_have_const_cap (ARM64_HAS_ADDRESS_AUTH );
777+ return cpus_have_final_boot_cap (ARM64_HAS_ADDRESS_AUTH );
794778}
795779
796780static inline bool system_supports_generic_auth (void )
797781{
798- return IS_ENABLED (CONFIG_ARM64_PTR_AUTH ) &&
799- cpus_have_const_cap (ARM64_HAS_GENERIC_AUTH );
782+ return alternative_has_cap_unlikely (ARM64_HAS_GENERIC_AUTH );
800783}
801784
802785static inline bool system_has_full_ptr_auth (void )
@@ -806,14 +789,12 @@ static inline bool system_has_full_ptr_auth(void)
806789
807790static __always_inline bool system_uses_irq_prio_masking (void )
808791{
809- return IS_ENABLED (CONFIG_ARM64_PSEUDO_NMI ) &&
810- cpus_have_const_cap (ARM64_HAS_GIC_PRIO_MASKING );
792+ return alternative_has_cap_unlikely (ARM64_HAS_GIC_PRIO_MASKING );
811793}
812794
813795static inline bool system_supports_mte (void )
814796{
815- return IS_ENABLED (CONFIG_ARM64_MTE ) &&
816- cpus_have_const_cap (ARM64_MTE );
797+ return alternative_has_cap_unlikely (ARM64_MTE );
817798}
818799
819800static inline bool system_has_prio_mask_debugging (void )
@@ -824,13 +805,18 @@ static inline bool system_has_prio_mask_debugging(void)
824805
825806static inline bool system_supports_bti (void )
826807{
827- return IS_ENABLED (CONFIG_ARM64_BTI ) && cpus_have_const_cap (ARM64_BTI );
808+ return cpus_have_final_cap (ARM64_BTI );
809+ }
810+
811+ static inline bool system_supports_bti_kernel (void )
812+ {
813+ return IS_ENABLED (CONFIG_ARM64_BTI_KERNEL ) &&
814+ cpus_have_final_boot_cap (ARM64_BTI );
828815}
829816
830817static inline bool system_supports_tlb_range (void )
831818{
832- return IS_ENABLED (CONFIG_ARM64_TLB_RANGE ) &&
833- cpus_have_const_cap (ARM64_HAS_TLB_RANGE );
819+ return alternative_has_cap_unlikely (ARM64_HAS_TLB_RANGE );
834820}
835821
836822int do_emulate_mrs (struct pt_regs * regs , u32 sys_reg , u32 rt );
0 commit comments