iPXE
vmbus.h File Reference

Hyper-V virtual machine bus. More...

#include <byteswap.h>
#include <ipxe/uuid.h>
#include <ipxe/device.h>
#include <ipxe/tables.h>
#include <ipxe/iobuf.h>
#include <ipxe/hyperv.h>

Go to the source code of this file.

Data Structures

union  vmbus_version
 VMBus version number. More...
struct  vmbus_gpa_range
 Guest physical address range descriptor. More...
struct  vmbus_message_header
 VMBus message header. More...
struct  vmbus_offer_channel
 VMBus "offer channel" message. More...
struct  vmbus_open_channel
 VMBus "open channel" message. More...
struct  vmbus_open_channel_result
 VMBus "open channel result" message. More...
struct  vmbus_close_channel
 VMBus "close channel" message. More...
struct  vmbus_gpadl_header
 VMBus "GPADL header" message. More...
struct  vmbus_gpadl_created
 VMBus "GPADL created" message. More...
struct  vmbus_gpadl_teardown
 VMBus "GPADL teardown" message. More...
struct  vmbus_gpadl_torndown
 VMBus "GPADL torndown" message. More...
struct  vmbus_initiate_contact
 VMBus "initiate contact" message. More...
struct  vmbus_version_response
 VMBus "version response" message. More...
union  vmbus_message
 VMBus message. More...
struct  vmbus_packet_header
 VMBus packet header. More...
struct  vmbus_gpa_direct_header
 VMBus GPA direct header. More...
struct  vmbus_xfer_page_range
 VMBus transfer page range. More...
struct  vmbus_xfer_page_header
 VMBus transfer page header. More...
union  vmbus_packet_header_max
 VMBus maximum-sized packet header. More...
struct  vmbus_packet_footer
 VMBus packet footer. More...
struct  vmbus_ring
 VMBus ring buffer. More...
struct  vmbus_interrupt
 VMBus interrupt page. More...
struct  vmbus
 A virtual machine bus. More...
struct  vmbus_channel_operations
 VMBus channel operations. More...
struct  vmbus_xfer_pages_operations
 VMBus transfer page set operations. More...
struct  vmbus_xfer_pages
 VMBus transfer page set. More...
struct  vmbus_device
 A VMBus device. More...
struct  vmbus_driver
 A VMBus device driver. More...

Macros

#define VMBUS_MESSAGE_ID   1
 VMBus message connection ID.
#define VMBUS_EVENT_ID   2
 VMBus event connection ID.
#define VMBUS_MESSAGE_TYPE   1
 VMBus message type.
#define VMBUS_MESSAGE_SINT   2
 VMBus message synthetic interrupt.
#define VMBUS_PACKET_MAX_HEADER_LEN   64
 Maximum expected size of VMBus packet header.
#define VMBUS_DRIVERS   __table ( struct vmbus_driver, "vmbus_drivers" )
 VMBus device driver table.
#define __vmbus_driver   __table_entry ( VMBUS_DRIVERS, 01 )
 Declare a VMBus device driver.
#define VMBUS_ROM(_name, _desc)
 Define build rules for a VMBus device driver.
#define VMBUS_TYPE(a, b, c, d, e0, e1, e2, e3, e4, e5)
 Construct VMBus type.

Enumerations

enum  vmbus_raw_version { VMBUS_VERSION_WS2008 = ( ( 0 << 16 ) | ( 13 << 0 ) ) , VMBUS_VERSION_WIN7 = ( ( 1 << 16 ) | ( 1 << 0 ) ) , VMBUS_VERSION_WIN8 = ( ( 2 << 16 ) | ( 4 << 0 ) ) , VMBUS_VERSION_WIN8_1 = ( ( 3 << 16 ) | ( 0 << 0 ) ) }
 Known VMBus protocol versions. More...
enum  vmbus_message_type {
  VMBUS_OFFER_CHANNEL = 1 , VMBUS_REQUEST_OFFERS = 3 , VMBUS_ALL_OFFERS_DELIVERED = 4 , VMBUS_OPEN_CHANNEL = 5 ,
  VMBUS_OPEN_CHANNEL_RESULT = 6 , VMBUS_CLOSE_CHANNEL = 7 , VMBUS_GPADL_HEADER = 8 , VMBUS_GPADL_CREATED = 10 ,
  VMBUS_GPADL_TEARDOWN = 11 , VMBUS_GPADL_TORNDOWN = 12 , VMBUS_INITIATE_CONTACT = 14 , VMBUS_VERSION_RESPONSE = 15 ,
  VMBUS_UNLOAD = 16 , VMBUS_UNLOAD_RESPONSE = 17
}
 VMBus message types. More...
enum  vmbus_packet_type {
  VMBUS_DATA_INBAND = 6 , VMBUS_DATA_XFER_PAGES = 7 , VMBUS_DATA_GPA_DIRECT = 9 , VMBUS_CANCELLATION = 10 ,
  VMBUS_COMPLETION = 11
}
 VMBus packet types. More...
enum  vmbus_packet_flags { VMBUS_COMPLETION_REQUESTED = 0x0001 }
 VMBus packet flags. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static void vmbus_set_drvdata (struct vmbus_device *vmdev, void *priv)
 Set VMBus device driver-private data.
static void * vmbus_get_drvdata (struct vmbus_device *vmdev)
 Get VMBus device driver-private data.
static int vmbus_has_data (struct vmbus_device *vmdev)
 Check if data is present in ring buffer.
static int vmbus_register_pages (struct vmbus_device *vmdev, struct vmbus_xfer_pages *pages)
 Register transfer page set.
static void vmbus_unregister_pages (struct vmbus_device *vmdev, struct vmbus_xfer_pages *pages)
 Unregister transfer page set.
static int vmbus_gpadl_is_obsolete (unsigned int gpadl)
 Check if GPADL is obsolete.
int vmbus_establish_gpadl (struct vmbus_device *vmdev, void *data, size_t len)
 Establish GPA descriptor list.
int vmbus_gpadl_teardown (struct vmbus_device *vmdev, unsigned int gpadl)
 Tear down GPA descriptor list.
int vmbus_open (struct vmbus_device *vmdev, struct vmbus_channel_operations *op, size_t out_len, size_t in_len, size_t mtu)
 Open VMBus channel.
void vmbus_close (struct vmbus_device *vmdev)
 Close VMBus channel.
