18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2015, 2016 ARM Ltd. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci#ifndef __KVM_ARM_VGIC_NEW_H__ 68c2ecf20Sopenharmony_ci#define __KVM_ARM_VGIC_NEW_H__ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/irqchip/arm-gic-common.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#define PRODUCT_ID_KVM 0x4b /* ASCII code K */ 118c2ecf20Sopenharmony_ci#define IMPLEMENTER_ARM 0x43b 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#define VGIC_ADDR_UNDEF (-1) 148c2ecf20Sopenharmony_ci#define IS_VGIC_ADDR_UNDEF(_x) ((_x) == VGIC_ADDR_UNDEF) 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define INTERRUPT_ID_BITS_SPIS 10 178c2ecf20Sopenharmony_ci#define INTERRUPT_ID_BITS_ITS 16 188c2ecf20Sopenharmony_ci#define VGIC_PRI_BITS 5 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define vgic_irq_is_sgi(intid) ((intid) < VGIC_NR_SGIS) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#define VGIC_AFFINITY_0_SHIFT 0 238c2ecf20Sopenharmony_ci#define VGIC_AFFINITY_0_MASK (0xffUL << VGIC_AFFINITY_0_SHIFT) 248c2ecf20Sopenharmony_ci#define VGIC_AFFINITY_1_SHIFT 8 258c2ecf20Sopenharmony_ci#define VGIC_AFFINITY_1_MASK (0xffUL << VGIC_AFFINITY_1_SHIFT) 268c2ecf20Sopenharmony_ci#define VGIC_AFFINITY_2_SHIFT 16 278c2ecf20Sopenharmony_ci#define VGIC_AFFINITY_2_MASK (0xffUL << VGIC_AFFINITY_2_SHIFT) 288c2ecf20Sopenharmony_ci#define VGIC_AFFINITY_3_SHIFT 24 298c2ecf20Sopenharmony_ci#define VGIC_AFFINITY_3_MASK (0xffUL << VGIC_AFFINITY_3_SHIFT) 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define VGIC_AFFINITY_LEVEL(reg, level) \ 328c2ecf20Sopenharmony_ci ((((reg) & VGIC_AFFINITY_## level ##_MASK) \ 338c2ecf20Sopenharmony_ci >> VGIC_AFFINITY_## level ##_SHIFT) << MPIDR_LEVEL_SHIFT(level)) 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/* 368c2ecf20Sopenharmony_ci * The Userspace encodes the affinity differently from the MPIDR, 378c2ecf20Sopenharmony_ci * Below macro converts vgic userspace format to MPIDR reg format. 388c2ecf20Sopenharmony_ci */ 398c2ecf20Sopenharmony_ci#define VGIC_TO_MPIDR(val) (VGIC_AFFINITY_LEVEL(val, 0) | \ 408c2ecf20Sopenharmony_ci VGIC_AFFINITY_LEVEL(val, 1) | \ 418c2ecf20Sopenharmony_ci VGIC_AFFINITY_LEVEL(val, 2) | \ 428c2ecf20Sopenharmony_ci VGIC_AFFINITY_LEVEL(val, 3)) 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* 458c2ecf20Sopenharmony_ci * As per Documentation/virt/kvm/devices/arm-vgic-v3.rst, 468c2ecf20Sopenharmony_ci * below macros are defined for CPUREG encoding. 478c2ecf20Sopenharmony_ci */ 488c2ecf20Sopenharmony_ci#define KVM_REG_ARM_VGIC_SYSREG_OP0_MASK 0x000000000000c000 498c2ecf20Sopenharmony_ci#define KVM_REG_ARM_VGIC_SYSREG_OP0_SHIFT 14 508c2ecf20Sopenharmony_ci#define KVM_REG_ARM_VGIC_SYSREG_OP1_MASK 0x0000000000003800 518c2ecf20Sopenharmony_ci#define KVM_REG_ARM_VGIC_SYSREG_OP1_SHIFT 11 528c2ecf20Sopenharmony_ci#define KVM_REG_ARM_VGIC_SYSREG_CRN_MASK 0x0000000000000780 538c2ecf20Sopenharmony_ci#define KVM_REG_ARM_VGIC_SYSREG_CRN_SHIFT 7 548c2ecf20Sopenharmony_ci#define KVM_REG_ARM_VGIC_SYSREG_CRM_MASK 0x0000000000000078 558c2ecf20Sopenharmony_ci#define KVM_REG_ARM_VGIC_SYSREG_CRM_SHIFT 3 568c2ecf20Sopenharmony_ci#define KVM_REG_ARM_VGIC_SYSREG_OP2_MASK 0x0000000000000007 578c2ecf20Sopenharmony_ci#define KVM_REG_ARM_VGIC_SYSREG_OP2_SHIFT 0 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define KVM_DEV_ARM_VGIC_SYSREG_MASK (KVM_REG_ARM_VGIC_SYSREG_OP0_MASK | \ 608c2ecf20Sopenharmony_ci KVM_REG_ARM_VGIC_SYSREG_OP1_MASK | \ 618c2ecf20Sopenharmony_ci KVM_REG_ARM_VGIC_SYSREG_CRN_MASK | \ 628c2ecf20Sopenharmony_ci KVM_REG_ARM_VGIC_SYSREG_CRM_MASK | \ 638c2ecf20Sopenharmony_ci KVM_REG_ARM_VGIC_SYSREG_OP2_MASK) 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci/* 668c2ecf20Sopenharmony_ci * As per Documentation/virt/kvm/devices/arm-vgic-its.rst, 678c2ecf20Sopenharmony_ci * below macros are defined for ITS table entry encoding. 688c2ecf20Sopenharmony_ci */ 698c2ecf20Sopenharmony_ci#define KVM_ITS_CTE_VALID_SHIFT 63 708c2ecf20Sopenharmony_ci#define KVM_ITS_CTE_VALID_MASK BIT_ULL(63) 718c2ecf20Sopenharmony_ci#define KVM_ITS_CTE_RDBASE_SHIFT 16 728c2ecf20Sopenharmony_ci#define KVM_ITS_CTE_ICID_MASK GENMASK_ULL(15, 0) 738c2ecf20Sopenharmony_ci#define KVM_ITS_ITE_NEXT_SHIFT 48 748c2ecf20Sopenharmony_ci#define KVM_ITS_ITE_PINTID_SHIFT 16 758c2ecf20Sopenharmony_ci#define KVM_ITS_ITE_PINTID_MASK GENMASK_ULL(47, 16) 768c2ecf20Sopenharmony_ci#define KVM_ITS_ITE_ICID_MASK GENMASK_ULL(15, 0) 778c2ecf20Sopenharmony_ci#define KVM_ITS_DTE_VALID_SHIFT 63 788c2ecf20Sopenharmony_ci#define KVM_ITS_DTE_VALID_MASK BIT_ULL(63) 798c2ecf20Sopenharmony_ci#define KVM_ITS_DTE_NEXT_SHIFT 49 808c2ecf20Sopenharmony_ci#define KVM_ITS_DTE_NEXT_MASK GENMASK_ULL(62, 49) 818c2ecf20Sopenharmony_ci#define KVM_ITS_DTE_ITTADDR_SHIFT 5 828c2ecf20Sopenharmony_ci#define KVM_ITS_DTE_ITTADDR_MASK GENMASK_ULL(48, 5) 838c2ecf20Sopenharmony_ci#define KVM_ITS_DTE_SIZE_MASK GENMASK_ULL(4, 0) 848c2ecf20Sopenharmony_ci#define KVM_ITS_L1E_VALID_MASK BIT_ULL(63) 858c2ecf20Sopenharmony_ci/* we only support 64 kB translation table page size */ 868c2ecf20Sopenharmony_ci#define KVM_ITS_L1E_ADDR_MASK GENMASK_ULL(51, 16) 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci#define KVM_VGIC_V3_RDIST_INDEX_MASK GENMASK_ULL(11, 0) 898c2ecf20Sopenharmony_ci#define KVM_VGIC_V3_RDIST_FLAGS_MASK GENMASK_ULL(15, 12) 908c2ecf20Sopenharmony_ci#define KVM_VGIC_V3_RDIST_FLAGS_SHIFT 12 918c2ecf20Sopenharmony_ci#define KVM_VGIC_V3_RDIST_BASE_MASK GENMASK_ULL(51, 16) 928c2ecf20Sopenharmony_ci#define KVM_VGIC_V3_RDIST_COUNT_MASK GENMASK_ULL(63, 52) 938c2ecf20Sopenharmony_ci#define KVM_VGIC_V3_RDIST_COUNT_SHIFT 52 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_SPINLOCK 968c2ecf20Sopenharmony_ci#define DEBUG_SPINLOCK_BUG_ON(p) BUG_ON(p) 978c2ecf20Sopenharmony_ci#else 988c2ecf20Sopenharmony_ci#define DEBUG_SPINLOCK_BUG_ON(p) 998c2ecf20Sopenharmony_ci#endif 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci/* Requires the irq_lock to be held by the caller. */ 1028c2ecf20Sopenharmony_cistatic inline bool irq_is_pending(struct vgic_irq *irq) 1038c2ecf20Sopenharmony_ci{ 1048c2ecf20Sopenharmony_ci if (irq->config == VGIC_CONFIG_EDGE) 1058c2ecf20Sopenharmony_ci return irq->pending_latch; 1068c2ecf20Sopenharmony_ci else 1078c2ecf20Sopenharmony_ci return irq->pending_latch || irq->line_level; 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic inline bool vgic_irq_is_mapped_level(struct vgic_irq *irq) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci return irq->config == VGIC_CONFIG_LEVEL && irq->hw; 1138c2ecf20Sopenharmony_ci} 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_cistatic inline int vgic_irq_get_lr_count(struct vgic_irq *irq) 1168c2ecf20Sopenharmony_ci{ 1178c2ecf20Sopenharmony_ci /* Account for the active state as an interrupt */ 1188c2ecf20Sopenharmony_ci if (vgic_irq_is_sgi(irq->intid) && irq->source) 1198c2ecf20Sopenharmony_ci return hweight8(irq->source) + irq->active; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci return irq_is_pending(irq) || irq->active; 1228c2ecf20Sopenharmony_ci} 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistatic inline bool vgic_irq_is_multi_sgi(struct vgic_irq *irq) 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci return vgic_irq_get_lr_count(irq) > 1; 1278c2ecf20Sopenharmony_ci} 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci/* 1308c2ecf20Sopenharmony_ci * This struct provides an intermediate representation of the fields contained 1318c2ecf20Sopenharmony_ci * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC 1328c2ecf20Sopenharmony_ci * state to userspace can generate either GICv2 or GICv3 CPU interface 1338c2ecf20Sopenharmony_ci * registers regardless of the hardware backed GIC used. 1348c2ecf20Sopenharmony_ci */ 1358c2ecf20Sopenharmony_cistruct vgic_vmcr { 1368c2ecf20Sopenharmony_ci u32 grpen0; 1378c2ecf20Sopenharmony_ci u32 grpen1; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci u32 ackctl; 1408c2ecf20Sopenharmony_ci u32 fiqen; 1418c2ecf20Sopenharmony_ci u32 cbpr; 1428c2ecf20Sopenharmony_ci u32 eoim; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci u32 abpr; 1458c2ecf20Sopenharmony_ci u32 bpr; 1468c2ecf20Sopenharmony_ci u32 pmr; /* Priority mask field in the GICC_PMR and 1478c2ecf20Sopenharmony_ci * ICC_PMR_EL1 priority field format */ 1488c2ecf20Sopenharmony_ci}; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_cistruct vgic_reg_attr { 1518c2ecf20Sopenharmony_ci struct kvm_vcpu *vcpu; 1528c2ecf20Sopenharmony_ci gpa_t addr; 1538c2ecf20Sopenharmony_ci}; 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ciint vgic_v3_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr, 1568c2ecf20Sopenharmony_ci struct vgic_reg_attr *reg_attr); 1578c2ecf20Sopenharmony_ciint vgic_v2_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr, 1588c2ecf20Sopenharmony_ci struct vgic_reg_attr *reg_attr); 1598c2ecf20Sopenharmony_ciconst struct vgic_register_region * 1608c2ecf20Sopenharmony_civgic_get_mmio_region(struct kvm_vcpu *vcpu, struct vgic_io_device *iodev, 1618c2ecf20Sopenharmony_ci gpa_t addr, int len); 1628c2ecf20Sopenharmony_cistruct vgic_irq *vgic_get_irq(struct kvm *kvm, struct kvm_vcpu *vcpu, 1638c2ecf20Sopenharmony_ci u32 intid); 1648c2ecf20Sopenharmony_civoid __vgic_put_lpi_locked(struct kvm *kvm, struct vgic_irq *irq); 1658c2ecf20Sopenharmony_civoid vgic_put_irq(struct kvm *kvm, struct vgic_irq *irq); 1668c2ecf20Sopenharmony_cibool vgic_get_phys_line_level(struct vgic_irq *irq); 1678c2ecf20Sopenharmony_civoid vgic_irq_set_phys_pending(struct vgic_irq *irq, bool pending); 1688c2ecf20Sopenharmony_civoid vgic_irq_set_phys_active(struct vgic_irq *irq, bool active); 1698c2ecf20Sopenharmony_cibool vgic_queue_irq_unlock(struct kvm *kvm, struct vgic_irq *irq, 1708c2ecf20Sopenharmony_ci unsigned long flags); 1718c2ecf20Sopenharmony_civoid vgic_kick_vcpus(struct kvm *kvm); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ciint vgic_check_ioaddr(struct kvm *kvm, phys_addr_t *ioaddr, 1748c2ecf20Sopenharmony_ci phys_addr_t addr, phys_addr_t alignment); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_civoid vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu); 1778c2ecf20Sopenharmony_civoid vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr); 1788c2ecf20Sopenharmony_civoid vgic_v2_clear_lr(struct kvm_vcpu *vcpu, int lr); 1798c2ecf20Sopenharmony_civoid vgic_v2_set_underflow(struct kvm_vcpu *vcpu); 1808c2ecf20Sopenharmony_civoid vgic_v2_set_npie(struct kvm_vcpu *vcpu); 1818c2ecf20Sopenharmony_ciint vgic_v2_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr); 1828c2ecf20Sopenharmony_ciint vgic_v2_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write, 1838c2ecf20Sopenharmony_ci int offset, u32 *val); 1848c2ecf20Sopenharmony_ciint vgic_v2_cpuif_uaccess(struct kvm_vcpu *vcpu, bool is_write, 1858c2ecf20Sopenharmony_ci int offset, u32 *val); 1868c2ecf20Sopenharmony_civoid vgic_v2_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); 1878c2ecf20Sopenharmony_civoid vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); 1888c2ecf20Sopenharmony_civoid vgic_v2_enable(struct kvm_vcpu *vcpu); 1898c2ecf20Sopenharmony_ciint vgic_v2_probe(const struct gic_kvm_info *info); 1908c2ecf20Sopenharmony_ciint vgic_v2_map_resources(struct kvm *kvm); 1918c2ecf20Sopenharmony_ciint vgic_register_dist_iodev(struct kvm *kvm, gpa_t dist_base_address, 1928c2ecf20Sopenharmony_ci enum vgic_type); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_civoid vgic_v2_init_lrs(void); 1958c2ecf20Sopenharmony_civoid vgic_v2_load(struct kvm_vcpu *vcpu); 1968c2ecf20Sopenharmony_civoid vgic_v2_put(struct kvm_vcpu *vcpu); 1978c2ecf20Sopenharmony_civoid vgic_v2_vmcr_sync(struct kvm_vcpu *vcpu); 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_civoid vgic_v2_save_state(struct kvm_vcpu *vcpu); 2008c2ecf20Sopenharmony_civoid vgic_v2_restore_state(struct kvm_vcpu *vcpu); 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cistatic inline void vgic_get_irq_kref(struct vgic_irq *irq) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci if (irq->intid < VGIC_MIN_LPI) 2058c2ecf20Sopenharmony_ci return; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci kref_get(&irq->refcount); 2088c2ecf20Sopenharmony_ci} 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_civoid vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu); 2118c2ecf20Sopenharmony_civoid vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr); 2128c2ecf20Sopenharmony_civoid vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr); 2138c2ecf20Sopenharmony_civoid vgic_v3_set_underflow(struct kvm_vcpu *vcpu); 2148c2ecf20Sopenharmony_civoid vgic_v3_set_npie(struct kvm_vcpu *vcpu); 2158c2ecf20Sopenharmony_civoid vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); 2168c2ecf20Sopenharmony_civoid vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); 2178c2ecf20Sopenharmony_civoid vgic_v3_enable(struct kvm_vcpu *vcpu); 2188c2ecf20Sopenharmony_ciint vgic_v3_probe(const struct gic_kvm_info *info); 2198c2ecf20Sopenharmony_ciint vgic_v3_map_resources(struct kvm *kvm); 2208c2ecf20Sopenharmony_ciint vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq); 2218c2ecf20Sopenharmony_ciint vgic_v3_save_pending_tables(struct kvm *kvm); 2228c2ecf20Sopenharmony_ciint vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count); 2238c2ecf20Sopenharmony_ciint vgic_register_redist_iodev(struct kvm_vcpu *vcpu); 2248c2ecf20Sopenharmony_cibool vgic_v3_check_base(struct kvm *kvm); 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_civoid vgic_v3_load(struct kvm_vcpu *vcpu); 2278c2ecf20Sopenharmony_civoid vgic_v3_put(struct kvm_vcpu *vcpu); 2288c2ecf20Sopenharmony_civoid vgic_v3_vmcr_sync(struct kvm_vcpu *vcpu); 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cibool vgic_has_its(struct kvm *kvm); 2318c2ecf20Sopenharmony_ciint kvm_vgic_register_its_device(void); 2328c2ecf20Sopenharmony_civoid vgic_enable_lpis(struct kvm_vcpu *vcpu); 2338c2ecf20Sopenharmony_civoid vgic_flush_pending_lpis(struct kvm_vcpu *vcpu); 2348c2ecf20Sopenharmony_ciint vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi); 2358c2ecf20Sopenharmony_ciint vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr); 2368c2ecf20Sopenharmony_ciint vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write, 2378c2ecf20Sopenharmony_ci int offset, u32 *val); 2388c2ecf20Sopenharmony_ciint vgic_v3_redist_uaccess(struct kvm_vcpu *vcpu, bool is_write, 2398c2ecf20Sopenharmony_ci int offset, u32 *val); 2408c2ecf20Sopenharmony_ciint vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, 2418c2ecf20Sopenharmony_ci u64 id, u64 *val); 2428c2ecf20Sopenharmony_ciint vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id, 2438c2ecf20Sopenharmony_ci u64 *reg); 2448c2ecf20Sopenharmony_ciint vgic_v3_line_level_info_uaccess(struct kvm_vcpu *vcpu, bool is_write, 2458c2ecf20Sopenharmony_ci u32 intid, u64 *val); 2468c2ecf20Sopenharmony_ciint kvm_register_vgic_device(unsigned long type); 2478c2ecf20Sopenharmony_civoid vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); 2488c2ecf20Sopenharmony_civoid vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); 2498c2ecf20Sopenharmony_ciint vgic_lazy_init(struct kvm *kvm); 2508c2ecf20Sopenharmony_ciint vgic_init(struct kvm *kvm); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_civoid vgic_debug_init(struct kvm *kvm); 2538c2ecf20Sopenharmony_civoid vgic_debug_destroy(struct kvm *kvm); 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_cibool lock_all_vcpus(struct kvm *kvm); 2568c2ecf20Sopenharmony_civoid unlock_all_vcpus(struct kvm *kvm); 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_cistatic inline int vgic_v3_max_apr_idx(struct kvm_vcpu *vcpu) 2598c2ecf20Sopenharmony_ci{ 2608c2ecf20Sopenharmony_ci struct vgic_cpu *cpu_if = &vcpu->arch.vgic_cpu; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci /* 2638c2ecf20Sopenharmony_ci * num_pri_bits are initialized with HW supported values. 2648c2ecf20Sopenharmony_ci * We can rely safely on num_pri_bits even if VM has not 2658c2ecf20Sopenharmony_ci * restored ICC_CTLR_EL1 before restoring APnR registers. 2668c2ecf20Sopenharmony_ci */ 2678c2ecf20Sopenharmony_ci switch (cpu_if->num_pri_bits) { 2688c2ecf20Sopenharmony_ci case 7: return 3; 2698c2ecf20Sopenharmony_ci case 6: return 1; 2708c2ecf20Sopenharmony_ci default: return 0; 2718c2ecf20Sopenharmony_ci } 2728c2ecf20Sopenharmony_ci} 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_cistatic inline bool 2758c2ecf20Sopenharmony_civgic_v3_redist_region_full(struct vgic_redist_region *region) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci if (!region->count) 2788c2ecf20Sopenharmony_ci return false; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci return (region->free_index >= region->count); 2818c2ecf20Sopenharmony_ci} 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistruct vgic_redist_region *vgic_v3_rdist_free_slot(struct list_head *rdregs); 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_cistatic inline size_t 2868c2ecf20Sopenharmony_civgic_v3_rd_region_size(struct kvm *kvm, struct vgic_redist_region *rdreg) 2878c2ecf20Sopenharmony_ci{ 2888c2ecf20Sopenharmony_ci if (!rdreg->count) 2898c2ecf20Sopenharmony_ci return atomic_read(&kvm->online_vcpus) * KVM_VGIC_V3_REDIST_SIZE; 2908c2ecf20Sopenharmony_ci else 2918c2ecf20Sopenharmony_ci return rdreg->count * KVM_VGIC_V3_REDIST_SIZE; 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_cistruct vgic_redist_region *vgic_v3_rdist_region_from_index(struct kvm *kvm, 2958c2ecf20Sopenharmony_ci u32 index); 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_cibool vgic_v3_rdist_overlap(struct kvm *kvm, gpa_t base, size_t size); 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_cistatic inline bool vgic_dist_overlap(struct kvm *kvm, gpa_t base, size_t size) 3008c2ecf20Sopenharmony_ci{ 3018c2ecf20Sopenharmony_ci struct vgic_dist *d = &kvm->arch.vgic; 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci return (base + size > d->vgic_dist_base) && 3048c2ecf20Sopenharmony_ci (base < d->vgic_dist_base + KVM_VGIC_V3_DIST_SIZE); 3058c2ecf20Sopenharmony_ci} 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ciint vgic_copy_lpi_list(struct kvm *kvm, struct kvm_vcpu *vcpu, u32 **intid_ptr); 3088c2ecf20Sopenharmony_ciint vgic_its_resolve_lpi(struct kvm *kvm, struct vgic_its *its, 3098c2ecf20Sopenharmony_ci u32 devid, u32 eventid, struct vgic_irq **irq); 3108c2ecf20Sopenharmony_cistruct vgic_its *vgic_msi_to_its(struct kvm *kvm, struct kvm_msi *msi); 3118c2ecf20Sopenharmony_ciint vgic_its_inject_cached_translation(struct kvm *kvm, struct kvm_msi *msi); 3128c2ecf20Sopenharmony_civoid vgic_lpi_translation_cache_init(struct kvm *kvm); 3138c2ecf20Sopenharmony_civoid vgic_lpi_translation_cache_destroy(struct kvm *kvm); 3148c2ecf20Sopenharmony_civoid vgic_its_invalidate_cache(struct kvm *kvm); 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_cibool vgic_supports_direct_msis(struct kvm *kvm); 3178c2ecf20Sopenharmony_ciint vgic_v4_init(struct kvm *kvm); 3188c2ecf20Sopenharmony_civoid vgic_v4_teardown(struct kvm *kvm); 3198c2ecf20Sopenharmony_civoid vgic_v4_configure_vsgis(struct kvm *kvm); 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_cistatic inline bool kvm_has_gicv3(struct kvm *kvm) 3228c2ecf20Sopenharmony_ci{ 3238c2ecf20Sopenharmony_ci return (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) && 3248c2ecf20Sopenharmony_ci irqchip_in_kernel(kvm) && 3258c2ecf20Sopenharmony_ci kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3); 3268c2ecf20Sopenharmony_ci} 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci#endif 329