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