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 */ 6828232a43SChristoffer Dall vmcr.cbpr = (val & ICC_CTLR_EL1_CBPR_MASK) >> ICC_CTLR_EL1_CBPR_SHIFT; 6928232a43SChristoffer Dall vmcr.eoim = (val & ICC_CTLR_EL1_EOImode_MASK) >> ICC_CTLR_EL1_EOImode_SHIFT; 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 */ 8628232a43SChristoffer Dall val |= (vmcr.cbpr << ICC_CTLR_EL1_CBPR_SHIFT) & ICC_CTLR_EL1_CBPR_MASK; 8728232a43SChristoffer Dall val |= (vmcr.eoim << ICC_CTLR_EL1_EOImode_SHIFT) & 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); 13828232a43SChristoffer Dall if (!vmcr.cbpr) { 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 u8 idx = r->Op2 & 3; 212d017d7b0SVijaya Kumar K 21350f5bd57SChristoffer Dall if (idx > vgic_v3_max_apr_idx(vcpu)) 214d017d7b0SVijaya Kumar K goto err; 215d017d7b0SVijaya Kumar K 21650f5bd57SChristoffer Dall vgic_v3_access_apr_reg(vcpu, p, apr, idx); 217d017d7b0SVijaya Kumar K return true; 218d017d7b0SVijaya Kumar K err: 219d017d7b0SVijaya Kumar K if (!p->is_write) 220d017d7b0SVijaya Kumar K p->regval = 0; 221d017d7b0SVijaya Kumar K 222d017d7b0SVijaya Kumar K return false; 223d017d7b0SVijaya Kumar K } 224d017d7b0SVijaya Kumar K 225d017d7b0SVijaya Kumar K static bool access_gic_ap0r(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 226d017d7b0SVijaya Kumar K const struct sys_reg_desc *r) 227d017d7b0SVijaya Kumar K 228d017d7b0SVijaya Kumar K { 229d017d7b0SVijaya Kumar K return access_gic_aprn(vcpu, p, r, 0); 230d017d7b0SVijaya Kumar K } 231d017d7b0SVijaya Kumar K 232d017d7b0SVijaya Kumar K static bool access_gic_ap1r(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 233d017d7b0SVijaya Kumar K const struct sys_reg_desc *r) 234d017d7b0SVijaya Kumar K { 235d017d7b0SVijaya Kumar K return access_gic_aprn(vcpu, p, r, 1); 236d017d7b0SVijaya Kumar K } 237d017d7b0SVijaya Kumar K 238d017d7b0SVijaya Kumar K static bool access_gic_sre(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 239d017d7b0SVijaya Kumar K const struct sys_reg_desc *r) 240d017d7b0SVijaya Kumar K { 241d017d7b0SVijaya Kumar K struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3; 242d017d7b0SVijaya Kumar K 243d017d7b0SVijaya Kumar K /* Validate SRE bit */ 244d017d7b0SVijaya Kumar K if (p->is_write) { 245d017d7b0SVijaya Kumar K if (!(p->regval & ICC_SRE_EL1_SRE)) 246d017d7b0SVijaya Kumar K return false; 247d017d7b0SVijaya Kumar K } else { 248d017d7b0SVijaya Kumar K p->regval = vgicv3->vgic_sre; 249d017d7b0SVijaya Kumar K } 250d017d7b0SVijaya Kumar K 251d017d7b0SVijaya Kumar K return true; 252d017d7b0SVijaya Kumar K } 253d017d7b0SVijaya Kumar K static const struct sys_reg_desc gic_v3_icc_reg_descs[] = { 2540959db6cSMark Rutland { SYS_DESC(SYS_ICC_PMR_EL1), access_gic_pmr }, 2550959db6cSMark Rutland { SYS_DESC(SYS_ICC_BPR0_EL1), access_gic_bpr0 }, 2560959db6cSMark Rutland { SYS_DESC(SYS_ICC_AP0R0_EL1), access_gic_ap0r }, 2570959db6cSMark Rutland { SYS_DESC(SYS_ICC_AP0R1_EL1), access_gic_ap0r }, 2580959db6cSMark Rutland { SYS_DESC(SYS_ICC_AP0R2_EL1), access_gic_ap0r }, 2590959db6cSMark Rutland { SYS_DESC(SYS_ICC_AP0R3_EL1), access_gic_ap0r }, 2600959db6cSMark Rutland { SYS_DESC(SYS_ICC_AP1R0_EL1), access_gic_ap1r }, 2610959db6cSMark Rutland { SYS_DESC(SYS_ICC_AP1R1_EL1), access_gic_ap1r }, 2620959db6cSMark Rutland { SYS_DESC(SYS_ICC_AP1R2_EL1), access_gic_ap1r }, 2630959db6cSMark Rutland { SYS_DESC(SYS_ICC_AP1R3_EL1), access_gic_ap1r }, 2640959db6cSMark Rutland { SYS_DESC(SYS_ICC_BPR1_EL1), access_gic_bpr1 }, 2650959db6cSMark Rutland { SYS_DESC(SYS_ICC_CTLR_EL1), access_gic_ctlr }, 2660959db6cSMark Rutland { SYS_DESC(SYS_ICC_SRE_EL1), access_gic_sre }, 2670959db6cSMark Rutland { SYS_DESC(SYS_ICC_IGRPEN0_EL1), access_gic_grpen0 }, 2680959db6cSMark Rutland { SYS_DESC(SYS_ICC_IGRPEN1_EL1), access_gic_grpen1 }, 269d017d7b0SVijaya Kumar K }; 270d017d7b0SVijaya Kumar K 271d017d7b0SVijaya Kumar K int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id, 272d017d7b0SVijaya Kumar K u64 *reg) 273d017d7b0SVijaya Kumar K { 274d017d7b0SVijaya Kumar K struct sys_reg_params params; 275d017d7b0SVijaya Kumar K u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64; 276d017d7b0SVijaya Kumar K 277d017d7b0SVijaya Kumar K params.regval = *reg; 278d017d7b0SVijaya Kumar K params.is_write = is_write; 279d017d7b0SVijaya Kumar K params.is_aarch32 = false; 280d017d7b0SVijaya Kumar K params.is_32bit = false; 281d017d7b0SVijaya Kumar K 282d017d7b0SVijaya Kumar K if (find_reg_by_id(sysreg, ¶ms, gic_v3_icc_reg_descs, 283d017d7b0SVijaya Kumar K ARRAY_SIZE(gic_v3_icc_reg_descs))) 284d017d7b0SVijaya Kumar K return 0; 285d017d7b0SVijaya Kumar K 286d017d7b0SVijaya Kumar K return -ENXIO; 287d017d7b0SVijaya Kumar K } 288d017d7b0SVijaya Kumar K 289d017d7b0SVijaya Kumar K int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id, 290d017d7b0SVijaya Kumar K u64 *reg) 291d017d7b0SVijaya Kumar K { 292d017d7b0SVijaya Kumar K struct sys_reg_params params; 293d017d7b0SVijaya Kumar K const struct sys_reg_desc *r; 294d017d7b0SVijaya Kumar K u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64; 295d017d7b0SVijaya Kumar K 296d017d7b0SVijaya Kumar K if (is_write) 297d017d7b0SVijaya Kumar K params.regval = *reg; 298d017d7b0SVijaya Kumar K params.is_write = is_write; 299d017d7b0SVijaya Kumar K params.is_aarch32 = false; 300d017d7b0SVijaya Kumar K params.is_32bit = false; 301d017d7b0SVijaya Kumar K 302d017d7b0SVijaya Kumar K r = find_reg_by_id(sysreg, ¶ms, gic_v3_icc_reg_descs, 303d017d7b0SVijaya Kumar K ARRAY_SIZE(gic_v3_icc_reg_descs)); 304d017d7b0SVijaya Kumar K if (!r) 305d017d7b0SVijaya Kumar K return -ENXIO; 306d017d7b0SVijaya Kumar K 307d017d7b0SVijaya Kumar K if (!r->access(vcpu, ¶ms, r)) 308d017d7b0SVijaya Kumar K return -EINVAL; 309d017d7b0SVijaya Kumar K 310d017d7b0SVijaya Kumar K if (!is_write) 311d017d7b0SVijaya Kumar K *reg = params.regval; 312d017d7b0SVijaya Kumar K 313d017d7b0SVijaya Kumar K return 0; 314d017d7b0SVijaya Kumar K } 315