Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * VGIC system registers handling functions for AArch64 mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <linux/irqchip/arm-gic-v3.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/kvm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/kvm_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <asm/kvm_emulate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include "vgic/vgic.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include "sys_regs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) static bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 			    const struct sys_reg_desc *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	u32 host_pri_bits, host_id_bits, host_seis, host_a3v, seis, a3v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	struct vgic_vmcr vmcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	vgic_get_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	if (p->is_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 		val = p->regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 		 * Disallow restoring VM state if not supported by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 		 * hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		host_pri_bits = ((val & ICC_CTLR_EL1_PRI_BITS_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 				 ICC_CTLR_EL1_PRI_BITS_SHIFT) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		if (host_pri_bits > vgic_v3_cpu->num_pri_bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		vgic_v3_cpu->num_pri_bits = host_pri_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		host_id_bits = (val & ICC_CTLR_EL1_ID_BITS_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 				ICC_CTLR_EL1_ID_BITS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		if (host_id_bits > vgic_v3_cpu->num_id_bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		vgic_v3_cpu->num_id_bits = host_id_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		host_seis = ((kvm_vgic_global_state.ich_vtr_el2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 			     ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		seis = (val & ICC_CTLR_EL1_SEIS_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 			ICC_CTLR_EL1_SEIS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		if (host_seis != seis)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		host_a3v = ((kvm_vgic_global_state.ich_vtr_el2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 			    ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		a3v = (val & ICC_CTLR_EL1_A3V_MASK) >> ICC_CTLR_EL1_A3V_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		if (host_a3v != a3v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		 * Here set VMCR.CTLR in ICC_CTLR_EL1 layout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		 * The vgic_set_vmcr() will convert to ICH_VMCR layout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		vmcr.cbpr = (val & ICC_CTLR_EL1_CBPR_MASK) >> ICC_CTLR_EL1_CBPR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		vmcr.eoim = (val & ICC_CTLR_EL1_EOImode_MASK) >> ICC_CTLR_EL1_EOImode_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		vgic_set_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		val |= (vgic_v3_cpu->num_pri_bits - 1) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 			ICC_CTLR_EL1_PRI_BITS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		val |= vgic_v3_cpu->num_id_bits << ICC_CTLR_EL1_ID_BITS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		val |= ((kvm_vgic_global_state.ich_vtr_el2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 			ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			ICC_CTLR_EL1_SEIS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		val |= ((kvm_vgic_global_state.ich_vtr_el2 &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 			ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT) <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			ICC_CTLR_EL1_A3V_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		 * The VMCR.CTLR value is in ICC_CTLR_EL1 layout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		 * Extract it directly using ICC_CTLR_EL1 reg definitions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		val |= (vmcr.cbpr << ICC_CTLR_EL1_CBPR_SHIFT) & ICC_CTLR_EL1_CBPR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		val |= (vmcr.eoim << ICC_CTLR_EL1_EOImode_SHIFT) & ICC_CTLR_EL1_EOImode_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		p->regval = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static bool access_gic_pmr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			   const struct sys_reg_desc *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	struct vgic_vmcr vmcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	vgic_get_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (p->is_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		vmcr.pmr = (p->regval & ICC_PMR_EL1_MASK) >> ICC_PMR_EL1_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		vgic_set_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		p->regval = (vmcr.pmr << ICC_PMR_EL1_SHIFT) & ICC_PMR_EL1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static bool access_gic_bpr0(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			    const struct sys_reg_desc *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	struct vgic_vmcr vmcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	vgic_get_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	if (p->is_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		vmcr.bpr = (p->regval & ICC_BPR0_EL1_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			    ICC_BPR0_EL1_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		vgic_set_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		p->regval = (vmcr.bpr << ICC_BPR0_EL1_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			     ICC_BPR0_EL1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static bool access_gic_bpr1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			    const struct sys_reg_desc *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	struct vgic_vmcr vmcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	if (!p->is_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		p->regval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	vgic_get_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	if (!vmcr.cbpr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		if (p->is_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 				     ICC_BPR1_EL1_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 			vgic_set_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			p->regval = (vmcr.abpr << ICC_BPR1_EL1_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 				     ICC_BPR1_EL1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		if (!p->is_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 			p->regval = min((vmcr.bpr + 1), 7U);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static bool access_gic_grpen0(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			      const struct sys_reg_desc *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	struct vgic_vmcr vmcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	vgic_get_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (p->is_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		vmcr.grpen0 = (p->regval & ICC_IGRPEN0_EL1_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			       ICC_IGRPEN0_EL1_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		vgic_set_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		p->regval = (vmcr.grpen0 << ICC_IGRPEN0_EL1_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			     ICC_IGRPEN0_EL1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static bool access_gic_grpen1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			      const struct sys_reg_desc *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	struct vgic_vmcr vmcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	vgic_get_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	if (p->is_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		vmcr.grpen1 = (p->regval & ICC_IGRPEN1_EL1_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			       ICC_IGRPEN1_EL1_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		vgic_set_vmcr(vcpu, &vmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		p->regval = (vmcr.grpen1 << ICC_IGRPEN1_EL1_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			     ICC_IGRPEN1_EL1_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static void vgic_v3_access_apr_reg(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 				   struct sys_reg_params *p, u8 apr, u8 idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	uint32_t *ap_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if (apr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		ap_reg = &vgicv3->vgic_ap1r[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		ap_reg = &vgicv3->vgic_ap0r[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	if (p->is_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		*ap_reg = p->regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		p->regval = *ap_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static bool access_gic_aprn(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			    const struct sys_reg_desc *r, u8 apr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	u8 idx = r->Op2 & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	if (idx > vgic_v3_max_apr_idx(vcpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	vgic_v3_access_apr_reg(vcpu, p, apr, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	if (!p->is_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		p->regval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static bool access_gic_ap0r(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			    const struct sys_reg_desc *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	return access_gic_aprn(vcpu, p, r, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static bool access_gic_ap1r(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			    const struct sys_reg_desc *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	return access_gic_aprn(vcpu, p, r, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static bool access_gic_sre(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			   const struct sys_reg_desc *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	/* Validate SRE bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (p->is_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		if (!(p->regval & ICC_SRE_EL1_SRE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		p->regval = vgicv3->vgic_sre;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) static const struct sys_reg_desc gic_v3_icc_reg_descs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	{ SYS_DESC(SYS_ICC_PMR_EL1), access_gic_pmr },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	{ SYS_DESC(SYS_ICC_BPR0_EL1), access_gic_bpr0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	{ SYS_DESC(SYS_ICC_AP0R0_EL1), access_gic_ap0r },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	{ SYS_DESC(SYS_ICC_AP0R1_EL1), access_gic_ap0r },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	{ SYS_DESC(SYS_ICC_AP0R2_EL1), access_gic_ap0r },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	{ SYS_DESC(SYS_ICC_AP0R3_EL1), access_gic_ap0r },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	{ SYS_DESC(SYS_ICC_AP1R0_EL1), access_gic_ap1r },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	{ SYS_DESC(SYS_ICC_AP1R1_EL1), access_gic_ap1r },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	{ SYS_DESC(SYS_ICC_AP1R2_EL1), access_gic_ap1r },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	{ SYS_DESC(SYS_ICC_AP1R3_EL1), access_gic_ap1r },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	{ SYS_DESC(SYS_ICC_BPR1_EL1), access_gic_bpr1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	{ SYS_DESC(SYS_ICC_CTLR_EL1), access_gic_ctlr },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	{ SYS_DESC(SYS_ICC_SRE_EL1), access_gic_sre },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	{ SYS_DESC(SYS_ICC_IGRPEN0_EL1), access_gic_grpen0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	{ SYS_DESC(SYS_ICC_IGRPEN1_EL1), access_gic_grpen1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 				u64 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	struct sys_reg_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	params.regval = *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	params.is_write = is_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	if (find_reg_by_id(sysreg, &params, gic_v3_icc_reg_descs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			      ARRAY_SIZE(gic_v3_icc_reg_descs)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 				u64 *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	struct sys_reg_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	const struct sys_reg_desc *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	if (is_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		params.regval = *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	params.is_write = is_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	r = find_reg_by_id(sysreg, &params, gic_v3_icc_reg_descs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 			   ARRAY_SIZE(gic_v3_icc_reg_descs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	if (!r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (!r->access(vcpu, &params, r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	if (!is_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		*reg = params.regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }