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