1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2016,2017 ARM Limited, All Rights Reserved. 4*4882a593Smuzhiyun * Author: Marc Zyngier <marc.zyngier@arm.com> 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #ifndef __LINUX_IRQCHIP_ARM_GIC_V4_H 8*4882a593Smuzhiyun #define __LINUX_IRQCHIP_ARM_GIC_V4_H 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun struct its_vpe; 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun /* 13*4882a593Smuzhiyun * Maximum number of ITTs when GITS_TYPER.VMOVP == 0, using the 14*4882a593Smuzhiyun * ITSList mechanism to perform inter-ITS synchronization. 15*4882a593Smuzhiyun */ 16*4882a593Smuzhiyun #define GICv4_ITS_LIST_MAX 16 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun /* Embedded in kvm.arch */ 19*4882a593Smuzhiyun struct its_vm { 20*4882a593Smuzhiyun struct fwnode_handle *fwnode; 21*4882a593Smuzhiyun struct irq_domain *domain; 22*4882a593Smuzhiyun struct page *vprop_page; 23*4882a593Smuzhiyun struct its_vpe **vpes; 24*4882a593Smuzhiyun int nr_vpes; 25*4882a593Smuzhiyun irq_hw_number_t db_lpi_base; 26*4882a593Smuzhiyun unsigned long *db_bitmap; 27*4882a593Smuzhiyun int nr_db_lpis; 28*4882a593Smuzhiyun u32 vlpi_count[GICv4_ITS_LIST_MAX]; 29*4882a593Smuzhiyun }; 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun /* Embedded in kvm_vcpu.arch */ 32*4882a593Smuzhiyun struct its_vpe { 33*4882a593Smuzhiyun struct page *vpt_page; 34*4882a593Smuzhiyun struct its_vm *its_vm; 35*4882a593Smuzhiyun /* per-vPE VLPI tracking */ 36*4882a593Smuzhiyun atomic_t vlpi_count; 37*4882a593Smuzhiyun /* Doorbell interrupt */ 38*4882a593Smuzhiyun int irq; 39*4882a593Smuzhiyun irq_hw_number_t vpe_db_lpi; 40*4882a593Smuzhiyun /* VPE resident */ 41*4882a593Smuzhiyun bool resident; 42*4882a593Smuzhiyun /* VPT parse complete */ 43*4882a593Smuzhiyun bool ready; 44*4882a593Smuzhiyun union { 45*4882a593Smuzhiyun /* GICv4.0 implementations */ 46*4882a593Smuzhiyun struct { 47*4882a593Smuzhiyun /* VPE proxy mapping */ 48*4882a593Smuzhiyun int vpe_proxy_event; 49*4882a593Smuzhiyun /* Implementation Defined Area Invalid */ 50*4882a593Smuzhiyun bool idai; 51*4882a593Smuzhiyun }; 52*4882a593Smuzhiyun /* GICv4.1 implementations */ 53*4882a593Smuzhiyun struct { 54*4882a593Smuzhiyun struct fwnode_handle *fwnode; 55*4882a593Smuzhiyun struct irq_domain *sgi_domain; 56*4882a593Smuzhiyun struct { 57*4882a593Smuzhiyun u8 priority; 58*4882a593Smuzhiyun bool enabled; 59*4882a593Smuzhiyun bool group; 60*4882a593Smuzhiyun } sgi_config[16]; 61*4882a593Smuzhiyun atomic_t vmapp_count; 62*4882a593Smuzhiyun }; 63*4882a593Smuzhiyun }; 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun /* 66*4882a593Smuzhiyun * Ensures mutual exclusion between affinity setting of the 67*4882a593Smuzhiyun * vPE and vLPI operations using vpe->col_idx. 68*4882a593Smuzhiyun */ 69*4882a593Smuzhiyun raw_spinlock_t vpe_lock; 70*4882a593Smuzhiyun /* 71*4882a593Smuzhiyun * This collection ID is used to indirect the target 72*4882a593Smuzhiyun * redistributor for this VPE. The ID itself isn't involved in 73*4882a593Smuzhiyun * programming of the ITS. 74*4882a593Smuzhiyun */ 75*4882a593Smuzhiyun u16 col_idx; 76*4882a593Smuzhiyun /* Unique (system-wide) VPE identifier */ 77*4882a593Smuzhiyun u16 vpe_id; 78*4882a593Smuzhiyun /* Pending VLPIs on schedule out? */ 79*4882a593Smuzhiyun bool pending_last; 80*4882a593Smuzhiyun }; 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun /* 83*4882a593Smuzhiyun * struct its_vlpi_map: structure describing the mapping of a 84*4882a593Smuzhiyun * VLPI. Only to be interpreted in the context of a physical interrupt 85*4882a593Smuzhiyun * it complements. To be used as the vcpu_info passed to 86*4882a593Smuzhiyun * irq_set_vcpu_affinity(). 87*4882a593Smuzhiyun * 88*4882a593Smuzhiyun * @vm: Pointer to the GICv4 notion of a VM 89*4882a593Smuzhiyun * @vpe: Pointer to the GICv4 notion of a virtual CPU (VPE) 90*4882a593Smuzhiyun * @vintid: Virtual LPI number 91*4882a593Smuzhiyun * @properties: Priority and enable bits (as written in the prop table) 92*4882a593Smuzhiyun * @db_enabled: Is the VPE doorbell to be generated? 93*4882a593Smuzhiyun */ 94*4882a593Smuzhiyun struct its_vlpi_map { 95*4882a593Smuzhiyun struct its_vm *vm; 96*4882a593Smuzhiyun struct its_vpe *vpe; 97*4882a593Smuzhiyun u32 vintid; 98*4882a593Smuzhiyun u8 properties; 99*4882a593Smuzhiyun bool db_enabled; 100*4882a593Smuzhiyun }; 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun enum its_vcpu_info_cmd_type { 103*4882a593Smuzhiyun MAP_VLPI, 104*4882a593Smuzhiyun GET_VLPI, 105*4882a593Smuzhiyun PROP_UPDATE_VLPI, 106*4882a593Smuzhiyun PROP_UPDATE_AND_INV_VLPI, 107*4882a593Smuzhiyun SCHEDULE_VPE, 108*4882a593Smuzhiyun DESCHEDULE_VPE, 109*4882a593Smuzhiyun COMMIT_VPE, 110*4882a593Smuzhiyun INVALL_VPE, 111*4882a593Smuzhiyun PROP_UPDATE_VSGI, 112*4882a593Smuzhiyun }; 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun struct its_cmd_info { 115*4882a593Smuzhiyun enum its_vcpu_info_cmd_type cmd_type; 116*4882a593Smuzhiyun union { 117*4882a593Smuzhiyun struct its_vlpi_map *map; 118*4882a593Smuzhiyun u8 config; 119*4882a593Smuzhiyun bool req_db; 120*4882a593Smuzhiyun struct { 121*4882a593Smuzhiyun bool g0en; 122*4882a593Smuzhiyun bool g1en; 123*4882a593Smuzhiyun }; 124*4882a593Smuzhiyun struct { 125*4882a593Smuzhiyun u8 priority; 126*4882a593Smuzhiyun bool group; 127*4882a593Smuzhiyun }; 128*4882a593Smuzhiyun }; 129*4882a593Smuzhiyun }; 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun int its_alloc_vcpu_irqs(struct its_vm *vm); 132*4882a593Smuzhiyun void its_free_vcpu_irqs(struct its_vm *vm); 133*4882a593Smuzhiyun int its_make_vpe_resident(struct its_vpe *vpe, bool g0en, bool g1en); 134*4882a593Smuzhiyun int its_make_vpe_non_resident(struct its_vpe *vpe, bool db); 135*4882a593Smuzhiyun int its_commit_vpe(struct its_vpe *vpe); 136*4882a593Smuzhiyun int its_invall_vpe(struct its_vpe *vpe); 137*4882a593Smuzhiyun int its_map_vlpi(int irq, struct its_vlpi_map *map); 138*4882a593Smuzhiyun int its_get_vlpi(int irq, struct its_vlpi_map *map); 139*4882a593Smuzhiyun int its_unmap_vlpi(int irq); 140*4882a593Smuzhiyun int its_prop_update_vlpi(int irq, u8 config, bool inv); 141*4882a593Smuzhiyun int its_prop_update_vsgi(int irq, u8 priority, bool group); 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun struct irq_domain_ops; 144*4882a593Smuzhiyun int its_init_v4(struct irq_domain *domain, 145*4882a593Smuzhiyun const struct irq_domain_ops *vpe_ops, 146*4882a593Smuzhiyun const struct irq_domain_ops *sgi_ops); 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun #endif 149