Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2016,2017 ARM Limited, All Rights Reserved.
0004  * Author: Marc Zyngier <marc.zyngier@arm.com>
0005  */
0006 
0007 #ifndef __LINUX_IRQCHIP_ARM_GIC_V4_H
0008 #define __LINUX_IRQCHIP_ARM_GIC_V4_H
0009 
0010 struct its_vpe;
0011 
0012 /*
0013  * Maximum number of ITTs when GITS_TYPER.VMOVP == 0, using the
0014  * ITSList mechanism to perform inter-ITS synchronization.
0015  */
0016 #define GICv4_ITS_LIST_MAX      16
0017 
0018 /* Embedded in kvm.arch */
0019 struct its_vm {
0020     struct fwnode_handle    *fwnode;
0021     struct irq_domain   *domain;
0022     struct page     *vprop_page;
0023     struct its_vpe      **vpes;
0024     int         nr_vpes;
0025     irq_hw_number_t     db_lpi_base;
0026     unsigned long       *db_bitmap;
0027     int         nr_db_lpis;
0028     u32         vlpi_count[GICv4_ITS_LIST_MAX];
0029 };
0030 
0031 /* Embedded in kvm_vcpu.arch */
0032 struct its_vpe {
0033     struct page         *vpt_page;
0034     struct its_vm       *its_vm;
0035     /* per-vPE VLPI tracking */
0036     atomic_t        vlpi_count;
0037     /* Doorbell interrupt */
0038     int         irq;
0039     irq_hw_number_t     vpe_db_lpi;
0040     /* VPE resident */
0041     bool            resident;
0042     /* VPT parse complete */
0043     bool            ready;
0044     union {
0045         /* GICv4.0 implementations */
0046         struct {
0047             /* VPE proxy mapping */
0048             int vpe_proxy_event;
0049             /* Implementation Defined Area Invalid */
0050             bool    idai;
0051         };
0052         /* GICv4.1 implementations */
0053         struct {
0054             struct fwnode_handle    *fwnode;
0055             struct irq_domain   *sgi_domain;
0056             struct {
0057                 u8  priority;
0058                 bool    enabled;
0059                 bool    group;
0060             }           sgi_config[16];
0061             atomic_t vmapp_count;
0062         };
0063     };
0064 
0065     /*
0066      * Ensures mutual exclusion between affinity setting of the
0067      * vPE and vLPI operations using vpe->col_idx.
0068      */
0069     raw_spinlock_t      vpe_lock;
0070     /*
0071      * This collection ID is used to indirect the target
0072      * redistributor for this VPE. The ID itself isn't involved in
0073      * programming of the ITS.
0074      */
0075     u16         col_idx;
0076     /* Unique (system-wide) VPE identifier */
0077     u16         vpe_id;
0078     /* Pending VLPIs on schedule out? */
0079     bool            pending_last;
0080 };
0081 
0082 /*
0083  * struct its_vlpi_map: structure describing the mapping of a
0084  * VLPI. Only to be interpreted in the context of a physical interrupt
0085  * it complements.  To be used as the vcpu_info passed to
0086  * irq_set_vcpu_affinity().
0087  *
0088  * @vm:     Pointer to the GICv4 notion of a VM
0089  * @vpe:    Pointer to the GICv4 notion of a virtual CPU (VPE)
0090  * @vintid: Virtual LPI number
0091  * @properties: Priority and enable bits (as written in the prop table)
0092  * @db_enabled: Is the VPE doorbell to be generated?
0093  */
0094 struct its_vlpi_map {
0095     struct its_vm       *vm;
0096     struct its_vpe      *vpe;
0097     u32         vintid;
0098     u8          properties;
0099     bool            db_enabled;
0100 };
0101 
0102 enum its_vcpu_info_cmd_type {
0103     MAP_VLPI,
0104     GET_VLPI,
0105     PROP_UPDATE_VLPI,
0106     PROP_UPDATE_AND_INV_VLPI,
0107     SCHEDULE_VPE,
0108     DESCHEDULE_VPE,
0109     COMMIT_VPE,
0110     INVALL_VPE,
0111     PROP_UPDATE_VSGI,
0112 };
0113 
0114 struct its_cmd_info {
0115     enum its_vcpu_info_cmd_type cmd_type;
0116     union {
0117         struct its_vlpi_map *map;
0118         u8          config;
0119         bool            req_db;
0120         struct {
0121             bool        g0en;
0122             bool        g1en;
0123         };
0124         struct {
0125             u8      priority;
0126             bool        group;
0127         };
0128     };
0129 };
0130 
0131 int its_alloc_vcpu_irqs(struct its_vm *vm);
0132 void its_free_vcpu_irqs(struct its_vm *vm);
0133 int its_make_vpe_resident(struct its_vpe *vpe, bool g0en, bool g1en);
0134 int its_make_vpe_non_resident(struct its_vpe *vpe, bool db);
0135 int its_commit_vpe(struct its_vpe *vpe);
0136 int its_invall_vpe(struct its_vpe *vpe);
0137 int its_map_vlpi(int irq, struct its_vlpi_map *map);
0138 int its_get_vlpi(int irq, struct its_vlpi_map *map);
0139 int its_unmap_vlpi(int irq);
0140 int its_prop_update_vlpi(int irq, u8 config, bool inv);
0141 int its_prop_update_vsgi(int irq, u8 priority, bool group);
0142 
0143 struct irq_domain_ops;
0144 int its_init_v4(struct irq_domain *domain,
0145         const struct irq_domain_ops *vpe_ops,
0146         const struct irq_domain_ops *sgi_ops);
0147 
0148 bool gic_cpuif_has_vsgi(void);
0149 
0150 #endif