int vmbus_send_control (struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
 Send control packet via ring buffer.
int vmbus_send_data (struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len, struct io_buffer *iobuf)
 Send data packet via ring buffer.
int vmbus_send_completion (struct vmbus_device *vmdev, uint64_t xid, const void *data, size_t len)
 Send completion packet via ring buffer.
int vmbus_send_cancellation (struct vmbus_device *vmdev, uint64_t xid)
 Send cancellation packet via ring buffer.
int vmbus_poll (struct vmbus_device *vmdev)
 Poll ring buffer.
void vmbus_dump_channel (struct vmbus_device *vmdev)
 Dump channel status (for debugging)
int vmbus_probe (struct hv_hypervisor *hv, struct device *parent)
 Probe Hyper-V virtual machine bus.
int vmbus_reset (struct hv_hypervisor *hv, struct device *parent)
 Reset Hyper-V virtual machine bus.
void vmbus_remove (struct hv_hypervisor *hv, struct device *parent)
 Remove Hyper-V virtual machine bus.

Variables

unsigned int vmbus_obsolete_gpadl
 Obsolete GPADL ID threshold.

Detailed Description

Hyper-V virtual machine bus.

Definition in file vmbus.h.

Macro Definition Documentation

◆ VMBUS_MESSAGE_ID

#define VMBUS_MESSAGE_ID   1

VMBus message connection ID.

Definition at line 20 of file vmbus.h.

Referenced by vmbus_post_message().

◆ VMBUS_EVENT_ID

#define VMBUS_EVENT_ID   2

VMBus event connection ID.

Definition at line 23 of file vmbus.h.

Referenced by vmbus_signal_event().

◆ VMBUS_MESSAGE_TYPE

#define VMBUS_MESSAGE_TYPE   1

VMBus message type.

Definition at line 26 of file vmbus.h.

Referenced by vmbus_post_message(), and vmbus_wait_for_any_message().

◆ VMBUS_MESSAGE_SINT

#define VMBUS_MESSAGE_SINT   2

VMBus message synthetic interrupt.

Definition at line 29 of file vmbus.h.

Referenced by vmbus_probe(), vmbus_remove(), vmbus_reset(), and vmbus_wait_for_any_message().

◆ VMBUS_PACKET_MAX_HEADER_LEN

#define VMBUS_PACKET_MAX_HEADER_LEN   64

Maximum expected size of VMBus packet header.

Definition at line 333 of file vmbus.h.

◆ VMBUS_DRIVERS

#define VMBUS_DRIVERS   __table ( struct vmbus_driver, "vmbus_drivers" )

VMBus device driver table.

Definition at line 545 of file vmbus.h.

Referenced by vmbus_find_driver().

◆ __vmbus_driver

#define __vmbus_driver   __table_entry ( VMBUS_DRIVERS, 01 )

Declare a VMBus device driver.

Definition at line 548 of file vmbus.h.

◆ VMBUS_ROM

#define VMBUS_ROM ( _name,
_desc )

Define build rules for a VMBus device driver.

Definition at line 551 of file vmbus.h.

◆ VMBUS_TYPE

#define VMBUS_TYPE ( a,
b,
c,
d,
e0,
e1,
e2,
e3,
e4,
e5 )
Value:
{ \
.canonical = { \
cpu_to_le32 ( a ), cpu_to_le16 ( b ), \
cpu_to_le16 ( c ), cpu_to_be16 ( d ), \
{ e0, e1, e2, e3, e4, e5 } \
} }
#define cpu_to_be16(value)
Definition byteswap.h:110
#define cpu_to_le16(value)
Definition byteswap.h:107

Construct VMBus type.

Definition at line 574 of file vmbus.h.

574#define VMBUS_TYPE( a, b, c, d, e0, e1, e2, e3, e4, e5 ) { \
575 .canonical = { \
576 cpu_to_le32 ( a ), cpu_to_le16 ( b ), \
577 cpu_to_le16 ( c ), cpu_to_be16 ( d ), \
578 { e0, e1, e2, e3, e4, e5 } \
579 } }

Enumeration Type Documentation

◆ vmbus_raw_version

Known VMBus protocol versions.

Enumerator
VMBUS_VERSION_WS2008 

Windows Server 2008.

VMBUS_VERSION_WIN7 

Windows 7.

VMBUS_VERSION_WIN8 

Windows 8.

VMBUS_VERSION_WIN8_1 

Windows 8.1.

Definition at line 45 of file vmbus.h.

45 {
46 /** Windows Server 2008 */
47 VMBUS_VERSION_WS2008 = ( ( 0 << 16 ) | ( 13 << 0 ) ),
48 /** Windows 7 */
49 VMBUS_VERSION_WIN7 = ( ( 1 << 16 ) | ( 1 << 0 ) ),
50 /** Windows 8 */
51 VMBUS_VERSION_WIN8 = ( ( 2 << 16 ) | ( 4 << 0 ) ),
52 /** Windows 8.1 */
53 VMBUS_VERSION_WIN8_1 = ( ( 3 << 16 ) | ( 0 << 0 ) ),
54};
@ VMBUS_VERSION_WIN7
Windows 7.
Definition vmbus.h:49
@ VMBUS_VERSION_WIN8_1
Windows 8.1.
Definition vmbus.h:53
@ VMBUS_VERSION_WIN8
Windows 8.
Definition vmbus.h:51
@ VMBUS_VERSION_WS2008
Windows Server 2008.
Definition vmbus.h:47

◆ vmbus_message_type

VMBus message types.

Enumerator
VMBUS_OFFER_CHANNEL 
VMBUS_REQUEST_OFFERS 
VMBUS_ALL_OFFERS_DELIVERED 
VMBUS_OPEN_CHANNEL 
VMBUS_OPEN_CHANNEL_RESULT 
VMBUS_CLOSE_CHANNEL 
VMBUS_GPADL_HEADER 
VMBUS_GPADL_CREATED 
VMBUS_GPADL_TEARDOWN 
VMBUS_GPADL_TORNDOWN 
VMBUS_INITIATE_CONTACT 
VMBUS_VERSION_RESPONSE 
VMBUS_UNLOAD 
VMBUS_UNLOAD_RESPONSE 

Definition at line 79 of file vmbus.h.

79 {
92 VMBUS_UNLOAD = 16,
94};
@ VMBUS_OPEN_CHANNEL_RESULT
Definition vmbus.h:84
@ VMBUS_GPADL_CREATED
Definition vmbus.h:87
@ VMBUS_REQUEST_OFFERS
Definition vmbus.h:81
@ VMBUS_INITIATE_CONTACT
Definition vmbus.h:90
@ VMBUS_GPADL_TORNDOWN
Definition vmbus.h:89
@ VMBUS_OPEN_CHANNEL
Definition vmbus.h:83
@ VMBUS_OFFER_CHANNEL
Definition vmbus.h:80
@ VMBUS_UNLOAD_RESPONSE
Definition vmbus.h:93
@ VMBUS_UNLOAD
Definition vmbus.h:92
@ VMBUS_GPADL_HEADER
Definition vmbus.h:86
@ VMBUS_VERSION_RESPONSE
Definition vmbus.h:91
@ VMBUS_ALL_OFFERS_DELIVERED
Definition vmbus.h:82
@ VMBUS_GPADL_TEARDOWN
Definition vmbus.h:88
@ VMBUS_CLOSE_CHANNEL
Definition vmbus.h:85

◆ vmbus_packet_type

VMBus packet types.

Enumerator
VMBUS_DATA_INBAND 
VMBUS_DATA_XFER_PAGES 
VMBUS_DATA_GPA_DIRECT 
VMBUS_CANCELLATION 
VMBUS_COMPLETION 

Definition at line 283 of file vmbus.h.

283 {
288 VMBUS_COMPLETION = 11,
289};
@ VMBUS_DATA_INBAND
Definition vmbus.h:284
@ VMBUS_COMPLETION
Definition vmbus.h:288
@ VMBUS_DATA_XFER_PAGES
Definition vmbus.h:285
@ VMBUS_CANCELLATION
Definition vmbus.h:287
@ VMBUS_DATA_GPA_DIRECT
Definition vmbus.h:286

◆ vmbus_packet_flags

VMBus packet flags.

Enumerator
VMBUS_COMPLETION_REQUESTED 

Definition at line 292 of file vmbus.h.

292 {
294};
@ VMBUS_COMPLETION_REQUESTED
Definition vmbus.h:293

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ vmbus_set_drvdata()

void vmbus_set_drvdata ( struct vmbus_device * vmdev,
void * priv )
inlinestatic

Set VMBus device driver-private data.

Parameters
vmdevVMBus device
privPrivate data

Definition at line 559 of file vmbus.h.

