1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2025, 2026 - Arm Ltd 4 */ 5 6 #include <linux/irqchip/arm-gic-v5.h> 7 8 #include <asm/kvm_hyp.h> 9 10 void __vgic_v5_save_apr(struct vgic_v5_cpu_if *cpu_if) 11 { 12 cpu_if->vgic_apr = read_sysreg_s(SYS_ICH_APR_EL2); 13 } 14 15 static void __vgic_v5_compat_mode_disable(void) 16 { 17 sysreg_clear_set_s(SYS_ICH_VCTLR_EL2, ICH_VCTLR_EL2_V3, 0); 18 isb(); 19 } 20 21 void __vgic_v5_restore_vmcr_apr(struct vgic_v5_cpu_if *cpu_if) 22 { 23 __vgic_v5_compat_mode_disable(); 24 25 write_sysreg_s(cpu_if->vgic_vmcr, SYS_ICH_VMCR_EL2); 26 write_sysreg_s(cpu_if->vgic_apr, SYS_ICH_APR_EL2); 27 } 28 29 void __vgic_v5_save_ppi_state(struct vgic_v5_cpu_if *cpu_if) 30 { 31 /* 32 * The following code assumes that the bitmap storage that we have for 33 * PPIs is either 64 (architected PPIs, only) or 128 bits (architected & 34 * impdef PPIs). 35 */ 36 BUILD_BUG_ON(VGIC_V5_NR_PRIVATE_IRQS % 64); 37 38 bitmap_write(host_data_ptr(vgic_v5_ppi_state)->activer_exit, 39 read_sysreg_s(SYS_ICH_PPI_ACTIVER0_EL2), 0, 64); 40 bitmap_write(host_data_ptr(vgic_v5_ppi_state)->pendr, 41 read_sysreg_s(SYS_ICH_PPI_PENDR0_EL2), 0, 64); 42 43 cpu_if->vgic_ppi_priorityr[0] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR0_EL2); 44 cpu_if->vgic_ppi_priorityr[1] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR1_EL2); 45 cpu_if->vgic_ppi_priorityr[2] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR2_EL2); 46 cpu_if->vgic_ppi_priorityr[3] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR3_EL2); 47 cpu_if->vgic_ppi_priorityr[4] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR4_EL2); 48 cpu_if->vgic_ppi_priorityr[5] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR5_EL2); 49 cpu_if->vgic_ppi_priorityr[6] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR6_EL2); 50 cpu_if->vgic_ppi_priorityr[7] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR7_EL2); 51 52 if (VGIC_V5_NR_PRIVATE_IRQS == 128) { 53 bitmap_write(host_data_ptr(vgic_v5_ppi_state)->activer_exit, 54 read_sysreg_s(SYS_ICH_PPI_ACTIVER1_EL2), 64, 64); 55 bitmap_write(host_data_ptr(vgic_v5_ppi_state)->pendr, 56 read_sysreg_s(SYS_ICH_PPI_PENDR1_EL2), 64, 64); 57 58 cpu_if->vgic_ppi_priorityr[8] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR8_EL2); 59 cpu_if->vgic_ppi_priorityr[9] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR9_EL2); 60 cpu_if->vgic_ppi_priorityr[10] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR10_EL2); 61 cpu_if->vgic_ppi_priorityr[11] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR11_EL2); 62 cpu_if->vgic_ppi_priorityr[12] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR12_EL2); 63 cpu_if->vgic_ppi_priorityr[13] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR13_EL2); 64 cpu_if->vgic_ppi_priorityr[14] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR14_EL2); 65 cpu_if->vgic_ppi_priorityr[15] = read_sysreg_s(SYS_ICH_PPI_PRIORITYR15_EL2); 66 } 67 68 /* Now that we are done, disable DVI */ 69 write_sysreg_s(0, SYS_ICH_PPI_DVIR0_EL2); 70 write_sysreg_s(0, SYS_ICH_PPI_DVIR1_EL2); 71 } 72 73 void __vgic_v5_restore_ppi_state(struct vgic_v5_cpu_if *cpu_if) 74 { 75 DECLARE_BITMAP(pendr, VGIC_V5_NR_PRIVATE_IRQS); 76 77 /* We assume 64 or 128 PPIs - see above comment */ 78 BUILD_BUG_ON(VGIC_V5_NR_PRIVATE_IRQS % 64); 79 80 /* Enable DVI so that the guest's interrupt config takes over */ 81 write_sysreg_s(bitmap_read(cpu_if->vgic_ppi_dvir, 0, 64), 82 SYS_ICH_PPI_DVIR0_EL2); 83 84 write_sysreg_s(bitmap_read(cpu_if->vgic_ppi_activer, 0, 64), 85 SYS_ICH_PPI_ACTIVER0_EL2); 86 write_sysreg_s(bitmap_read(cpu_if->vgic_ppi_enabler, 0, 64), 87 SYS_ICH_PPI_ENABLER0_EL2); 88 89 /* Update the pending state of the NON-DVI'd PPIs, only */ 90 bitmap_andnot(pendr, host_data_ptr(vgic_v5_ppi_state)->pendr, 91 cpu_if->vgic_ppi_dvir, VGIC_V5_NR_PRIVATE_IRQS); 92 write_sysreg_s(bitmap_read(pendr, 0, 64), SYS_ICH_PPI_PENDR0_EL2); 93 94 write_sysreg_s(cpu_if->vgic_ppi_priorityr[0], 95 SYS_ICH_PPI_PRIORITYR0_EL2); 96 write_sysreg_s(cpu_if->vgic_ppi_priorityr[1], 97 SYS_ICH_PPI_PRIORITYR1_EL2); 98 write_sysreg_s(cpu_if->vgic_ppi_priorityr[2], 99 SYS_ICH_PPI_PRIORITYR2_EL2); 100 write_sysreg_s(cpu_if->vgic_ppi_priorityr[3], 101 SYS_ICH_PPI_PRIORITYR3_EL2); 102 write_sysreg_s(cpu_if->vgic_ppi_priorityr[4], 103 SYS_ICH_PPI_PRIORITYR4_EL2); 104 write_sysreg_s(cpu_if->vgic_ppi_priorityr[5], 105 SYS_ICH_PPI_PRIORITYR5_EL2); 106 write_sysreg_s(cpu_if->vgic_ppi_priorityr[6], 107 SYS_ICH_PPI_PRIORITYR6_EL2); 108 write_sysreg_s(cpu_if->vgic_ppi_priorityr[7], 109 SYS_ICH_PPI_PRIORITYR7_EL2); 110 111 if (VGIC_V5_NR_PRIVATE_IRQS == 128) { 112 /* Enable DVI so that the guest's interrupt config takes over */ 113 write_sysreg_s(bitmap_read(cpu_if->vgic_ppi_dvir, 64, 64), 114 SYS_ICH_PPI_DVIR1_EL2); 115 116 write_sysreg_s(bitmap_read(cpu_if->vgic_ppi_activer, 64, 64), 117 SYS_ICH_PPI_ACTIVER1_EL2); 118 write_sysreg_s(bitmap_read(cpu_if->vgic_ppi_enabler, 64, 64), 119 SYS_ICH_PPI_ENABLER1_EL2); 120 write_sysreg_s(bitmap_read(pendr, 64, 64), 121 SYS_ICH_PPI_PENDR1_EL2); 122 123 write_sysreg_s(cpu_if->vgic_ppi_priorityr[8], 124 SYS_ICH_PPI_PRIORITYR8_EL2); 125 write_sysreg_s(cpu_if->vgic_ppi_priorityr[9], 126 SYS_ICH_PPI_PRIORITYR9_EL2); 127 write_sysreg_s(cpu_if->vgic_ppi_priorityr[10], 128 SYS_ICH_PPI_PRIORITYR10_EL2); 129 write_sysreg_s(cpu_if->vgic_ppi_priorityr[11], 130 SYS_ICH_PPI_PRIORITYR11_EL2); 131 write_sysreg_s(cpu_if->vgic_ppi_priorityr[12], 132 SYS_ICH_PPI_PRIORITYR12_EL2); 133 write_sysreg_s(cpu_if->vgic_ppi_priorityr[13], 134 SYS_ICH_PPI_PRIORITYR13_EL2); 135 write_sysreg_s(cpu_if->vgic_ppi_priorityr[14], 136 SYS_ICH_PPI_PRIORITYR14_EL2); 137 write_sysreg_s(cpu_if->vgic_ppi_priorityr[15], 138 SYS_ICH_PPI_PRIORITYR15_EL2); 139 } else { 140 write_sysreg_s(0, SYS_ICH_PPI_DVIR1_EL2); 141 142 write_sysreg_s(0, SYS_ICH_PPI_ACTIVER1_EL2); 143 write_sysreg_s(0, SYS_ICH_PPI_ENABLER1_EL2); 144 write_sysreg_s(0, SYS_ICH_PPI_PENDR1_EL2); 145 146 write_sysreg_s(0, SYS_ICH_PPI_PRIORITYR8_EL2); 147 write_sysreg_s(0, SYS_ICH_PPI_PRIORITYR9_EL2); 148 write_sysreg_s(0, SYS_ICH_PPI_PRIORITYR10_EL2); 149 write_sysreg_s(0, SYS_ICH_PPI_PRIORITYR11_EL2); 150 write_sysreg_s(0, SYS_ICH_PPI_PRIORITYR12_EL2); 151 write_sysreg_s(0, SYS_ICH_PPI_PRIORITYR13_EL2); 152 write_sysreg_s(0, SYS_ICH_PPI_PRIORITYR14_EL2); 153 write_sysreg_s(0, SYS_ICH_PPI_PRIORITYR15_EL2); 154 } 155 } 156 157 void __vgic_v5_save_state(struct vgic_v5_cpu_if *cpu_if) 158 { 159 cpu_if->vgic_vmcr = read_sysreg_s(SYS_ICH_VMCR_EL2); 160 cpu_if->vgic_icsr = read_sysreg_s(SYS_ICC_ICSR_EL1); 161 } 162 163 void __vgic_v5_restore_state(struct vgic_v5_cpu_if *cpu_if) 164 { 165 write_sysreg_s(cpu_if->vgic_icsr, SYS_ICC_ICSR_EL1); 166 } 167