Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
hv
hyperv_vmbus.h
Go to the documentation of this file.
1
/*
2
*
3
* 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.
17
*
18
* Authors:
19
* Haiyang Zhang <
[email protected]
>
20
* Hank Janssen <
[email protected]
>
21
* K. Y. Srinivasan <
[email protected]
>
22
*
23
*/
24
25
#ifndef _HYPERV_VMBUS_H
26
#define _HYPERV_VMBUS_H
27
28
#include <linux/list.h>
29
#include <asm/sync_bitops.h>
30
#include <
linux/atomic.h
>
31
#include <
linux/hyperv.h
>
32
33
/*
34
* The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
35
* is set by CPUID(HVCPUID_VERSION_FEATURES).
36
*/
37
enum
hv_cpuid_function
{
38
HVCPUID_VERSION_FEATURES
= 0x00000001,
39
HVCPUID_VENDOR_MAXFUNCTION
= 0x40000000,
40
HVCPUID_INTERFACE
= 0x40000001,
41
42
/*
43
* The remaining functions depend on the value of
44
* HVCPUID_INTERFACE
45
*/
46
HVCPUID_VERSION
= 0x40000002,
47
HVCPUID_FEATURES
= 0x40000003,
48
HVCPUID_ENLIGHTENMENT_INFO
= 0x40000004,
49
HVCPUID_IMPLEMENTATION_LIMITS
= 0x40000005,
50
};
51
52
/* Define version of the synthetic interrupt controller. */
53
#define HV_SYNIC_VERSION (1)
54
55
/* Define the expected SynIC version. */
56
#define HV_SYNIC_VERSION_1 (0x1)
57
58
/* Define synthetic interrupt controller message constants. */
59
#define HV_MESSAGE_SIZE (256)
60
#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
61
#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
62
#define HV_ANY_VP (0xFFFFFFFF)
63
64
/* Define synthetic interrupt controller flag constants. */
65
#define HV_EVENT_FLAGS_COUNT (256 * 8)
66
#define HV_EVENT_FLAGS_BYTE_COUNT (256)
67
#define HV_EVENT_FLAGS_DWORD_COUNT (256 / sizeof(u32))
68
69
/* Define hypervisor message types. */
70
enum
hv_message_type
{
71
HVMSG_NONE
= 0x00000000,
72
73
/* Memory access messages. */
74
HVMSG_UNMAPPED_GPA
= 0x80000000,
75
HVMSG_GPA_INTERCEPT
= 0x80000001,
76
77
/* Timer notification messages. */
78
HVMSG_TIMER_EXPIRED
= 0x80000010,
79
80
/* Error messages. */
81
HVMSG_INVALID_VP_REGISTER_VALUE
= 0x80000020,
82
HVMSG_UNRECOVERABLE_EXCEPTION
= 0x80000021,
83
HVMSG_UNSUPPORTED_FEATURE
= 0x80000022,
84
85
/* Trace buffer complete messages. */
86
HVMSG_EVENTLOG_BUFFERCOMPLETE
= 0x80000040,
87
88
/* Platform-specific processor intercept messages. */
89
HVMSG_X64_IOPORT_INTERCEPT
= 0x80010000,
90
HVMSG_X64_MSR_INTERCEPT
= 0x80010001,
91
HVMSG_X64_CPUID_INTERCEPT
= 0x80010002,
92
HVMSG_X64_EXCEPTION_INTERCEPT
= 0x80010003,
93
HVMSG_X64_APIC_EOI
= 0x80010004,
94
HVMSG_X64_LEGACY_FP_ERROR
= 0x80010005
95
};
96
97
/* Define the number of synthetic interrupt sources. */
98
#define HV_SYNIC_SINT_COUNT (16)
99
#define HV_SYNIC_STIMER_COUNT (4)
100
101
/* Define invalid partition identifier. */
102
#define HV_PARTITION_ID_INVALID ((u64)0x0)
103
104
/* Define connection identifier type. */
105
union
hv_connection_id
{
106
u32
asu32
;
107
struct
{
108
u32
id
:24;
109
u32
reserved
:8;
110
}
u
;
111
};
112
113
/* Define port identifier type. */
114
union
hv_port_id
{
115
u32
asu32
;
116
struct
{
117
u32
id
:24;
118
u32
reserved
:8;
119
}
u
;
120
};
121
122
/* Define port type. */
123
enum
hv_port_type
{
124
HVPORT_MSG
= 1,
125
HVPORT_EVENT
= 2,
126
HVPORT_MONITOR
= 3
127
};
128
129
/* Define port information structure. */
130
struct
hv_port_info
{
131
enum
hv_port_type
port_type
;
132
u32
padding
;
133
union
{
134
struct
{
135
u32
target_sint
;
136
u32
target_vp
;
137
u64
rsvdz
;
138
}
message_port_info
;
139
struct
{
140
u32
target_sint
;
141
u32
target_vp
;
142
u16
base_flag_bumber
;
143
u16
flag_count
;
144
u32
rsvdz
;
145
}
event_port_info
;
146
struct
{
147
u64
monitor_address
;
148
u64
rsvdz
;
149
}
monitor_port_info
;
150
};
151
};
152
153
struct
hv_connection_info
{
154
enum
hv_port_type
port_type
;
155
u32
padding
;
156
union
{
157
struct
{
158
u64
rsvdz
;
159
}
message_connection_info
;
160
struct
{
161
u64
rsvdz
;
162
}
event_connection_info
;
163
struct
{
164
u64
monitor_address
;
165
}
monitor_connection_info
;
166
};
167
};
168
169
/* Define synthetic interrupt controller message flags. */
170
union
hv_message_flags
{
171
u8
asu8
;
172
struct
{
173
u8
msg_pending
:1;
174
u8
reserved
:7;
175
};
176
};
177
178
/* Define synthetic interrupt controller message header. */
179
struct
hv_message_header
{
180
enum
hv_message_type
message_type
;
181
u8
payload_size
;
182
union
hv_message_flags
message_flags
;
183
u8
reserved
[2];
184
union
{
185
u64
sender
;
186
union
hv_port_id
port
;
187
};
188
};
189
190
/* Define timer message payload structure. */
191
struct
hv_timer_message_payload
{
192
u32
timer_index
;
193
u32
reserved
;
194
u64
expiration_time
;
/* When the timer expired */
195
u64
delivery_time
;
/* When the message was delivered */
196
};
197
198
/* Define synthetic interrupt controller message format. */
199
struct
hv_message
{
200
struct
hv_message_header
header
;
201
union
{
202
u64
payload
[
HV_MESSAGE_PAYLOAD_QWORD_COUNT
];
203
}
u
;
204
};
205
206
/* Define the number of message buffers associated with each port. */
207
#define HV_PORT_MESSAGE_BUFFER_COUNT (16)
208
209
/* Define the synthetic interrupt message page layout. */
210
struct
hv_message_page
{
211
struct
hv_message
sint_message
[
HV_SYNIC_SINT_COUNT
];
212
};
213
214
/* Define the synthetic interrupt controller event flags format. */
215
union
hv_synic_event_flags
{
216
u8
flags8
[
HV_EVENT_FLAGS_BYTE_COUNT
];
217
u32
flags32
[
HV_EVENT_FLAGS_DWORD_COUNT
];
218
};
219
220
/* Define the synthetic interrupt flags page layout. */
221
struct
hv_synic_event_flags_page
{
222
union
hv_synic_event_flags
sintevent_flags
[
HV_SYNIC_SINT_COUNT
];
223
};
224
225
/* Define SynIC control register. */
226
union
hv_synic_scontrol
{
227
u64
as_uint64
;
228
struct
{
229
u64
enable
:1;
230
u64
reserved
:63;
231
};
232
};
233
234
/* Define synthetic interrupt source. */
235
union
hv_synic_sint
{
236
u64
as_uint64
;
237
struct
{
238
u64
vector
:8;
239
u64
reserved1
:8;
240
u64
masked
:1;
241
u64
auto_eoi
:1;
242
u64
reserved2
:46;
243
};
244
};
245
246
/* Define the format of the SIMP register */
247
union
hv_synic_simp
{
248
u64
as_uint64
;
249
struct
{
250
u64
simp_enabled
:1;
251
u64
preserved
:11;
252
u64
base_simp_gpa
:52;
253
};
254
};
255
256
/* Define the format of the SIEFP register */
257
union
hv_synic_siefp
{
258
u64
as_uint64
;
259
struct
{
260
u64
siefp_enabled
:1;
261
u64
preserved
:11;
262
u64
base_siefp_gpa
:52;
263
};
264
};
265
266
/* Definitions for the monitored notification facility */
267
union
hv_monitor_trigger_group
{
268
u64
as_uint64
;
269
struct
{
270
u32
pending
;
271
u32
armed
;
272
};
273
};
274
275
struct
hv_monitor_parameter
{
276
union
hv_connection_id
connectionid
;
277
u16
flagnumber
;
278
u16
rsvdz
;
279
};
280
281
union
hv_monitor_trigger_state
{
282
u32
asu32
;
283
284
struct
{
285
u32
group_enable
:4;
286
u32
rsvdz
:28;
287
};
288
};
289
290
/* struct hv_monitor_page Layout */
291
/* ------------------------------------------------------ */
292
/* | 0 | TriggerState (4 bytes) | Rsvd1 (4 bytes) | */
293
/* | 8 | TriggerGroup[0] | */
294
/* | 10 | TriggerGroup[1] | */
295
/* | 18 | TriggerGroup[2] | */
296
/* | 20 | TriggerGroup[3] | */
297
/* | 28 | Rsvd2[0] | */
298
/* | 30 | Rsvd2[1] | */
299
/* | 38 | Rsvd2[2] | */
300
/* | 40 | NextCheckTime[0][0] | NextCheckTime[0][1] | */
301
/* | ... | */
302
/* | 240 | Latency[0][0..3] | */
303
/* | 340 | Rsvz3[0] | */
304
/* | 440 | Parameter[0][0] | */
305
/* | 448 | Parameter[0][1] | */
306
/* | ... | */
307
/* | 840 | Rsvd4[0] | */
308
/* ------------------------------------------------------ */
309
struct
hv_monitor_page
{
310
union
hv_monitor_trigger_state
trigger_state
;
311
u32
rsvdz1
;
312
313
union
hv_monitor_trigger_group
trigger_group
[4];
314
u64
rsvdz2
[3];
315
316
s32
next_checktime
[4][32];
317
318
u16
latency
[4][32];
319
u64
rsvdz3
[32];
320
321
struct
hv_monitor_parameter
parameter
[4][32];
322
323
u8
rsvdz4
[1984];
324
};
325
326
/* Declare the various hypercall operations. */
327
enum
hv_call_code
{
328
HVCALL_POST_MESSAGE
= 0x005c,
329
HVCALL_SIGNAL_EVENT
= 0x005d,
330
};
331
332
/* Definition of the hv_post_message hypercall input structure. */
333
struct
hv_input_post_message
{
334
union
hv_connection_id
connectionid
;
335
u32
reserved
;
336
enum
hv_message_type
message_type
;
337
u32
payload_size
;
338
u64
payload
[
HV_MESSAGE_PAYLOAD_QWORD_COUNT
];
339
};
340
341
/* Definition of the hv_signal_event hypercall input structure. */
342
struct
hv_input_signal_event
{
343
union
hv_connection_id
connectionid
;
344
u16
flag_number
;
345
u16
rsvdz
;
346
};
347
348
/*
349
* Versioning definitions used for guests reporting themselves to the
350
* hypervisor, and visa versa.
351
*/
352
353
/* Version info reported by guest OS's */
354
enum
hv_guest_os_vendor
{
355
HVGUESTOS_VENDOR_MICROSOFT
= 0x0001
356
};
357
358
enum
hv_guest_os_microsoft_ids
{
359
HVGUESTOS_MICROSOFT_UNDEFINED
= 0x00,
360
HVGUESTOS_MICROSOFT_MSDOS
= 0x01,
361
HVGUESTOS_MICROSOFT_WINDOWS3X
= 0x02,
362
HVGUESTOS_MICROSOFT_WINDOWS9X
= 0x03,
363
HVGUESTOS_MICROSOFT_WINDOWSNT
= 0x04,
364
HVGUESTOS_MICROSOFT_WINDOWSCE
= 0x05
365
};
366
367
/*
368
* Declare the MSR used to identify the guest OS.
369
*/
370
#define HV_X64_MSR_GUEST_OS_ID 0x40000000
371
372
union
hv_x64_msr_guest_os_id_contents
{
373
u64
as_uint64
;
374
struct
{
375
u64
build_number
:16;
376
u64
service_version
:8;
/* Service Pack, etc. */
377
u64
minor_version
:8;
378
u64
major_version
:8;
379
u64
os_id
:8;
/* enum hv_guest_os_microsoft_ids (if Vendor=MS) */
380
u64
vendor_id
:16;
/* enum hv_guest_os_vendor */
381
};
382
};
383
384
/*
385
* Declare the MSR used to setup pages used to communicate with the hypervisor.
386
*/
387
#define HV_X64_MSR_HYPERCALL 0x40000001
388
389
union
hv_x64_msr_hypercall_contents
{
390
u64
as_uint64
;
391
struct
{
392
u64
enable
:1;
393
u64
reserved
:11;
394
u64
guest_physical_address
:52;
395
};
396
};
397
398
399
enum
{
400
VMBUS_MESSAGE_CONNECTION_ID
= 1,
401
VMBUS_MESSAGE_PORT_ID
= 1,
402
VMBUS_EVENT_CONNECTION_ID
= 2,
403
VMBUS_EVENT_PORT_ID
= 2,
404
VMBUS_MONITOR_CONNECTION_ID
= 3,
405
VMBUS_MONITOR_PORT_ID
= 3,
406
VMBUS_MESSAGE_SINT
= 2,
407
};
408
409
/* #defines */
410
411
#define HV_PRESENT_BIT 0x80000000
412
413
/*
414
* The guest OS needs to register the guest ID with the hypervisor.
415
* The guest ID is a 64 bit entity and the structure of this ID is
416
* specified in the Hyper-V specification:
417
*
418
* http://msdn.microsoft.com/en-us/library/windows/hardware/ff542653%28v=vs.85%29.aspx
419
*
420
* While the current guideline does not specify how Linux guest ID(s)
421
* need to be generated, our plan is to publish the guidelines for
422
* Linux and other guest operating systems that currently are hosted
423
* on Hyper-V. The implementation here conforms to this yet
424
* unpublished guidelines.
425
*
426
*
427
* Bit(s)
428
* 63 - Indicates if the OS is Open Source or not; 1 is Open Source
429
* 62:56 - Os Type; Linux is 0x100
430
* 55:48 - Distro specific identification
431
* 47:16 - Linux kernel version number
432
* 15:0 - Distro specific identification
433
*
434
*
435
*/
436
437
#define HV_LINUX_VENDOR_ID 0x8100
438
439
/*
440
* Generate the guest ID based on the guideline described above.
441
*/
442
443
static
inline
__u64
generate_guest_id(
__u8
d_info1,
__u32
kernel_version
,
444
__u16
d_info2)
445
{
446
__u64
guest_id = 0;
447
448
guest_id = (((
__u64
)
HV_LINUX_VENDOR_ID
) << 48);
449
guest_id |= (((
__u64
)(d_info1)) << 48);
450
guest_id |= (((
__u64
)(kernel_version)) << 16);
451
guest_id |= ((
__u64
)(d_info2));
452
453
return
guest_id;
454
}
455
456
457
#define HV_CPU_POWER_MANAGEMENT (1 << 0)
458
#define HV_RECOMMENDATIONS_MAX 4
459
460
#define HV_X64_MAX 5
461
#define HV_CAPS_MAX 8
462
463
464
#define HV_HYPERCALL_PARAM_ALIGN sizeof(u64)
465
466
467
/* Service definitions */
468
469
#define HV_SERVICE_PARENT_PORT (0)
470
#define HV_SERVICE_PARENT_CONNECTION (0)
471
472
#define HV_SERVICE_CONNECT_RESPONSE_SUCCESS (0)
473
#define HV_SERVICE_CONNECT_RESPONSE_INVALID_PARAMETER (1)
474
#define HV_SERVICE_CONNECT_RESPONSE_UNKNOWN_SERVICE (2)
475
#define HV_SERVICE_CONNECT_RESPONSE_CONNECTION_REJECTED (3)
476
477
#define HV_SERVICE_CONNECT_REQUEST_MESSAGE_ID (1)
478
#define HV_SERVICE_CONNECT_RESPONSE_MESSAGE_ID (2)
479
#define HV_SERVICE_DISCONNECT_REQUEST_MESSAGE_ID (3)
480
#define HV_SERVICE_DISCONNECT_RESPONSE_MESSAGE_ID (4)
481
#define HV_SERVICE_MAX_MESSAGE_ID (4)
482
483
#define HV_SERVICE_PROTOCOL_VERSION (0x0010)
484
#define HV_CONNECT_PAYLOAD_BYTE_COUNT 64
485
486
/* #define VMBUS_REVISION_NUMBER 6 */
487
488
/* Our local vmbus's port and connection id. Anything >0 is fine */
489
/* #define VMBUS_PORT_ID 11 */
490
491
/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */
492
static
const
uuid_le
VMBUS_SERVICE_ID = {
493
.
b
= {
494
0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c,
495
0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4
496
},
497
};
498
499
500
501
struct
hv_input_signal_event_buffer
{
502
u64
align8
;
503
struct
hv_input_signal_event
event
;
504
};
505
506
struct
hv_context
{
507
/* We only support running on top of Hyper-V
508
* So at this point this really can only contain the Hyper-V ID
509
*/
510
u64
guestid
;
511
512
void
*
hypercall_page
;
513
514
bool
synic_initialized
;
515
516
/*
517
* This is used as an input param to HvCallSignalEvent hypercall. The
518
* input param is immutable in our usage and must be dynamic mem (vs
519
* stack or global). */
520
struct
hv_input_signal_event_buffer
*
signal_event_buffer
;
521
/* 8-bytes aligned of the buffer above */
522
struct
hv_input_signal_event
*
signal_event_param
;
523
524
void
*
synic_message_page
[
NR_CPUS
];
525
void
*
synic_event_page
[
NR_CPUS
];
526
};
527
528
extern
struct
hv_context
hv_context
;
529
530
531
/* Hv Interface */
532
533
extern
int
hv_init
(
void
);
534
535
extern
void
hv_cleanup
(
void
);
536
537
extern
int
hv_post_message
(
union
hv_connection_id
connection_id,
538
enum
hv_message_type
message_type,
539
void
*
payload
,
size_t
payload_size
);
540
541
extern
u16
hv_signal_event
(
void
);
542
543
extern
void
hv_synic_init
(
void
*irqarg);
544
545
extern
void
hv_synic_cleanup
(
void
*
arg
);
546
547
548
/* Interface */
549
550
551
int
hv_ringbuffer_init
(
struct
hv_ring_buffer_info *
ring_info
,
void
*
buffer
,
552
u32
buflen
);
553
554
void
hv_ringbuffer_cleanup
(
struct
hv_ring_buffer_info *
ring_info
);
555
556
int
hv_ringbuffer_write
(
struct
hv_ring_buffer_info *
ring_info
,
557
struct
scatterlist
*sglist,
558
u32
sgcount);
559
560
int
hv_ringbuffer_peek
(
struct
hv_ring_buffer_info *
ring_info
,
void
*
buffer
,
561
u32
buflen
);
562
563
int
hv_ringbuffer_read
(
struct
hv_ring_buffer_info *
ring_info
,
564
void
*
buffer
,
565
u32
buflen
,
566
u32
offset
);
567
568
u32
hv_get_ringbuffer_interrupt_mask
(
struct
hv_ring_buffer_info *
ring_info
);
569
570
void
hv_ringbuffer_get_debuginfo
(
struct
hv_ring_buffer_info *
ring_info
,
571
struct
hv_ring_buffer_debug_info *
debug_info
);
572
573
/*
574
* Maximum channels is determined by the size of the interrupt page
575
* which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt
576
* and the other is receive endpoint interrupt
577
*/
578
#define MAX_NUM_CHANNELS ((PAGE_SIZE >> 1) << 3)
/* 16348 channels */
579
580
/* The value here must be in multiple of 32 */
581
/* TODO: Need to make this configurable */
582
#define MAX_NUM_CHANNELS_SUPPORTED 256
583
584
585
enum
vmbus_connect_state
{
586
DISCONNECTED
,
587
CONNECTING
,
588
CONNECTED
,
589
DISCONNECTING
590
};
591
592
#define MAX_SIZE_CHANNEL_MESSAGE HV_MESSAGE_PAYLOAD_BYTE_COUNT
593
594
struct
vmbus_connection
{
595
enum
vmbus_connect_state
conn_state
;
596
597
atomic_t
next_gpadl_handle
;
598
599
/*
600
* Represents channel interrupts. Each bit position represents a
601
* channel. When a channel sends an interrupt via VMBUS, it finds its
602
* bit in the sendInterruptPage, set it and calls Hv to generate a port
603
* event. The other end receives the port event and parse the
604
* recvInterruptPage to see which bit is set
605
*/
606
void
*
int_page
;
607
void
*
send_int_page
;
608
void
*
recv_int_page
;
609
610
/*
611
* 2 pages - 1st page for parent->child notification and 2nd
612
* is child->parent notification
613
*/
614
void
*
monitor_pages
;
615
struct
list_head
chn_msg_list
;
616
spinlock_t
channelmsg_lock
;
617
618
/* List of channels */
619
struct
list_head
chn_list
;
620
spinlock_t
channel_lock
;
621
622
struct
workqueue_struct
*
work_queue
;
623
};
624
625
626
struct
vmbus_msginfo
{
627
/* Bookkeeping stuff */
628
struct
list_head
msglist_entry
;
629
630
/* The message itself */
631
unsigned
char
msg
[0];
632
};
633
634
635
extern
struct
vmbus_connection
vmbus_connection
;
636
637
/* General vmbus interface */
638
639
struct
hv_device *
vmbus_device_create
(
uuid_le
*
type
,
640
uuid_le
*instance,
641
struct
vmbus_channel *
channel
);
642
643
int
vmbus_device_register
(
struct
hv_device *child_device_obj);
644
void
vmbus_device_unregister
(
struct
hv_device *device_obj);
645
646
/* static void */
647
/* VmbusChildDeviceDestroy( */
648
/* struct hv_device *); */
649
650
struct
vmbus_channel *
relid2channel
(
u32
relid);
651
652
void
vmbus_free_channels
(
void
);
653
654
/* Connection interface */
655
656
int
vmbus_connect
(
void
);
657
658
int
vmbus_post_msg
(
void
*
buffer
,
size_t
buflen
);
659
660
int
vmbus_set_event
(
u32
child_relid);
661
662
void
vmbus_on_event
(
unsigned
long
data
);
663
664
665
#endif
/* _HYPERV_VMBUS_H */
Generated on Thu Jan 10 2013 13:34:25 for Linux Kernel by
1.8.2