^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, ¶ms, 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, ¶ms, 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, ¶ms, 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) }