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
10struct 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 */
19struct 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 */
32struct 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 */
94struct 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
102enum 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
114struct 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
131int its_alloc_vcpu_irqs(struct its_vm *vm);
132void its_free_vcpu_irqs(struct its_vm *vm);
133int its_make_vpe_resident(struct its_vpe *vpe, bool g0en, bool g1en);
134int its_make_vpe_non_resident(struct its_vpe *vpe, bool db);
135int its_commit_vpe(struct its_vpe *vpe);
136int its_invall_vpe(struct its_vpe *vpe);
137int its_map_vlpi(int irq, struct its_vlpi_map *map);
138int its_get_vlpi(int irq, struct its_vlpi_map *map);
139int its_unmap_vlpi(int irq);
140int its_prop_update_vlpi(int irq, u8 config, bool inv);
141int its_prop_update_vsgi(int irq, u8 priority, bool group);
142
143struct irq_domain_ops;
144int its_init_v4(struct irq_domain *domain,
145		const struct irq_domain_ops *vpe_ops,
146		const struct irq_domain_ops *sgi_ops);
147
148bool gic_cpuif_has_vsgi(void);
149
150#endif
151