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