559 {
560 vmdev->priv = priv;
561}
void * priv
Driver-private data.
Definition vmbus.h:516
static struct tlan_private * priv
Definition tlan.c:225

References priv, and vmbus_device::priv.

Referenced by netvsc_probe().

◆ vmbus_get_drvdata()

void * vmbus_get_drvdata ( struct vmbus_device * vmdev)
inlinestatic

Get VMBus device driver-private data.

Parameters
vmdevVMBus device
Return values
privPrivate data

Definition at line 569 of file vmbus.h.

569 {
570 return vmdev->priv;
571}

References vmbus_device::priv.

Referenced by netvsc_recv_cancellation(), netvsc_recv_completion(), netvsc_recv_control(), netvsc_recv_data(), netvsc_remove(), and netvsc_reset().

◆ vmbus_has_data()

int vmbus_has_data ( struct vmbus_device * vmdev)
inlinestatic

Check if data is present in ring buffer.

Parameters
vmdevVMBus device
has_dataData is present

Definition at line 588 of file vmbus.h.

588 {
589
590 return ( vmdev->in->prod != vmdev->in->cons );
591}
struct vmbus_ring * in
Inbound ring buffer.
Definition vmbus.h:500
uint32_t cons
Consumer index (modulo ring length)
Definition vmbus.h:364
uint32_t prod
Producer index (modulo ring length)
Definition vmbus.h:362

References vmbus_ring::cons, vmbus_device::in, and vmbus_ring::prod.

Referenced by netvsc_poll(), and vmbus_poll().

◆ vmbus_register_pages()

int vmbus_register_pages ( struct vmbus_device * vmdev,
struct vmbus_xfer_pages * pages )
inlinestatic

Register transfer page set.

Parameters
vmdevVMBus device
pagesTransfer page set
Return values
rcReturn status code

Definition at line 601 of file vmbus.h.

602 {
603
604 list_add ( &pages->list, &vmdev->pages );
605 return 0;
606}
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
struct list_head pages
List of transfer page sets.
Definition vmbus.h:511
struct list_head list
List of all transfer page sets.
Definition vmbus.h:467

References list_add, and vmbus_device::pages.

Referenced by netvsc_create_buffer().

◆ vmbus_unregister_pages()

void vmbus_unregister_pages ( struct vmbus_device * vmdev,
struct vmbus_xfer_pages * pages )
inlinestatic

Unregister transfer page set.

Parameters
vmdevVMBus device
pagesTransfer page set

Definition at line 615 of file vmbus.h.

616 {
617
618 list_check_contains_entry ( pages, &vmdev->pages, list );
619 list_del ( &pages->list );
620}
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define list_check_contains_entry(entry, head, member)
Check list contains a specified entry.
Definition list.h:550

References list_check_contains_entry, list_del, and vmbus_device::pages.

Referenced by netvsc_create_buffer(), and netvsc_destroy_buffer().

◆ vmbus_gpadl_is_obsolete()

int vmbus_gpadl_is_obsolete ( unsigned int gpadl)
inlinestatic

Check if GPADL is obsolete.

Parameters
gpadlGPADL ID
is_obsoleteGPADL ID is obsolete

Check if GPADL is obsolete (i.e. was created before the most recent Hyper-V reset).

Definition at line 634 of file vmbus.h.

634 {
635
636 return ( gpadl <= vmbus_obsolete_gpadl );
637}
uint32_t gpadl
GPADL ID.
Definition netvsc.h:3
unsigned int vmbus_obsolete_gpadl
Obsolete GPADL ID threshold.
Definition vmbus.c:61

References gpadl, and vmbus_obsolete_gpadl.

Referenced by vmbus_gpadl_teardown().

◆ vmbus_establish_gpadl()

int vmbus_establish_gpadl ( struct vmbus_device * vmdev,
void * data,
size_t len )
extern

Establish GPA descriptor list.

Parameters
vmdevVMBus device
dataData buffer
lenLength of data buffer
Return values
gpadlGPADL ID, or negative error

Definition at line 276 of file vmbus.c.

