xref: /openbmc/linux/arch/arm64/kvm/vgic-sys-reg-v3.c (revision d017d7b0)
1d017d7b0SVijaya Kumar K /*
2d017d7b0SVijaya Kumar K  * VGIC system registers handling functions for AArch64 mode
3d017d7b0SVijaya Kumar K  *
4d017d7b0SVijaya Kumar K  * This program is free software; you can redistribute it and/or modify
5d017d7b0SVijaya Kumar K  * it under the terms of the GNU General Public License version 2 as
6d017d7b0SVijaya Kumar K  * published by the Free Software Foundation.
7d017d7b0SVijaya Kumar K  *
8d017d7b0SVijaya Kumar K  * This program is distributed in the hope that it will be useful,
9d017d7b0SVijaya Kumar K  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10d017d7b0SVijaya Kumar K  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11d017d7b0SVijaya Kumar K  * GNU General Public License for more details.
12d017d7b0SVijaya Kumar K  */
13d017d7b0SVijaya Kumar K 
14d017d7b0SVijaya Kumar K #include <linux/irqchip/arm-gic-v3.h>
15d017d7b0SVijaya Kumar K #include <linux/kvm.h>
16d017d7b0SVijaya Kumar K #include <linux/kvm_host.h>
17d017d7b0SVijaya Kumar K #include <asm/kvm_emulate.h>
18d017d7b0SVijaya Kumar K #include "vgic.h"
19d017d7b0SVijaya Kumar K #include "sys_regs.h"
20d017d7b0SVijaya Kumar K 
21d017d7b0SVijaya Kumar K static bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
22d017d7b0SVijaya Kumar K 			    const struct sys_reg_desc *r)
23d017d7b0SVijaya Kumar K {
24d017d7b0SVijaya Kumar K 	u32 host_pri_bits, host_id_bits, host_seis, host_a3v, seis, a3v;
25d017d7b0SVijaya Kumar K 	struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu;
26d017d7b0SVijaya Kumar K 	struct vgic_vmcr vmcr;
27d017d7b0SVijaya Kumar K 	u64 val;
28d017d7b0SVijaya Kumar K 
29d017d7b0SVijaya Kumar K 	vgic_get_vmcr(vcpu, &vmcr);
30d017d7b0SVijaya Kumar K 	if (p->is_write) {
31d017d7b0SVijaya Kumar K 		val = p->regval;
32d017d7b0SVijaya Kumar K 
33d017d7b0SVijaya Kumar K 		/*
34d017d7b0SVijaya Kumar K 		 * Disallow restoring VM state if not supported by this
35d017d7b0SVijaya Kumar K 		 * hardware.
36d017d7b0SVijaya Kumar K 		 */
37d017d7b0SVijaya Kumar K 		host_pri_bits = ((val & ICC_CTLR_EL1_PRI_BITS_MASK) >>
38d017d7b0SVijaya Kumar K 				 ICC_CTLR_EL1_PRI_BITS_SHIFT) + 1;
39d017d7b0SVijaya Kumar K 		if (host_pri_bits > vgic_v3_cpu->num_pri_bits)
40d017d7b0SVijaya Kumar K 			return false;
41d017d7b0SVijaya Kumar K 
42d017d7b0SVijaya Kumar K 		vgic_v3_cpu->num_pri_bits = host_pri_bits;
43d017d7b0SVijaya Kumar K 
44d017d7b0SVijaya Kumar K 		host_id_bits = (val & ICC_CTLR_EL1_ID_BITS_MASK) >>
45d017d7b0SVijaya Kumar K 				ICC_CTLR_EL1_ID_BITS_SHIFT;
46d017d7b0SVijaya Kumar K 		if (host_id_bits > vgic_v3_cpu->num_id_bits)
47d017d7b0SVijaya Kumar K 			return false;
48d017d7b0SVijaya Kumar K 
49d017d7b0SVijaya Kumar K 		vgic_v3_cpu->num_id_bits = host_id_bits;
50d017d7b0SVijaya Kumar K 
51d017d7b0SVijaya Kumar K 		host_seis = ((kvm_vgic_global_state.ich_vtr_el2 &
52d017d7b0SVijaya Kumar K 			     ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT);
53d017d7b0SVijaya Kumar K 		seis = (val & ICC_CTLR_EL1_SEIS_MASK) >>
54d017d7b0SVijaya Kumar K 			ICC_CTLR_EL1_SEIS_SHIFT;
55d017d7b0SVijaya Kumar K 		if (host_seis != seis)
56d017d7b0SVijaya Kumar K 			return false;
57d017d7b0SVijaya Kumar K 
58d017d7b0SVijaya Kumar K 		host_a3v = ((kvm_vgic_global_state.ich_vtr_el2 &
59d017d7b0SVijaya Kumar K 			    ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT);
60d017d7b0SVijaya Kumar K 		a3v = (val & ICC_CTLR_EL1_A3V_MASK) >> ICC_CTLR_EL1_A3V_SHIFT;
61d017d7b0SVijaya Kumar K 		if (host_a3v != a3v)
62d017d7b0SVijaya Kumar K 			return false;
63d017d7b0SVijaya Kumar K 
64d017d7b0SVijaya Kumar K 		/*
65d017d7b0SVijaya Kumar K 		 * Here set VMCR.CTLR in ICC_CTLR_EL1 layout.
66d017d7b0SVijaya Kumar K 		 * The vgic_set_vmcr() will convert to ICH_VMCR layout.
67d017d7b0SVijaya Kumar K 		 */
68d017d7b0SVijaya Kumar K 		vmcr.ctlr = val & ICC_CTLR_EL1_CBPR_MASK;
69d017d7b0SVijaya Kumar K 		vmcr.ctlr |= val & ICC_CTLR_EL1_EOImode_MASK;
70d017d7b0SVijaya Kumar K 		vgic_set_vmcr(vcpu, &vmcr);
71d017d7b0SVijaya Kumar K 	} else {
72d017d7b0SVijaya Kumar K 		val = 0;
73d017d7b0SVijaya Kumar K 		val |= (vgic_v3_cpu->num_pri_bits - 1) <<
74d017d7b0SVijaya Kumar K 			ICC_CTLR_EL1_PRI_BITS_SHIFT;
75d017d7b0SVijaya Kumar K 		val |= vgic_v3_cpu->num_id_bits << ICC_CTLR_EL1_ID_BITS_SHIFT;
76d017d7b0SVijaya Kumar K 		val |= ((kvm_vgic_global_state.ich_vtr_el2 &
77d017d7b0SVijaya Kumar K 			ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT) <<
78d017d7b0SVijaya Kumar K 			ICC_CTLR_EL1_SEIS_SHIFT;
79d017d7b0SVijaya Kumar K 		val |= ((kvm_vgic_global_state.ich_vtr_el2 &
80d017d7b0SVijaya Kumar K 			ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT) <<
81d017d7b0SVijaya Kumar K 			ICC_CTLR_EL1_A3V_SHIFT;
82d017d7b0SVijaya Kumar K 		/*
83d017d7b0SVijaya Kumar K 		 * The VMCR.CTLR value is in ICC_CTLR_EL1 layout.
84d017d7b0SVijaya Kumar K 		 * Extract it directly using ICC_CTLR_EL1 reg definitions.
85d017d7b0SVijaya Kumar K 		 */
86d017d7b0SVijaya Kumar K 		val |= vmcr.ctlr & ICC_CTLR_EL1_CBPR_MASK;
87d017d7b0SVijaya Kumar K 		val |= vmcr.ctlr & ICC_CTLR_EL1_EOImode_MASK;
88d017d7b0SVijaya Kumar K 
89d017d7b0SVijaya Kumar K 		p->regval = val;
90d017d7b0SVijaya Kumar K 	}
91d017d7b0SVijaya Kumar K 
92d017d7b0SVijaya Kumar K 	return true;
93d017d7b0SVijaya Kumar K }
94d017d7b0SVijaya Kumar K 
95d017d7b0SVijaya Kumar K static bool access_gic_pmr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
96d017d7b0SVijaya Kumar K 			   const struct sys_reg_desc *r)
97d017d7b0SVijaya Kumar K {
98d017d7b0SVijaya Kumar K 	struct vgic_vmcr vmcr;
99d017d7b0SVijaya Kumar K 
100d017d7b0SVijaya Kumar K 	vgic_get_vmcr(vcpu, &vmcr);
101d017d7b0SVijaya Kumar K 	if (p->is_write) {
102d017d7b0SVijaya Kumar K 		vmcr.pmr = (p->regval & ICC_PMR_EL1_MASK) >> ICC_PMR_EL1_SHIFT;
103d017d7b0SVijaya Kumar K 		vgic_set_vmcr(vcpu, &vmcr);
104d017d7b0SVijaya Kumar K 	} else {
105d017d7b0SVijaya Kumar K 		p->regval = (vmcr.pmr << ICC_PMR_EL1_SHIFT) & ICC_PMR_EL1_MASK;
106d017d7b0SVijaya Kumar K 	}
107d017d7b0SVijaya Kumar K 
108d017d7b0SVijaya Kumar K 	return true;
109d017d7b0SVijaya Kumar K }
110d017d7b0SVijaya Kumar K 
111d017d7b0SVijaya Kumar K static bool access_gic_bpr0(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
112d017d7b0SVijaya Kumar K 			    const struct sys_reg_desc *r)
113d017d7b0SVijaya Kumar K {
114d017d7b0SVijaya Kumar K 	struct vgic_vmcr vmcr;
115d017d7b0SVijaya Kumar K 
116d017d7b0SVijaya Kumar K 	vgic_get_vmcr(vcpu, &vmcr);
117d017d7b0SVijaya Kumar K 	if (p->is_write) {
118d017d7b0SVijaya Kumar K 		vmcr.bpr = (p->regval & ICC_BPR0_EL1_MASK) >>
119d017d7b0SVijaya Kumar K 			    ICC_BPR0_EL1_SHIFT;
120d017d7b0SVijaya Kumar K 		vgic_set_vmcr(vcpu, &vmcr);
121d017d7b0SVijaya Kumar K 	} else {
122d017d7b0SVijaya Kumar K 		p->regval = (vmcr.bpr << ICC_BPR0_EL1_SHIFT) &
123d017d7b0SVijaya Kumar K 			     ICC_BPR0_EL1_MASK;
124d017d7b0SVijaya Kumar K 	}
125d017d7b0SVijaya Kumar K 
126d017d7b0SVijaya Kumar K 	return true;
127d017d7b0SVijaya Kumar K }
128d017d7b0SVijaya Kumar K 
129d017d7b0SVijaya Kumar K static bool access_gic_bpr1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
130d017d7b0SVijaya Kumar K 			    const struct sys_reg_desc *r)
131d017d7b0SVijaya Kumar K {
132d017d7b0SVijaya Kumar K 	struct vgic_vmcr vmcr;
133d017d7b0SVijaya Kumar K 
134d017d7b0SVijaya Kumar K 	if (!p->is_write)
135d017d7b0SVijaya Kumar K 		p->regval = 0;
136d017d7b0SVijaya Kumar K 
137d017d7b0SVijaya Kumar K 	vgic_get_vmcr(vcpu, &vmcr);
138d017d7b0SVijaya Kumar K 	if (!((vmcr.ctlr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT)) {
139d017d7b0SVijaya Kumar K 		if (p->is_write) {
140d017d7b0SVijaya Kumar K 			vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >>
141d017d7b0SVijaya Kumar K 				     ICC_BPR1_EL1_SHIFT;
142d017d7b0SVijaya Kumar K 			vgic_set_vmcr(vcpu, &vmcr);
143d017d7b0SVijaya Kumar K 		} else {
144d017d7b0SVijaya Kumar K 			p->regval = (vmcr.abpr << ICC_BPR1_EL1_SHIFT) &
145d017d7b0SVijaya Kumar K 				     ICC_BPR1_EL1_MASK;
146d017d7b0SVijaya Kumar K 		}
147d017d7b0SVijaya Kumar K 	} else {
148d017d7b0SVijaya Kumar K 		if (!p->is_write)
149d017d7b0SVijaya Kumar K 			p->regval = min((vmcr.bpr + 1), 7U);
150d017d7b0SVijaya Kumar K 	}
151d017d7b0SVijaya Kumar K 
152d017d7b0SVijaya Kumar K 	return true;
153d017d7b0SVijaya Kumar K }
154d017d7b0SVijaya Kumar K 
155d017d7b0SVijaya Kumar K static bool access_gic_grpen0(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
156d017d7b0SVijaya Kumar K 			      const struct sys_reg_desc *r)
157d017d7b0SVijaya Kumar K {
158d017d7b0SVijaya Kumar K 	struct vgic_vmcr vmcr;
159d017d7b0SVijaya Kumar K 
160d017d7b0SVijaya Kumar K 	vgic_get_vmcr(vcpu, &vmcr);
161d017d7b0SVijaya Kumar K 	if (p->is_write) {
162d017d7b0SVijaya Kumar K 		vmcr.grpen0 = (p->regval & ICC_IGRPEN0_EL1_MASK) >>
163d017d7b0SVijaya Kumar K 			       ICC_IGRPEN0_EL1_SHIFT;
164d017d7b0SVijaya Kumar K 		vgic_set_vmcr(vcpu, &vmcr);
165d017d7b0SVijaya Kumar K 	} else {
166d017d7b0SVijaya Kumar K 		p->regval = (vmcr.grpen0 << ICC_IGRPEN0_EL1_SHIFT) &
167d017d7b0SVijaya Kumar K 			     ICC_IGRPEN0_EL1_MASK;
168d017d7b0SVijaya Kumar K 	}
169d017d7b0SVijaya Kumar K 
170d017d7b0SVijaya Kumar K 	return true;
171d017d7b0SVijaya Kumar K }
172d017d7b0SVijaya Kumar K 
173d017d7b0SVijaya Kumar K static bool access_gic_grpen1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
174d017d7b0SVijaya Kumar K 			      const struct sys_reg_desc *r)
175d017d7b0SVijaya Kumar K {
176d017d7b0SVijaya Kumar K 	struct vgic_vmcr vmcr;
177d017d7b0SVijaya Kumar K 
178d017d7b0SVijaya Kumar K 	vgic_get_vmcr(vcpu, &vmcr);
179d017d7b0SVijaya Kumar K 	if (p->is_write) {
180d017d7b0SVijaya Kumar K 		vmcr.grpen1 = (p->regval & ICC_IGRPEN1_EL1_MASK) >>
181d017d7b0SVijaya Kumar K 			       ICC_IGRPEN1_EL1_SHIFT;
182d017d7b0SVijaya Kumar K 		vgic_set_vmcr(vcpu, &vmcr);
183d017d7b0SVijaya Kumar K 	} else {
184d017d7b0SVijaya Kumar K 		p->regval = (vmcr.grpen1 << ICC_IGRPEN1_EL1_SHIFT) &
185d017d7b0SVijaya Kumar K 			     ICC_IGRPEN1_EL1_MASK;
186d017d7b0SVijaya Kumar K 	}
187d017d7b0SVijaya Kumar K 
188d017d7b0SVijaya Kumar K 	return true;
189d017d7b0SVijaya Kumar K }
190d017d7b0SVijaya Kumar K 
191d017d7b0SVijaya Kumar K static void vgic_v3_access_apr_reg(struct kvm_vcpu *vcpu,
192d017d7b0SVijaya Kumar K 				   struct sys_reg_params *p, u8 apr, u8 idx)
193d017d7b0SVijaya Kumar K {
194d017d7b0SVijaya Kumar K 	struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
195d017d7b0SVijaya Kumar K 	uint32_t *ap_reg;
196d017d7b0SVijaya Kumar K 
197d017d7b0SVijaya Kumar K 	if (apr)
198d017d7b0SVijaya Kumar K 		ap_reg = &vgicv3->vgic_ap1r[idx];
199d017d7b0SVijaya Kumar K 	else
200d017d7b0SVijaya Kumar K 		ap_reg = &vgicv3->vgic_ap0r[idx];
201d017d7b0SVijaya Kumar K 
202d017d7b0SVijaya Kumar K 	if (p->is_write)
203d017d7b0SVijaya Kumar K 		*ap_reg = p->regval;
204d017d7b0SVijaya Kumar K 	else
205d017d7b0SVijaya Kumar K 		p->regval = *ap_reg;
206d017d7b0SVijaya Kumar K }
207d017d7b0SVijaya Kumar K 
208d017d7b0SVijaya Kumar K static bool access_gic_aprn(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
209d017d7b0SVijaya Kumar K 			    const struct sys_reg_desc *r, u8 apr)
210d017d7b0SVijaya Kumar K {
211d017d7b0SVijaya Kumar K 	struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu;
212d017d7b0SVijaya Kumar K 	u8 idx = r->Op2 & 3;
213d017d7b0SVijaya Kumar K 
214d017d7b0SVijaya Kumar K 	/*
215d017d7b0SVijaya Kumar K 	 * num_pri_bits are initialized with HW supported values.
216d017d7b0SVijaya Kumar K 	 * We can rely safely on num_pri_bits even if VM has not
217d017d7b0SVijaya Kumar K 	 * restored ICC_CTLR_EL1 before restoring APnR registers.
218d017d7b0SVijaya Kumar K 	 */
219d017d7b0SVijaya Kumar K 	switch (vgic_v3_cpu->num_pri_bits) {
220d017d7b0SVijaya Kumar K 	case 7:
221d017d7b0SVijaya Kumar K 		vgic_v3_access_apr_reg(vcpu, p, apr, idx);
222d017d7b0SVijaya Kumar K 		break;
223d017d7b0SVijaya Kumar K 	case 6:
224d017d7b0SVijaya Kumar K 		if (idx > 1)
225d017d7b0SVijaya Kumar K 			goto err;
226d017d7b0SVijaya Kumar K 		vgic_v3_access_apr_reg(vcpu, p, apr, idx);
227d017d7b0SVijaya Kumar K 		break;
228d017d7b0SVijaya Kumar K 	default:
229d017d7b0SVijaya Kumar K 		if (idx > 0)
230d017d7b0SVijaya Kumar K 			goto err;
231d017d7b0SVijaya Kumar K 		vgic_v3_access_apr_reg(vcpu, p, apr, idx);
232d017d7b0SVijaya Kumar K 	}
233d017d7b0SVijaya Kumar K 
234d017d7b0SVijaya Kumar K 	return true;
235d017d7b0SVijaya Kumar K err:
236d017d7b0SVijaya Kumar K 	if (!p->is_write)
237d017d7b0SVijaya Kumar K 		p->regval = 0;
238d017d7b0SVijaya Kumar K 
239d017d7b0SVijaya Kumar K 	return false;
240d017d7b0SVijaya Kumar K }
241d017d7b0SVijaya Kumar K 
242d017d7b0SVijaya Kumar K static bool access_gic_ap0r(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
243d017d7b0SVijaya Kumar K 			    const struct sys_reg_desc *r)
244d017d7b0SVijaya Kumar K 
245d017d7b0SVijaya Kumar K {
246d017d7b0SVijaya Kumar K 	return access_gic_aprn(vcpu, p, r, 0);
247d017d7b0SVijaya Kumar K }
248d017d7b0SVijaya Kumar K 
249d017d7b0SVijaya Kumar K static bool access_gic_ap1r(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
250d017d7b0SVijaya Kumar K 			    const struct sys_reg_desc *r)
251d017d7b0SVijaya Kumar K {
252d017d7b0SVijaya Kumar K 	return access_gic_aprn(vcpu, p, r, 1);
253d017d7b0SVijaya Kumar K }
254d017d7b0SVijaya Kumar K 
255d017d7b0SVijaya Kumar K static bool access_gic_sre(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
256d017d7b0SVijaya Kumar K 			   const struct sys_reg_desc *r)
257d017d7b0SVijaya Kumar K {
258d017d7b0SVijaya Kumar K 	struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
259d017d7b0SVijaya Kumar K 
260d017d7b0SVijaya Kumar K 	/* Validate SRE bit */
261d017d7b0SVijaya Kumar K 	if (p->is_write) {
262d017d7b0SVijaya Kumar K 		if (!(p->regval & ICC_SRE_EL1_SRE))
263d017d7b0SVijaya Kumar K 			return false;
264d017d7b0SVijaya Kumar K 	} else {
265d017d7b0SVijaya Kumar K 		p->regval = vgicv3->vgic_sre;
266d017d7b0SVijaya Kumar K 	}
267d017d7b0SVijaya Kumar K 
268d017d7b0SVijaya Kumar K 	return true;
269d017d7b0SVijaya Kumar K }
270d017d7b0SVijaya Kumar K static const struct sys_reg_desc gic_v3_icc_reg_descs[] = {
271d017d7b0SVijaya Kumar K 	/* ICC_PMR_EL1 */
272d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(4), CRm(6), Op2(0), access_gic_pmr },
273d017d7b0SVijaya Kumar K 	/* ICC_BPR0_EL1 */
274d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(8), Op2(3), access_gic_bpr0 },
275d017d7b0SVijaya Kumar K 	/* ICC_AP0R0_EL1 */
276d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(8), Op2(4), access_gic_ap0r },
277d017d7b0SVijaya Kumar K 	/* ICC_AP0R1_EL1 */
278d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(8), Op2(5), access_gic_ap0r },
279d017d7b0SVijaya Kumar K 	/* ICC_AP0R2_EL1 */
280d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(8), Op2(6), access_gic_ap0r },
281d017d7b0SVijaya Kumar K 	/* ICC_AP0R3_EL1 */
282d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(8), Op2(7), access_gic_ap0r },
283d017d7b0SVijaya Kumar K 	/* ICC_AP1R0_EL1 */
284d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(9), Op2(0), access_gic_ap1r },
285d017d7b0SVijaya Kumar K 	/* ICC_AP1R1_EL1 */
286d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(9), Op2(1), access_gic_ap1r },
287d017d7b0SVijaya Kumar K 	/* ICC_AP1R2_EL1 */
288d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(9), Op2(2), access_gic_ap1r },
289d017d7b0SVijaya Kumar K 	/* ICC_AP1R3_EL1 */
290d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(9), Op2(3), access_gic_ap1r },
291d017d7b0SVijaya Kumar K 	/* ICC_BPR1_EL1 */
292d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(12), Op2(3), access_gic_bpr1 },
293d017d7b0SVijaya Kumar K 	/* ICC_CTLR_EL1 */
294d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(12), Op2(4), access_gic_ctlr },
295d017d7b0SVijaya Kumar K 	/* ICC_SRE_EL1 */
296d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(12), Op2(5), access_gic_sre },
297d017d7b0SVijaya Kumar K 	/* ICC_IGRPEN0_EL1 */
298d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(12), Op2(6), access_gic_grpen0 },
299d017d7b0SVijaya Kumar K 	/* ICC_GRPEN1_EL1 */
300d017d7b0SVijaya Kumar K 	{ Op0(3), Op1(0), CRn(12), CRm(12), Op2(7), access_gic_grpen1 },
301d017d7b0SVijaya Kumar K };
302d017d7b0SVijaya Kumar K 
303d017d7b0SVijaya Kumar K int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id,
304d017d7b0SVijaya Kumar K 				u64 *reg)
305d017d7b0SVijaya Kumar K {
306d017d7b0SVijaya Kumar K 	struct sys_reg_params params;
307d017d7b0SVijaya Kumar K 	u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
308d017d7b0SVijaya Kumar K 
309d017d7b0SVijaya Kumar K 	params.regval = *reg;
310d017d7b0SVijaya Kumar K 	params.is_write = is_write;
311d017d7b0SVijaya Kumar K 	params.is_aarch32 = false;
312d017d7b0SVijaya Kumar K 	params.is_32bit = false;
313d017d7b0SVijaya Kumar K 
314d017d7b0SVijaya Kumar K 	if (find_reg_by_id(sysreg, &params, gic_v3_icc_reg_descs,
315d017d7b0SVijaya Kumar K 			      ARRAY_SIZE(gic_v3_icc_reg_descs)))
316d017d7b0SVijaya Kumar K 		return 0;
317d017d7b0SVijaya Kumar K 
318d017d7b0SVijaya Kumar K 	return -ENXIO;
319d017d7b0SVijaya Kumar K }
320d017d7b0SVijaya Kumar K 
321d017d7b0SVijaya Kumar K int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id,
322d017d7b0SVijaya Kumar K 				u64 *reg)
323d017d7b0SVijaya Kumar K {
324d017d7b0SVijaya Kumar K 	struct sys_reg_params params;
325d017d7b0SVijaya Kumar K 	const struct sys_reg_desc *r;
326d017d7b0SVijaya Kumar K 	u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
327d017d7b0SVijaya Kumar K 
328d017d7b0SVijaya Kumar K 	if (is_write)
329d017d7b0SVijaya Kumar K 		params.regval = *reg;
330d017d7b0SVijaya Kumar K 	params.is_write = is_write;
331d017d7b0SVijaya Kumar K 	params.is_aarch32 = false;
332d017d7b0SVijaya Kumar K 	params.is_32bit = false;
333d017d7b0SVijaya Kumar K 
334d017d7b0SVijaya Kumar K 	r = find_reg_by_id(sysreg, &params, gic_v3_icc_reg_descs,
335d017d7b0SVijaya Kumar K 			   ARRAY_SIZE(gic_v3_icc_reg_descs));
336d017d7b0SVijaya Kumar K 	if (!r)
337d017d7b0SVijaya Kumar K 		return -ENXIO;
338d017d7b0SVijaya Kumar K 
339d017d7b0SVijaya Kumar K 	if (!r->access(vcpu, &params, r))
340d017d7b0SVijaya Kumar K 		return -EINVAL;
341d017d7b0SVijaya Kumar K 
342d017d7b0SVijaya Kumar K 	if (!is_write)
343d017d7b0SVijaya Kumar K 		*reg = params.regval;
344d017d7b0SVijaya Kumar K 
345d017d7b0SVijaya Kumar K 	return 0;
346d017d7b0SVijaya Kumar K }
347