13b20eb23SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
246a97191SGreg Kroah-Hartman /*
346a97191SGreg Kroah-Hartman *
446a97191SGreg Kroah-Hartman * Copyright (c) 2011, Microsoft Corporation.
546a97191SGreg Kroah-Hartman *
646a97191SGreg Kroah-Hartman * Authors:
746a97191SGreg Kroah-Hartman * Haiyang Zhang <haiyangz@microsoft.com>
846a97191SGreg Kroah-Hartman * Hank Janssen <hjanssen@microsoft.com>
946a97191SGreg Kroah-Hartman * K. Y. Srinivasan <kys@microsoft.com>
1046a97191SGreg Kroah-Hartman */
1146a97191SGreg Kroah-Hartman
1246a97191SGreg Kroah-Hartman #ifndef _HYPERV_VMBUS_H
1346a97191SGreg Kroah-Hartman #define _HYPERV_VMBUS_H
1446a97191SGreg Kroah-Hartman
1546a97191SGreg Kroah-Hartman #include <linux/list.h>
168017c996SArnd Bergmann #include <linux/bitops.h>
1746a97191SGreg Kroah-Hartman #include <asm/sync_bitops.h>
185a485803SVitaly Kuznetsov #include <asm/hyperv-tlfs.h>
1946a97191SGreg Kroah-Hartman #include <linux/atomic.h>
2046a97191SGreg Kroah-Hartman #include <linux/hyperv.h>
2137cdd991SStephen Hemminger #include <linux/interrupt.h>
2246a97191SGreg Kroah-Hartman
23c9fe0f8fSVitaly Kuznetsov #include "hv_trace.h"
24c9fe0f8fSVitaly Kuznetsov
2546a97191SGreg Kroah-Hartman /*
26c0b200cfSK. Y. Srinivasan * Timeout for services such as KVP and fcopy.
27c0b200cfSK. Y. Srinivasan */
28c0b200cfSK. Y. Srinivasan #define HV_UTIL_TIMEOUT 30
29c0b200cfSK. Y. Srinivasan
30c0b200cfSK. Y. Srinivasan /*
314dbfc2e6SVitaly Kuznetsov * Timeout for guest-host handshake for services.
324dbfc2e6SVitaly Kuznetsov */
33d7edd31bSVitaly Kuznetsov #define HV_UTIL_NEGO_TIMEOUT 55
344dbfc2e6SVitaly Kuznetsov
3546a97191SGreg Kroah-Hartman
3646a97191SGreg Kroah-Hartman /* Definitions for the monitored notification facility */
3746a97191SGreg Kroah-Hartman union hv_monitor_trigger_group {
3846a97191SGreg Kroah-Hartman u64 as_uint64;
3946a97191SGreg Kroah-Hartman struct {
4046a97191SGreg Kroah-Hartman u32 pending;
4146a97191SGreg Kroah-Hartman u32 armed;
4246a97191SGreg Kroah-Hartman };
4346a97191SGreg Kroah-Hartman };
4446a97191SGreg Kroah-Hartman
4546a97191SGreg Kroah-Hartman struct hv_monitor_parameter {
4646a97191SGreg Kroah-Hartman union hv_connection_id connectionid;
4746a97191SGreg Kroah-Hartman u16 flagnumber;
4846a97191SGreg Kroah-Hartman u16 rsvdz;
4946a97191SGreg Kroah-Hartman };
5046a97191SGreg Kroah-Hartman
5146a97191SGreg Kroah-Hartman union hv_monitor_trigger_state {
5246a97191SGreg Kroah-Hartman u32 asu32;
5346a97191SGreg Kroah-Hartman
5446a97191SGreg Kroah-Hartman struct {
5546a97191SGreg Kroah-Hartman u32 group_enable:4;
5646a97191SGreg Kroah-Hartman u32 rsvdz:28;
5746a97191SGreg Kroah-Hartman };
5846a97191SGreg Kroah-Hartman };
5946a97191SGreg Kroah-Hartman
6046a97191SGreg Kroah-Hartman /* struct hv_monitor_page Layout */
6146a97191SGreg Kroah-Hartman /* ------------------------------------------------------ */
6246a97191SGreg Kroah-Hartman /* | 0 | TriggerState (4 bytes) | Rsvd1 (4 bytes) | */
6346a97191SGreg Kroah-Hartman /* | 8 | TriggerGroup[0] | */
6446a97191SGreg Kroah-Hartman /* | 10 | TriggerGroup[1] | */
6546a97191SGreg Kroah-Hartman /* | 18 | TriggerGroup[2] | */
6646a97191SGreg Kroah-Hartman /* | 20 | TriggerGroup[3] | */
6746a97191SGreg Kroah-Hartman /* | 28 | Rsvd2[0] | */
6846a97191SGreg Kroah-Hartman /* | 30 | Rsvd2[1] | */
6946a97191SGreg Kroah-Hartman /* | 38 | Rsvd2[2] | */
7046a97191SGreg Kroah-Hartman /* | 40 | NextCheckTime[0][0] | NextCheckTime[0][1] | */
7146a97191SGreg Kroah-Hartman /* | ... | */
7246a97191SGreg Kroah-Hartman /* | 240 | Latency[0][0..3] | */
7346a97191SGreg Kroah-Hartman /* | 340 | Rsvz3[0] | */
7446a97191SGreg Kroah-Hartman /* | 440 | Parameter[0][0] | */
7546a97191SGreg Kroah-Hartman /* | 448 | Parameter[0][1] | */
7646a97191SGreg Kroah-Hartman /* | ... | */
7746a97191SGreg Kroah-Hartman /* | 840 | Rsvd4[0] | */
7846a97191SGreg Kroah-Hartman /* ------------------------------------------------------ */
7946a97191SGreg Kroah-Hartman struct hv_monitor_page {
8046a97191SGreg Kroah-Hartman union hv_monitor_trigger_state trigger_state;
8146a97191SGreg Kroah-Hartman u32 rsvdz1;
8246a97191SGreg Kroah-Hartman
8346a97191SGreg Kroah-Hartman union hv_monitor_trigger_group trigger_group[4];
8446a97191SGreg Kroah-Hartman u64 rsvdz2[3];
8546a97191SGreg Kroah-Hartman
8646a97191SGreg Kroah-Hartman s32 next_checktime[4][32];
8746a97191SGreg Kroah-Hartman
8846a97191SGreg Kroah-Hartman u16 latency[4][32];
8946a97191SGreg Kroah-Hartman u64 rsvdz3[32];
9046a97191SGreg Kroah-Hartman
9146a97191SGreg Kroah-Hartman struct hv_monitor_parameter parameter[4][32];
9246a97191SGreg Kroah-Hartman
9346a97191SGreg Kroah-Hartman u8 rsvdz4[1984];
9446a97191SGreg Kroah-Hartman };
9546a97191SGreg Kroah-Hartman
968e27a236SK. Y. Srinivasan #define HV_HYPERCALL_PARAM_ALIGN sizeof(u64)
978e27a236SK. Y. Srinivasan
9846a97191SGreg Kroah-Hartman /* Definition of the hv_post_message hypercall input structure. */
9946a97191SGreg Kroah-Hartman struct hv_input_post_message {
10046a97191SGreg Kroah-Hartman union hv_connection_id connectionid;
10146a97191SGreg Kroah-Hartman u32 reserved;
1027797dcf6SAndrey Smetanin u32 message_type;
10346a97191SGreg Kroah-Hartman u32 payload_size;
10446a97191SGreg Kroah-Hartman u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
10546a97191SGreg Kroah-Hartman };
10646a97191SGreg Kroah-Hartman
10746a97191SGreg Kroah-Hartman
10846a97191SGreg Kroah-Hartman enum {
10946a97191SGreg Kroah-Hartman VMBUS_MESSAGE_CONNECTION_ID = 1,
110ae20b254SDexuan Cui VMBUS_MESSAGE_CONNECTION_ID_4 = 4,
11146a97191SGreg Kroah-Hartman VMBUS_MESSAGE_PORT_ID = 1,
11246a97191SGreg Kroah-Hartman VMBUS_EVENT_CONNECTION_ID = 2,
11346a97191SGreg Kroah-Hartman VMBUS_EVENT_PORT_ID = 2,
11446a97191SGreg Kroah-Hartman VMBUS_MONITOR_CONNECTION_ID = 3,
11546a97191SGreg Kroah-Hartman VMBUS_MONITOR_PORT_ID = 3,
11646a97191SGreg Kroah-Hartman VMBUS_MESSAGE_SINT = 2,
11746a97191SGreg Kroah-Hartman };
11846a97191SGreg Kroah-Hartman
11937cdd991SStephen Hemminger /*
12037cdd991SStephen Hemminger * Per cpu state for channel handling
12137cdd991SStephen Hemminger */
12237cdd991SStephen Hemminger struct hv_per_cpu_context {
12337cdd991SStephen Hemminger void *synic_message_page;
12437cdd991SStephen Hemminger void *synic_event_page;
12537cdd991SStephen Hemminger
12637cdd991SStephen Hemminger /*
12723378295SDexuan Cui * The page is only used in hv_post_message() for a TDX VM (with the
12823378295SDexuan Cui * paravisor) to post a messages to Hyper-V: when such a VM calls
12923378295SDexuan Cui * HVCALL_POST_MESSAGE, it can't use the hyperv_pcpu_input_arg (which
13023378295SDexuan Cui * is encrypted in such a VM) as the hypercall input page, because
13123378295SDexuan Cui * the input page for HVCALL_POST_MESSAGE must be decrypted in such a
13223378295SDexuan Cui * VM, so post_msg_page (which is decrypted in hv_synic_alloc()) is
13323378295SDexuan Cui * introduced for this purpose. See hyperv_init() for more comments.
13423378295SDexuan Cui */
13523378295SDexuan Cui void *post_msg_page;
13623378295SDexuan Cui
13723378295SDexuan Cui /*
13837cdd991SStephen Hemminger * Starting with win8, we can take channel interrupts on any CPU;
13937cdd991SStephen Hemminger * we will manage the tasklet that handles events messages on a per CPU
14037cdd991SStephen Hemminger * basis.
14137cdd991SStephen Hemminger */
14237cdd991SStephen Hemminger struct tasklet_struct msg_dpc;
14337cdd991SStephen Hemminger };
14437cdd991SStephen Hemminger
14546a97191SGreg Kroah-Hartman struct hv_context {
14646a97191SGreg Kroah-Hartman /* We only support running on top of Hyper-V
14746a97191SGreg Kroah-Hartman * So at this point this really can only contain the Hyper-V ID
14846a97191SGreg Kroah-Hartman */
14946a97191SGreg Kroah-Hartman u64 guestid;
15046a97191SGreg Kroah-Hartman
15137cdd991SStephen Hemminger struct hv_per_cpu_context __percpu *cpu_context;
15237cdd991SStephen Hemminger
153917ea427SK. Y. Srinivasan /*
1549f01ec53SK. Y. Srinivasan * To manage allocations in a NUMA node.
1559f01ec53SK. Y. Srinivasan * Array indexed by numa node ID.
1569f01ec53SK. Y. Srinivasan */
1579f01ec53SK. Y. Srinivasan struct cpumask *hv_numa_map;
15846a97191SGreg Kroah-Hartman };
15946a97191SGreg Kroah-Hartman
16046a97191SGreg Kroah-Hartman extern struct hv_context hv_context;
16146a97191SGreg Kroah-Hartman
16246a97191SGreg Kroah-Hartman /* Hv Interface */
16346a97191SGreg Kroah-Hartman
16446a97191SGreg Kroah-Hartman extern int hv_init(void);
16546a97191SGreg Kroah-Hartman
166415f0a02SDan Carpenter extern int hv_post_message(union hv_connection_id connection_id,
16746a97191SGreg Kroah-Hartman enum hv_message_type message_type,
16846a97191SGreg Kroah-Hartman void *payload, size_t payload_size);
16946a97191SGreg Kroah-Hartman
1702608fb65SJason Wang extern int hv_synic_alloc(void);
1712608fb65SJason Wang
1722608fb65SJason Wang extern void hv_synic_free(void);
1732608fb65SJason Wang
174dba61cdaSDexuan Cui extern void hv_synic_enable_regs(unsigned int cpu);
17576d36ab7SVitaly Kuznetsov extern int hv_synic_init(unsigned int cpu);
17646a97191SGreg Kroah-Hartman
177dba61cdaSDexuan Cui extern void hv_synic_disable_regs(unsigned int cpu);
17876d36ab7SVitaly Kuznetsov extern int hv_synic_cleanup(unsigned int cpu);
17946a97191SGreg Kroah-Hartman
18046a97191SGreg Kroah-Hartman /* Interface */
18146a97191SGreg Kroah-Hartman
18214948e39SKimberly Brown void hv_ringbuffer_pre_init(struct vmbus_channel *channel);
18346a97191SGreg Kroah-Hartman
1849988ce68SVitaly Kuznetsov int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
185adae1e93SAndres Beltran struct page *pages, u32 pagecnt, u32 max_pkt_size);
18646a97191SGreg Kroah-Hartman
18746a97191SGreg Kroah-Hartman void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info);
18846a97191SGreg Kroah-Hartman
1891f6ee4e7SK. Y. Srinivasan int hv_ringbuffer_write(struct vmbus_channel *channel,
190e8b7db38SAndres Beltran const struct kvec *kv_list, u32 kv_count,
191b03afa57SAndrea Parri (Microsoft) u64 requestid, u64 *trans_id);
19246a97191SGreg Kroah-Hartman
1933372592aSK. Y. Srinivasan int hv_ringbuffer_read(struct vmbus_channel *channel,
194940b68e2SVitaly Kuznetsov void *buffer, u32 buflen, u32 *buffer_actual_len,
1953372592aSK. Y. Srinivasan u64 *requestid, bool raw);
19646a97191SGreg Kroah-Hartman
19746a97191SGreg Kroah-Hartman /*
1985c641feeSStefan Eschenbacher * The Maximum number of channels (16384) is determined by the size of the
19983527ef7SMaya Nakamura * interrupt page, which is HV_HYP_PAGE_SIZE. 1/2 of HV_HYP_PAGE_SIZE is to
20083527ef7SMaya Nakamura * send endpoint interrupts, and the other is to receive endpoint interrupts.
20146a97191SGreg Kroah-Hartman */
20283527ef7SMaya Nakamura #define MAX_NUM_CHANNELS ((HV_HYP_PAGE_SIZE >> 1) << 3)
20346a97191SGreg Kroah-Hartman
20446a97191SGreg Kroah-Hartman /* The value here must be in multiple of 32 */
20546a97191SGreg Kroah-Hartman #define MAX_NUM_CHANNELS_SUPPORTED 256
20646a97191SGreg Kroah-Hartman
2078b6a877cSAndrea Parri (Microsoft) #define MAX_CHANNEL_RELIDS \
2088b6a877cSAndrea Parri (Microsoft) max(MAX_NUM_CHANNELS_SUPPORTED, HV_EVENT_FLAGS_COUNT)
20946a97191SGreg Kroah-Hartman
21046a97191SGreg Kroah-Hartman enum vmbus_connect_state {
21146a97191SGreg Kroah-Hartman DISCONNECTED,
21246a97191SGreg Kroah-Hartman CONNECTING,
21346a97191SGreg Kroah-Hartman CONNECTED,
21446a97191SGreg Kroah-Hartman DISCONNECTING
21546a97191SGreg Kroah-Hartman };
21646a97191SGreg Kroah-Hartman
21746a97191SGreg Kroah-Hartman #define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT
21846a97191SGreg Kroah-Hartman
21954a66265SK. Y. Srinivasan /*
2208a857c55SAndrea Parri (Microsoft) * The CPU that Hyper-V will interrupt for VMBUS messages, such as
2218a857c55SAndrea Parri (Microsoft) * CHANNELMSG_OFFERCHANNEL and CHANNELMSG_RESCIND_CHANNELOFFER.
22254a66265SK. Y. Srinivasan */
2238a857c55SAndrea Parri (Microsoft) #define VMBUS_CONNECT_CPU 0
22454a66265SK. Y. Srinivasan
2258a857c55SAndrea Parri (Microsoft) struct vmbus_connection {
226ae20b254SDexuan Cui u32 msg_conn_id;
227ae20b254SDexuan Cui
22854a66265SK. Y. Srinivasan atomic_t offer_in_progress;
22954a66265SK. Y. Srinivasan
23046a97191SGreg Kroah-Hartman enum vmbus_connect_state conn_state;
23146a97191SGreg Kroah-Hartman
23246a97191SGreg Kroah-Hartman atomic_t next_gpadl_handle;
23346a97191SGreg Kroah-Hartman
2342db84effSK. Y. Srinivasan struct completion unload_event;
23546a97191SGreg Kroah-Hartman /*
23646a97191SGreg Kroah-Hartman * Represents channel interrupts. Each bit position represents a
23746a97191SGreg Kroah-Hartman * channel. When a channel sends an interrupt via VMBUS, it finds its
23846a97191SGreg Kroah-Hartman * bit in the sendInterruptPage, set it and calls Hv to generate a port
23946a97191SGreg Kroah-Hartman * event. The other end receives the port event and parse the
24046a97191SGreg Kroah-Hartman * recvInterruptPage to see which bit is set
24146a97191SGreg Kroah-Hartman */
24246a97191SGreg Kroah-Hartman void *int_page;
24346a97191SGreg Kroah-Hartman void *send_int_page;
24446a97191SGreg Kroah-Hartman void *recv_int_page;
24546a97191SGreg Kroah-Hartman
24646a97191SGreg Kroah-Hartman /*
24746a97191SGreg Kroah-Hartman * 2 pages - 1st page for parent->child notification and 2nd
24846a97191SGreg Kroah-Hartman * is child->parent notification
24946a97191SGreg Kroah-Hartman */
2508681db44SGreg Kroah-Hartman struct hv_monitor_page *monitor_pages[2];
25146a97191SGreg Kroah-Hartman struct list_head chn_msg_list;
25246a97191SGreg Kroah-Hartman spinlock_t channelmsg_lock;
25346a97191SGreg Kroah-Hartman
25446a97191SGreg Kroah-Hartman /* List of channels */
25546a97191SGreg Kroah-Hartman struct list_head chn_list;
256d6f591e3SDexuan Cui struct mutex channel_mutex;
25746a97191SGreg Kroah-Hartman
2588b6a877cSAndrea Parri (Microsoft) /* Array of channels */
2598b6a877cSAndrea Parri (Microsoft) struct vmbus_channel **channels;
2608b6a877cSAndrea Parri (Microsoft)
26137c2578cSDexuan Cui /*
26237c2578cSDexuan Cui * An offer message is handled first on the work_queue, and then
26337c2578cSDexuan Cui * is further handled on handle_primary_chan_wq or
26437c2578cSDexuan Cui * handle_sub_chan_wq.
26537c2578cSDexuan Cui */
26646a97191SGreg Kroah-Hartman struct workqueue_struct *work_queue;
26737c2578cSDexuan Cui struct workqueue_struct *handle_primary_chan_wq;
26837c2578cSDexuan Cui struct workqueue_struct *handle_sub_chan_wq;
26952be9355SShradha Gupta struct workqueue_struct *rescind_work_queue;
27052be9355SShradha Gupta
27152be9355SShradha Gupta /*
27252be9355SShradha Gupta * On suspension of the vmbus, the accumulated offer messages
27352be9355SShradha Gupta * must be dropped.
27452be9355SShradha Gupta */
27552be9355SShradha Gupta bool ignore_any_offer_msg;
276b307b389SDexuan Cui
277b307b389SDexuan Cui /*
278b307b389SDexuan Cui * The number of sub-channels and hv_sock channels that should be
279b307b389SDexuan Cui * cleaned up upon suspend: sub-channels will be re-created upon
280b307b389SDexuan Cui * resume, and hv_sock channels should not survive suspend.
281b307b389SDexuan Cui */
282b307b389SDexuan Cui atomic_t nr_chan_close_on_suspend;
283b307b389SDexuan Cui /*
284b307b389SDexuan Cui * vmbus_bus_suspend() waits for "nr_chan_close_on_suspend" to
285b307b389SDexuan Cui * drop to zero.
286b307b389SDexuan Cui */
287b307b389SDexuan Cui struct completion ready_for_suspend_event;
288d8bd2d44SDexuan Cui
289d8bd2d44SDexuan Cui /*
290d8bd2d44SDexuan Cui * The number of primary channels that should be "fixed up"
291d8bd2d44SDexuan Cui * upon resume: these channels are re-offered upon resume, and some
292d8bd2d44SDexuan Cui * fields of the channel offers (i.e. child_relid and connection_id)
293d8bd2d44SDexuan Cui * can change, so the old offermsg must be fixed up, before the resume
294d8bd2d44SDexuan Cui * callbacks of the VSC drivers start to further touch the channels.
295d8bd2d44SDexuan Cui */
296d8bd2d44SDexuan Cui atomic_t nr_chan_fixup_on_resume;
297d8bd2d44SDexuan Cui /*
298d8bd2d44SDexuan Cui * vmbus_bus_resume() waits for "nr_chan_fixup_on_resume" to
299d8bd2d44SDexuan Cui * drop to zero.
300d8bd2d44SDexuan Cui */
301d8bd2d44SDexuan Cui struct completion ready_for_resume_event;
30246a97191SGreg Kroah-Hartman };
30346a97191SGreg Kroah-Hartman
30446a97191SGreg Kroah-Hartman
30546a97191SGreg Kroah-Hartman struct vmbus_msginfo {
30646a97191SGreg Kroah-Hartman /* Bookkeeping stuff */
30746a97191SGreg Kroah-Hartman struct list_head msglist_entry;
30846a97191SGreg Kroah-Hartman
30946a97191SGreg Kroah-Hartman /* The message itself */
310032d4a48SGustavo A. R. Silva unsigned char msg[];
31146a97191SGreg Kroah-Hartman };
31246a97191SGreg Kroah-Hartman
31346a97191SGreg Kroah-Hartman
31446a97191SGreg Kroah-Hartman extern struct vmbus_connection vmbus_connection;
31546a97191SGreg Kroah-Hartman
316f53335e3SDexuan Cui int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version);
317f53335e3SDexuan Cui
vmbus_send_interrupt(u32 relid)3185c1bec61SStephen Hemminger static inline void vmbus_send_interrupt(u32 relid)
3195c1bec61SStephen Hemminger {
3205c1bec61SStephen Hemminger sync_set_bit(relid, vmbus_connection.send_int_page);
3215c1bec61SStephen Hemminger }
3225c1bec61SStephen Hemminger
323652594c7SDexuan Cui enum vmbus_message_handler_type {
324652594c7SDexuan Cui /* The related handler can sleep. */
325652594c7SDexuan Cui VMHT_BLOCKING = 0,
326652594c7SDexuan Cui
327652594c7SDexuan Cui /* The related handler must NOT sleep. */
328652594c7SDexuan Cui VMHT_NON_BLOCKING = 1,
329652594c7SDexuan Cui };
330652594c7SDexuan Cui
331652594c7SDexuan Cui struct vmbus_channel_message_table_entry {
332652594c7SDexuan Cui enum vmbus_channel_message_type message_type;
333652594c7SDexuan Cui enum vmbus_message_handler_type handler_type;
334652594c7SDexuan Cui void (*message_handler)(struct vmbus_channel_message_header *msg);
33552c7803fSVitaly Kuznetsov u32 min_payload_len;
336652594c7SDexuan Cui };
337652594c7SDexuan Cui
338e6242fa0SStephen Hemminger extern const struct vmbus_channel_message_table_entry
339652594c7SDexuan Cui channel_message_table[CHANNELMSG_COUNT];
340652594c7SDexuan Cui
3410f70b669SVitaly Kuznetsov
34246a97191SGreg Kroah-Hartman /* General vmbus interface */
34346a97191SGreg Kroah-Hartman
344593db803SAndy Shevchenko struct hv_device *vmbus_device_create(const guid_t *type,
345593db803SAndy Shevchenko const guid_t *instance,
34646a97191SGreg Kroah-Hartman struct vmbus_channel *channel);
34746a97191SGreg Kroah-Hartman
34846a97191SGreg Kroah-Hartman int vmbus_device_register(struct hv_device *child_device_obj);
34946a97191SGreg Kroah-Hartman void vmbus_device_unregister(struct hv_device *device_obj);
350c2e5df61SStephen Hemminger int vmbus_add_channel_kobj(struct hv_device *device_obj,
351c2e5df61SStephen Hemminger struct vmbus_channel *channel);
35246a97191SGreg Kroah-Hartman
35346fc1548SKimberly Brown void vmbus_remove_channel_attr_group(struct vmbus_channel *channel);
35446fc1548SKimberly Brown
3558b6a877cSAndrea Parri (Microsoft) void vmbus_channel_map_relid(struct vmbus_channel *channel);
3568b6a877cSAndrea Parri (Microsoft) void vmbus_channel_unmap_relid(struct vmbus_channel *channel);
3578b6a877cSAndrea Parri (Microsoft)
358d43e2fe7SDexuan Cui struct vmbus_channel *relid2channel(u32 relid);
35946a97191SGreg Kroah-Hartman
36093e5bd06SK. Y. Srinivasan void vmbus_free_channels(void);
36146a97191SGreg Kroah-Hartman
36246a97191SGreg Kroah-Hartman /* Connection interface */
36346a97191SGreg Kroah-Hartman
36446a97191SGreg Kroah-Hartman int vmbus_connect(void);
36509a19628SVitaly Kuznetsov void vmbus_disconnect(void);
36646a97191SGreg Kroah-Hartman
367c0bb0392SVitaly Kuznetsov int vmbus_post_msg(void *buffer, size_t buflen, bool can_sleep);
36846a97191SGreg Kroah-Hartman
36946a97191SGreg Kroah-Hartman void vmbus_on_event(unsigned long data);
370d81274aaSK. Y. Srinivasan void vmbus_on_msg_dpc(unsigned long data);
37146a97191SGreg Kroah-Hartman
3722a9d7de2SStephen Hemminger int hv_kvp_init(struct hv_util_service *srv);
373*89fcec5eSMichael Kelley int hv_kvp_init_transport(void);
3743647a83dSVitaly Kuznetsov void hv_kvp_deinit(void);
37554e19d34SDexuan Cui int hv_kvp_pre_suspend(void);
37654e19d34SDexuan Cui int hv_kvp_pre_resume(void);
3772a9d7de2SStephen Hemminger void hv_kvp_onchannelcallback(void *context);
3783647a83dSVitaly Kuznetsov
3792a9d7de2SStephen Hemminger int hv_vss_init(struct hv_util_service *srv);
380*89fcec5eSMichael Kelley int hv_vss_init_transport(void);
3813647a83dSVitaly Kuznetsov void hv_vss_deinit(void);
38254e19d34SDexuan Cui int hv_vss_pre_suspend(void);
38354e19d34SDexuan Cui int hv_vss_pre_resume(void);
3842a9d7de2SStephen Hemminger void hv_vss_onchannelcallback(void *context);
3853647a83dSVitaly Kuznetsov
3862a9d7de2SStephen Hemminger int hv_fcopy_init(struct hv_util_service *srv);
38701325476SK. Y. Srinivasan void hv_fcopy_deinit(void);
38854e19d34SDexuan Cui int hv_fcopy_pre_suspend(void);
38954e19d34SDexuan Cui int hv_fcopy_pre_resume(void);
3902a9d7de2SStephen Hemminger void hv_fcopy_onchannelcallback(void *context);
39175ff3a8aSVitaly Kuznetsov void vmbus_initiate_unload(bool crash);
39201325476SK. Y. Srinivasan
hv_poll_channel(struct vmbus_channel * channel,void (* cb)(void *))3938efe78fdSVitaly Kuznetsov static inline void hv_poll_channel(struct vmbus_channel *channel,
3948efe78fdSVitaly Kuznetsov void (*cb)(void *))
3958efe78fdSVitaly Kuznetsov {
3968efe78fdSVitaly Kuznetsov if (!channel)
3978efe78fdSVitaly Kuznetsov return;
3981e052a16SK. Y. Srinivasan cb(channel);
3998efe78fdSVitaly Kuznetsov }
40046a97191SGreg Kroah-Hartman
401636c88daSVitaly Kuznetsov enum hvutil_device_state {
402636c88daSVitaly Kuznetsov HVUTIL_DEVICE_INIT = 0, /* driver is loaded, waiting for userspace */
403636c88daSVitaly Kuznetsov HVUTIL_READY, /* userspace is registered */
404636c88daSVitaly Kuznetsov HVUTIL_HOSTMSG_RECEIVED, /* message from the host was received */
405636c88daSVitaly Kuznetsov HVUTIL_USERSPACE_REQ, /* request to userspace was sent */
406636c88daSVitaly Kuznetsov HVUTIL_USERSPACE_RECV, /* reply from userspace was received */
407636c88daSVitaly Kuznetsov HVUTIL_DEVICE_DYING, /* driver unload is in progress */
408636c88daSVitaly Kuznetsov };
409636c88daSVitaly Kuznetsov
410af9ca6f9SBranden Bonaby enum delay {
411af9ca6f9SBranden Bonaby INTERRUPT_DELAY = 0,
412af9ca6f9SBranden Bonaby MESSAGE_DELAY = 1,
413af9ca6f9SBranden Bonaby };
414af9ca6f9SBranden Bonaby
415afaa33daSAndrea Parri (Microsoft) extern const struct vmbus_device vmbus_devs[];
416afaa33daSAndrea Parri (Microsoft)
hv_is_perf_channel(struct vmbus_channel * channel)417afaa33daSAndrea Parri (Microsoft) static inline bool hv_is_perf_channel(struct vmbus_channel *channel)
418afaa33daSAndrea Parri (Microsoft) {
419afaa33daSAndrea Parri (Microsoft) return vmbus_devs[channel->device_id].perf_device;
420afaa33daSAndrea Parri (Microsoft) }
421afaa33daSAndrea Parri (Microsoft)
hv_is_allocated_cpu(unsigned int cpu)422de96e8a0SVitaly Kuznetsov static inline bool hv_is_allocated_cpu(unsigned int cpu)
423afaa33daSAndrea Parri (Microsoft) {
424afaa33daSAndrea Parri (Microsoft) struct vmbus_channel *channel, *sc;
425afaa33daSAndrea Parri (Microsoft)
426afaa33daSAndrea Parri (Microsoft) lockdep_assert_held(&vmbus_connection.channel_mutex);
427afaa33daSAndrea Parri (Microsoft) /*
428afaa33daSAndrea Parri (Microsoft) * List additions/deletions as well as updates of the target CPUs are
429afaa33daSAndrea Parri (Microsoft) * protected by channel_mutex.
430afaa33daSAndrea Parri (Microsoft) */
431afaa33daSAndrea Parri (Microsoft) list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) {
432afaa33daSAndrea Parri (Microsoft) if (!hv_is_perf_channel(channel))
433afaa33daSAndrea Parri (Microsoft) continue;
434afaa33daSAndrea Parri (Microsoft) if (channel->target_cpu == cpu)
435afaa33daSAndrea Parri (Microsoft) return true;
436afaa33daSAndrea Parri (Microsoft) list_for_each_entry(sc, &channel->sc_list, sc_list) {
437afaa33daSAndrea Parri (Microsoft) if (sc->target_cpu == cpu)
438afaa33daSAndrea Parri (Microsoft) return true;
439afaa33daSAndrea Parri (Microsoft) }
440afaa33daSAndrea Parri (Microsoft) }
441afaa33daSAndrea Parri (Microsoft) return false;
442afaa33daSAndrea Parri (Microsoft) }
443afaa33daSAndrea Parri (Microsoft)
hv_set_allocated_cpu(unsigned int cpu)444de96e8a0SVitaly Kuznetsov static inline void hv_set_allocated_cpu(unsigned int cpu)
445afaa33daSAndrea Parri (Microsoft) {
446afaa33daSAndrea Parri (Microsoft) cpumask_set_cpu(cpu, &hv_context.hv_numa_map[cpu_to_node(cpu)]);
447afaa33daSAndrea Parri (Microsoft) }
448afaa33daSAndrea Parri (Microsoft)
hv_clear_allocated_cpu(unsigned int cpu)449de96e8a0SVitaly Kuznetsov static inline void hv_clear_allocated_cpu(unsigned int cpu)
450afaa33daSAndrea Parri (Microsoft) {
451de96e8a0SVitaly Kuznetsov if (hv_is_allocated_cpu(cpu))
452afaa33daSAndrea Parri (Microsoft) return;
453afaa33daSAndrea Parri (Microsoft) cpumask_clear_cpu(cpu, &hv_context.hv_numa_map[cpu_to_node(cpu)]);
454afaa33daSAndrea Parri (Microsoft) }
455afaa33daSAndrea Parri (Microsoft)
hv_update_allocated_cpus(unsigned int old_cpu,unsigned int new_cpu)456de96e8a0SVitaly Kuznetsov static inline void hv_update_allocated_cpus(unsigned int old_cpu,
457afaa33daSAndrea Parri (Microsoft) unsigned int new_cpu)
458afaa33daSAndrea Parri (Microsoft) {
459de96e8a0SVitaly Kuznetsov hv_set_allocated_cpu(new_cpu);
460de96e8a0SVitaly Kuznetsov hv_clear_allocated_cpu(old_cpu);
461afaa33daSAndrea Parri (Microsoft) }
462afaa33daSAndrea Parri (Microsoft)
463af9ca6f9SBranden Bonaby #ifdef CONFIG_HYPERV_TESTING
464af9ca6f9SBranden Bonaby
465af9ca6f9SBranden Bonaby int hv_debug_add_dev_dir(struct hv_device *dev);
466af9ca6f9SBranden Bonaby void hv_debug_rm_dev_dir(struct hv_device *dev);
467af9ca6f9SBranden Bonaby void hv_debug_rm_all_dir(void);
468af9ca6f9SBranden Bonaby int hv_debug_init(void);
469af9ca6f9SBranden Bonaby void hv_debug_delay_test(struct vmbus_channel *channel, enum delay delay_type);
470af9ca6f9SBranden Bonaby
471af9ca6f9SBranden Bonaby #else /* CONFIG_HYPERV_TESTING */
472af9ca6f9SBranden Bonaby
hv_debug_rm_dev_dir(struct hv_device * dev)473af9ca6f9SBranden Bonaby static inline void hv_debug_rm_dev_dir(struct hv_device *dev) {};
hv_debug_rm_all_dir(void)474af9ca6f9SBranden Bonaby static inline void hv_debug_rm_all_dir(void) {};
hv_debug_delay_test(struct vmbus_channel * channel,enum delay delay_type)475af9ca6f9SBranden Bonaby static inline void hv_debug_delay_test(struct vmbus_channel *channel,
476af9ca6f9SBranden Bonaby enum delay delay_type) {};
hv_debug_init(void)477af9ca6f9SBranden Bonaby static inline int hv_debug_init(void)
478af9ca6f9SBranden Bonaby {
479af9ca6f9SBranden Bonaby return -1;
480af9ca6f9SBranden Bonaby }
481af9ca6f9SBranden Bonaby
hv_debug_add_dev_dir(struct hv_device * dev)482af9ca6f9SBranden Bonaby static inline int hv_debug_add_dev_dir(struct hv_device *dev)
483af9ca6f9SBranden Bonaby {
484af9ca6f9SBranden Bonaby return -1;
485af9ca6f9SBranden Bonaby }
486af9ca6f9SBranden Bonaby
487af9ca6f9SBranden Bonaby #endif /* CONFIG_HYPERV_TESTING */
488af9ca6f9SBranden Bonaby
48946a97191SGreg Kroah-Hartman #endif /* _HYPERV_VMBUS_H */
490