277 {
278 struct hv_hypervisor *hv = vmdev->hv;
279 struct vmbus *vmbus = hv->vmbus;
280 physaddr_t addr = virt_to_phys ( data );
281 unsigned int pfn_count = hv_pfn_count ( addr, len );
282 struct {
283 struct vmbus_gpadl_header gpadlhdr;
284 struct vmbus_gpa_range range;
285 uint64_t pfn[pfn_count];
286 } __attribute__ (( packed )) gpadlhdr;
287 const struct vmbus_gpadl_created *created = &vmbus->message->created;
288 unsigned int gpadl;
289 unsigned int i;
290 int rc;
291
292 /* Allocate GPADL ID */
293 gpadl = ++vmbus_gpadl;
294
295 /* Construct message */
296 memset ( &gpadlhdr, 0, sizeof ( gpadlhdr ) );
297 gpadlhdr.gpadlhdr.header.type = cpu_to_le32 ( VMBUS_GPADL_HEADER );
298 gpadlhdr.gpadlhdr.channel = cpu_to_le32 ( vmdev->channel );
299 gpadlhdr.gpadlhdr.gpadl = cpu_to_le32 ( gpadl );
300 gpadlhdr.gpadlhdr.range_len =
301 cpu_to_le16 ( ( sizeof ( gpadlhdr.range ) +
302 sizeof ( gpadlhdr.pfn ) ) );
303 gpadlhdr.gpadlhdr.range_count = cpu_to_le16 ( 1 );
304 gpadlhdr.range.len = cpu_to_le32 ( len );
305 gpadlhdr.range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
306 for ( i = 0 ; i < pfn_count ; i++ )
307 gpadlhdr.pfn[i] = ( ( addr / PAGE_SIZE ) + i );
308
309 /* Post message */
310 if ( ( rc = vmbus_post_message ( hv, &gpadlhdr.gpadlhdr.header,
311 sizeof ( gpadlhdr ) ) ) != 0 )
312 return rc;
313
314 /* Wait for response */
315 if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_GPADL_CREATED ) ) != 0 )
316 return rc;
317
318 /* Check response */
319 if ( created->channel != cpu_to_le32 ( vmdev->channel ) ) {
320 DBGC ( vmdev, "VMBUS %s unexpected GPADL channel %d\n",
321 vmdev->dev.name, le32_to_cpu ( created->channel ) );
322 return -EPROTO;
323 }
324 if ( created->gpadl != cpu_to_le32 ( gpadl ) ) {
325 DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
326 vmdev->dev.name, le32_to_cpu ( created->gpadl ) );
327 return -EPROTO;
328 }
329 if ( created->status != 0 ) {
330 DBGC ( vmdev, "VMBUS %s GPADL creation failed: %#08x\n",
331 vmdev->dev.name, le32_to_cpu ( created->status ) );
332 return -EPROTO;
333 }
334
335 DBGC ( vmdev, "VMBUS %s GPADL %#08x is [%08lx,%08lx)\n",
336 vmdev->dev.name, gpadl, addr, ( addr + len ) );
337 return gpadl;
338}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned long physaddr_t
Definition stdint.h:20
unsigned long long uint64_t
Definition stdint.h:13
ring len
Length.
Definition dwmac.h:226
uint32_t addr
Buffer address.
Definition dwmac.h:9
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define DBGC(...)
Definition compiler.h:505
#define EPROTO
Protocol error.
Definition errno.h:625
#define le32_to_cpu(value)
Definition byteswap.h:114
#define cpu_to_le32(value)
Definition byteswap.h:108
#define __attribute__(x)
Definition compiler.h:10
static unsigned int hv_pfn_count(physaddr_t data, size_t len)
Calculate the number of pages covering an address range.
Definition hyperv.h:223
#define PAGE_SIZE
Page size.
Definition io.h:28
void * memset(void *dest, int character, size_t len) __nonnull
struct pci_range range
PCI bus:dev.fn address range.
Definition pcicloud.c:40
char name[40]
Name.
Definition device.h:79
A Hyper-V hypervisor.
Definition hyperv.h:203
struct vmbus * vmbus
Virtual machine bus.
Definition hyperv.h:211
struct hv_hypervisor * hv
Hyper-V hypervisor.
Definition vmbus.h:479
unsigned int channel
Channel ID.
Definition vmbus.h:484
struct device dev
Generic iPXE device.
Definition vmbus.h:477
VMBus "GPADL created" message.
Definition vmbus.h:181
uint32_t channel
Channel ID.
Definition vmbus.h:185
uint32_t gpadl
GPADL ID.
Definition vmbus.h:187
uint32_t status
Creation status.
Definition vmbus.h:189
A virtual machine bus.
Definition vmbus.h:382
const union vmbus_message * message
Received message buffer.
Definition vmbus.h:390
struct vmbus_gpadl_created created
"GPADL created" message
Definition vmbus.h:253
static int vmbus_wait_for_message(struct hv_hypervisor *hv, unsigned int type)
Wait for received message of a specified type, ignoring any others.
Definition vmbus.c:136
static unsigned int vmbus_gpadl
Current (i.e.
Definition vmbus.c:54
static int vmbus_post_message(struct hv_hypervisor *hv, const struct vmbus_message_header *header, size_t len)
Post message.
Definition vmbus.c:71

References __attribute__, addr, vmbus_device::channel, vmbus_gpadl_created::channel, cpu_to_le16, cpu_to_le32, vmbus_message::created, data, DBGC, vmbus_device::dev, EPROTO, gpadl, vmbus_gpadl_created::gpadl, vmbus_device::hv, hv_pfn_count(), le32_to_cpu, len, memset(), vmbus::message, device::name, PAGE_SIZE, range, rc, vmbus_gpadl_created::status, hv_hypervisor::vmbus, vmbus_gpadl, VMBUS_GPADL_CREATED, VMBUS_GPADL_HEADER, vmbus_post_message(), and vmbus_wait_for_message().

Referenced by netvsc_create_buffer(), and vmbus_open().

◆ vmbus_gpadl_teardown()

int vmbus_gpadl_teardown ( struct vmbus_device * vmdev,
unsigned int gpadl )
extern

Tear down GPA descriptor list.

Parameters
vmdevVMBus device
gpadlGPADL ID
Return values
rcReturn status code

Definition at line 347 of file vmbus.c.

347 {
348 struct hv_hypervisor *hv = vmdev->hv;
349 struct vmbus *vmbus = hv->vmbus;
350 struct vmbus_gpadl_teardown teardown;
351 const struct vmbus_gpadl_torndown *torndown = &vmbus->message->torndown;
352 int rc;
353
354 /* If GPADL is obsolete (i.e. was created before the most
355 * recent Hyper-V reset), then we will never receive a
356 * response to the teardown message. Since the GPADL is
357 * already destroyed as far as the hypervisor is concerned, no
358 * further action is required.
359 */
361 return 0;
362
363 /* Construct message */
364 memset ( &teardown, 0, sizeof ( teardown ) );
365 teardown.header.type = cpu_to_le32 ( VMBUS_GPADL_TEARDOWN );
366 teardown.channel = cpu_to_le32 ( vmdev->channel );
367 teardown.gpadl = cpu_to_le32 ( gpadl );
368
369 /* Post message */
370 if ( ( rc = vmbus_post_message ( hv, &teardown.header,
371 sizeof ( teardown ) ) ) != 0 )
372 return rc;
373
374 /* Wait for response */
375 if ( ( rc = vmbus_wait_for_message ( hv, VMBUS_GPADL_TORNDOWN ) ) != 0 )
376 return rc;
377
378 /* Check response */
379 if ( torndown->gpadl != cpu_to_le32 ( gpadl ) ) {
380 DBGC ( vmdev, "VMBUS %s unexpected GPADL ID %#08x\n",
381 vmdev->dev.name, le32_to_cpu ( torndown->gpadl ) );
382 return -EPROTO;
383 }
384
385 return 0;
386}
VMBus "GPADL teardown" message.
Definition vmbus.h:193
VMBus "GPADL torndown" message.
Definition vmbus.h:203
uint32_t gpadl
GPADL ID.
Definition vmbus.h:207
struct vmbus_gpadl_torndown torndown
"GPADL torndown" message
Definition vmbus.h:257
static int vmbus_gpadl_is_obsolete(unsigned int gpadl)
Check if GPADL is obsolete.
Definition vmbus.h:634

References vmbus_device::channel, vmbus_gpadl_teardown::channel, cpu_to_le32, DBGC, vmbus_device::dev, EPROTO, gpadl, vmbus_gpadl_teardown::gpadl, vmbus_gpadl_torndown::gpadl, vmbus_gpadl_teardown::header, vmbus_device::hv, le32_to_cpu, memset(), vmbus::message, device::name, rc, vmbus_message::torndown, vmbus_message_header::type, hv_hypervisor::vmbus, vmbus_gpadl_is_obsolete(), VMBUS_GPADL_TEARDOWN, VMBUS_GPADL_TORNDOWN, vmbus_post_message(), and vmbus_wait_for_message().

Referenced by netvsc_create_buffer(), and vmbus_open().

◆ vmbus_open()

int vmbus_open ( struct vmbus_device * vmdev,
struct vmbus_channel_operations * op,
size_t out_len,
size_t in_len,
size_t mtu )
extern

Open VMBus channel.

Parameters
vmdevVMBus device
opChannel operations
out_lenOutbound ring buffer length
in_lenInbound ring buffer length
mtuMaximum expected data packet length (including headers)
Return values
rcReturn status code

Both outbound and inbound ring buffer lengths must be a power of two and a multiple of PAGE_SIZE. The requirement to be a power of two is a policy decision taken to simplify the ring buffer indexing logic.

Definition at line 403 of file vmbus.c.

405 {
406 struct hv_hypervisor *hv = vmdev->hv;
407 struct vmbus *vmbus = hv->vmbus;
409 const struct vmbus_open_channel_result *opened =
411 size_t len;
412 void *ring;
413 void *packet;
414 int gpadl;
415 uint32_t open_id;
416 int rc;
417
418 /* Sanity checks */
419 assert ( ( out_len % PAGE_SIZE ) == 0 );
420 assert ( ( out_len & ( out_len - 1 ) ) == 0 );
421 assert ( ( in_len % PAGE_SIZE ) == 0 );
422 assert ( ( in_len & ( in_len - 1 ) ) == 0 );
423 assert ( mtu >= ( sizeof ( struct vmbus_packet_header ) +
424 sizeof ( struct vmbus_packet_footer ) ) );
425
426 /* Allocate packet buffer */
427 packet = malloc ( mtu );
428 if ( ! packet ) {
429 rc = -ENOMEM;
430 goto err_alloc_packet;
431 }
432
433 /* Allocate ring buffer */
434 len = ( sizeof ( *vmdev->out ) + out_len +
435 sizeof ( *vmdev->in ) + in_len );
436 assert ( ( len % PAGE_SIZE ) == 0 );
437 ring = malloc_phys ( len, PAGE_SIZE );
438 if ( ! ring ) {
439 rc = -ENOMEM;
440 goto err_alloc_ring;
441 }
442 memset ( ring, 0, len );
443
444 /* Establish GPADL for ring buffer */
445 gpadl = vmbus_establish_gpadl ( vmdev, ring, len );
446 if ( gpadl < 0 ) {
447 rc = gpadl;
448 goto err_establish;
449 }
450
451 /* Construct message */
452 memset ( &open, 0, sizeof ( open ) );
453 open.header.type = cpu_to_le32 ( VMBUS_OPEN_CHANNEL );
454 open.channel = cpu_to_le32 ( vmdev->channel );
455 open_id = random();
456 open.id = open_id; /* Opaque random value: endianness irrelevant */
457 open.gpadl = cpu_to_le32 ( gpadl );
458 open.out_pages = ( ( sizeof ( *vmdev->out ) / PAGE_SIZE ) +
459 ( out_len / PAGE_SIZE ) );
460
461 /* Post message */
462 if ( ( rc = vmbus_post_message ( hv, &open.header,
463 sizeof ( open ) ) ) != 0 )
464 goto err_post_message;
465
466 /* Wait for response */
467 if ( ( rc = vmbus_wait_for_message ( hv,
469 goto err_wait_for_message;
470
471 /* Check response */
472 if ( opened->channel != cpu_to_le32 ( vmdev->channel ) ) {
473 DBGC ( vmdev, "VMBUS %s unexpected opened channel %#08x\n",
474 vmdev->dev.name, le32_to_cpu ( opened->channel ) );
475 rc = -EPROTO;
476 goto err_check_response;
477 }
478 if ( opened->id != open_id /* Non-endian */ ) {
479 DBGC ( vmdev, "VMBUS %s unexpected open ID %#08x\n",
480 vmdev->dev.name, le32_to_cpu ( opened->id ) );
481 rc = -EPROTO;
482 goto err_check_response;
483 }
484 if ( opened->status != 0 ) {
485 DBGC ( vmdev, "VMBUS %s open failed: %#08x\n",
486 vmdev->dev.name, le32_to_cpu ( opened->status ) );
487 rc = -EPROTO;
488 goto err_check_response;
489 }
490
491 /* Store channel parameters */
492 vmdev->out_len = out_len;
493 vmdev->in_len = in_len;
494 vmdev->out = ring;
495 vmdev->in = ( ring + sizeof ( *vmdev->out ) + out_len );
496 vmdev->gpadl = gpadl;
497 vmdev->op = op;
498 vmdev->mtu = mtu;
499 vmdev->packet = packet;
500
501 DBGC ( vmdev, "VMBUS %s channel GPADL %#08x ring "
502 "[%#08lx,%#08lx,%#08lx)\n", vmdev->dev.name, vmdev->gpadl,
503 virt_to_phys ( vmdev->out ), virt_to_phys ( vmdev->in ),
504 ( virt_to_phys ( vmdev->out ) + len ) );
505 return 0;
506
507 err_check_response:
508 err_wait_for_message:
509 err_post_message:
510 vmbus_gpadl_teardown ( vmdev, vmdev->gpadl );
511 err_establish:
512 free_phys ( ring, len );
513 err_alloc_ring:
514 free ( packet );
515 err_alloc_packet:
516 return rc;
517}
unsigned int uint32_t
Definition stdint.h:12
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
uint32_t mtu
Maximum MTU.
Definition ena.h:17
#define ENOMEM
Not enough space.
Definition errno.h:535
void * malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition malloc.c:707
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition malloc.c:723
static uint16_t struct vmbus_xfer_pages_operations * op
Definition netvsc.h:327
int open(const char *uri_string)
Open file.
Definition posix_io.c:176
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
void * packet
Packet buffer.
Definition vmbus.h:509
unsigned int gpadl
Ring buffer GPADL ID.
Definition vmbus.h:502
struct vmbus_channel_operations * op
Channel operations.
Definition vmbus.h:505
uint32_t out_len
Outbound ring buffer length.
Definition vmbus.h:494
struct vmbus_ring * out
Outbound ring buffer.
Definition vmbus.h:498
size_t mtu
Maximum expected data packet length.
Definition vmbus.h:507
uint32_t in_len
Inbound ring buffer length.
Definition vmbus.h:496
VMBus "open channel result" message.
Definition vmbus.h:145
uint32_t status
Status.
Definition vmbus.h:153
uint32_t channel
Channel ID.
Definition vmbus.h:149
uint32_t id
Open ID.
Definition vmbus.h:151
VMBus "open channel" message.
Definition vmbus.h:127
VMBus packet header.
Definition vmbus.h:265
struct vmbus_open_channel_result opened
"Open channel result" message
Definition vmbus.h:247
int vmbus_establish_gpadl(struct vmbus_device *vmdev, void *data, size_t len)
Establish GPA descriptor list.
Definition vmbus.c:276
int vmbus_gpadl_teardown(struct vmbus_device *vmdev, unsigned int gpadl)
Tear down GPA descriptor list.
Definition vmbus.c:347

References assert, vmbus_device::channel, vmbus_open_channel_result::channel, cpu_to_le32, DBGC, vmbus_device::dev, ENOMEM, EPROTO, free, free_phys(), gpadl, vmbus_device::gpadl, vmbus_device::hv, vmbus_open_channel_result::id, vmbus_device::in, vmbus_device::in_len, le32_to_cpu, len, malloc(), malloc_phys(), memset(), vmbus::message, mtu, vmbus_device::mtu, device::name, op, vmbus_device::op, open(), vmbus_message::opened, vmbus_device::out, vmbus_device::out_len, vmbus_device::packet, PAGE_SIZE, random(), rc, vmbus_open_channel_result::status, hv_hypervisor::vmbus, vmbus_establish_gpadl(), vmbus_gpadl_teardown(), VMBUS_OPEN_CHANNEL, VMBUS_OPEN_CHANNEL_RESULT, vmbus_post_message(), and vmbus_wait_for_message().

Referenced by netvsc_open().

◆ vmbus_close()

void vmbus_close ( struct vmbus_device * vmdev)
extern

Close VMBus channel.

Parameters
vmdevVMBus device

Definition at line 524 of file vmbus.c.

524 {
525 struct hv_hypervisor *hv = vmdev->hv;
527 size_t len;
528 int rc;
529
530 /* Construct message */
531 memset ( &close, 0, sizeof ( close ) );
532 close.header.type = cpu_to_le32 ( VMBUS_CLOSE_CHANNEL );
533 close.channel = cpu_to_le32 ( vmdev->channel );
534
535 /* Post message */
536 if ( ( rc = vmbus_post_message ( hv, &close.header,
537 sizeof ( close ) ) ) != 0 ) {
538 DBGC ( vmdev, "VMBUS %s failed to close: %s\n",
539 vmdev->dev.name, strerror ( rc ) );
540 /* Continue to attempt to tear down GPADL, so that our
541 * memory is no longer accessible by the remote VM.
542 */
543 }
544
545 /* Tear down GPADL */
546 if ( ( rc = vmbus_gpadl_teardown ( vmdev, vmdev->gpadl ) ) != 0 ) {
547 DBGC ( vmdev, "VMBUS %s failed to tear down channel GPADL: "
548 "%s\n", vmdev->dev.name, strerror ( rc ) );
549 /* We can't prevent the remote VM from continuing to
550 * access this memory, so leak it.
551 */
552 return;
553 }
554
555 /* Free ring buffer */
556 len = ( sizeof ( *vmdev->out ) + vmdev->out_len +
557 sizeof ( *vmdev->in ) + vmdev->in_len );
558 free_phys ( vmdev->out, len );
559 vmdev->out = NULL;
560 vmdev->in = NULL;
561
562 /* Free packet buffer */
563 free ( vmdev->packet );
564 vmdev->packet = NULL;
565
566 DBGC ( vmdev, "VMBUS %s closed\n", vmdev->dev.name );
567}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
VMBus "close channel" message.
Definition vmbus.h:157
static struct evtchn_close * close
Definition xenevent.h:24

References vmbus_device::channel, close, cpu_to_le32, DBGC, vmbus_device::dev, free, free_phys(), vmbus_device::gpadl, vmbus_device::hv, vmbus_device::in, vmbus_device::in_len, len, memset(), device::name, NULL, vmbus_device::out, vmbus_device::out_len, vmbus_device::packet, rc, strerror(), VMBUS_CLOSE_CHANNEL, and vmbus_post_message().

Referenced by netvsc_close(), and netvsc_open().

◆ vmbus_send_control()

int vmbus_send_control ( struct vmbus_device * vmdev,
uint64_t xid,
const void * data,
size_t len )
extern

Send control packet via ring buffer.

Parameters
vmdevVMBus device
xidTransaction ID (or zero to not request completion)
dataData
lenLength of data
Return values
rcReturn status code

Send data using a VMBUS_DATA_INBAND packet.

Definition at line 765 of file vmbus.c.

766 {
767 struct vmbus_packet_header *header = vmdev->packet;
768
769 /* Construct header in packet buffer */
770 assert ( header != NULL );
772 header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
773 header->flags = ( xid ?
775 header->xid = xid; /* Non-endian */
776
777 return vmbus_send ( vmdev, header, data, len );
778}
struct ena_llq_option header
Header locations.
Definition ena.h:5
uint64_t xid
Transaction ID.
Definition vmbus.h:279
static int vmbus_send(struct vmbus_device *vmdev, struct vmbus_packet_header *header, const void *data, size_t len)
Send packet via ring buffer.
Definition vmbus.c:677

References assert, cpu_to_le16, data, header, len, NULL, vmbus_device::packet, VMBUS_COMPLETION_REQUESTED, VMBUS_DATA_INBAND, vmbus_send(), and vmbus_packet_header::xid.

Referenced by netvsc_control().

◆ vmbus_send_data()

int vmbus_send_data ( struct vmbus_device * vmdev,
uint64_t xid,
const void * data,
size_t len,
struct io_buffer * iobuf )
extern

Send data packet via ring buffer.

Parameters
vmdevVMBus device
xidTransaction ID
dataData
lenLength of data
iobufI/O buffer
Return values
rcReturn status code

Send data using a VMBUS_DATA_GPA_DIRECT packet. The caller is responsible for ensuring that the I/O buffer remains untouched until the corresponding completion has been received.

Definition at line 794 of file vmbus.c.

795 {
796 physaddr_t addr = virt_to_phys ( iobuf->data );
797 unsigned int pfn_count = hv_pfn_count ( addr, iob_len ( iobuf ) );
798 struct {
799 struct vmbus_gpa_direct_header gpa;
800 struct vmbus_gpa_range range;
801 uint64_t pfn[pfn_count];
802 } __attribute__ (( packed )) *header = vmdev->packet;
803 unsigned int i;
804
805 /* Sanity check */
806 assert ( header != NULL );
807 assert ( sizeof ( *header ) <= vmdev->mtu );
808
809 /* Construct header in packet buffer */
810 header->gpa.header.type = cpu_to_le16 ( VMBUS_DATA_GPA_DIRECT );
811 header->gpa.header.hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
812 header->gpa.header.flags = cpu_to_le16 ( VMBUS_COMPLETION_REQUESTED );
813 header->gpa.header.xid = xid; /* Non-endian */
814 header->gpa.range_count = 1;
815 header->range.len = cpu_to_le32 ( iob_len ( iobuf ) );
816 header->range.offset = cpu_to_le32 ( addr & ( PAGE_SIZE - 1 ) );
817 for ( i = 0 ; i < pfn_count ; i++ )
818 header->pfn[i] = ( ( addr / PAGE_SIZE ) + i );
819
820 return vmbus_send ( vmdev, &header->gpa.header, data, len );
821}
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
void * data
Start of data.
Definition iobuf.h:53
VMBus GPA direct header.
Definition vmbus.h:297
Guest physical address range descriptor.
Definition vmbus.h:57
uint64_t pfn[0]
Page frame numbers.
Definition vmbus.h:67

References __attribute__, addr, assert, cpu_to_le16, cpu_to_le32, data, io_buffer::data, header, hv_pfn_count(), iob_len(), len, vmbus_device::mtu, NULL, vmbus_device::packet, PAGE_SIZE, range, VMBUS_COMPLETION_REQUESTED, VMBUS_DATA_GPA_DIRECT, and vmbus_send().

Referenced by netvsc_transmit().

◆ vmbus_send_completion()

int vmbus_send_completion ( struct vmbus_device * vmdev,
uint64_t xid,
const void * data,
size_t len )
extern

Send completion packet via ring buffer.

Parameters
vmdevVMBus device
xidTransaction ID
dataData
lenLength of data
Return values
rcReturn status code

Send data using a VMBUS_COMPLETION packet.

Definition at line 834 of file vmbus.c.

835 {
836 struct vmbus_packet_header *header = vmdev->packet;
837
838 /* Construct header in packet buffer */
839 assert ( header != NULL );
841 header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
842 header->flags = 0;
843 header->xid = xid; /* Non-endian */
844
845 return vmbus_send ( vmdev, header, data, len );
846}

References assert, cpu_to_le16, data, header, len, NULL, vmbus_device::packet, VMBUS_COMPLETION, vmbus_send(), and vmbus_packet_header::xid.

Referenced by netvsc_recv_data().

◆ vmbus_send_cancellation()

int vmbus_send_cancellation ( struct vmbus_device * vmdev,
uint64_t xid )
extern

Send cancellation packet via ring buffer.

Parameters
vmdevVMBus device
xidTransaction ID
Return values
rcReturn status code

Send data using a VMBUS_CANCELLATION packet.

Definition at line 857 of file vmbus.c.

857 {
858 struct vmbus_packet_header *header = vmdev->packet;
859
860 /* Construct header in packet buffer */
861 assert ( header != NULL );
863 header->hdr_qlen = cpu_to_le16 ( sizeof ( *header ) / 8 );
864 header->flags = 0;
865 header->xid = xid; /* Non-endian */
866
867 return vmbus_send ( vmdev, header, NULL, 0 );
868}

References assert, cpu_to_le16, header, NULL, vmbus_device::packet, VMBUS_CANCELLATION, vmbus_send(), and vmbus_packet_header::xid.

Referenced by netvsc_cancel_transmit().

◆ vmbus_poll()

int vmbus_poll ( struct vmbus_device * vmdev)
extern

Poll ring buffer.

Parameters
vmdevVMBus device
Return values
rcReturn status code

Definition at line 972 of file vmbus.c.

972 {
973 struct vmbus_packet_header *header = vmdev->packet;
974 struct list_head list;
975 void *data;
976 size_t header_len;
977 size_t len;
978 size_t footer_len;
979 size_t ring_len;
980 size_t cons;
981 size_t old_cons;
982 uint64_t xid;
983 int rc;
984
985 /* Sanity checks */
986 assert ( vmdev->packet != NULL );
987 assert ( vmdev->in != NULL );
988
989 /* Return immediately if buffer is empty */
990 if ( ! vmbus_has_data ( vmdev ) )
991 return 0;
992 cons = le32_to_cpu ( vmdev->in->cons );
993 old_cons = cons;
994
995 /* Consume (start of) header */
996 cons = vmbus_consume ( vmdev, cons, header, sizeof ( *header ) );
997
998 /* Parse and sanity check header */
999 header_len = ( le16_to_cpu ( header->hdr_qlen ) * 8 );
1000 if ( header_len < sizeof ( *header ) ) {
1001 DBGC ( vmdev, "VMBUS %s received underlength header (%zd "
1002 "bytes)\n", vmdev->dev.name, header_len );
1003 return -EINVAL;
1004 }
1005 len = ( ( le16_to_cpu ( header->qlen ) * 8 ) - header_len );
1006 footer_len = sizeof ( struct vmbus_packet_footer );
1007 ring_len = ( header_len + len + footer_len );
1008 if ( ring_len > vmdev->mtu ) {
1009 DBGC ( vmdev, "VMBUS %s received overlength packet (%zd "
1010 "bytes)\n", vmdev->dev.name, ring_len );
1011 return -ERANGE;
1012 }
1013 xid = le64_to_cpu ( header->xid );
1014
1015 /* Consume remainder of packet */
1016 cons = vmbus_consume ( vmdev, cons,
1017 ( ( ( void * ) header ) + sizeof ( *header ) ),
1018 ( ring_len - sizeof ( *header ) ) );
1019 DBGC2 ( vmdev, "VMBUS %s received:\n", vmdev->dev.name );
1020 DBGC2_HDA ( vmdev, old_cons, header, ring_len );
1021 assert ( ( ( cons - old_cons ) & ( vmdev->in_len - 1 ) ) == ring_len );
1022
1023 /* Allocate I/O buffers, if applicable */
1024 INIT_LIST_HEAD ( &list );
1025 if ( header->type == cpu_to_le16 ( VMBUS_DATA_XFER_PAGES ) ) {
1026 if ( ( rc = vmbus_xfer_page_iobufs ( vmdev, header,
1027 &list ) ) != 0 )
1028 return rc;
1029 }
1030
1031 /* Update producer index */
1032 rmb();
1033 vmdev->in->cons = cpu_to_le32 ( cons );
1034
1035 /* Handle packet */
1036 data = ( ( ( void * ) header ) + header_len );
1037 switch ( header->type ) {
1038
1040 if ( ( rc = vmdev->op->recv_control ( vmdev, xid, data,
1041 len ) ) != 0 ) {
1042 DBGC ( vmdev, "VMBUS %s could not handle control "
1043 "packet: %s\n",
1044 vmdev->dev.name, strerror ( rc ) );
1045 return rc;
1046 }
1047 break;
1048
1050 if ( ( rc = vmdev->op->recv_data ( vmdev, xid, data, len,
1051 &list ) ) != 0 ) {
1052 DBGC ( vmdev, "VMBUS %s could not handle data packet: "
1053 "%s\n", vmdev->dev.name, strerror ( rc ) );
1054 return rc;
1055 }
1056 break;
1057
1058 case cpu_to_le16 ( VMBUS_COMPLETION ) :
1059 if ( ( rc = vmdev->op->recv_completion ( vmdev, xid, data,
1060 len ) ) != 0 ) {
1061 DBGC ( vmdev, "VMBUS %s could not handle completion: "
1062 "%s\n", vmdev->dev.name, strerror ( rc ) );
1063 return rc;
1064 }
1065 break;
1066
1068 if ( ( rc = vmdev->op->recv_cancellation ( vmdev, xid ) ) != 0){
1069 DBGC ( vmdev, "VMBUS %s could not handle cancellation: "
1070 "%s\n", vmdev->dev.name, strerror ( rc ) );
1071 return rc;
1072 }
1073 break;
1074
1075 default:
1076 DBGC ( vmdev, "VMBUS %s unknown packet type %d\n",
1077 vmdev->dev.name, le16_to_cpu ( header->type ) );
1078 return -ENOTSUP;
1079 }
1080
1081 return 0;
1082}
uint16_t cons
Consumer index.
Definition ena.h:11
#define DBGC2(...)
Definition compiler.h:522
#define DBGC2_HDA(...)
Definition compiler.h:523
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define le16_to_cpu(value)
Definition byteswap.h:113
#define le64_to_cpu(value)
Definition byteswap.h:115
#define rmb()
Definition io.h:545
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
if(natsemi->flags &NATSEMI_64BIT) return 1
A doubly-linked list entry (or list head)
Definition list.h:19
static size_t vmbus_consume(struct vmbus_device *vmdev, size_t cons, void *data, size_t len)
Consume inbound ring buffer.
Definition vmbus.c:645
static int vmbus_xfer_page_iobufs(struct vmbus_device *vmdev, struct vmbus_packet_header *header, struct list_head *list)
Construct I/O buffer list from transfer pages.
Definition vmbus.c:900
static int vmbus_has_data(struct vmbus_device *vmdev)
Check if data is present in ring buffer.
Definition vmbus.h:588

References assert, cons, vmbus_ring::cons, cpu_to_le16, cpu_to_le32, data, DBGC, DBGC2, DBGC2_HDA, vmbus_device::dev, EINVAL, ENOTSUP, header, vmbus_device::in, vmbus_device::in_len, INIT_LIST_HEAD, le16_to_cpu, le32_to_cpu, le64_to_cpu, len, vmbus_device::mtu, device::name, NULL, vmbus_device::op, vmbus_device::packet, rc, vmbus_channel_operations::recv_cancellation, vmbus_channel_operations::recv_completion, vmbus_channel_operations::recv_control, vmbus_channel_operations::recv_data, rmb, strerror(), VMBUS_CANCELLATION, VMBUS_COMPLETION, vmbus_consume(), VMBUS_DATA_INBAND, VMBUS_DATA_XFER_PAGES, vmbus_has_data(), and vmbus_xfer_page_iobufs().

Referenced by netvsc_control(), and netvsc_poll().

◆ vmbus_dump_channel()

void vmbus_dump_channel ( struct vmbus_device * vmdev)
extern

Dump channel status (for debugging)

Parameters
vmdevVMBus device

Definition at line 1089 of file vmbus.c.

1089 {
1090 size_t out_prod = le32_to_cpu ( vmdev->out->prod );
1091 size_t out_cons = le32_to_cpu ( vmdev->out->cons );
1092 size_t in_prod = le32_to_cpu ( vmdev->in->prod );
1093 size_t in_cons = le32_to_cpu ( vmdev->in->cons );
1094 size_t in_len;
1095 size_t first;
1096 size_t second;
1097
1098 /* Dump ring status */
1099 DBGC ( vmdev, "VMBUS %s out %03zx:%03zx%s in %03zx:%03zx%s\n",
1100 vmdev->dev.name, out_prod, out_cons,
1101 ( vmdev->out->intr_mask ? "(m)" : "" ), in_prod, in_cons,
1102 ( vmdev->in->intr_mask ? "(m)" : "" ) );
1103
1104 /* Dump inbound ring contents, if any */
1105 if ( in_prod != in_cons ) {
1106 in_len = ( ( in_prod - in_cons ) &
1107 ( vmdev->in_len - 1 ) );
1108 first = ( vmdev->in_len - in_cons );
1109 if ( first > in_len )
1110 first = in_len;
1111 second = ( in_len - first );
1112 DBGC_HDA ( vmdev, in_cons, &vmdev->in->data[in_cons], first );
1113 DBGC_HDA ( vmdev, 0, &vmdev->in->data[0], second );
1114 }
1115}
#define DBGC_HDA(...)
Definition compiler.h:506
uint32_t first
First block in range.
Definition pccrr.h:1
uint32_t intr_mask
Interrupt mask.
Definition vmbus.h:366
uint8_t data[0]
Ring buffer contents.
Definition vmbus.h:370

References vmbus_ring::cons, vmbus_ring::data, DBGC, DBGC_HDA, vmbus_device::dev, first, vmbus_device::in, vmbus_device::in_len, vmbus_ring::intr_mask, le32_to_cpu, device::name, vmbus_device::out, and vmbus_ring::prod.

Referenced by netvsc_control().

◆ vmbus_probe()

int vmbus_probe ( struct hv_hypervisor * hv,
struct device * parent )
extern

Probe Hyper-V virtual machine bus.

Parameters
hvHyper-V hypervisor
parentParent device
Return values
rcReturn status code

Definition at line 1365 of file vmbus.c.

1365 {
1366 struct vmbus *vmbus;
1367 int rc;
1368
1369 /* Allocate and initialise structure */
1370 vmbus = zalloc ( sizeof ( *vmbus ) );
1371 if ( ! vmbus ) {
1372 rc = -ENOMEM;
1373 goto err_alloc;
1374 }
1375 hv->vmbus = vmbus;
1376
1377 /* Initialise message buffer pointer
1378 *
1379 * We use a pointer to the fixed-size Hyper-V received message
1380 * buffer. This allows us to access fields within received
1381 * messages without first checking the message size: any
1382 * fields beyond the end of the message will read as zero.
1383 */
1384 vmbus->message = ( ( void * ) hv->message->received.data );
1385 assert ( sizeof ( *vmbus->message ) <=
1386 sizeof ( hv->message->received.data ) );
1387
1388 /* Allocate interrupt and monitor pages */
1389 if ( ( rc = hv_alloc_pages ( hv, &vmbus->intr, &vmbus->monitor_in,
1390 &vmbus->monitor_out, NULL ) ) != 0 )
1391 goto err_alloc_pages;
1392
1393 /* Enable message interrupt */
1395
1396 /* Negotiate protocol version */
1397 if ( ( rc = vmbus_negotiate_version ( hv ) ) != 0 )
1398 goto err_negotiate_version;
1399
1400 /* Enumerate channels */
1401 if ( ( rc = vmbus_probe_channels ( hv, parent ) ) != 0 )
1402 goto err_probe_channels;
1403
1404 return 0;
1405
1406 vmbus_remove_channels ( hv, parent );
1407 err_probe_channels:
1408 vmbus_unload ( hv );
1409 err_negotiate_version:
1412 NULL );
1413 err_alloc_pages:
1414 free ( vmbus );
1415 err_alloc:
1416 return rc;
1417}
void hv_disable_sint(struct hv_hypervisor *hv, unsigned int sintx)
Disable synthetic interrupt.
Definition hyperv.c:423
void hv_free_pages(struct hv_hypervisor *hv,...)
Free pages.
Definition hyperv.c:113
int hv_alloc_pages(struct hv_hypervisor *hv,...)
Allocate zeroed pages.
Definition hyperv.c:78
void hv_enable_sint(struct hv_hypervisor *hv, unsigned int sintx)
Enable synthetic interrupt.
Definition hyperv.c:397
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
union hv_message_buffer * message
Message buffer.
Definition hyperv.h:209
uint8_t data[240]
Message.
Definition hyperv.h:112
struct vmbus_interrupt * intr
Interrupt page.
Definition vmbus.h:384
struct hv_monitor * monitor_out
Outbound notifications.
Definition vmbus.h:388
struct hv_monitor * monitor_in
Inbound notifications.
Definition vmbus.h:386
struct hv_message received
Received message.
Definition hyperv.h:197
static void vmbus_remove_channels(struct hv_hypervisor *hv __unused, struct device *parent)
Remove channels.
Definition vmbus.c:1339
static int vmbus_probe_channels(struct hv_hypervisor *hv, struct device *parent)
Probe channels.
Definition vmbus.c:1140
static int vmbus_negotiate_version(struct hv_hypervisor *hv)
Negotiate protocol version.
Definition vmbus.c:231
static int vmbus_unload(struct hv_hypervisor *hv)
Terminate contact.
Definition vmbus.c:211
#define VMBUS_MESSAGE_SINT
VMBus message synthetic interrupt.
Definition vmbus.h:29

References assert, hv_message::data, ENOMEM, free, hv_alloc_pages(), hv_disable_sint(), hv_enable_sint(), hv_free_pages(), vmbus::intr, hv_hypervisor::message, vmbus::message, vmbus::monitor_in, vmbus::monitor_out, NULL, rc, hv_message_buffer::received, hv_hypervisor::vmbus, VMBUS_MESSAGE_SINT, vmbus_negotiate_version(), vmbus_probe_channels(), vmbus_remove_channels(), vmbus_unload(), and zalloc().

Referenced by hv_probe().

◆ vmbus_reset()

int vmbus_reset ( struct hv_hypervisor * hv,
struct device * parent )
extern

Reset Hyper-V virtual machine bus.

Parameters
hvHyper-V hypervisor
parentParent device
Return values
rcReturn status code

Definition at line 1426 of file vmbus.c.

1426 {
1427 struct vmbus *vmbus = hv->vmbus;
1428 int rc;
1429
1430 /* Mark all existent GPADLs as obsolete */
1432
1433 /* Clear interrupt and monitor pages */
1434 memset ( vmbus->intr, 0, PAGE_SIZE );
1437
1438 /* Enable message interrupt */
1440
1441 /* Renegotiate protocol version */
1442 if ( ( rc = vmbus_negotiate_version ( hv ) ) != 0 )
1443 return rc;
1444
1445 /* Reenumerate channels */
1446 if ( ( rc = vmbus_reset_channels ( hv, parent ) ) != 0 )
1447 return rc;
1448
1449 return 0;
1450}
static int vmbus_reset_channels(struct hv_hypervisor *hv, struct device *parent)
Reset channels.
Definition vmbus.c:1270

References hv_enable_sint(), vmbus::intr, memset(), vmbus::monitor_in, vmbus::monitor_out, PAGE_SIZE, rc, hv_hypervisor::vmbus, vmbus_gpadl, VMBUS_MESSAGE_SINT, vmbus_negotiate_version(), vmbus_obsolete_gpadl, and vmbus_reset_channels().

Referenced by hv_unquiesce().

◆ vmbus_remove()

void vmbus_remove ( struct hv_hypervisor * hv,
struct device * parent )
extern

Remove Hyper-V virtual machine bus.

Parameters
hvHyper-V hypervisor
parentParent device

Definition at line 1458 of file vmbus.c.

1458 {
1459 struct vmbus *vmbus = hv->vmbus;
1460
1461 vmbus_remove_channels ( hv, parent );
1462 vmbus_unload ( hv );
1465 NULL );
1466 free ( vmbus );
1467}

References free, hv_disable_sint(), hv_free_pages(), vmbus::intr, vmbus::monitor_in, vmbus::monitor_out, NULL, hv_hypervisor::vmbus, VMBUS_MESSAGE_SINT, vmbus_remove_channels(), and vmbus_unload().

Referenced by hv_probe(), and hv_remove().

Variable Documentation

◆ vmbus_obsolete_gpadl

unsigned int vmbus_obsolete_gpadl
extern

Obsolete GPADL ID threshold.

When the Hyper-V connection is reset, any previous GPADLs are automatically rendered obsolete.

Definition at line 61 of file vmbus.c.

Referenced by vmbus_gpadl_is_obsolete(), and vmbus_reset().