diff options
Diffstat (limited to 'drivers/staging/hv/hyperv_vmbus.h')
-rw-r--r-- | drivers/staging/hv/hyperv_vmbus.h | 629 |
1 files changed, 0 insertions, 629 deletions
diff --git a/drivers/staging/hv/hyperv_vmbus.h b/drivers/staging/hv/hyperv_vmbus.h deleted file mode 100644 index 349ad80ce328..000000000000 --- a/drivers/staging/hv/hyperv_vmbus.h +++ /dev/null @@ -1,629 +0,0 @@ -/* - * - * Copyright (c) 2011, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang <haiyangz@microsoft.com> - * Hank Janssen <hjanssen@microsoft.com> - * K. Y. Srinivasan <kys@microsoft.com> - * - */ - -#ifndef _HYPERV_VMBUS_H -#define _HYPERV_VMBUS_H - -#include <linux/list.h> -#include <asm/sync_bitops.h> -#include <linux/atomic.h> - -#include "hyperv.h" - -/* - * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent - * is set by CPUID(HVCPUID_VERSION_FEATURES). - */ -enum hv_cpuid_function { - HVCPUID_VERSION_FEATURES = 0x00000001, - HVCPUID_VENDOR_MAXFUNCTION = 0x40000000, - HVCPUID_INTERFACE = 0x40000001, - - /* - * The remaining functions depend on the value of - * HVCPUID_INTERFACE - */ - HVCPUID_VERSION = 0x40000002, - HVCPUID_FEATURES = 0x40000003, - HVCPUID_ENLIGHTENMENT_INFO = 0x40000004, - HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005, -}; - -/* Define version of the synthetic interrupt controller. */ -#define HV_SYNIC_VERSION (1) - -/* Define the expected SynIC version. */ -#define HV_SYNIC_VERSION_1 (0x1) - -/* Define synthetic interrupt controller message constants. */ -#define HV_MESSAGE_SIZE (256) -#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240) -#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30) -#define HV_ANY_VP (0xFFFFFFFF) - -/* Define synthetic interrupt controller flag constants. */ -#define HV_EVENT_FLAGS_COUNT (256 * 8) -#define HV_EVENT_FLAGS_BYTE_COUNT (256) -#define HV_EVENT_FLAGS_DWORD_COUNT (256 / sizeof(u32)) - -/* Define hypervisor message types. */ -enum hv_message_type { - HVMSG_NONE = 0x00000000, - - /* Memory access messages. */ - HVMSG_UNMAPPED_GPA = 0x80000000, - HVMSG_GPA_INTERCEPT = 0x80000001, - - /* Timer notification messages. */ - HVMSG_TIMER_EXPIRED = 0x80000010, - - /* Error messages. */ - HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020, - HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021, - HVMSG_UNSUPPORTED_FEATURE = 0x80000022, - - /* Trace buffer complete messages. */ - HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040, - - /* Platform-specific processor intercept messages. */ - HVMSG_X64_IOPORT_INTERCEPT = 0x80010000, - HVMSG_X64_MSR_INTERCEPT = 0x80010001, - HVMSG_X64_CPUID_INTERCEPT = 0x80010002, - HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003, - HVMSG_X64_APIC_EOI = 0x80010004, - HVMSG_X64_LEGACY_FP_ERROR = 0x80010005 -}; - -/* Define the number of synthetic interrupt sources. */ -#define HV_SYNIC_SINT_COUNT (16) -#define HV_SYNIC_STIMER_COUNT (4) - -/* Define invalid partition identifier. */ -#define HV_PARTITION_ID_INVALID ((u64)0x0) - -/* Define connection identifier type. */ -union hv_connection_id { - u32 asu32; - struct { - u32 id:24; - u32 reserved:8; - } u; -}; - -/* Define port identifier type. */ -union hv_port_id { - u32 asu32; - struct { - u32 id:24; - u32 reserved:8; - } u ; -}; - -/* Define port type. */ -enum hv_port_type { - HVPORT_MSG = 1, - HVPORT_EVENT = 2, - HVPORT_MONITOR = 3 -}; - -/* Define port information structure. */ -struct hv_port_info { - enum hv_port_type port_type; - u32 padding; - union { - struct { - u32 target_sint; - u32 target_vp; - u64 rsvdz; - } message_port_info; - struct { - u32 target_sint; - u32 target_vp; - u16 base_flag_bumber; - u16 flag_count; - u32 rsvdz; - } event_port_info; - struct { - u64 monitor_address; - u64 rsvdz; - } monitor_port_info; - }; -}; - -struct hv_connection_info { - enum hv_port_type port_type; - u32 padding; - union { - struct { - u64 rsvdz; - } message_connection_info; - struct { - u64 rsvdz; - } event_connection_info; - struct { - u64 monitor_address; - } monitor_connection_info; - }; -}; - -/* Define synthetic interrupt controller message flags. */ -union hv_message_flags { - u8 asu8; - struct { - u8 msg_pending:1; - u8 reserved:7; - }; -}; - -/* Define synthetic interrupt controller message header. */ -struct hv_message_header { - enum hv_message_type message_type; - u8 payload_size; - union hv_message_flags message_flags; - u8 reserved[2]; - union { - u64 sender; - union hv_port_id port; - }; -}; - -/* Define timer message payload structure. */ -struct hv_timer_message_payload { - u32 timer_index; - u32 reserved; - u64 expiration_time; /* When the timer expired */ - u64 delivery_time; /* When the message was delivered */ -}; - -/* Define synthetic interrupt controller message format. */ -struct hv_message { - struct hv_message_header header; - union { - u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT]; - } u ; -}; - -/* Define the number of message buffers associated with each port. */ -#define HV_PORT_MESSAGE_BUFFER_COUNT (16) - -/* Define the synthetic interrupt message page layout. */ -struct hv_message_page { - struct hv_message sint_message[HV_SYNIC_SINT_COUNT]; -}; - -/* Define the synthetic interrupt controller event flags format. */ -union hv_synic_event_flags { - u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT]; - u32 flags32[HV_EVENT_FLAGS_DWORD_COUNT]; -}; - -/* Define the synthetic interrupt flags page layout. */ -struct hv_synic_event_flags_page { - union hv_synic_event_flags sintevent_flags[HV_SYNIC_SINT_COUNT]; -}; - -/* Define SynIC control register. */ -union hv_synic_scontrol { - u64 as_uint64; - struct { - u64 enable:1; - u64 reserved:63; - }; -}; - -/* Define synthetic interrupt source. */ -union hv_synic_sint { - u64 as_uint64; - struct { - u64 vector:8; - u64 reserved1:8; - u64 masked:1; - u64 auto_eoi:1; - u64 reserved2:46; - }; -}; - -/* Define the format of the SIMP register */ -union hv_synic_simp { - u64 as_uint64; - struct { - u64 simp_enabled:1; - u64 preserved:11; - u64 base_simp_gpa:52; - }; -}; - -/* Define the format of the SIEFP register */ -union hv_synic_siefp { - u64 as_uint64; - struct { - u64 siefp_enabled:1; - u64 preserved:11; - u64 base_siefp_gpa:52; - }; -}; - -/* Definitions for the monitored notification facility */ -union hv_monitor_trigger_group { - u64 as_uint64; - struct { - u32 pending; - u32 armed; - }; -}; - -struct hv_monitor_parameter { - union hv_connection_id connectionid; - u16 flagnumber; - u16 rsvdz; -}; - -union hv_monitor_trigger_state { - u32 asu32; - - struct { - u32 group_enable:4; - u32 rsvdz:28; - }; -}; - -/* struct hv_monitor_page Layout */ -/* ------------------------------------------------------ */ -/* | 0 | TriggerState (4 bytes) | Rsvd1 (4 bytes) | */ -/* | 8 | TriggerGroup[0] | */ -/* | 10 | TriggerGroup[1] | */ -/* | 18 | TriggerGroup[2] | */ -/* | 20 | TriggerGroup[3] | */ -/* | 28 | Rsvd2[0] | */ -/* | 30 | Rsvd2[1] | */ -/* | 38 | Rsvd2[2] | */ -/* | 40 | NextCheckTime[0][0] | NextCheckTime[0][1] | */ -/* | ... | */ -/* | 240 | Latency[0][0..3] | */ -/* | 340 | Rsvz3[0] | */ -/* | 440 | Parameter[0][0] | */ -/* | 448 | Parameter[0][1] | */ -/* | ... | */ -/* | 840 | Rsvd4[0] | */ -/* ------------------------------------------------------ */ -struct hv_monitor_page { - union hv_monitor_trigger_state trigger_state; - u32 rsvdz1; - - union hv_monitor_trigger_group trigger_group[4]; - u64 rsvdz2[3]; - - s32 next_checktime[4][32]; - - u16 latency[4][32]; - u64 rsvdz3[32]; - - struct hv_monitor_parameter parameter[4][32]; - - u8 rsvdz4[1984]; -}; - -/* Declare the various hypercall operations. */ -enum hv_call_code { - HVCALL_POST_MESSAGE = 0x005c, - HVCALL_SIGNAL_EVENT = 0x005d, -}; - -/* Definition of the hv_post_message hypercall input structure. */ -struct hv_input_post_message { - union hv_connection_id connectionid; - u32 reserved; - enum hv_message_type message_type; - u32 payload_size; - u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT]; -}; - -/* Definition of the hv_signal_event hypercall input structure. */ -struct hv_input_signal_event { - union hv_connection_id connectionid; - u16 flag_number; - u16 rsvdz; -}; - -/* - * Versioning definitions used for guests reporting themselves to the - * hypervisor, and visa versa. - */ - -/* Version info reported by guest OS's */ -enum hv_guest_os_vendor { - HVGUESTOS_VENDOR_MICROSOFT = 0x0001 -}; - -enum hv_guest_os_microsoft_ids { - HVGUESTOS_MICROSOFT_UNDEFINED = 0x00, - HVGUESTOS_MICROSOFT_MSDOS = 0x01, - HVGUESTOS_MICROSOFT_WINDOWS3X = 0x02, - HVGUESTOS_MICROSOFT_WINDOWS9X = 0x03, - HVGUESTOS_MICROSOFT_WINDOWSNT = 0x04, - HVGUESTOS_MICROSOFT_WINDOWSCE = 0x05 -}; - -/* - * Declare the MSR used to identify the guest OS. - */ -#define HV_X64_MSR_GUEST_OS_ID 0x40000000 - -union hv_x64_msr_guest_os_id_contents { - u64 as_uint64; - struct { - u64 build_number:16; - u64 service_version:8; /* Service Pack, etc. */ - u64 minor_version:8; - u64 major_version:8; - u64 os_id:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */ - u64 vendor_id:16; /* enum hv_guest_os_vendor */ - }; -}; - -/* - * Declare the MSR used to setup pages used to communicate with the hypervisor. - */ -#define HV_X64_MSR_HYPERCALL 0x40000001 - -union hv_x64_msr_hypercall_contents { - u64 as_uint64; - struct { - u64 enable:1; - u64 reserved:11; - u64 guest_physical_address:52; - }; -}; - - -enum { - VMBUS_MESSAGE_CONNECTION_ID = 1, - VMBUS_MESSAGE_PORT_ID = 1, - VMBUS_EVENT_CONNECTION_ID = 2, - VMBUS_EVENT_PORT_ID = 2, - VMBUS_MONITOR_CONNECTION_ID = 3, - VMBUS_MONITOR_PORT_ID = 3, - VMBUS_MESSAGE_SINT = 2, -}; - -/* #defines */ - -#define HV_PRESENT_BIT 0x80000000 - -#define HV_LINUX_GUEST_ID_LO 0x00000000 -#define HV_LINUX_GUEST_ID_HI 0xB16B00B5 -#define HV_LINUX_GUEST_ID (((u64)HV_LINUX_GUEST_ID_HI << 32) | \ - HV_LINUX_GUEST_ID_LO) - -#define HV_CPU_POWER_MANAGEMENT (1 << 0) -#define HV_RECOMMENDATIONS_MAX 4 - -#define HV_X64_MAX 5 -#define HV_CAPS_MAX 8 - - -#define HV_HYPERCALL_PARAM_ALIGN sizeof(u64) - - -/* Service definitions */ - -#define HV_SERVICE_PARENT_PORT (0) -#define HV_SERVICE_PARENT_CONNECTION (0) - -#define HV_SERVICE_CONNECT_RESPONSE_SUCCESS (0) -#define HV_SERVICE_CONNECT_RESPONSE_INVALID_PARAMETER (1) -#define HV_SERVICE_CONNECT_RESPONSE_UNKNOWN_SERVICE (2) -#define HV_SERVICE_CONNECT_RESPONSE_CONNECTION_REJECTED (3) - -#define HV_SERVICE_CONNECT_REQUEST_MESSAGE_ID (1) -#define HV_SERVICE_CONNECT_RESPONSE_MESSAGE_ID (2) -#define HV_SERVICE_DISCONNECT_REQUEST_MESSAGE_ID (3) -#define HV_SERVICE_DISCONNECT_RESPONSE_MESSAGE_ID (4) -#define HV_SERVICE_MAX_MESSAGE_ID (4) - -#define HV_SERVICE_PROTOCOL_VERSION (0x0010) -#define HV_CONNECT_PAYLOAD_BYTE_COUNT 64 - -/* #define VMBUS_REVISION_NUMBER 6 */ - -/* Our local vmbus's port and connection id. Anything >0 is fine */ -/* #define VMBUS_PORT_ID 11 */ - -/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */ -static const struct hv_guid VMBUS_SERVICE_ID = { - .data = { - 0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c, - 0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4 - }, -}; - -#define MAX_NUM_CPUS 32 - - -struct hv_input_signal_event_buffer { - u64 align8; - struct hv_input_signal_event event; -}; - -struct hv_context { - /* We only support running on top of Hyper-V - * So at this point this really can only contain the Hyper-V ID - */ - u64 guestid; - - void *hypercall_page; - - bool synic_initialized; - - /* - * This is used as an input param to HvCallSignalEvent hypercall. The - * input param is immutable in our usage and must be dynamic mem (vs - * stack or global). */ - struct hv_input_signal_event_buffer *signal_event_buffer; - /* 8-bytes aligned of the buffer above */ - struct hv_input_signal_event *signal_event_param; - - void *synic_message_page[MAX_NUM_CPUS]; - void *synic_event_page[MAX_NUM_CPUS]; -}; - -extern struct hv_context hv_context; - - -/* Hv Interface */ - -extern int hv_init(void); - -extern void hv_cleanup(void); - -extern u16 hv_post_message(union hv_connection_id connection_id, - enum hv_message_type message_type, - void *payload, size_t payload_size); - -extern u16 hv_signal_event(void); - -extern void hv_synic_init(void *irqarg); - -extern void hv_synic_cleanup(void *arg); - - -/* Interface */ - - -int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer, - u32 buflen); - -void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info); - -int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info, - struct scatterlist *sglist, - u32 sgcount); - -int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer, - u32 buflen); - -int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info, - void *buffer, - u32 buflen, - u32 offset); - -u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info); - -void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix); - -void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info, - struct hv_ring_buffer_debug_info *debug_info); - -/* - * Maximum channels is determined by the size of the interrupt page - * which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt - * and the other is receive endpoint interrupt - */ -#define MAX_NUM_CHANNELS ((PAGE_SIZE >> 1) << 3) /* 16348 channels */ - -/* The value here must be in multiple of 32 */ -/* TODO: Need to make this configurable */ -#define MAX_NUM_CHANNELS_SUPPORTED 256 - - -enum vmbus_connect_state { - DISCONNECTED, - CONNECTING, - CONNECTED, - DISCONNECTING -}; - -#define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT - -struct vmbus_connection { - enum vmbus_connect_state conn_state; - - atomic_t next_gpadl_handle; - - /* - * Represents channel interrupts. Each bit position represents a - * channel. When a channel sends an interrupt via VMBUS, it finds its - * bit in the sendInterruptPage, set it and calls Hv to generate a port - * event. The other end receives the port event and parse the - * recvInterruptPage to see which bit is set - */ - void *int_page; - void *send_int_page; - void *recv_int_page; - - /* - * 2 pages - 1st page for parent->child notification and 2nd - * is child->parent notification - */ - void *monitor_pages; - struct list_head chn_msg_list; - spinlock_t channelmsg_lock; - - /* List of channels */ - struct list_head chn_list; - spinlock_t channel_lock; - - struct workqueue_struct *work_queue; -}; - - -struct vmbus_msginfo { - /* Bookkeeping stuff */ - struct list_head msglist_entry; - - /* The message itself */ - unsigned char msg[0]; -}; - - -extern struct vmbus_connection vmbus_connection; - -/* General vmbus interface */ - -struct hv_device *vmbus_child_device_create(struct hv_guid *type, - struct hv_guid *instance, - struct vmbus_channel *channel); - -int vmbus_child_device_register(struct hv_device *child_device_obj); -void vmbus_child_device_unregister(struct hv_device *device_obj); - -/* static void */ -/* VmbusChildDeviceDestroy( */ -/* struct hv_device *); */ - -struct vmbus_channel *relid2channel(u32 relid); - - -/* Connection interface */ - -int vmbus_connect(void); - -int vmbus_post_msg(void *buffer, size_t buflen); - -int vmbus_set_event(u32 child_relid); - -void vmbus_on_event(unsigned long data); - - -#endif /* _HYPERV_VMBUS_H */ |