xref: /linux/arch/arm64/kvm/hyp/vgic-v5-sr.c (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
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