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

Configure Feed

Select the types of activity you want to include in your feed.

irqchip/gic-v3: Detect GICD_CTRL.DS and SCR_EL3.FIQ earlier

In subsequent patches the GICv3 driver will choose the regular interrupt
priority at boot time, dependent on the configuration of GICD_CTRL.DS
and SCR_EL3.FIQ. This will need to be chosen before we configure the
distributor with default prioirities for all the interrupts, which
happens before we currently detect these in gic_cpu_sys_reg_init().

Add a new gic_prio_init() function to detect these earlier and log them
to the console so that any problems can be debugged more easily. This
also allows the uniformity checks in gic_cpu_sys_reg_init() to be
simplified, as we can compare directly with the boot CPU values which
were recorded earlier.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Alexandru Elisei <alexandru.elisei@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Will Deacon <will@kernel.org>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Tested-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240617111841.2529370-5-mark.rutland@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>

authored by

Mark Rutland and committed by
Catalin Marinas
d447bf09 a6156e70

+63 -54
+63 -54
drivers/irqchip/irq-gic-v3.c
··· 134 134 __priority; \ 135 135 }) 136 136 137 + static u32 gic_get_pribits(void) 138 + { 139 + u32 pribits; 140 + 141 + pribits = gic_read_ctlr(); 142 + pribits &= ICC_CTLR_EL1_PRI_BITS_MASK; 143 + pribits >>= ICC_CTLR_EL1_PRI_BITS_SHIFT; 144 + pribits++; 145 + 146 + return pribits; 147 + } 148 + 149 + static bool gic_has_group0(void) 150 + { 151 + u32 val; 152 + u32 old_pmr; 153 + 154 + old_pmr = gic_read_pmr(); 155 + 156 + /* 157 + * Let's find out if Group0 is under control of EL3 or not by 158 + * setting the highest possible, non-zero priority in PMR. 159 + * 160 + * If SCR_EL3.FIQ is set, the priority gets shifted down in 161 + * order for the CPU interface to set bit 7, and keep the 162 + * actual priority in the non-secure range. In the process, it 163 + * looses the least significant bit and the actual priority 164 + * becomes 0x80. Reading it back returns 0, indicating that 165 + * we're don't have access to Group0. 166 + */ 167 + gic_write_pmr(BIT(8 - gic_get_pribits())); 168 + val = gic_read_pmr(); 169 + 170 + gic_write_pmr(old_pmr); 171 + 172 + return val != 0; 173 + } 174 + 175 + static inline bool gic_dist_security_disabled(void) 176 + { 177 + return readl_relaxed(gic_data.dist_base + GICD_CTLR) & GICD_CTLR_DS; 178 + } 179 + 180 + static bool cpus_have_security_disabled __ro_after_init; 181 + static bool cpus_have_group0 __ro_after_init; 182 + 183 + static void __init gic_prio_init(void) 184 + { 185 + cpus_have_security_disabled = gic_dist_security_disabled(); 186 + cpus_have_group0 = gic_has_group0(); 187 + 188 + pr_info("GICD_CTRL.DS=%d, SCR_EL3.FIQ=%d\n", 189 + cpus_have_security_disabled, 190 + !cpus_have_group0); 191 + } 192 + 137 193 /* rdist_nmi_refs[n] == number of cpus having the rdist interrupt n set as NMI */ 138 194 static refcount_t *rdist_nmi_refs; 139 195 ··· 924 868 __gic_handle_irq_from_irqson(regs); 925 869 } 926 870 927 - static u32 gic_get_pribits(void) 928 - { 929 - u32 pribits; 930 - 931 - pribits = gic_read_ctlr(); 932 - pribits &= ICC_CTLR_EL1_PRI_BITS_MASK; 933 - pribits >>= ICC_CTLR_EL1_PRI_BITS_SHIFT; 934 - pribits++; 935 - 936 - return pribits; 937 - } 938 - 939 - static bool gic_has_group0(void) 940 - { 941 - u32 val; 942 - u32 old_pmr; 943 - 944 - old_pmr = gic_read_pmr(); 945 - 946 - /* 947 - * Let's find out if Group0 is under control of EL3 or not by 948 - * setting the highest possible, non-zero priority in PMR. 949 - * 950 - * If SCR_EL3.FIQ is set, the priority gets shifted down in 951 - * order for the CPU interface to set bit 7, and keep the 952 - * actual priority in the non-secure range. In the process, it 953 - * looses the least significant bit and the actual priority 954 - * becomes 0x80. Reading it back returns 0, indicating that 955 - * we're don't have access to Group0. 956 - */ 957 - gic_write_pmr(BIT(8 - gic_get_pribits())); 958 - val = gic_read_pmr(); 959 - 960 - gic_write_pmr(old_pmr); 961 - 962 - return val != 0; 963 - } 964 - 965 871 static void __init gic_dist_init(void) 966 872 { 967 873 unsigned int i; ··· 1140 1122 gic_data.rdists.has_vpend_valid_dirty ? "Valid+Dirty " : ""); 1141 1123 } 1142 1124 1143 - /* Check whether it's single security state view */ 1144 - static inline bool gic_dist_security_disabled(void) 1145 - { 1146 - return readl_relaxed(gic_data.dist_base + GICD_CTLR) & GICD_CTLR_DS; 1147 - } 1148 - 1149 1125 static void gic_cpu_sys_reg_init(void) 1150 1126 { 1151 1127 int i, cpu = smp_processor_id(); ··· 1167 1155 write_gicreg(DEFAULT_PMR_VALUE, ICC_PMR_EL1); 1168 1156 } else if (gic_supports_nmi()) { 1169 1157 /* 1170 - * Mismatch configuration with boot CPU, the system is likely 1171 - * to die as interrupt masking will not work properly on all 1172 - * CPUs 1158 + * Check that all CPUs use the same priority space. 1173 1159 * 1174 - * The boot CPU calls this function before enabling NMI support, 1175 - * and as a result we'll never see this warning in the boot path 1176 - * for that CPU. 1160 + * If there's a mismatch with the boot CPU, the system is 1161 + * likely to die as interrupt masking will not work properly on 1162 + * all CPUs. 1177 1163 */ 1178 - if (static_branch_unlikely(&gic_nonsecure_priorities)) 1179 - WARN_ON(!group0 || gic_dist_security_disabled()); 1180 - else 1181 - WARN_ON(group0 && !gic_dist_security_disabled()); 1164 + WARN_ON(group0 != cpus_have_group0); 1165 + WARN_ON(gic_dist_security_disabled() != cpus_have_security_disabled); 1182 1166 } 1183 1167 1184 1168 /* ··· 2070 2062 2071 2063 gic_update_rdist_properties(); 2072 2064 2065 + gic_prio_init(); 2073 2066 gic_dist_init(); 2074 2067 gic_cpu_init(); 2075 2068 gic_enable_nmi_support();