18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * VGIC system registers handling functions for AArch64 mode 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/irqchip/arm-gic-v3.h> 78c2ecf20Sopenharmony_ci#include <linux/kvm.h> 88c2ecf20Sopenharmony_ci#include <linux/kvm_host.h> 98c2ecf20Sopenharmony_ci#include <asm/kvm_emulate.h> 108c2ecf20Sopenharmony_ci#include "vgic/vgic.h" 118c2ecf20Sopenharmony_ci#include "sys_regs.h" 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistatic bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 148c2ecf20Sopenharmony_ci const struct sys_reg_desc *r) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci u32 host_pri_bits, host_id_bits, host_seis, host_a3v, seis, a3v; 178c2ecf20Sopenharmony_ci struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu; 188c2ecf20Sopenharmony_ci struct vgic_vmcr vmcr; 198c2ecf20Sopenharmony_ci u64 val; 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci vgic_get_vmcr(vcpu, &vmcr); 228c2ecf20Sopenharmony_ci if (p->is_write) { 238c2ecf20Sopenharmony_ci val = p->regval; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci /* 268c2ecf20Sopenharmony_ci * Disallow restoring VM state if not supported by this 278c2ecf20Sopenharmony_ci * hardware. 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_ci host_pri_bits = ((val & ICC_CTLR_EL1_PRI_BITS_MASK) >> 308c2ecf20Sopenharmony_ci ICC_CTLR_EL1_PRI_BITS_SHIFT) + 1; 318c2ecf20Sopenharmony_ci if (host_pri_bits > vgic_v3_cpu->num_pri_bits) 328c2ecf20Sopenharmony_ci return false; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci vgic_v3_cpu->num_pri_bits = host_pri_bits; 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci host_id_bits = (val & ICC_CTLR_EL1_ID_BITS_MASK) >> 378c2ecf20Sopenharmony_ci ICC_CTLR_EL1_ID_BITS_SHIFT; 388c2ecf20Sopenharmony_ci if (host_id_bits > vgic_v3_cpu->num_id_bits) 398c2ecf20Sopenharmony_ci return false; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci vgic_v3_cpu->num_id_bits = host_id_bits; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci host_seis = ((kvm_vgic_global_state.ich_vtr_el2 & 448c2ecf20Sopenharmony_ci ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT); 458c2ecf20Sopenharmony_ci seis = (val & ICC_CTLR_EL1_SEIS_MASK) >> 468c2ecf20Sopenharmony_ci ICC_CTLR_EL1_SEIS_SHIFT; 478c2ecf20Sopenharmony_ci if (host_seis != seis) 488c2ecf20Sopenharmony_ci return false; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci host_a3v = ((kvm_vgic_global_state.ich_vtr_el2 & 518c2ecf20Sopenharmony_ci ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT); 528c2ecf20Sopenharmony_ci a3v = (val & ICC_CTLR_EL1_A3V_MASK) >> ICC_CTLR_EL1_A3V_SHIFT; 538c2ecf20Sopenharmony_ci if (host_a3v != a3v) 548c2ecf20Sopenharmony_ci return false; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci /* 578c2ecf20Sopenharmony_ci * Here set VMCR.CTLR in ICC_CTLR_EL1 layout. 588c2ecf20Sopenharmony_ci * The vgic_set_vmcr() will convert to ICH_VMCR layout. 598c2ecf20Sopenharmony_ci */ 608c2ecf20Sopenharmony_ci vmcr.cbpr = (val & ICC_CTLR_EL1_CBPR_MASK) >> ICC_CTLR_EL1_CBPR_SHIFT; 618c2ecf20Sopenharmony_ci vmcr.eoim = (val & ICC_CTLR_EL1_EOImode_MASK) >> ICC_CTLR_EL1_EOImode_SHIFT; 628c2ecf20Sopenharmony_ci vgic_set_vmcr(vcpu, &vmcr); 638c2ecf20Sopenharmony_ci } else { 648c2ecf20Sopenharmony_ci val = 0; 658c2ecf20Sopenharmony_ci val |= (vgic_v3_cpu->num_pri_bits - 1) << 668c2ecf20Sopenharmony_ci ICC_CTLR_EL1_PRI_BITS_SHIFT; 678c2ecf20Sopenharmony_ci val |= vgic_v3_cpu->num_id_bits << ICC_CTLR_EL1_ID_BITS_SHIFT; 688c2ecf20Sopenharmony_ci val |= ((kvm_vgic_global_state.ich_vtr_el2 & 698c2ecf20Sopenharmony_ci ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT) << 708c2ecf20Sopenharmony_ci ICC_CTLR_EL1_SEIS_SHIFT; 718c2ecf20Sopenharmony_ci val |= ((kvm_vgic_global_state.ich_vtr_el2 & 728c2ecf20Sopenharmony_ci ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT) << 738c2ecf20Sopenharmony_ci ICC_CTLR_EL1_A3V_SHIFT; 748c2ecf20Sopenharmony_ci /* 758c2ecf20Sopenharmony_ci * The VMCR.CTLR value is in ICC_CTLR_EL1 layout. 768c2ecf20Sopenharmony_ci * Extract it directly using ICC_CTLR_EL1 reg definitions. 778c2ecf20Sopenharmony_ci */ 788c2ecf20Sopenharmony_ci val |= (vmcr.cbpr << ICC_CTLR_EL1_CBPR_SHIFT) & ICC_CTLR_EL1_CBPR_MASK; 798c2ecf20Sopenharmony_ci val |= (vmcr.eoim << ICC_CTLR_EL1_EOImode_SHIFT) & ICC_CTLR_EL1_EOImode_MASK; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci p->regval = val; 828c2ecf20Sopenharmony_ci } 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci return true; 858c2ecf20Sopenharmony_ci} 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_cistatic bool access_gic_pmr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 888c2ecf20Sopenharmony_ci const struct sys_reg_desc *r) 898c2ecf20Sopenharmony_ci{ 908c2ecf20Sopenharmony_ci struct vgic_vmcr vmcr; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci vgic_get_vmcr(vcpu, &vmcr); 938c2ecf20Sopenharmony_ci if (p->is_write) { 948c2ecf20Sopenharmony_ci vmcr.pmr = (p->regval & ICC_PMR_EL1_MASK) >> ICC_PMR_EL1_SHIFT; 958c2ecf20Sopenharmony_ci vgic_set_vmcr(vcpu, &vmcr); 968c2ecf20Sopenharmony_ci } else { 978c2ecf20Sopenharmony_ci p->regval = (vmcr.pmr << ICC_PMR_EL1_SHIFT) & ICC_PMR_EL1_MASK; 988c2ecf20Sopenharmony_ci } 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci return true; 1018c2ecf20Sopenharmony_ci} 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistatic bool access_gic_bpr0(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 1048c2ecf20Sopenharmony_ci const struct sys_reg_desc *r) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci struct vgic_vmcr vmcr; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci vgic_get_vmcr(vcpu, &vmcr); 1098c2ecf20Sopenharmony_ci if (p->is_write) { 1108c2ecf20Sopenharmony_ci vmcr.bpr = (p->regval & ICC_BPR0_EL1_MASK) >> 1118c2ecf20Sopenharmony_ci ICC_BPR0_EL1_SHIFT; 1128c2ecf20Sopenharmony_ci vgic_set_vmcr(vcpu, &vmcr); 1138c2ecf20Sopenharmony_ci } else { 1148c2ecf20Sopenharmony_ci p->regval = (vmcr.bpr << ICC_BPR0_EL1_SHIFT) & 1158c2ecf20Sopenharmony_ci ICC_BPR0_EL1_MASK; 1168c2ecf20Sopenharmony_ci } 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci return true; 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistatic bool access_gic_bpr1(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 1228c2ecf20Sopenharmony_ci const struct sys_reg_desc *r) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci struct vgic_vmcr vmcr; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci if (!p->is_write) 1278c2ecf20Sopenharmony_ci p->regval = 0; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci vgic_get_vmcr(vcpu, &vmcr); 1308c2ecf20Sopenharmony_ci if (!vmcr.cbpr) { 1318c2ecf20Sopenharmony_ci if (p->is_write) { 1328c2ecf20Sopenharmony_ci vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >> 1338c2ecf20Sopenharmony_ci ICC_BPR1_EL1_SHIFT; 1348c2ecf20Sopenharmony_ci vgic_set_vmcr(vcpu, &vmcr); 1358c2ecf20Sopenharmony_ci } else { 1368c2ecf20Sopenharmony_ci p->regval = (vmcr.abpr << ICC_BPR1_EL1_SHIFT) & 1378c2ecf20Sopenharmony_ci ICC_BPR1_EL1_MASK; 1388c2ecf20Sopenharmony_ci } 1398c2ecf20Sopenharmony_ci } else { 1408c2ecf20Sopenharmony_ci if (!p->is_write) 1418c2ecf20Sopenharmony_ci p->regval = min((vmcr.bpr + 1), 7U); 1428c2ecf20Sopenharmony_ci } 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci return true; 1458c2ecf20Sopenharmony_ci} 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_cistatic bool access_gic_grpen0(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 1488c2ecf20Sopenharmony_ci const struct sys_reg_desc *r) 1498c2ecf20Sopenharmony_ci{ 1508c2ecf20Sopenharmony_ci struct vgic_vmcr vmcr; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci vgic_get_vmcr(vcpu, &vmcr); 1538c2ecf20Sopenharmony_ci if (p->is_write) { 1548c2ecf20Sopenharmony_ci vmcr.grpen0 = (p->regval & ICC_IGRPEN0_EL1_MASK) >> 1558c2ecf20Sopenharmony_ci ICC_IGRPEN0_EL1_SHIFT; 1568c2ecf20Sopenharmony_ci vgic_set_vmcr(vcpu, &vmcr); 1578c2ecf20Sopenharmony_ci } else { 1588c2ecf20Sopenharmony_ci p->regval = (vmcr.grpen0 << ICC_IGRPEN0_EL1_SHIFT) & 1598c2ecf20Sopenharmony_ci ICC_IGRPEN0_EL1_MASK; 1608c2ecf20Sopenharmony_ci } 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci return true; 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cistatic bool access_gic_grpen1(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 1668c2ecf20Sopenharmony_ci const struct sys_reg_desc *r) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci struct vgic_vmcr vmcr; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci vgic_get_vmcr(vcpu, &vmcr); 1718c2ecf20Sopenharmony_ci if (p->is_write) { 1728c2ecf20Sopenharmony_ci vmcr.grpen1 = (p->regval & ICC_IGRPEN1_EL1_MASK) >> 1738c2ecf20Sopenharmony_ci ICC_IGRPEN1_EL1_SHIFT; 1748c2ecf20Sopenharmony_ci vgic_set_vmcr(vcpu, &vmcr); 1758c2ecf20Sopenharmony_ci } else { 1768c2ecf20Sopenharmony_ci p->regval = (vmcr.grpen1 << ICC_IGRPEN1_EL1_SHIFT) & 1778c2ecf20Sopenharmony_ci ICC_IGRPEN1_EL1_MASK; 1788c2ecf20Sopenharmony_ci } 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci return true; 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cistatic void vgic_v3_access_apr_reg(struct kvm_vcpu *vcpu, 1848c2ecf20Sopenharmony_ci struct sys_reg_params *p, u8 apr, u8 idx) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3; 1878c2ecf20Sopenharmony_ci uint32_t *ap_reg; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci if (apr) 1908c2ecf20Sopenharmony_ci ap_reg = &vgicv3->vgic_ap1r[idx]; 1918c2ecf20Sopenharmony_ci else 1928c2ecf20Sopenharmony_ci ap_reg = &vgicv3->vgic_ap0r[idx]; 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci if (p->is_write) 1958c2ecf20Sopenharmony_ci *ap_reg = p->regval; 1968c2ecf20Sopenharmony_ci else 1978c2ecf20Sopenharmony_ci p->regval = *ap_reg; 1988c2ecf20Sopenharmony_ci} 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_cistatic bool access_gic_aprn(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 2018c2ecf20Sopenharmony_ci const struct sys_reg_desc *r, u8 apr) 2028c2ecf20Sopenharmony_ci{ 2038c2ecf20Sopenharmony_ci u8 idx = r->Op2 & 3; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci if (idx > vgic_v3_max_apr_idx(vcpu)) 2068c2ecf20Sopenharmony_ci goto err; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci vgic_v3_access_apr_reg(vcpu, p, apr, idx); 2098c2ecf20Sopenharmony_ci return true; 2108c2ecf20Sopenharmony_cierr: 2118c2ecf20Sopenharmony_ci if (!p->is_write) 2128c2ecf20Sopenharmony_ci p->regval = 0; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci return false; 2158c2ecf20Sopenharmony_ci} 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_cistatic bool access_gic_ap0r(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 2188c2ecf20Sopenharmony_ci const struct sys_reg_desc *r) 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci{ 2218c2ecf20Sopenharmony_ci return access_gic_aprn(vcpu, p, r, 0); 2228c2ecf20Sopenharmony_ci} 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_cistatic bool access_gic_ap1r(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 2258c2ecf20Sopenharmony_ci const struct sys_reg_desc *r) 2268c2ecf20Sopenharmony_ci{ 2278c2ecf20Sopenharmony_ci return access_gic_aprn(vcpu, p, r, 1); 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cistatic bool access_gic_sre(struct kvm_vcpu *vcpu, struct sys_reg_params *p, 2318c2ecf20Sopenharmony_ci const struct sys_reg_desc *r) 2328c2ecf20Sopenharmony_ci{ 2338c2ecf20Sopenharmony_ci struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci /* Validate SRE bit */ 2368c2ecf20Sopenharmony_ci if (p->is_write) { 2378c2ecf20Sopenharmony_ci if (!(p->regval & ICC_SRE_EL1_SRE)) 2388c2ecf20Sopenharmony_ci return false; 2398c2ecf20Sopenharmony_ci } else { 2408c2ecf20Sopenharmony_ci p->regval = vgicv3->vgic_sre; 2418c2ecf20Sopenharmony_ci } 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci return true; 2448c2ecf20Sopenharmony_ci} 2458c2ecf20Sopenharmony_cistatic const struct sys_reg_desc gic_v3_icc_reg_descs[] = { 2468c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_PMR_EL1), access_gic_pmr }, 2478c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_BPR0_EL1), access_gic_bpr0 }, 2488c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_AP0R0_EL1), access_gic_ap0r }, 2498c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_AP0R1_EL1), access_gic_ap0r }, 2508c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_AP0R2_EL1), access_gic_ap0r }, 2518c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_AP0R3_EL1), access_gic_ap0r }, 2528c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_AP1R0_EL1), access_gic_ap1r }, 2538c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_AP1R1_EL1), access_gic_ap1r }, 2548c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_AP1R2_EL1), access_gic_ap1r }, 2558c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_AP1R3_EL1), access_gic_ap1r }, 2568c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_BPR1_EL1), access_gic_bpr1 }, 2578c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_CTLR_EL1), access_gic_ctlr }, 2588c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_SRE_EL1), access_gic_sre }, 2598c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_IGRPEN0_EL1), access_gic_grpen0 }, 2608c2ecf20Sopenharmony_ci { SYS_DESC(SYS_ICC_IGRPEN1_EL1), access_gic_grpen1 }, 2618c2ecf20Sopenharmony_ci}; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ciint vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id, 2648c2ecf20Sopenharmony_ci u64 *reg) 2658c2ecf20Sopenharmony_ci{ 2668c2ecf20Sopenharmony_ci struct sys_reg_params params; 2678c2ecf20Sopenharmony_ci u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64; 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci params.regval = *reg; 2708c2ecf20Sopenharmony_ci params.is_write = is_write; 2718c2ecf20Sopenharmony_ci params.is_aarch32 = false; 2728c2ecf20Sopenharmony_ci params.is_32bit = false; 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci if (find_reg_by_id(sysreg, ¶ms, gic_v3_icc_reg_descs, 2758c2ecf20Sopenharmony_ci ARRAY_SIZE(gic_v3_icc_reg_descs))) 2768c2ecf20Sopenharmony_ci return 0; 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci return -ENXIO; 2798c2ecf20Sopenharmony_ci} 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ciint vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id, 2828c2ecf20Sopenharmony_ci u64 *reg) 2838c2ecf20Sopenharmony_ci{ 2848c2ecf20Sopenharmony_ci struct sys_reg_params params; 2858c2ecf20Sopenharmony_ci const struct sys_reg_desc *r; 2868c2ecf20Sopenharmony_ci u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64; 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci if (is_write) 2898c2ecf20Sopenharmony_ci params.regval = *reg; 2908c2ecf20Sopenharmony_ci params.is_write = is_write; 2918c2ecf20Sopenharmony_ci params.is_aarch32 = false; 2928c2ecf20Sopenharmony_ci params.is_32bit = false; 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci r = find_reg_by_id(sysreg, ¶ms, gic_v3_icc_reg_descs, 2958c2ecf20Sopenharmony_ci ARRAY_SIZE(gic_v3_icc_reg_descs)); 2968c2ecf20Sopenharmony_ci if (!r) 2978c2ecf20Sopenharmony_ci return -ENXIO; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci if (!r->access(vcpu, ¶ms, r)) 3008c2ecf20Sopenharmony_ci return -EINVAL; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci if (!is_write) 3038c2ecf20Sopenharmony_ci *reg = params.regval; 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci return 0; 3068c2ecf20Sopenharmony_ci} 307