11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2d017d7b0SVijaya Kumar K /* 3d017d7b0SVijaya Kumar K * VGIC system registers handling functions for AArch64 mode 4d017d7b0SVijaya Kumar K */ 5d017d7b0SVijaya Kumar K 6d017d7b0SVijaya Kumar K #include <linux/irqchip/arm-gic-v3.h> 7d017d7b0SVijaya Kumar K #include <linux/kvm.h> 8d017d7b0SVijaya Kumar K #include <linux/kvm_host.h> 9d017d7b0SVijaya Kumar K #include <asm/kvm_emulate.h> 109ed24f4bSMarc Zyngier #include "vgic/vgic.h" 11d017d7b0SVijaya Kumar K #include "sys_regs.h" 12d017d7b0SVijaya Kumar K 13*cbcf14ddSMarc Zyngier static int set_gic_ctlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 14*cbcf14ddSMarc Zyngier u64 val) 15d017d7b0SVijaya Kumar K { 16d017d7b0SVijaya Kumar K u32 host_pri_bits, host_id_bits, host_seis, host_a3v, seis, a3v; 17d017d7b0SVijaya Kumar K struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu; 18d017d7b0SVijaya Kumar K struct vgic_vmcr vmcr; 19d017d7b0SVijaya Kumar K 20d017d7b0SVijaya Kumar K vgic_get_vmcr(vcpu, &vmcr); 21d017d7b0SVijaya Kumar K 22d017d7b0SVijaya Kumar K /* 23d017d7b0SVijaya Kumar K * Disallow restoring VM state if not supported by this 24d017d7b0SVijaya Kumar K * hardware. 25d017d7b0SVijaya Kumar K */ 26d017d7b0SVijaya Kumar K host_pri_bits = ((val & ICC_CTLR_EL1_PRI_BITS_MASK) >> 27d017d7b0SVijaya Kumar K ICC_CTLR_EL1_PRI_BITS_SHIFT) + 1; 28d017d7b0SVijaya Kumar K if (host_pri_bits > vgic_v3_cpu->num_pri_bits) 29*cbcf14ddSMarc Zyngier return -EINVAL; 30d017d7b0SVijaya Kumar K 31d017d7b0SVijaya Kumar K vgic_v3_cpu->num_pri_bits = host_pri_bits; 32d017d7b0SVijaya Kumar K 33d017d7b0SVijaya Kumar K host_id_bits = (val & ICC_CTLR_EL1_ID_BITS_MASK) >> 34d017d7b0SVijaya Kumar K ICC_CTLR_EL1_ID_BITS_SHIFT; 35d017d7b0SVijaya Kumar K if (host_id_bits > vgic_v3_cpu->num_id_bits) 36*cbcf14ddSMarc Zyngier return -EINVAL; 37d017d7b0SVijaya Kumar K 38d017d7b0SVijaya Kumar K vgic_v3_cpu->num_id_bits = host_id_bits; 39d017d7b0SVijaya Kumar K 40d017d7b0SVijaya Kumar K host_seis = ((kvm_vgic_global_state.ich_vtr_el2 & 41d017d7b0SVijaya Kumar K ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT); 42d017d7b0SVijaya Kumar K seis = (val & ICC_CTLR_EL1_SEIS_MASK) >> 43d017d7b0SVijaya Kumar K ICC_CTLR_EL1_SEIS_SHIFT; 44d017d7b0SVijaya Kumar K if (host_seis != seis) 45*cbcf14ddSMarc Zyngier return -EINVAL; 46d017d7b0SVijaya Kumar K 47d017d7b0SVijaya Kumar K host_a3v = ((kvm_vgic_global_state.ich_vtr_el2 & 48d017d7b0SVijaya Kumar K ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT); 49d017d7b0SVijaya Kumar K a3v = (val & ICC_CTLR_EL1_A3V_MASK) >> ICC_CTLR_EL1_A3V_SHIFT; 50d017d7b0SVijaya Kumar K if (host_a3v != a3v) 51*cbcf14ddSMarc Zyngier return -EINVAL; 52d017d7b0SVijaya Kumar K 53d017d7b0SVijaya Kumar K /* 54d017d7b0SVijaya Kumar K * Here set VMCR.CTLR in ICC_CTLR_EL1 layout. 55d017d7b0SVijaya Kumar K * The vgic_set_vmcr() will convert to ICH_VMCR layout. 56d017d7b0SVijaya Kumar K */ 5728232a43SChristoffer Dall vmcr.cbpr = (val & ICC_CTLR_EL1_CBPR_MASK) >> ICC_CTLR_EL1_CBPR_SHIFT; 5828232a43SChristoffer Dall vmcr.eoim = (val & ICC_CTLR_EL1_EOImode_MASK) >> ICC_CTLR_EL1_EOImode_SHIFT; 59d017d7b0SVijaya Kumar K vgic_set_vmcr(vcpu, &vmcr); 60*cbcf14ddSMarc Zyngier 61*cbcf14ddSMarc Zyngier return 0; 62*cbcf14ddSMarc Zyngier } 63*cbcf14ddSMarc Zyngier 64*cbcf14ddSMarc Zyngier static int get_gic_ctlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 65*cbcf14ddSMarc Zyngier u64 *valp) 66*cbcf14ddSMarc Zyngier { 67*cbcf14ddSMarc Zyngier struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu; 68*cbcf14ddSMarc Zyngier struct vgic_vmcr vmcr; 69*cbcf14ddSMarc Zyngier u64 val; 70*cbcf14ddSMarc Zyngier 71*cbcf14ddSMarc Zyngier vgic_get_vmcr(vcpu, &vmcr); 72d017d7b0SVijaya Kumar K val = 0; 73*cbcf14ddSMarc Zyngier val |= (vgic_v3_cpu->num_pri_bits - 1) << ICC_CTLR_EL1_PRI_BITS_SHIFT; 74d017d7b0SVijaya Kumar K val |= vgic_v3_cpu->num_id_bits << ICC_CTLR_EL1_ID_BITS_SHIFT; 75d017d7b0SVijaya Kumar K val |= ((kvm_vgic_global_state.ich_vtr_el2 & 76d017d7b0SVijaya Kumar K ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT) << 77d017d7b0SVijaya Kumar K ICC_CTLR_EL1_SEIS_SHIFT; 78d017d7b0SVijaya Kumar K val |= ((kvm_vgic_global_state.ich_vtr_el2 & 79d017d7b0SVijaya Kumar K ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT) << 80d017d7b0SVijaya Kumar K ICC_CTLR_EL1_A3V_SHIFT; 81d017d7b0SVijaya Kumar K /* 82d017d7b0SVijaya Kumar K * The VMCR.CTLR value is in ICC_CTLR_EL1 layout. 83d017d7b0SVijaya Kumar K * Extract it directly using ICC_CTLR_EL1 reg definitions. 84d017d7b0SVijaya Kumar K */ 8528232a43SChristoffer Dall val |= (vmcr.cbpr << ICC_CTLR_EL1_CBPR_SHIFT) & ICC_CTLR_EL1_CBPR_MASK; 8628232a43SChristoffer Dall val |= (vmcr.eoim << ICC_CTLR_EL1_EOImode_SHIFT) & ICC_CTLR_EL1_EOImode_MASK; 87d017d7b0SVijaya Kumar K 88*cbcf14ddSMarc Zyngier *valp = val; 89*cbcf14ddSMarc Zyngier 90*cbcf14ddSMarc Zyngier return 0; 91d017d7b0SVijaya Kumar K } 92d017d7b0SVijaya Kumar K 93*cbcf14ddSMarc Zyngier static int set_gic_pmr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 94*cbcf14ddSMarc Zyngier u64 val) 95d017d7b0SVijaya Kumar K { 96d017d7b0SVijaya Kumar K struct vgic_vmcr vmcr; 97d017d7b0SVijaya Kumar K 98d017d7b0SVijaya Kumar K vgic_get_vmcr(vcpu, &vmcr); 99*cbcf14ddSMarc Zyngier vmcr.pmr = (val & ICC_PMR_EL1_MASK) >> ICC_PMR_EL1_SHIFT; 100d017d7b0SVijaya Kumar K vgic_set_vmcr(vcpu, &vmcr); 101*cbcf14ddSMarc Zyngier 102*cbcf14ddSMarc Zyngier return 0; 103d017d7b0SVijaya Kumar K } 104d017d7b0SVijaya Kumar K 105*cbcf14ddSMarc Zyngier static int get_gic_pmr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 106*cbcf14ddSMarc Zyngier u64 *val) 107d017d7b0SVijaya Kumar K { 108d017d7b0SVijaya Kumar K struct vgic_vmcr vmcr; 109d017d7b0SVijaya Kumar K 110d017d7b0SVijaya Kumar K vgic_get_vmcr(vcpu, &vmcr); 111*cbcf14ddSMarc Zyngier *val = (vmcr.pmr << ICC_PMR_EL1_SHIFT) & ICC_PMR_EL1_MASK; 112*cbcf14ddSMarc Zyngier 113*cbcf14ddSMarc Zyngier return 0; 114d017d7b0SVijaya Kumar K } 115d017d7b0SVijaya Kumar K 116*cbcf14ddSMarc Zyngier static int set_gic_bpr0(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 117*cbcf14ddSMarc Zyngier u64 val) 118d017d7b0SVijaya Kumar K { 119d017d7b0SVijaya Kumar K struct vgic_vmcr vmcr; 120d017d7b0SVijaya Kumar K 121*cbcf14ddSMarc Zyngier vgic_get_vmcr(vcpu, &vmcr); 122*cbcf14ddSMarc Zyngier vmcr.bpr = (val & ICC_BPR0_EL1_MASK) >> ICC_BPR0_EL1_SHIFT; 123*cbcf14ddSMarc Zyngier vgic_set_vmcr(vcpu, &vmcr); 124*cbcf14ddSMarc Zyngier 125*cbcf14ddSMarc Zyngier return 0; 126*cbcf14ddSMarc Zyngier } 127*cbcf14ddSMarc Zyngier 128*cbcf14ddSMarc Zyngier static int get_gic_bpr0(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 129*cbcf14ddSMarc Zyngier u64 *val) 130*cbcf14ddSMarc Zyngier { 131*cbcf14ddSMarc Zyngier struct vgic_vmcr vmcr; 132*cbcf14ddSMarc Zyngier 133*cbcf14ddSMarc Zyngier vgic_get_vmcr(vcpu, &vmcr); 134*cbcf14ddSMarc Zyngier *val = (vmcr.bpr << ICC_BPR0_EL1_SHIFT) & ICC_BPR0_EL1_MASK; 135*cbcf14ddSMarc Zyngier 136*cbcf14ddSMarc Zyngier return 0; 137*cbcf14ddSMarc Zyngier } 138*cbcf14ddSMarc Zyngier 139*cbcf14ddSMarc Zyngier static int set_gic_bpr1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 140*cbcf14ddSMarc Zyngier u64 val) 141*cbcf14ddSMarc Zyngier { 142*cbcf14ddSMarc Zyngier struct vgic_vmcr vmcr; 143d017d7b0SVijaya Kumar K 144d017d7b0SVijaya Kumar K vgic_get_vmcr(vcpu, &vmcr); 14528232a43SChristoffer Dall if (!vmcr.cbpr) { 146*cbcf14ddSMarc Zyngier vmcr.abpr = (val & ICC_BPR1_EL1_MASK) >> ICC_BPR1_EL1_SHIFT; 147d017d7b0SVijaya Kumar K vgic_set_vmcr(vcpu, &vmcr); 148d017d7b0SVijaya Kumar K } 149d017d7b0SVijaya Kumar K 150*cbcf14ddSMarc Zyngier return 0; 151d017d7b0SVijaya Kumar K } 152d017d7b0SVijaya Kumar K 153*cbcf14ddSMarc Zyngier static int get_gic_bpr1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 154*cbcf14ddSMarc Zyngier u64 *val) 155d017d7b0SVijaya Kumar K { 156d017d7b0SVijaya Kumar K struct vgic_vmcr vmcr; 157d017d7b0SVijaya Kumar K 158d017d7b0SVijaya Kumar K vgic_get_vmcr(vcpu, &vmcr); 159*cbcf14ddSMarc Zyngier if (!vmcr.cbpr) 160*cbcf14ddSMarc Zyngier *val = (vmcr.abpr << ICC_BPR1_EL1_SHIFT) & ICC_BPR1_EL1_MASK; 161*cbcf14ddSMarc Zyngier else 162*cbcf14ddSMarc Zyngier *val = min((vmcr.bpr + 1), 7U); 163*cbcf14ddSMarc Zyngier 164*cbcf14ddSMarc Zyngier 165*cbcf14ddSMarc Zyngier return 0; 166d017d7b0SVijaya Kumar K } 167d017d7b0SVijaya Kumar K 168*cbcf14ddSMarc Zyngier static int set_gic_grpen0(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 169*cbcf14ddSMarc Zyngier u64 val) 170d017d7b0SVijaya Kumar K { 171d017d7b0SVijaya Kumar K struct vgic_vmcr vmcr; 172d017d7b0SVijaya Kumar K 173d017d7b0SVijaya Kumar K vgic_get_vmcr(vcpu, &vmcr); 174*cbcf14ddSMarc Zyngier vmcr.grpen0 = (val & ICC_IGRPEN0_EL1_MASK) >> ICC_IGRPEN0_EL1_SHIFT; 175d017d7b0SVijaya Kumar K vgic_set_vmcr(vcpu, &vmcr); 176*cbcf14ddSMarc Zyngier 177*cbcf14ddSMarc Zyngier return 0; 178d017d7b0SVijaya Kumar K } 179d017d7b0SVijaya Kumar K 180*cbcf14ddSMarc Zyngier static int get_gic_grpen0(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 181*cbcf14ddSMarc Zyngier u64 *val) 182*cbcf14ddSMarc Zyngier { 183*cbcf14ddSMarc Zyngier struct vgic_vmcr vmcr; 184*cbcf14ddSMarc Zyngier 185*cbcf14ddSMarc Zyngier vgic_get_vmcr(vcpu, &vmcr); 186*cbcf14ddSMarc Zyngier *val = (vmcr.grpen0 << ICC_IGRPEN0_EL1_SHIFT) & ICC_IGRPEN0_EL1_MASK; 187*cbcf14ddSMarc Zyngier 188*cbcf14ddSMarc Zyngier return 0; 189d017d7b0SVijaya Kumar K } 190d017d7b0SVijaya Kumar K 191*cbcf14ddSMarc Zyngier static int set_gic_grpen1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 192*cbcf14ddSMarc Zyngier u64 val) 193*cbcf14ddSMarc Zyngier { 194*cbcf14ddSMarc Zyngier struct vgic_vmcr vmcr; 195*cbcf14ddSMarc Zyngier 196*cbcf14ddSMarc Zyngier vgic_get_vmcr(vcpu, &vmcr); 197*cbcf14ddSMarc Zyngier vmcr.grpen1 = (val & ICC_IGRPEN1_EL1_MASK) >> ICC_IGRPEN1_EL1_SHIFT; 198*cbcf14ddSMarc Zyngier vgic_set_vmcr(vcpu, &vmcr); 199*cbcf14ddSMarc Zyngier 200*cbcf14ddSMarc Zyngier return 0; 201*cbcf14ddSMarc Zyngier } 202*cbcf14ddSMarc Zyngier 203*cbcf14ddSMarc Zyngier static int get_gic_grpen1(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 204*cbcf14ddSMarc Zyngier u64 *val) 205*cbcf14ddSMarc Zyngier { 206*cbcf14ddSMarc Zyngier struct vgic_vmcr vmcr; 207*cbcf14ddSMarc Zyngier 208*cbcf14ddSMarc Zyngier vgic_get_vmcr(vcpu, &vmcr); 209*cbcf14ddSMarc Zyngier *val = (vmcr.grpen1 << ICC_IGRPEN1_EL1_SHIFT) & ICC_IGRPEN1_EL1_MASK; 210*cbcf14ddSMarc Zyngier 211*cbcf14ddSMarc Zyngier return 0; 212*cbcf14ddSMarc Zyngier } 213*cbcf14ddSMarc Zyngier 214*cbcf14ddSMarc Zyngier static void set_apr_reg(struct kvm_vcpu *vcpu, u64 val, u8 apr, u8 idx) 215d017d7b0SVijaya Kumar K { 216d017d7b0SVijaya Kumar K struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3; 217d017d7b0SVijaya Kumar K 218d017d7b0SVijaya Kumar K if (apr) 219*cbcf14ddSMarc Zyngier vgicv3->vgic_ap1r[idx] = val; 220d017d7b0SVijaya Kumar K else 221*cbcf14ddSMarc Zyngier vgicv3->vgic_ap0r[idx] = val; 222d017d7b0SVijaya Kumar K } 223d017d7b0SVijaya Kumar K 224*cbcf14ddSMarc Zyngier static u64 get_apr_reg(struct kvm_vcpu *vcpu, u8 apr, u8 idx) 225*cbcf14ddSMarc Zyngier { 226*cbcf14ddSMarc Zyngier struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3; 227*cbcf14ddSMarc Zyngier 228*cbcf14ddSMarc Zyngier if (apr) 229*cbcf14ddSMarc Zyngier return vgicv3->vgic_ap1r[idx]; 230*cbcf14ddSMarc Zyngier else 231*cbcf14ddSMarc Zyngier return vgicv3->vgic_ap0r[idx]; 232*cbcf14ddSMarc Zyngier } 233*cbcf14ddSMarc Zyngier 234*cbcf14ddSMarc Zyngier static int set_gic_ap0r(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 235*cbcf14ddSMarc Zyngier u64 val) 236*cbcf14ddSMarc Zyngier 237d017d7b0SVijaya Kumar K { 238d017d7b0SVijaya Kumar K u8 idx = r->Op2 & 3; 239d017d7b0SVijaya Kumar K 24050f5bd57SChristoffer Dall if (idx > vgic_v3_max_apr_idx(vcpu)) 241*cbcf14ddSMarc Zyngier return -EINVAL; 242d017d7b0SVijaya Kumar K 243*cbcf14ddSMarc Zyngier set_apr_reg(vcpu, val, 0, idx); 244*cbcf14ddSMarc Zyngier return 0; 245d017d7b0SVijaya Kumar K } 246d017d7b0SVijaya Kumar K 247*cbcf14ddSMarc Zyngier static int get_gic_ap0r(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 248*cbcf14ddSMarc Zyngier u64 *val) 249*cbcf14ddSMarc Zyngier { 250*cbcf14ddSMarc Zyngier u8 idx = r->Op2 & 3; 251*cbcf14ddSMarc Zyngier 252*cbcf14ddSMarc Zyngier if (idx > vgic_v3_max_apr_idx(vcpu)) 253*cbcf14ddSMarc Zyngier return -EINVAL; 254*cbcf14ddSMarc Zyngier 255*cbcf14ddSMarc Zyngier *val = get_apr_reg(vcpu, 0, idx); 256*cbcf14ddSMarc Zyngier 257*cbcf14ddSMarc Zyngier return 0; 258*cbcf14ddSMarc Zyngier } 259*cbcf14ddSMarc Zyngier 260*cbcf14ddSMarc Zyngier static int set_gic_ap1r(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 261*cbcf14ddSMarc Zyngier u64 val) 262d017d7b0SVijaya Kumar K 263d017d7b0SVijaya Kumar K { 264*cbcf14ddSMarc Zyngier u8 idx = r->Op2 & 3; 265*cbcf14ddSMarc Zyngier 266*cbcf14ddSMarc Zyngier if (idx > vgic_v3_max_apr_idx(vcpu)) 267*cbcf14ddSMarc Zyngier return -EINVAL; 268*cbcf14ddSMarc Zyngier 269*cbcf14ddSMarc Zyngier set_apr_reg(vcpu, val, 1, idx); 270*cbcf14ddSMarc Zyngier return 0; 271d017d7b0SVijaya Kumar K } 272d017d7b0SVijaya Kumar K 273*cbcf14ddSMarc Zyngier static int get_gic_ap1r(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 274*cbcf14ddSMarc Zyngier u64 *val) 275d017d7b0SVijaya Kumar K { 276*cbcf14ddSMarc Zyngier u8 idx = r->Op2 & 3; 277*cbcf14ddSMarc Zyngier 278*cbcf14ddSMarc Zyngier if (idx > vgic_v3_max_apr_idx(vcpu)) 279*cbcf14ddSMarc Zyngier return -EINVAL; 280*cbcf14ddSMarc Zyngier 281*cbcf14ddSMarc Zyngier *val = get_apr_reg(vcpu, 1, idx); 282*cbcf14ddSMarc Zyngier 283*cbcf14ddSMarc Zyngier return 0; 284d017d7b0SVijaya Kumar K } 285d017d7b0SVijaya Kumar K 286*cbcf14ddSMarc Zyngier static int set_gic_sre(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 287*cbcf14ddSMarc Zyngier u64 val) 288*cbcf14ddSMarc Zyngier { 289*cbcf14ddSMarc Zyngier /* Validate SRE bit */ 290*cbcf14ddSMarc Zyngier if (!(val & ICC_SRE_EL1_SRE)) 291*cbcf14ddSMarc Zyngier return -EINVAL; 292*cbcf14ddSMarc Zyngier 293*cbcf14ddSMarc Zyngier return 0; 294*cbcf14ddSMarc Zyngier } 295*cbcf14ddSMarc Zyngier 296*cbcf14ddSMarc Zyngier static int get_gic_sre(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r, 297*cbcf14ddSMarc Zyngier u64 *val) 298d017d7b0SVijaya Kumar K { 299d017d7b0SVijaya Kumar K struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3; 300d017d7b0SVijaya Kumar K 301*cbcf14ddSMarc Zyngier *val = vgicv3->vgic_sre; 302*cbcf14ddSMarc Zyngier 303*cbcf14ddSMarc Zyngier return 0; 304d017d7b0SVijaya Kumar K } 305d017d7b0SVijaya Kumar K 306d017d7b0SVijaya Kumar K static const struct sys_reg_desc gic_v3_icc_reg_descs[] = { 307*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_PMR_EL1), 308*cbcf14ddSMarc Zyngier .set_user = set_gic_pmr, .get_user = get_gic_pmr, }, 309*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_BPR0_EL1), 310*cbcf14ddSMarc Zyngier .set_user = set_gic_bpr0, .get_user = get_gic_bpr0, }, 311*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_AP0R0_EL1), 312*cbcf14ddSMarc Zyngier .set_user = set_gic_ap0r, .get_user = get_gic_ap0r, }, 313*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_AP0R1_EL1), 314*cbcf14ddSMarc Zyngier .set_user = set_gic_ap0r, .get_user = get_gic_ap0r, }, 315*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_AP0R2_EL1), 316*cbcf14ddSMarc Zyngier .set_user = set_gic_ap0r, .get_user = get_gic_ap0r, }, 317*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_AP0R3_EL1), 318*cbcf14ddSMarc Zyngier .set_user = set_gic_ap0r, .get_user = get_gic_ap0r, }, 319*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_AP1R0_EL1), 320*cbcf14ddSMarc Zyngier .set_user = set_gic_ap1r, .get_user = get_gic_ap1r, }, 321*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_AP1R1_EL1), 322*cbcf14ddSMarc Zyngier .set_user = set_gic_ap1r, .get_user = get_gic_ap1r, }, 323*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_AP1R2_EL1), 324*cbcf14ddSMarc Zyngier .set_user = set_gic_ap1r, .get_user = get_gic_ap1r, }, 325*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_AP1R3_EL1), 326*cbcf14ddSMarc Zyngier .set_user = set_gic_ap1r, .get_user = get_gic_ap1r, }, 327*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_BPR1_EL1), 328*cbcf14ddSMarc Zyngier .set_user = set_gic_bpr1, .get_user = get_gic_bpr1, }, 329*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_CTLR_EL1), 330*cbcf14ddSMarc Zyngier .set_user = set_gic_ctlr, .get_user = get_gic_ctlr, }, 331*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_SRE_EL1), 332*cbcf14ddSMarc Zyngier .set_user = set_gic_sre, .get_user = get_gic_sre, }, 333*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_IGRPEN0_EL1), 334*cbcf14ddSMarc Zyngier .set_user = set_gic_grpen0, .get_user = get_gic_grpen0, }, 335*cbcf14ddSMarc Zyngier { SYS_DESC(SYS_ICC_IGRPEN1_EL1), 336*cbcf14ddSMarc Zyngier .set_user = set_gic_grpen1, .get_user = get_gic_grpen1, }, 337d017d7b0SVijaya Kumar K }; 338d017d7b0SVijaya Kumar K 339b61fc085SMarc Zyngier static u64 attr_to_id(u64 attr) 340d017d7b0SVijaya Kumar K { 341b61fc085SMarc Zyngier return ARM64_SYS_REG(FIELD_GET(KVM_REG_ARM_VGIC_SYSREG_OP0_MASK, attr), 342b61fc085SMarc Zyngier FIELD_GET(KVM_REG_ARM_VGIC_SYSREG_OP1_MASK, attr), 343b61fc085SMarc Zyngier FIELD_GET(KVM_REG_ARM_VGIC_SYSREG_CRN_MASK, attr), 344b61fc085SMarc Zyngier FIELD_GET(KVM_REG_ARM_VGIC_SYSREG_CRM_MASK, attr), 345b61fc085SMarc Zyngier FIELD_GET(KVM_REG_ARM_VGIC_SYSREG_OP2_MASK, attr)); 346b61fc085SMarc Zyngier } 347d017d7b0SVijaya Kumar K 348b61fc085SMarc Zyngier int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr) 349b61fc085SMarc Zyngier { 350b61fc085SMarc Zyngier if (get_reg_by_id(attr_to_id(attr->attr), gic_v3_icc_reg_descs, 351d017d7b0SVijaya Kumar K ARRAY_SIZE(gic_v3_icc_reg_descs))) 352d017d7b0SVijaya Kumar K return 0; 353d017d7b0SVijaya Kumar K 354d017d7b0SVijaya Kumar K return -ENXIO; 355d017d7b0SVijaya Kumar K } 356d017d7b0SVijaya Kumar K 357db25081eSMarc Zyngier int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, 358db25081eSMarc Zyngier struct kvm_device_attr *attr, 359db25081eSMarc Zyngier bool is_write) 360d017d7b0SVijaya Kumar K { 361*cbcf14ddSMarc Zyngier struct kvm_one_reg reg = { 362*cbcf14ddSMarc Zyngier .id = attr_to_id(attr->attr), 363*cbcf14ddSMarc Zyngier .addr = attr->addr, 364*cbcf14ddSMarc Zyngier }; 365d017d7b0SVijaya Kumar K 366*cbcf14ddSMarc Zyngier if (is_write) 367*cbcf14ddSMarc Zyngier return kvm_sys_reg_set_user(vcpu, ®, gic_v3_icc_reg_descs, 368d017d7b0SVijaya Kumar K ARRAY_SIZE(gic_v3_icc_reg_descs)); 369*cbcf14ddSMarc Zyngier else 370*cbcf14ddSMarc Zyngier return kvm_sys_reg_get_user(vcpu, ®, gic_v3_icc_reg_descs, 371*cbcf14ddSMarc Zyngier ARRAY_SIZE(gic_v3_icc_reg_descs)); 372d017d7b0SVijaya Kumar K } 373