xref: /linux/drivers/hv/mshv_root.h (revision 4f9786035f9e519db41375818e1d0b5f20da2f10)
1*621191d7SNuno Das Neves /* SPDX-License-Identifier: GPL-2.0-only */
2*621191d7SNuno Das Neves /*
3*621191d7SNuno Das Neves  * Copyright (c) 2023, Microsoft Corporation.
4*621191d7SNuno Das Neves  */
5*621191d7SNuno Das Neves 
6*621191d7SNuno Das Neves #ifndef _MSHV_ROOT_H_
7*621191d7SNuno Das Neves #define _MSHV_ROOT_H_
8*621191d7SNuno Das Neves 
9*621191d7SNuno Das Neves #include <linux/spinlock.h>
10*621191d7SNuno Das Neves #include <linux/mutex.h>
11*621191d7SNuno Das Neves #include <linux/semaphore.h>
12*621191d7SNuno Das Neves #include <linux/sched.h>
13*621191d7SNuno Das Neves #include <linux/srcu.h>
14*621191d7SNuno Das Neves #include <linux/wait.h>
15*621191d7SNuno Das Neves #include <linux/hashtable.h>
16*621191d7SNuno Das Neves #include <linux/dev_printk.h>
17*621191d7SNuno Das Neves #include <linux/build_bug.h>
18*621191d7SNuno Das Neves #include <uapi/linux/mshv.h>
19*621191d7SNuno Das Neves 
20*621191d7SNuno Das Neves /*
21*621191d7SNuno Das Neves  * Hypervisor must be between these version numbers (inclusive)
22*621191d7SNuno Das Neves  * to guarantee compatibility
23*621191d7SNuno Das Neves  */
24*621191d7SNuno Das Neves #define MSHV_HV_MIN_VERSION		(27744)
25*621191d7SNuno Das Neves #define MSHV_HV_MAX_VERSION		(27751)
26*621191d7SNuno Das Neves 
27*621191d7SNuno Das Neves static_assert(HV_HYP_PAGE_SIZE == MSHV_HV_PAGE_SIZE);
28*621191d7SNuno Das Neves 
29*621191d7SNuno Das Neves #define MSHV_MAX_VPS			256
30*621191d7SNuno Das Neves 
31*621191d7SNuno Das Neves #define MSHV_PARTITIONS_HASH_BITS	9
32*621191d7SNuno Das Neves 
33*621191d7SNuno Das Neves #define MSHV_PIN_PAGES_BATCH_SIZE	(0x10000000ULL / HV_HYP_PAGE_SIZE)
34*621191d7SNuno Das Neves 
35*621191d7SNuno Das Neves struct mshv_vp {
36*621191d7SNuno Das Neves 	u32 vp_index;
37*621191d7SNuno Das Neves 	struct mshv_partition *vp_partition;
38*621191d7SNuno Das Neves 	struct mutex vp_mutex;
39*621191d7SNuno Das Neves 	struct hv_vp_register_page *vp_register_page;
40*621191d7SNuno Das Neves 	struct hv_message *vp_intercept_msg_page;
41*621191d7SNuno Das Neves 	void *vp_ghcb_page;
42*621191d7SNuno Das Neves 	struct hv_stats_page *vp_stats_pages[2];
43*621191d7SNuno Das Neves 	struct {
44*621191d7SNuno Das Neves 		atomic64_t vp_signaled_count;
45*621191d7SNuno Das Neves 		struct {
46*621191d7SNuno Das Neves 			u64 intercept_suspend: 1;
47*621191d7SNuno Das Neves 			u64 root_sched_blocked: 1; /* root scheduler only */
48*621191d7SNuno Das Neves 			u64 root_sched_dispatched: 1; /* root scheduler only */
49*621191d7SNuno Das Neves 			u64 reserved: 61;
50*621191d7SNuno Das Neves 		} flags;
51*621191d7SNuno Das Neves 		unsigned int kicked_by_hv;
52*621191d7SNuno Das Neves 		wait_queue_head_t vp_suspend_queue;
53*621191d7SNuno Das Neves 	} run;
54*621191d7SNuno Das Neves };
55*621191d7SNuno Das Neves 
56*621191d7SNuno Das Neves #define vp_fmt(fmt) "p%lluvp%u: " fmt
57*621191d7SNuno Das Neves #define vp_devprintk(level, v, fmt, ...) \
58*621191d7SNuno Das Neves do { \
59*621191d7SNuno Das Neves 	const struct mshv_vp *__vp = (v); \
60*621191d7SNuno Das Neves 	const struct mshv_partition *__pt = __vp->vp_partition; \
61*621191d7SNuno Das Neves 	dev_##level(__pt->pt_module_dev, vp_fmt(fmt), __pt->pt_id, \
62*621191d7SNuno Das Neves 		    __vp->vp_index, ##__VA_ARGS__); \
63*621191d7SNuno Das Neves } while (0)
64*621191d7SNuno Das Neves #define vp_emerg(v, fmt, ...)	vp_devprintk(emerg, v, fmt, ##__VA_ARGS__)
65*621191d7SNuno Das Neves #define vp_crit(v, fmt, ...)	vp_devprintk(crit, v, fmt, ##__VA_ARGS__)
66*621191d7SNuno Das Neves #define vp_alert(v, fmt, ...)	vp_devprintk(alert, v, fmt, ##__VA_ARGS__)
67*621191d7SNuno Das Neves #define vp_err(v, fmt, ...)	vp_devprintk(err, v, fmt, ##__VA_ARGS__)
68*621191d7SNuno Das Neves #define vp_warn(v, fmt, ...)	vp_devprintk(warn, v, fmt, ##__VA_ARGS__)
69*621191d7SNuno Das Neves #define vp_notice(v, fmt, ...)	vp_devprintk(notice, v, fmt, ##__VA_ARGS__)
70*621191d7SNuno Das Neves #define vp_info(v, fmt, ...)	vp_devprintk(info, v, fmt, ##__VA_ARGS__)
71*621191d7SNuno Das Neves #define vp_dbg(v, fmt, ...)	vp_devprintk(dbg, v, fmt, ##__VA_ARGS__)
72*621191d7SNuno Das Neves 
73*621191d7SNuno Das Neves struct mshv_mem_region {
74*621191d7SNuno Das Neves 	struct hlist_node hnode;
75*621191d7SNuno Das Neves 	u64 nr_pages;
76*621191d7SNuno Das Neves 	u64 start_gfn;
77*621191d7SNuno Das Neves 	u64 start_uaddr;
78*621191d7SNuno Das Neves 	u32 hv_map_flags;
79*621191d7SNuno Das Neves 	struct {
80*621191d7SNuno Das Neves 		u64 large_pages:  1; /* 2MiB */
81*621191d7SNuno Das Neves 		u64 range_pinned: 1;
82*621191d7SNuno Das Neves 		u64 reserved:	 62;
83*621191d7SNuno Das Neves 	} flags;
84*621191d7SNuno Das Neves 	struct mshv_partition *partition;
85*621191d7SNuno Das Neves 	struct page *pages[];
86*621191d7SNuno Das Neves };
87*621191d7SNuno Das Neves 
88*621191d7SNuno Das Neves struct mshv_irq_ack_notifier {
89*621191d7SNuno Das Neves 	struct hlist_node link;
90*621191d7SNuno Das Neves 	unsigned int irq_ack_gsi;
91*621191d7SNuno Das Neves 	void (*irq_acked)(struct mshv_irq_ack_notifier *mian);
92*621191d7SNuno Das Neves };
93*621191d7SNuno Das Neves 
94*621191d7SNuno Das Neves struct mshv_partition {
95*621191d7SNuno Das Neves 	struct device *pt_module_dev;
96*621191d7SNuno Das Neves 
97*621191d7SNuno Das Neves 	struct hlist_node pt_hnode;
98*621191d7SNuno Das Neves 	u64 pt_id;
99*621191d7SNuno Das Neves 	refcount_t pt_ref_count;
100*621191d7SNuno Das Neves 	struct mutex pt_mutex;
101*621191d7SNuno Das Neves 	struct hlist_head pt_mem_regions; // not ordered
102*621191d7SNuno Das Neves 
103*621191d7SNuno Das Neves 	u32 pt_vp_count;
104*621191d7SNuno Das Neves 	struct mshv_vp *pt_vp_array[MSHV_MAX_VPS];
105*621191d7SNuno Das Neves 
106*621191d7SNuno Das Neves 	struct mutex pt_irq_lock;
107*621191d7SNuno Das Neves 	struct srcu_struct pt_irq_srcu;
108*621191d7SNuno Das Neves 	struct hlist_head irq_ack_notifier_list;
109*621191d7SNuno Das Neves 
110*621191d7SNuno Das Neves 	struct hlist_head pt_devices;
111*621191d7SNuno Das Neves 
112*621191d7SNuno Das Neves 	/*
113*621191d7SNuno Das Neves 	 * MSHV does not support more than one async hypercall in flight
114*621191d7SNuno Das Neves 	 * for a single partition. Thus, it is okay to define per partition
115*621191d7SNuno Das Neves 	 * async hypercall status.
116*621191d7SNuno Das Neves 	 */
117*621191d7SNuno Das Neves 	struct completion async_hypercall;
118*621191d7SNuno Das Neves 	u64 async_hypercall_status;
119*621191d7SNuno Das Neves 
120*621191d7SNuno Das Neves 	spinlock_t	  pt_irqfds_lock;
121*621191d7SNuno Das Neves 	struct hlist_head pt_irqfds_list;
122*621191d7SNuno Das Neves 	struct mutex	  irqfds_resampler_lock;
123*621191d7SNuno Das Neves 	struct hlist_head irqfds_resampler_list;
124*621191d7SNuno Das Neves 
125*621191d7SNuno Das Neves 	struct hlist_head ioeventfds_list;
126*621191d7SNuno Das Neves 
127*621191d7SNuno Das Neves 	struct mshv_girq_routing_table __rcu *pt_girq_tbl;
128*621191d7SNuno Das Neves 	u64 isolation_type;
129*621191d7SNuno Das Neves 	bool import_completed;
130*621191d7SNuno Das Neves 	bool pt_initialized;
131*621191d7SNuno Das Neves };
132*621191d7SNuno Das Neves 
133*621191d7SNuno Das Neves #define pt_fmt(fmt) "p%llu: " fmt
134*621191d7SNuno Das Neves #define pt_devprintk(level, p, fmt, ...) \
135*621191d7SNuno Das Neves do { \
136*621191d7SNuno Das Neves 	const struct mshv_partition *__pt = (p); \
137*621191d7SNuno Das Neves 	dev_##level(__pt->pt_module_dev, pt_fmt(fmt), __pt->pt_id, \
138*621191d7SNuno Das Neves 		    ##__VA_ARGS__); \
139*621191d7SNuno Das Neves } while (0)
140*621191d7SNuno Das Neves #define pt_emerg(p, fmt, ...)	pt_devprintk(emerg, p, fmt, ##__VA_ARGS__)
141*621191d7SNuno Das Neves #define pt_crit(p, fmt, ...)	pt_devprintk(crit, p, fmt, ##__VA_ARGS__)
142*621191d7SNuno Das Neves #define pt_alert(p, fmt, ...)	pt_devprintk(alert, p, fmt, ##__VA_ARGS__)
143*621191d7SNuno Das Neves #define pt_err(p, fmt, ...)	pt_devprintk(err, p, fmt, ##__VA_ARGS__)
144*621191d7SNuno Das Neves #define pt_warn(p, fmt, ...)	pt_devprintk(warn, p, fmt, ##__VA_ARGS__)
145*621191d7SNuno Das Neves #define pt_notice(p, fmt, ...)	pt_devprintk(notice, p, fmt, ##__VA_ARGS__)
146*621191d7SNuno Das Neves #define pt_info(p, fmt, ...)	pt_devprintk(info, p, fmt, ##__VA_ARGS__)
147*621191d7SNuno Das Neves #define pt_dbg(p, fmt, ...)	pt_devprintk(dbg, p, fmt, ##__VA_ARGS__)
148*621191d7SNuno Das Neves 
149*621191d7SNuno Das Neves struct mshv_lapic_irq {
150*621191d7SNuno Das Neves 	u32 lapic_vector;
151*621191d7SNuno Das Neves 	u64 lapic_apic_id;
152*621191d7SNuno Das Neves 	union hv_interrupt_control lapic_control;
153*621191d7SNuno Das Neves };
154*621191d7SNuno Das Neves 
155*621191d7SNuno Das Neves #define MSHV_MAX_GUEST_IRQS		4096
156*621191d7SNuno Das Neves 
157*621191d7SNuno Das Neves /* representation of one guest irq entry, either msi or legacy */
158*621191d7SNuno Das Neves struct mshv_guest_irq_ent {
159*621191d7SNuno Das Neves 	u32 girq_entry_valid;	/* vfio looks at this */
160*621191d7SNuno Das Neves 	u32 guest_irq_num;	/* a unique number for each irq */
161*621191d7SNuno Das Neves 	u32 girq_addr_lo;	/* guest irq msi address info */
162*621191d7SNuno Das Neves 	u32 girq_addr_hi;
163*621191d7SNuno Das Neves 	u32 girq_irq_data;	/* idt vector in some cases */
164*621191d7SNuno Das Neves };
165*621191d7SNuno Das Neves 
166*621191d7SNuno Das Neves struct mshv_girq_routing_table {
167*621191d7SNuno Das Neves 	u32 num_rt_entries;
168*621191d7SNuno Das Neves 	struct mshv_guest_irq_ent mshv_girq_info_tbl[];
169*621191d7SNuno Das Neves };
170*621191d7SNuno Das Neves 
171*621191d7SNuno Das Neves struct hv_synic_pages {
172*621191d7SNuno Das Neves 	struct hv_message_page *synic_message_page;
173*621191d7SNuno Das Neves 	struct hv_synic_event_flags_page *synic_event_flags_page;
174*621191d7SNuno Das Neves 	struct hv_synic_event_ring_page *synic_event_ring_page;
175*621191d7SNuno Das Neves };
176*621191d7SNuno Das Neves 
177*621191d7SNuno Das Neves struct mshv_root {
178*621191d7SNuno Das Neves 	struct hv_synic_pages __percpu *synic_pages;
179*621191d7SNuno Das Neves 	spinlock_t pt_ht_lock;
180*621191d7SNuno Das Neves 	DECLARE_HASHTABLE(pt_htable, MSHV_PARTITIONS_HASH_BITS);
181*621191d7SNuno Das Neves };
182*621191d7SNuno Das Neves 
183*621191d7SNuno Das Neves /*
184*621191d7SNuno Das Neves  * Callback for doorbell events.
185*621191d7SNuno Das Neves  * NOTE: This is called in interrupt context. Callback
186*621191d7SNuno Das Neves  * should defer slow and sleeping logic to later.
187*621191d7SNuno Das Neves  */
188*621191d7SNuno Das Neves typedef void (*doorbell_cb_t) (int doorbell_id, void *);
189*621191d7SNuno Das Neves 
190*621191d7SNuno Das Neves /*
191*621191d7SNuno Das Neves  * port table information
192*621191d7SNuno Das Neves  */
193*621191d7SNuno Das Neves struct port_table_info {
194*621191d7SNuno Das Neves 	struct rcu_head portbl_rcu;
195*621191d7SNuno Das Neves 	enum hv_port_type hv_port_type;
196*621191d7SNuno Das Neves 	union {
197*621191d7SNuno Das Neves 		struct {
198*621191d7SNuno Das Neves 			u64 reserved[2];
199*621191d7SNuno Das Neves 		} hv_port_message;
200*621191d7SNuno Das Neves 		struct {
201*621191d7SNuno Das Neves 			u64 reserved[2];
202*621191d7SNuno Das Neves 		} hv_port_event;
203*621191d7SNuno Das Neves 		struct {
204*621191d7SNuno Das Neves 			u64 reserved[2];
205*621191d7SNuno Das Neves 		} hv_port_monitor;
206*621191d7SNuno Das Neves 		struct {
207*621191d7SNuno Das Neves 			doorbell_cb_t doorbell_cb;
208*621191d7SNuno Das Neves 			void *data;
209*621191d7SNuno Das Neves 		} hv_port_doorbell;
210*621191d7SNuno Das Neves 	};
211*621191d7SNuno Das Neves };
212*621191d7SNuno Das Neves 
213*621191d7SNuno Das Neves int mshv_update_routing_table(struct mshv_partition *partition,
214*621191d7SNuno Das Neves 			      const struct mshv_user_irq_entry *entries,
215*621191d7SNuno Das Neves 			      unsigned int numents);
216*621191d7SNuno Das Neves void mshv_free_routing_table(struct mshv_partition *partition);
217*621191d7SNuno Das Neves 
218*621191d7SNuno Das Neves struct mshv_guest_irq_ent mshv_ret_girq_entry(struct mshv_partition *partition,
219*621191d7SNuno Das Neves 					      u32 irq_num);
220*621191d7SNuno Das Neves 
221*621191d7SNuno Das Neves void mshv_copy_girq_info(struct mshv_guest_irq_ent *src_irq,
222*621191d7SNuno Das Neves 			 struct mshv_lapic_irq *dest_irq);
223*621191d7SNuno Das Neves 
224*621191d7SNuno Das Neves void mshv_irqfd_routing_update(struct mshv_partition *partition);
225*621191d7SNuno Das Neves 
226*621191d7SNuno Das Neves void mshv_port_table_fini(void);
227*621191d7SNuno Das Neves int mshv_portid_alloc(struct port_table_info *info);
228*621191d7SNuno Das Neves int mshv_portid_lookup(int port_id, struct port_table_info *info);
229*621191d7SNuno Das Neves void mshv_portid_free(int port_id);
230*621191d7SNuno Das Neves 
231*621191d7SNuno Das Neves int mshv_register_doorbell(u64 partition_id, doorbell_cb_t doorbell_cb,
232*621191d7SNuno Das Neves 			   void *data, u64 gpa, u64 val, u64 flags);
233*621191d7SNuno Das Neves void mshv_unregister_doorbell(u64 partition_id, int doorbell_portid);
234*621191d7SNuno Das Neves 
235*621191d7SNuno Das Neves void mshv_isr(void);
236*621191d7SNuno Das Neves int mshv_synic_init(unsigned int cpu);
237*621191d7SNuno Das Neves int mshv_synic_cleanup(unsigned int cpu);
238*621191d7SNuno Das Neves 
239*621191d7SNuno Das Neves static inline bool mshv_partition_encrypted(struct mshv_partition *partition)
240*621191d7SNuno Das Neves {
241*621191d7SNuno Das Neves 	return partition->isolation_type == HV_PARTITION_ISOLATION_TYPE_SNP;
242*621191d7SNuno Das Neves }
243*621191d7SNuno Das Neves 
244*621191d7SNuno Das Neves struct mshv_partition *mshv_partition_get(struct mshv_partition *partition);
245*621191d7SNuno Das Neves void mshv_partition_put(struct mshv_partition *partition);
246*621191d7SNuno Das Neves struct mshv_partition *mshv_partition_find(u64 partition_id) __must_hold(RCU);
247*621191d7SNuno Das Neves 
248*621191d7SNuno Das Neves /* hypercalls */
249*621191d7SNuno Das Neves 
250*621191d7SNuno Das Neves int hv_call_withdraw_memory(u64 count, int node, u64 partition_id);
251*621191d7SNuno Das Neves int hv_call_create_partition(u64 flags,
252*621191d7SNuno Das Neves 			     struct hv_partition_creation_properties creation_properties,
253*621191d7SNuno Das Neves 			     union hv_partition_isolation_properties isolation_properties,
254*621191d7SNuno Das Neves 			     u64 *partition_id);
255*621191d7SNuno Das Neves int hv_call_initialize_partition(u64 partition_id);
256*621191d7SNuno Das Neves int hv_call_finalize_partition(u64 partition_id);
257*621191d7SNuno Das Neves int hv_call_delete_partition(u64 partition_id);
258*621191d7SNuno Das Neves int hv_call_map_mmio_pages(u64 partition_id, u64 gfn, u64 mmio_spa, u64 numpgs);
259*621191d7SNuno Das Neves int hv_call_map_gpa_pages(u64 partition_id, u64 gpa_target, u64 page_count,
260*621191d7SNuno Das Neves 			  u32 flags, struct page **pages);
261*621191d7SNuno Das Neves int hv_call_unmap_gpa_pages(u64 partition_id, u64 gpa_target, u64 page_count,
262*621191d7SNuno Das Neves 			    u32 flags);
263*621191d7SNuno Das Neves int hv_call_delete_vp(u64 partition_id, u32 vp_index);
264*621191d7SNuno Das Neves int hv_call_assert_virtual_interrupt(u64 partition_id, u32 vector,
265*621191d7SNuno Das Neves 				     u64 dest_addr,
266*621191d7SNuno Das Neves 				     union hv_interrupt_control control);
267*621191d7SNuno Das Neves int hv_call_clear_virtual_interrupt(u64 partition_id);
268*621191d7SNuno Das Neves int hv_call_get_gpa_access_states(u64 partition_id, u32 count, u64 gpa_base_pfn,
269*621191d7SNuno Das Neves 				  union hv_gpa_page_access_state_flags state_flags,
270*621191d7SNuno Das Neves 				  int *written_total,
271*621191d7SNuno Das Neves 				  union hv_gpa_page_access_state *states);
272*621191d7SNuno Das Neves int hv_call_get_vp_state(u32 vp_index, u64 partition_id,
273*621191d7SNuno Das Neves 			 struct hv_vp_state_data state_data,
274*621191d7SNuno Das Neves 			 /* Choose between pages and ret_output */
275*621191d7SNuno Das Neves 			 u64 page_count, struct page **pages,
276*621191d7SNuno Das Neves 			 union hv_output_get_vp_state *ret_output);
277*621191d7SNuno Das Neves int hv_call_set_vp_state(u32 vp_index, u64 partition_id,
278*621191d7SNuno Das Neves 			 /* Choose between pages and bytes */
279*621191d7SNuno Das Neves 			 struct hv_vp_state_data state_data, u64 page_count,
280*621191d7SNuno Das Neves 			 struct page **pages, u32 num_bytes, u8 *bytes);
281*621191d7SNuno Das Neves int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
282*621191d7SNuno Das Neves 			      union hv_input_vtl input_vtl,
283*621191d7SNuno Das Neves 			      struct page **state_page);
284*621191d7SNuno Das Neves int hv_call_unmap_vp_state_page(u64 partition_id, u32 vp_index, u32 type,
285*621191d7SNuno Das Neves 				union hv_input_vtl input_vtl);
286*621191d7SNuno Das Neves int hv_call_create_port(u64 port_partition_id, union hv_port_id port_id,
287*621191d7SNuno Das Neves 			u64 connection_partition_id, struct hv_port_info *port_info,
288*621191d7SNuno Das Neves 			u8 port_vtl, u8 min_connection_vtl, int node);
289*621191d7SNuno Das Neves int hv_call_delete_port(u64 port_partition_id, union hv_port_id port_id);
290*621191d7SNuno Das Neves int hv_call_connect_port(u64 port_partition_id, union hv_port_id port_id,
291*621191d7SNuno Das Neves 			 u64 connection_partition_id,
292*621191d7SNuno Das Neves 			 union hv_connection_id connection_id,
293*621191d7SNuno Das Neves 			 struct hv_connection_info *connection_info,
294*621191d7SNuno Das Neves 			 u8 connection_vtl, int node);
295*621191d7SNuno Das Neves int hv_call_disconnect_port(u64 connection_partition_id,
296*621191d7SNuno Das Neves 			    union hv_connection_id connection_id);
297*621191d7SNuno Das Neves int hv_call_notify_port_ring_empty(u32 sint_index);
298*621191d7SNuno Das Neves int hv_call_map_stat_page(enum hv_stats_object_type type,
299*621191d7SNuno Das Neves 			  const union hv_stats_object_identity *identity,
300*621191d7SNuno Das Neves 			  void **addr);
301*621191d7SNuno Das Neves int hv_call_unmap_stat_page(enum hv_stats_object_type type,
302*621191d7SNuno Das Neves 			    const union hv_stats_object_identity *identity);
303*621191d7SNuno Das Neves int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages,
304*621191d7SNuno Das Neves 				   u64 page_struct_count, u32 host_access,
305*621191d7SNuno Das Neves 				   u32 flags, u8 acquire);
306*621191d7SNuno Das Neves 
307*621191d7SNuno Das Neves extern struct mshv_root mshv_root;
308*621191d7SNuno Das Neves extern enum hv_scheduler_type hv_scheduler_type;
309*621191d7SNuno Das Neves extern u8 * __percpu *hv_synic_eventring_tail;
310*621191d7SNuno Das Neves 
311*621191d7SNuno Das Neves #endif /* _MSHV_ROOT_H_ */
312