162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2015, 2016 ARM Ltd. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci#ifndef __KVM_ARM_VGIC_H 662306a36Sopenharmony_ci#define __KVM_ARM_VGIC_H 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/bits.h> 962306a36Sopenharmony_ci#include <linux/kvm.h> 1062306a36Sopenharmony_ci#include <linux/irqreturn.h> 1162306a36Sopenharmony_ci#include <linux/kref.h> 1262306a36Sopenharmony_ci#include <linux/mutex.h> 1362306a36Sopenharmony_ci#include <linux/spinlock.h> 1462306a36Sopenharmony_ci#include <linux/static_key.h> 1562306a36Sopenharmony_ci#include <linux/types.h> 1662306a36Sopenharmony_ci#include <kvm/iodev.h> 1762306a36Sopenharmony_ci#include <linux/list.h> 1862306a36Sopenharmony_ci#include <linux/jump_label.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#include <linux/irqchip/arm-gic-v4.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#define VGIC_V3_MAX_CPUS 512 2362306a36Sopenharmony_ci#define VGIC_V2_MAX_CPUS 8 2462306a36Sopenharmony_ci#define VGIC_NR_IRQS_LEGACY 256 2562306a36Sopenharmony_ci#define VGIC_NR_SGIS 16 2662306a36Sopenharmony_ci#define VGIC_NR_PPIS 16 2762306a36Sopenharmony_ci#define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS) 2862306a36Sopenharmony_ci#define VGIC_MAX_PRIVATE (VGIC_NR_PRIVATE_IRQS - 1) 2962306a36Sopenharmony_ci#define VGIC_MAX_SPI 1019 3062306a36Sopenharmony_ci#define VGIC_MAX_RESERVED 1023 3162306a36Sopenharmony_ci#define VGIC_MIN_LPI 8192 3262306a36Sopenharmony_ci#define KVM_IRQCHIP_NUM_PINS (1020 - 32) 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define irq_is_ppi(irq) ((irq) >= VGIC_NR_SGIS && (irq) < VGIC_NR_PRIVATE_IRQS) 3562306a36Sopenharmony_ci#define irq_is_spi(irq) ((irq) >= VGIC_NR_PRIVATE_IRQS && \ 3662306a36Sopenharmony_ci (irq) <= VGIC_MAX_SPI) 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_cienum vgic_type { 3962306a36Sopenharmony_ci VGIC_V2, /* Good ol' GICv2 */ 4062306a36Sopenharmony_ci VGIC_V3, /* New fancy GICv3 */ 4162306a36Sopenharmony_ci}; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/* same for all guests, as depending only on the _host's_ GIC model */ 4462306a36Sopenharmony_cistruct vgic_global { 4562306a36Sopenharmony_ci /* type of the host GIC */ 4662306a36Sopenharmony_ci enum vgic_type type; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci /* Physical address of vgic virtual cpu interface */ 4962306a36Sopenharmony_ci phys_addr_t vcpu_base; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci /* GICV mapping, kernel VA */ 5262306a36Sopenharmony_ci void __iomem *vcpu_base_va; 5362306a36Sopenharmony_ci /* GICV mapping, HYP VA */ 5462306a36Sopenharmony_ci void __iomem *vcpu_hyp_va; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci /* virtual control interface mapping, kernel VA */ 5762306a36Sopenharmony_ci void __iomem *vctrl_base; 5862306a36Sopenharmony_ci /* virtual control interface mapping, HYP VA */ 5962306a36Sopenharmony_ci void __iomem *vctrl_hyp; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci /* Number of implemented list registers */ 6262306a36Sopenharmony_ci int nr_lr; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci /* Maintenance IRQ number */ 6562306a36Sopenharmony_ci unsigned int maint_irq; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci /* maximum number of VCPUs allowed (GICv2 limits us to 8) */ 6862306a36Sopenharmony_ci int max_gic_vcpus; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci /* Only needed for the legacy KVM_CREATE_IRQCHIP */ 7162306a36Sopenharmony_ci bool can_emulate_gicv2; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci /* Hardware has GICv4? */ 7462306a36Sopenharmony_ci bool has_gicv4; 7562306a36Sopenharmony_ci bool has_gicv4_1; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci /* Pseudo GICv3 from outer space */ 7862306a36Sopenharmony_ci bool no_hw_deactivation; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci /* GIC system register CPU interface */ 8162306a36Sopenharmony_ci struct static_key_false gicv3_cpuif; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci u32 ich_vtr_el2; 8462306a36Sopenharmony_ci}; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ciextern struct vgic_global kvm_vgic_global_state; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci#define VGIC_V2_MAX_LRS (1 << 6) 8962306a36Sopenharmony_ci#define VGIC_V3_MAX_LRS 16 9062306a36Sopenharmony_ci#define VGIC_V3_LR_INDEX(lr) (VGIC_V3_MAX_LRS - 1 - lr) 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cienum vgic_irq_config { 9362306a36Sopenharmony_ci VGIC_CONFIG_EDGE = 0, 9462306a36Sopenharmony_ci VGIC_CONFIG_LEVEL 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci/* 9862306a36Sopenharmony_ci * Per-irq ops overriding some common behavious. 9962306a36Sopenharmony_ci * 10062306a36Sopenharmony_ci * Always called in non-preemptible section and the functions can use 10162306a36Sopenharmony_ci * kvm_arm_get_running_vcpu() to get the vcpu pointer for private IRQs. 10262306a36Sopenharmony_ci */ 10362306a36Sopenharmony_cistruct irq_ops { 10462306a36Sopenharmony_ci /* Per interrupt flags for special-cased interrupts */ 10562306a36Sopenharmony_ci unsigned long flags; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci#define VGIC_IRQ_SW_RESAMPLE BIT(0) /* Clear the active state for resampling */ 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci /* 11062306a36Sopenharmony_ci * Callback function pointer to in-kernel devices that can tell us the 11162306a36Sopenharmony_ci * state of the input level of mapped level-triggered IRQ faster than 11262306a36Sopenharmony_ci * peaking into the physical GIC. 11362306a36Sopenharmony_ci */ 11462306a36Sopenharmony_ci bool (*get_input_level)(int vintid); 11562306a36Sopenharmony_ci}; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistruct vgic_irq { 11862306a36Sopenharmony_ci raw_spinlock_t irq_lock; /* Protects the content of the struct */ 11962306a36Sopenharmony_ci struct list_head lpi_list; /* Used to link all LPIs together */ 12062306a36Sopenharmony_ci struct list_head ap_list; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci struct kvm_vcpu *vcpu; /* SGIs and PPIs: The VCPU 12362306a36Sopenharmony_ci * SPIs and LPIs: The VCPU whose ap_list 12462306a36Sopenharmony_ci * this is queued on. 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci struct kvm_vcpu *target_vcpu; /* The VCPU that this interrupt should 12862306a36Sopenharmony_ci * be sent to, as a result of the 12962306a36Sopenharmony_ci * targets reg (v2) or the 13062306a36Sopenharmony_ci * affinity reg (v3). 13162306a36Sopenharmony_ci */ 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci u32 intid; /* Guest visible INTID */ 13462306a36Sopenharmony_ci bool line_level; /* Level only */ 13562306a36Sopenharmony_ci bool pending_latch; /* The pending latch state used to calculate 13662306a36Sopenharmony_ci * the pending state for both level 13762306a36Sopenharmony_ci * and edge triggered IRQs. */ 13862306a36Sopenharmony_ci bool active; /* not used for LPIs */ 13962306a36Sopenharmony_ci bool enabled; 14062306a36Sopenharmony_ci bool hw; /* Tied to HW IRQ */ 14162306a36Sopenharmony_ci struct kref refcount; /* Used for LPIs */ 14262306a36Sopenharmony_ci u32 hwintid; /* HW INTID number */ 14362306a36Sopenharmony_ci unsigned int host_irq; /* linux irq corresponding to hwintid */ 14462306a36Sopenharmony_ci union { 14562306a36Sopenharmony_ci u8 targets; /* GICv2 target VCPUs mask */ 14662306a36Sopenharmony_ci u32 mpidr; /* GICv3 target VCPU */ 14762306a36Sopenharmony_ci }; 14862306a36Sopenharmony_ci u8 source; /* GICv2 SGIs only */ 14962306a36Sopenharmony_ci u8 active_source; /* GICv2 SGIs only */ 15062306a36Sopenharmony_ci u8 priority; 15162306a36Sopenharmony_ci u8 group; /* 0 == group 0, 1 == group 1 */ 15262306a36Sopenharmony_ci enum vgic_irq_config config; /* Level or edge */ 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci struct irq_ops *ops; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci void *owner; /* Opaque pointer to reserve an interrupt 15762306a36Sopenharmony_ci for in-kernel devices. */ 15862306a36Sopenharmony_ci}; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_cistatic inline bool vgic_irq_needs_resampling(struct vgic_irq *irq) 16162306a36Sopenharmony_ci{ 16262306a36Sopenharmony_ci return irq->ops && (irq->ops->flags & VGIC_IRQ_SW_RESAMPLE); 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistruct vgic_register_region; 16662306a36Sopenharmony_cistruct vgic_its; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_cienum iodev_type { 16962306a36Sopenharmony_ci IODEV_CPUIF, 17062306a36Sopenharmony_ci IODEV_DIST, 17162306a36Sopenharmony_ci IODEV_REDIST, 17262306a36Sopenharmony_ci IODEV_ITS 17362306a36Sopenharmony_ci}; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_cistruct vgic_io_device { 17662306a36Sopenharmony_ci gpa_t base_addr; 17762306a36Sopenharmony_ci union { 17862306a36Sopenharmony_ci struct kvm_vcpu *redist_vcpu; 17962306a36Sopenharmony_ci struct vgic_its *its; 18062306a36Sopenharmony_ci }; 18162306a36Sopenharmony_ci const struct vgic_register_region *regions; 18262306a36Sopenharmony_ci enum iodev_type iodev_type; 18362306a36Sopenharmony_ci int nr_regions; 18462306a36Sopenharmony_ci struct kvm_io_device dev; 18562306a36Sopenharmony_ci}; 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_cistruct vgic_its { 18862306a36Sopenharmony_ci /* The base address of the ITS control register frame */ 18962306a36Sopenharmony_ci gpa_t vgic_its_base; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci bool enabled; 19262306a36Sopenharmony_ci struct vgic_io_device iodev; 19362306a36Sopenharmony_ci struct kvm_device *dev; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci /* These registers correspond to GITS_BASER{0,1} */ 19662306a36Sopenharmony_ci u64 baser_device_table; 19762306a36Sopenharmony_ci u64 baser_coll_table; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci /* Protects the command queue */ 20062306a36Sopenharmony_ci struct mutex cmd_lock; 20162306a36Sopenharmony_ci u64 cbaser; 20262306a36Sopenharmony_ci u32 creadr; 20362306a36Sopenharmony_ci u32 cwriter; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci /* migration ABI revision in use */ 20662306a36Sopenharmony_ci u32 abi_rev; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci /* Protects the device and collection lists */ 20962306a36Sopenharmony_ci struct mutex its_lock; 21062306a36Sopenharmony_ci struct list_head device_list; 21162306a36Sopenharmony_ci struct list_head collection_list; 21262306a36Sopenharmony_ci}; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_cistruct vgic_state_iter; 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_cistruct vgic_redist_region { 21762306a36Sopenharmony_ci u32 index; 21862306a36Sopenharmony_ci gpa_t base; 21962306a36Sopenharmony_ci u32 count; /* number of redistributors or 0 if single region */ 22062306a36Sopenharmony_ci u32 free_index; /* index of the next free redistributor */ 22162306a36Sopenharmony_ci struct list_head list; 22262306a36Sopenharmony_ci}; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_cistruct vgic_dist { 22562306a36Sopenharmony_ci bool in_kernel; 22662306a36Sopenharmony_ci bool ready; 22762306a36Sopenharmony_ci bool initialized; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci /* vGIC model the kernel emulates for the guest (GICv2 or GICv3) */ 23062306a36Sopenharmony_ci u32 vgic_model; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci /* Implementation revision as reported in the GICD_IIDR */ 23362306a36Sopenharmony_ci u32 implementation_rev; 23462306a36Sopenharmony_ci#define KVM_VGIC_IMP_REV_2 2 /* GICv2 restorable groups */ 23562306a36Sopenharmony_ci#define KVM_VGIC_IMP_REV_3 3 /* GICv3 GICR_CTLR.{IW,CES,RWP} */ 23662306a36Sopenharmony_ci#define KVM_VGIC_IMP_REV_LATEST KVM_VGIC_IMP_REV_3 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci /* Userspace can write to GICv2 IGROUPR */ 23962306a36Sopenharmony_ci bool v2_groups_user_writable; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci /* Do injected MSIs require an additional device ID? */ 24262306a36Sopenharmony_ci bool msis_require_devid; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci int nr_spis; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci /* base addresses in guest physical address space: */ 24762306a36Sopenharmony_ci gpa_t vgic_dist_base; /* distributor */ 24862306a36Sopenharmony_ci union { 24962306a36Sopenharmony_ci /* either a GICv2 CPU interface */ 25062306a36Sopenharmony_ci gpa_t vgic_cpu_base; 25162306a36Sopenharmony_ci /* or a number of GICv3 redistributor regions */ 25262306a36Sopenharmony_ci struct list_head rd_regions; 25362306a36Sopenharmony_ci }; 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci /* distributor enabled */ 25662306a36Sopenharmony_ci bool enabled; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci /* Wants SGIs without active state */ 25962306a36Sopenharmony_ci bool nassgireq; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci struct vgic_irq *spis; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci struct vgic_io_device dist_iodev; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci bool has_its; 26662306a36Sopenharmony_ci bool table_write_in_progress; 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci /* 26962306a36Sopenharmony_ci * Contains the attributes and gpa of the LPI configuration table. 27062306a36Sopenharmony_ci * Since we report GICR_TYPER.CommonLPIAff as 0b00, we can share 27162306a36Sopenharmony_ci * one address across all redistributors. 27262306a36Sopenharmony_ci * GICv3 spec: IHI 0069E 6.1.1 "LPI Configuration tables" 27362306a36Sopenharmony_ci */ 27462306a36Sopenharmony_ci u64 propbaser; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci /* Protects the lpi_list and the count value below. */ 27762306a36Sopenharmony_ci raw_spinlock_t lpi_list_lock; 27862306a36Sopenharmony_ci struct list_head lpi_list_head; 27962306a36Sopenharmony_ci int lpi_list_count; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci /* LPI translation cache */ 28262306a36Sopenharmony_ci struct list_head lpi_translation_cache; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci /* used by vgic-debug */ 28562306a36Sopenharmony_ci struct vgic_state_iter *iter; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci /* 28862306a36Sopenharmony_ci * GICv4 ITS per-VM data, containing the IRQ domain, the VPE 28962306a36Sopenharmony_ci * array, the property table pointer as well as allocation 29062306a36Sopenharmony_ci * data. This essentially ties the Linux IRQ core and ITS 29162306a36Sopenharmony_ci * together, and avoids leaking KVM's data structures anywhere 29262306a36Sopenharmony_ci * else. 29362306a36Sopenharmony_ci */ 29462306a36Sopenharmony_ci struct its_vm its_vm; 29562306a36Sopenharmony_ci}; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_cistruct vgic_v2_cpu_if { 29862306a36Sopenharmony_ci u32 vgic_hcr; 29962306a36Sopenharmony_ci u32 vgic_vmcr; 30062306a36Sopenharmony_ci u32 vgic_apr; 30162306a36Sopenharmony_ci u32 vgic_lr[VGIC_V2_MAX_LRS]; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci unsigned int used_lrs; 30462306a36Sopenharmony_ci}; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_cistruct vgic_v3_cpu_if { 30762306a36Sopenharmony_ci u32 vgic_hcr; 30862306a36Sopenharmony_ci u32 vgic_vmcr; 30962306a36Sopenharmony_ci u32 vgic_sre; /* Restored only, change ignored */ 31062306a36Sopenharmony_ci u32 vgic_ap0r[4]; 31162306a36Sopenharmony_ci u32 vgic_ap1r[4]; 31262306a36Sopenharmony_ci u64 vgic_lr[VGIC_V3_MAX_LRS]; 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci /* 31562306a36Sopenharmony_ci * GICv4 ITS per-VPE data, containing the doorbell IRQ, the 31662306a36Sopenharmony_ci * pending table pointer, the its_vm pointer and a few other 31762306a36Sopenharmony_ci * HW specific things. As for the its_vm structure, this is 31862306a36Sopenharmony_ci * linking the Linux IRQ subsystem and the ITS together. 31962306a36Sopenharmony_ci */ 32062306a36Sopenharmony_ci struct its_vpe its_vpe; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci unsigned int used_lrs; 32362306a36Sopenharmony_ci}; 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_cistruct vgic_cpu { 32662306a36Sopenharmony_ci /* CPU vif control registers for world switch */ 32762306a36Sopenharmony_ci union { 32862306a36Sopenharmony_ci struct vgic_v2_cpu_if vgic_v2; 32962306a36Sopenharmony_ci struct vgic_v3_cpu_if vgic_v3; 33062306a36Sopenharmony_ci }; 33162306a36Sopenharmony_ci 33262306a36Sopenharmony_ci struct vgic_irq private_irqs[VGIC_NR_PRIVATE_IRQS]; 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci raw_spinlock_t ap_list_lock; /* Protects the ap_list */ 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci /* 33762306a36Sopenharmony_ci * List of IRQs that this VCPU should consider because they are either 33862306a36Sopenharmony_ci * Active or Pending (hence the name; AP list), or because they recently 33962306a36Sopenharmony_ci * were one of the two and need to be migrated off this list to another 34062306a36Sopenharmony_ci * VCPU. 34162306a36Sopenharmony_ci */ 34262306a36Sopenharmony_ci struct list_head ap_list_head; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci /* 34562306a36Sopenharmony_ci * Members below are used with GICv3 emulation only and represent 34662306a36Sopenharmony_ci * parts of the redistributor. 34762306a36Sopenharmony_ci */ 34862306a36Sopenharmony_ci struct vgic_io_device rd_iodev; 34962306a36Sopenharmony_ci struct vgic_redist_region *rdreg; 35062306a36Sopenharmony_ci u32 rdreg_index; 35162306a36Sopenharmony_ci atomic_t syncr_busy; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci /* Contains the attributes and gpa of the LPI pending tables. */ 35462306a36Sopenharmony_ci u64 pendbaser; 35562306a36Sopenharmony_ci /* GICR_CTLR.{ENABLE_LPIS,RWP} */ 35662306a36Sopenharmony_ci atomic_t ctlr; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci /* Cache guest priority bits */ 35962306a36Sopenharmony_ci u32 num_pri_bits; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci /* Cache guest interrupt ID bits */ 36262306a36Sopenharmony_ci u32 num_id_bits; 36362306a36Sopenharmony_ci}; 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ciextern struct static_key_false vgic_v2_cpuif_trap; 36662306a36Sopenharmony_ciextern struct static_key_false vgic_v3_cpuif_trap; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ciint kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev_addr); 36962306a36Sopenharmony_civoid kvm_vgic_early_init(struct kvm *kvm); 37062306a36Sopenharmony_ciint kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu); 37162306a36Sopenharmony_ciint kvm_vgic_create(struct kvm *kvm, u32 type); 37262306a36Sopenharmony_civoid kvm_vgic_destroy(struct kvm *kvm); 37362306a36Sopenharmony_civoid kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu); 37462306a36Sopenharmony_ciint kvm_vgic_map_resources(struct kvm *kvm); 37562306a36Sopenharmony_ciint kvm_vgic_hyp_init(void); 37662306a36Sopenharmony_civoid kvm_vgic_init_cpu_hardware(void); 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ciint kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid, 37962306a36Sopenharmony_ci bool level, void *owner); 38062306a36Sopenharmony_ciint kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq, 38162306a36Sopenharmony_ci u32 vintid, struct irq_ops *ops); 38262306a36Sopenharmony_ciint kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid); 38362306a36Sopenharmony_ciint kvm_vgic_get_map(struct kvm_vcpu *vcpu, unsigned int vintid); 38462306a36Sopenharmony_cibool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid); 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ciint kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_civoid kvm_vgic_load(struct kvm_vcpu *vcpu); 38962306a36Sopenharmony_civoid kvm_vgic_put(struct kvm_vcpu *vcpu); 39062306a36Sopenharmony_civoid kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci#define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) 39362306a36Sopenharmony_ci#define vgic_initialized(k) ((k)->arch.vgic.initialized) 39462306a36Sopenharmony_ci#define vgic_ready(k) ((k)->arch.vgic.ready) 39562306a36Sopenharmony_ci#define vgic_valid_spi(k, i) (((i) >= VGIC_NR_PRIVATE_IRQS) && \ 39662306a36Sopenharmony_ci ((i) < (k)->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)) 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_cibool kvm_vcpu_has_pending_irqs(struct kvm_vcpu *vcpu); 39962306a36Sopenharmony_civoid kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu); 40062306a36Sopenharmony_civoid kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu); 40162306a36Sopenharmony_civoid kvm_vgic_reset_mapped_irq(struct kvm_vcpu *vcpu, u32 vintid); 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_civoid vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg, bool allow_group1); 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci/** 40662306a36Sopenharmony_ci * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW 40762306a36Sopenharmony_ci * 40862306a36Sopenharmony_ci * The host's GIC naturally limits the maximum amount of VCPUs a guest 40962306a36Sopenharmony_ci * can use. 41062306a36Sopenharmony_ci */ 41162306a36Sopenharmony_cistatic inline int kvm_vgic_get_max_vcpus(void) 41262306a36Sopenharmony_ci{ 41362306a36Sopenharmony_ci return kvm_vgic_global_state.max_gic_vcpus; 41462306a36Sopenharmony_ci} 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci/** 41762306a36Sopenharmony_ci * kvm_vgic_setup_default_irq_routing: 41862306a36Sopenharmony_ci * Setup a default flat gsi routing table mapping all SPIs 41962306a36Sopenharmony_ci */ 42062306a36Sopenharmony_ciint kvm_vgic_setup_default_irq_routing(struct kvm *kvm); 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ciint kvm_vgic_set_owner(struct kvm_vcpu *vcpu, unsigned int intid, void *owner); 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cistruct kvm_kernel_irq_routing_entry; 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ciint kvm_vgic_v4_set_forwarding(struct kvm *kvm, int irq, 42762306a36Sopenharmony_ci struct kvm_kernel_irq_routing_entry *irq_entry); 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ciint kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int irq, 43062306a36Sopenharmony_ci struct kvm_kernel_irq_routing_entry *irq_entry); 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ciint vgic_v4_load(struct kvm_vcpu *vcpu); 43362306a36Sopenharmony_civoid vgic_v4_commit(struct kvm_vcpu *vcpu); 43462306a36Sopenharmony_ciint vgic_v4_put(struct kvm_vcpu *vcpu); 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci/* CPU HP callbacks */ 43762306a36Sopenharmony_civoid kvm_vgic_cpu_up(void); 43862306a36Sopenharmony_civoid kvm_vgic_cpu_down(void); 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci#endif /* __KVM_ARM_VGIC_H */ 441