hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/hv/hyperv_vmbus.h
....@@ -1,25 +1,12 @@
1
+/* SPDX-License-Identifier: GPL-2.0-only */
12 /*
23 *
34 * Copyright (c) 2011, Microsoft Corporation.
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms and conditions of the GNU General Public License,
7
- * version 2, as published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope it will be useful, but WITHOUT
10
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
- * more details.
13
- *
14
- * You should have received a copy of the GNU General Public License along with
15
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16
- * Place - Suite 330, Boston, MA 02111-1307 USA.
175 *
186 * Authors:
197 * Haiyang Zhang <haiyangz@microsoft.com>
208 * Hank Janssen <hjanssen@microsoft.com>
219 * K. Y. Srinivasan <kys@microsoft.com>
22
- *
2310 */
2411
2512 #ifndef _HYPERV_VMBUS_H
....@@ -32,7 +19,6 @@
3219 #include <linux/atomic.h>
3320 #include <linux/hyperv.h>
3421 #include <linux/interrupt.h>
35
-#include <linux/irq.h>
3622
3723 #include "hv_trace.h"
3824
....@@ -46,74 +32,6 @@
4632 */
4733 #define HV_UTIL_NEGO_TIMEOUT 55
4834
49
-/* Define synthetic interrupt controller flag constants. */
50
-#define HV_EVENT_FLAGS_COUNT (256 * 8)
51
-#define HV_EVENT_FLAGS_LONG_COUNT (256 / sizeof(unsigned long))
52
-
53
-/*
54
- * Timer configuration register.
55
- */
56
-union hv_timer_config {
57
- u64 as_uint64;
58
- struct {
59
- u64 enable:1;
60
- u64 periodic:1;
61
- u64 lazy:1;
62
- u64 auto_enable:1;
63
- u64 apic_vector:8;
64
- u64 direct_mode:1;
65
- u64 reserved_z0:3;
66
- u64 sintx:4;
67
- u64 reserved_z1:44;
68
- };
69
-};
70
-
71
-
72
-/* Define the synthetic interrupt controller event flags format. */
73
-union hv_synic_event_flags {
74
- unsigned long flags[HV_EVENT_FLAGS_LONG_COUNT];
75
-};
76
-
77
-/* Define SynIC control register. */
78
-union hv_synic_scontrol {
79
- u64 as_uint64;
80
- struct {
81
- u64 enable:1;
82
- u64 reserved:63;
83
- };
84
-};
85
-
86
-/* Define synthetic interrupt source. */
87
-union hv_synic_sint {
88
- u64 as_uint64;
89
- struct {
90
- u64 vector:8;
91
- u64 reserved1:8;
92
- u64 masked:1;
93
- u64 auto_eoi:1;
94
- u64 reserved2:46;
95
- };
96
-};
97
-
98
-/* Define the format of the SIMP register */
99
-union hv_synic_simp {
100
- u64 as_uint64;
101
- struct {
102
- u64 simp_enabled:1;
103
- u64 preserved:11;
104
- u64 base_simp_gpa:52;
105
- };
106
-};
107
-
108
-/* Define the format of the SIEFP register */
109
-union hv_synic_siefp {
110
- u64 as_uint64;
111
- struct {
112
- u64 siefp_enabled:1;
113
- u64 preserved:11;
114
- u64 base_siefp_gpa:52;
115
- };
116
-};
11735
11836 /* Definitions for the monitored notification facility */
11937 union hv_monitor_trigger_group {
....@@ -215,13 +133,6 @@
215133 * basis.
216134 */
217135 struct tasklet_struct msg_dpc;
218
-
219
- /*
220
- * To optimize the mapping of relid to channel, maintain
221
- * per-cpu list of the channels based on their CPU affinity.
222
- */
223
- struct list_head chan_list;
224
- struct clock_event_device *clk_evt;
225136 };
226137
227138 struct hv_context {
....@@ -229,10 +140,6 @@
229140 * So at this point this really can only contain the Hyper-V ID
230141 */
231142 u64 guestid;
232
-
233
- void *tsc_page;
234
-
235
- bool synic_initialized;
236143
237144 struct hv_per_cpu_context __percpu *cpu_context;
238145
....@@ -257,14 +164,15 @@
257164
258165 extern void hv_synic_free(void);
259166
167
+extern void hv_synic_enable_regs(unsigned int cpu);
260168 extern int hv_synic_init(unsigned int cpu);
261169
170
+extern void hv_synic_disable_regs(unsigned int cpu);
262171 extern int hv_synic_cleanup(unsigned int cpu);
263
-
264
-extern void hv_synic_clockevents_cleanup(void);
265172
266173 /* Interface */
267174
175
+void hv_ringbuffer_pre_init(struct vmbus_channel *channel);
268176
269177 int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
270178 struct page *pages, u32 pagecnt);
....@@ -279,16 +187,18 @@
279187 u64 *requestid, bool raw);
280188
281189 /*
282
- * Maximum channels is determined by the size of the interrupt page
283
- * which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt
284
- * and the other is receive endpoint interrupt
190
+ * The Maximum number of channels (16348) is determined by the size of the
191
+ * interrupt page, which is HV_HYP_PAGE_SIZE. 1/2 of HV_HYP_PAGE_SIZE is to
192
+ * send endpoint interrupts, and the other is to receive endpoint interrupts.
285193 */
286
-#define MAX_NUM_CHANNELS ((PAGE_SIZE >> 1) << 3) /* 16348 channels */
194
+#define MAX_NUM_CHANNELS ((HV_HYP_PAGE_SIZE >> 1) << 3)
287195
288196 /* The value here must be in multiple of 32 */
289197 /* TODO: Need to make this configurable */
290198 #define MAX_NUM_CHANNELS_SUPPORTED 256
291199
200
+#define MAX_CHANNEL_RELIDS \
201
+ max(MAX_NUM_CHANNELS_SUPPORTED, HV_EVENT_FLAGS_COUNT)
292202
293203 enum vmbus_connect_state {
294204 DISCONNECTED,
....@@ -299,12 +209,13 @@
299209
300210 #define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT
301211
302
-struct vmbus_connection {
303
- /*
304
- * CPU on which the initial host contact was made.
305
- */
306
- int connect_cpu;
212
+/*
213
+ * The CPU that Hyper-V will interrupt for VMBUS messages, such as
214
+ * CHANNELMSG_OFFERCHANNEL and CHANNELMSG_RESCIND_CHANNELOFFER.
215
+ */
216
+#define VMBUS_CONNECT_CPU 0
307217
218
+struct vmbus_connection {
308219 u32 msg_conn_id;
309220
310221 atomic_t offer_in_progress;
....@@ -337,6 +248,9 @@
337248 struct list_head chn_list;
338249 struct mutex channel_mutex;
339250
251
+ /* Array of channels */
252
+ struct vmbus_channel **channels;
253
+
340254 /*
341255 * An offer message is handled first on the work_queue, and then
342256 * is further handled on handle_primary_chan_wq or
....@@ -345,6 +259,32 @@
345259 struct workqueue_struct *work_queue;
346260 struct workqueue_struct *handle_primary_chan_wq;
347261 struct workqueue_struct *handle_sub_chan_wq;
262
+
263
+ /*
264
+ * The number of sub-channels and hv_sock channels that should be
265
+ * cleaned up upon suspend: sub-channels will be re-created upon
266
+ * resume, and hv_sock channels should not survive suspend.
267
+ */
268
+ atomic_t nr_chan_close_on_suspend;
269
+ /*
270
+ * vmbus_bus_suspend() waits for "nr_chan_close_on_suspend" to
271
+ * drop to zero.
272
+ */
273
+ struct completion ready_for_suspend_event;
274
+
275
+ /*
276
+ * The number of primary channels that should be "fixed up"
277
+ * upon resume: these channels are re-offered upon resume, and some
278
+ * fields of the channel offers (i.e. child_relid and connection_id)
279
+ * can change, so the old offermsg must be fixed up, before the resume
280
+ * callbacks of the VSC drivers start to further touch the channels.
281
+ */
282
+ atomic_t nr_chan_fixup_on_resume;
283
+ /*
284
+ * vmbus_bus_resume() waits for "nr_chan_fixup_on_resume" to
285
+ * drop to zero.
286
+ */
287
+ struct completion ready_for_resume_event;
348288 };
349289
350290
....@@ -353,11 +293,13 @@
353293 struct list_head msglist_entry;
354294
355295 /* The message itself */
356
- unsigned char msg[0];
296
+ unsigned char msg[];
357297 };
358298
359299
360300 extern struct vmbus_connection vmbus_connection;
301
+
302
+int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version);
361303
362304 static inline void vmbus_send_interrupt(u32 relid)
363305 {
....@@ -376,6 +318,7 @@
376318 enum vmbus_channel_message_type message_type;
377319 enum vmbus_message_handler_type handler_type;
378320 void (*message_handler)(struct vmbus_channel_message_header *msg);
321
+ u32 min_payload_len;
379322 };
380323
381324 extern const struct vmbus_channel_message_table_entry
....@@ -384,8 +327,8 @@
384327
385328 /* General vmbus interface */
386329
387
-struct hv_device *vmbus_device_create(const uuid_le *type,
388
- const uuid_le *instance,
330
+struct hv_device *vmbus_device_create(const guid_t *type,
331
+ const guid_t *instance,
389332 struct vmbus_channel *channel);
390333
391334 int vmbus_device_register(struct hv_device *child_device_obj);
....@@ -394,6 +337,9 @@
394337 struct vmbus_channel *channel);
395338
396339 void vmbus_remove_channel_attr_group(struct vmbus_channel *channel);
340
+
341
+void vmbus_channel_map_relid(struct vmbus_channel *channel);
342
+void vmbus_channel_unmap_relid(struct vmbus_channel *channel);
397343
398344 struct vmbus_channel *relid2channel(u32 relid);
399345
....@@ -411,14 +357,20 @@
411357
412358 int hv_kvp_init(struct hv_util_service *srv);
413359 void hv_kvp_deinit(void);
360
+int hv_kvp_pre_suspend(void);
361
+int hv_kvp_pre_resume(void);
414362 void hv_kvp_onchannelcallback(void *context);
415363
416364 int hv_vss_init(struct hv_util_service *srv);
417365 void hv_vss_deinit(void);
366
+int hv_vss_pre_suspend(void);
367
+int hv_vss_pre_resume(void);
418368 void hv_vss_onchannelcallback(void *context);
419369
420370 int hv_fcopy_init(struct hv_util_service *srv);
421371 void hv_fcopy_deinit(void);
372
+int hv_fcopy_pre_suspend(void);
373
+int hv_fcopy_pre_resume(void);
422374 void hv_fcopy_onchannelcallback(void *context);
423375 void vmbus_initiate_unload(bool crash);
424376
....@@ -427,12 +379,7 @@
427379 {
428380 if (!channel)
429381 return;
430
-
431
- if (in_interrupt() && (channel->target_cpu == smp_processor_id())) {
432
- cb(channel);
433
- return;
434
- }
435
- smp_call_function_single(channel->target_cpu, cb, channel, true);
382
+ cb(channel);
436383 }
437384
438385 enum hvutil_device_state {
....@@ -444,4 +391,83 @@
444391 HVUTIL_DEVICE_DYING, /* driver unload is in progress */
445392 };
446393
394
+enum delay {
395
+ INTERRUPT_DELAY = 0,
396
+ MESSAGE_DELAY = 1,
397
+};
398
+
399
+extern const struct vmbus_device vmbus_devs[];
400
+
401
+static inline bool hv_is_perf_channel(struct vmbus_channel *channel)
402
+{
403
+ return vmbus_devs[channel->device_id].perf_device;
404
+}
405
+
406
+static inline bool hv_is_alloced_cpu(unsigned int cpu)
407
+{
408
+ struct vmbus_channel *channel, *sc;
409
+
410
+ lockdep_assert_held(&vmbus_connection.channel_mutex);
411
+ /*
412
+ * List additions/deletions as well as updates of the target CPUs are
413
+ * protected by channel_mutex.
414
+ */
415
+ list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
416
+ if (!hv_is_perf_channel(channel))
417
+ continue;
418
+ if (channel->target_cpu == cpu)
419
+ return true;
420
+ list_for_each_entry(sc, &channel->sc_list, sc_list) {
421
+ if (sc->target_cpu == cpu)
422
+ return true;
423
+ }
424
+ }
425
+ return false;
426
+}
427
+
428
+static inline void hv_set_alloced_cpu(unsigned int cpu)
429
+{
430
+ cpumask_set_cpu(cpu, &hv_context.hv_numa_map[cpu_to_node(cpu)]);
431
+}
432
+
433
+static inline void hv_clear_alloced_cpu(unsigned int cpu)
434
+{
435
+ if (hv_is_alloced_cpu(cpu))
436
+ return;
437
+ cpumask_clear_cpu(cpu, &hv_context.hv_numa_map[cpu_to_node(cpu)]);
438
+}
439
+
440
+static inline void hv_update_alloced_cpus(unsigned int old_cpu,
441
+ unsigned int new_cpu)
442
+{
443
+ hv_set_alloced_cpu(new_cpu);
444
+ hv_clear_alloced_cpu(old_cpu);
445
+}
446
+
447
+#ifdef CONFIG_HYPERV_TESTING
448
+
449
+int hv_debug_add_dev_dir(struct hv_device *dev);
450
+void hv_debug_rm_dev_dir(struct hv_device *dev);
451
+void hv_debug_rm_all_dir(void);
452
+int hv_debug_init(void);
453
+void hv_debug_delay_test(struct vmbus_channel *channel, enum delay delay_type);
454
+
455
+#else /* CONFIG_HYPERV_TESTING */
456
+
457
+static inline void hv_debug_rm_dev_dir(struct hv_device *dev) {};
458
+static inline void hv_debug_rm_all_dir(void) {};
459
+static inline void hv_debug_delay_test(struct vmbus_channel *channel,
460
+ enum delay delay_type) {};
461
+static inline int hv_debug_init(void)
462
+{
463
+ return -1;
464
+}
465
+
466
+static inline int hv_debug_add_dev_dir(struct hv_device *dev)
467
+{
468
+ return -1;
469
+}
470
+
471
+#endif /* CONFIG_HYPERV_TESTING */
472
+
447473 #endif /* _HYPERV_VMBUS_H */