iPXE
Data Structures | Macros | Functions | Variables
hyperv.h File Reference

Hyper-V interface. More...

#include <stdint.h>
#include <ipxe/io.h>
#include <bits/hyperv.h>

Go to the source code of this file.

Data Structures

struct  hv_post_message
 A posted message. More...
 
struct  hv_message
 A received message. More...
 
struct  hv_signal_event
 A signalled event. More...
 
struct  hv_event
 A received event. More...
 
struct  hv_monitor_trigger
 A monitor trigger group. More...
 
struct  hv_monitor_parameter
 A monitor parameter set. More...
 
struct  hv_monitor
 A monitor page. More...
 
struct  hv_synic
 A synthetic interrupt controller. More...
 
union  hv_message_buffer
 A message buffer. More...
 
struct  hv_hypervisor
 A Hyper-V hypervisor. More...
 

Macros

#define HV_INTERFACE_ID   0x31237648 /* "Hv#1" */
 Hyper-V interface identification. More...
 
#define HV_GUEST_OS_ID_IPXE   ( ( 1ULL << 63 ) | ( 0x18aeULL << 48 ) )
 Guest OS identity for iPXE. More...
 
#define HV_GUEST_OS_ID_UEFI   ( 1ULL << 40 )
 Guest OS identity for Gen 2 UEFI firmware. More...
 
#define HV_HYPERCALL_ENABLE   0x00000001UL
 Enable hypercall page. More...
 
#define HV_SCONTROL_ENABLE   0x00000001UL
 Enable SynIC. More...
 
#define HV_SIEFP_ENABLE   0x00000001UL
 Enable SynIC event flags. More...
 
#define HV_SIMP_ENABLE   0x00000001UL
 Enable SynIC messages. More...
 
#define HV_SINT_AUTO_EOI   0x00020000UL
 Perform implicit EOI upon synthetic interrupt delivery. More...
 
#define HV_SINT_MASKED   0x00010000UL
 Mask synthetic interrupt. More...
 
#define HV_SINT_VECTOR(x)   ( (x) << 0 )
 Synthetic interrupt vector. More...
 
#define HV_SINT_VECTOR_MASK   HV_SINT_VECTOR ( 0xff )
 Synthetic interrupt vector mask. More...
 
#define HV_SINT_MAX   15
 Maximum synthetic interrupt number. More...
 
#define HV_POST_MESSAGE   0x005c
 Post message. More...
 
#define HV_SIGNAL_EVENT   0x005d
 Signal event. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
struct hv_post_message __attribute__ ((packed))
 
static unsigned int hv_pfn_count (physaddr_t data, size_t len)
 Calculate the number of pages covering an address range. More...
 
 __attribute__ ((sentinel)) int hv_alloc_pages(struct hv_hypervisor *hv
 
void hv_enable_sint (struct hv_hypervisor *hv, unsigned int sintx)
 Enable synthetic interrupt. More...
 
void hv_disable_sint (struct hv_hypervisor *hv, unsigned int sintx)
 Disable synthetic interrupt. More...
 
int hv_post_message (struct hv_hypervisor *hv, unsigned int id, unsigned int type, const void *data, size_t len)
 Post message. More...
 
int hv_wait_for_message (struct hv_hypervisor *hv, unsigned int sintx)
 Wait for received message. More...
 
int hv_signal_event (struct hv_hypervisor *hv, unsigned int id, unsigned int flag)
 Signal event. More...
 

Variables

uint32_t id
 Connection ID. More...
 
uint32_t reserved
 Padding. More...
 
uint32_t type
 Type. More...
 
uint32_t len
 Length of message. More...
 
uint8_t data [240]
 Message. More...
 
uint8_t flags
 Flags. More...
 
uint64_t origin
 Origin. More...
 
uint16_t flag
 Flag number. More...
 
uint32_t pending
 Pending events. More...
 
uint32_t armed
 Armed events. More...
 
uint8_t reserved_a [4]
 Reserved. More...
 
struct hv_monitor_trigger trigger [4]
 Trigger groups. More...
 
uint8_t reserved_b [536]
 Reserved. More...
 
uint16 latency [4][32]
 Latencies. More...
 
uint8_t reserved_c [256]
 Reserved. More...
 
struct hv_monitor_parameter param [4][32]
 Parameters. More...
 
uint8_t reserved_d [1984]
 Reserved. More...
 
struct hv_synic __attribute__
 

Detailed Description

Hyper-V interface.

Definition in file hyperv.h.

Macro Definition Documentation

◆ HV_INTERFACE_ID

#define HV_INTERFACE_ID   0x31237648 /* "Hv#1" */

Hyper-V interface identification.

Definition at line 16 of file hyperv.h.

◆ HV_GUEST_OS_ID_IPXE

#define HV_GUEST_OS_ID_IPXE   ( ( 1ULL << 63 ) | ( 0x18aeULL << 48 ) )

Guest OS identity for iPXE.

This field comprises:

Bit 63 : set to 1 to indicate an open source OS Bits 62:56 : OS Type Bits 55:48 : OS ID Bits 47:16 : Version Bits 15:0 : Build number

There appears to be no central registry for the "OS Type". The specification states that "Linux is 0x100", and the FreeBSD source states that "FreeBSD is 0x200". Both of these statements are actually referring to the combined "OS Type" and "OS ID" field.

We choose to use 0x98ae: this is generated by setting bit 63 (to indicate an open source OS) and setting the OS Type+ID equal to the PnP vendor ID used in romprefix.S. No version information or build number is included.

Definition at line 38 of file hyperv.h.

◆ HV_GUEST_OS_ID_UEFI

#define HV_GUEST_OS_ID_UEFI   ( 1ULL << 40 )

Guest OS identity for Gen 2 UEFI firmware.

This does not conform to the documented structure for guest OS identities.

Definition at line 45 of file hyperv.h.

◆ HV_HYPERCALL_ENABLE

#define HV_HYPERCALL_ENABLE   0x00000001UL

Enable hypercall page.

Definition at line 48 of file hyperv.h.

◆ HV_SCONTROL_ENABLE

#define HV_SCONTROL_ENABLE   0x00000001UL

Enable SynIC.

Definition at line 51 of file hyperv.h.

◆ HV_SIEFP_ENABLE

#define HV_SIEFP_ENABLE   0x00000001UL

Enable SynIC event flags.

Definition at line 54 of file hyperv.h.

◆ HV_SIMP_ENABLE

#define HV_SIMP_ENABLE   0x00000001UL

Enable SynIC messages.

Definition at line 57 of file hyperv.h.

◆ HV_SINT_AUTO_EOI

#define HV_SINT_AUTO_EOI   0x00020000UL

Perform implicit EOI upon synthetic interrupt delivery.

Definition at line 60 of file hyperv.h.

◆ HV_SINT_MASKED

#define HV_SINT_MASKED   0x00010000UL

Mask synthetic interrupt.

Definition at line 63 of file hyperv.h.

◆ HV_SINT_VECTOR

#define HV_SINT_VECTOR (   x)    ( (x) << 0 )

Synthetic interrupt vector.

Definition at line 66 of file hyperv.h.

◆ HV_SINT_VECTOR_MASK

#define HV_SINT_VECTOR_MASK   HV_SINT_VECTOR ( 0xff )

Synthetic interrupt vector mask.

Definition at line 69 of file hyperv.h.

◆ HV_SINT_MAX

#define HV_SINT_MAX   15

Maximum synthetic interrupt number.

Definition at line 72 of file hyperv.h.

◆ HV_POST_MESSAGE

#define HV_POST_MESSAGE   0x005c

Post message.

Definition at line 75 of file hyperv.h.

◆ HV_SIGNAL_EVENT

#define HV_SIGNAL_EVENT   0x005d

Signal event.

Definition at line 116 of file hyperv.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ __attribute__() [1/2]

struct hv_post_message __attribute__ ( (packed)  )

◆ hv_pfn_count()

static unsigned int hv_pfn_count ( physaddr_t  data,
size_t  len 
)
inlinestatic

Calculate the number of pages covering an address range.

Parameters
dataStart of data
lenLength of data (must be non-zero)
Return values
pfn_countNumber of pages covered

Definition at line 223 of file hyperv.h.

223  {
224  unsigned int first_pfn = ( data / PAGE_SIZE );
225  unsigned int last_pfn = ( ( data + len - 1 ) / PAGE_SIZE );
226 
227  return ( last_pfn - first_pfn + 1 );
228 }
uint32_t len
Length of message.
Definition: hyperv.h:18
#define PAGE_SIZE
Page size.
Definition: io.h:27
uint8_t data[240]
Message.
Definition: hyperv.h:20

References data, len, and PAGE_SIZE.

Referenced by vmbus_establish_gpadl(), and vmbus_send_data().

◆ __attribute__() [2/2]

__attribute__ ( (sentinel)  )

◆ hv_enable_sint()

void hv_enable_sint ( struct hv_hypervisor hv,
unsigned int  sintx 
)

Enable synthetic interrupt.

Parameters
hvHyper-V hypervisor
sintxSynthetic interrupt number

Definition at line 397 of file hyperv.c.

397  {
398  unsigned long msr = HV_X64_MSR_SINT ( sintx );
399  uint64_t sint;
400 
401  /* Enable synthetic interrupt
402  *
403  * We have to enable the interrupt, otherwise messages will
404  * not be delivered (even though the documentation implies
405  * that polling for messages is possible). We enable AutoEOI
406  * and hook the interrupt to the obsolete IRQ13 (FPU
407  * exception) vector, which will be implemented as a no-op.
408  */
409  sint = rdmsr ( msr );
410  sint &= ~( HV_SINT_MASKED | HV_SINT_VECTOR_MASK );
411  sint |= ( HV_SINT_AUTO_EOI |
412  HV_SINT_VECTOR ( IRQ_INT ( 13 /* See comment above */ ) ) );
413  DBGC2 ( hv, "HV %p SINT%d MSR is %#08llx\n", hv, sintx, sint );
414  wrmsr ( msr, sint );
415 }
unsigned long long uint64_t
Definition: stdint.h:13
#define HV_X64_MSR_SINT(x)
SynIC interrupt source MSRs.
Definition: hyperv.h:61
#define IRQ_INT(irq)
Definition: pic8259.h:60
#define DBGC2(...)
Definition: compiler.h:522
#define HV_SINT_AUTO_EOI
Perform implicit EOI upon synthetic interrupt delivery.
Definition: hyperv.h:60
#define HV_SINT_MASKED
Mask synthetic interrupt.
Definition: hyperv.h:63
#define HV_SINT_VECTOR_MASK
Synthetic interrupt vector mask.
Definition: hyperv.h:69
#define HV_SINT_VECTOR(x)
Synthetic interrupt vector.
Definition: hyperv.h:66

References DBGC2, HV_SINT_AUTO_EOI, HV_SINT_MASKED, HV_SINT_VECTOR, HV_SINT_VECTOR_MASK, HV_X64_MSR_SINT, and IRQ_INT.

Referenced by vmbus_probe(), and vmbus_reset().

◆ hv_disable_sint()

void hv_disable_sint ( struct hv_hypervisor hv,
unsigned int  sintx 
)

Disable synthetic interrupt.

Parameters
hvHyper-V hypervisor
sintxSynthetic interrupt number

Definition at line 423 of file hyperv.c.

423  {
424  unsigned long msr = HV_X64_MSR_SINT ( sintx );
425  uint64_t sint;
426 
427  /* Do nothing if interrupt is already disabled */
428  sint = rdmsr ( msr );
429  if ( sint & HV_SINT_MASKED )
430  return;
431 
432  /* Disable synthetic interrupt */
433  sint &= ~HV_SINT_AUTO_EOI;
434  sint |= HV_SINT_MASKED;
435  DBGC2 ( hv, "HV %p SINT%d MSR is %#08llx\n", hv, sintx, sint );
436  wrmsr ( msr, sint );
437 }
unsigned long long uint64_t
Definition: stdint.h:13
#define HV_X64_MSR_SINT(x)
SynIC interrupt source MSRs.
Definition: hyperv.h:61
#define DBGC2(...)
Definition: compiler.h:522
#define HV_SINT_AUTO_EOI
Perform implicit EOI upon synthetic interrupt delivery.
Definition: hyperv.h:60
#define HV_SINT_MASKED
Mask synthetic interrupt.
Definition: hyperv.h:63

References DBGC2, HV_SINT_AUTO_EOI, HV_SINT_MASKED, and HV_X64_MSR_SINT.

Referenced by hv_quiesce(), vmbus_probe(), and vmbus_remove().

◆ hv_post_message()

int hv_post_message ( struct hv_hypervisor hv,
unsigned int  id,
unsigned int  type,
const void *  data,
size_t  len 
)

Post message.

Parameters
hvHyper-V hypervisor
idConnection ID
typeMessage type
dataMessage
lenLength of message
Return values
rcReturn status code

Definition at line 449 of file hyperv.c.

450  {
451  struct hv_post_message *msg = &hv->message->posted;
452  int status;
453  int rc;
454 
455  /* Sanity check */
456  assert ( len <= sizeof ( msg->data ) );
457 
458  /* Construct message */
459  memset ( msg, 0, sizeof ( *msg ) );
460  msg->id = cpu_to_le32 ( id );
461  msg->type = cpu_to_le32 ( type );
462  msg->len = cpu_to_le32 ( len );
463  memcpy ( msg->data, data, len );
464  DBGC2 ( hv, "HV %p connection %d posting message type %#08x:\n",
465  hv, id, type );
466  DBGC2_HDA ( hv, 0, msg->data, len );
467 
468  /* Post message */
469  if ( ( status = hv_call ( hv, HV_POST_MESSAGE, msg, NULL ) ) != 0 ) {
470  rc = -EHV ( status );
471  DBGC ( hv, "HV %p could not post message to %#08x: %s\n",
472  hv, id, strerror ( rc ) );
473  return rc;
474  }
475 
476  return 0;
477 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
uint8_t status
Status.
Definition: ena.h:16
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define HV_POST_MESSAGE
Post message.
Definition: hyperv.h:75
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define cpu_to_le32(value)
Definition: byteswap.h:107
#define DBGC2_HDA(...)
Definition: compiler.h:523
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
A posted message.
Definition: hyperv.h:81
union hv_message_buffer * message
Message buffer.
Definition: hyperv.h:209
#define EHV(status)
Convert a Hyper-V status code to an iPXE status code.
Definition: hyperv.c:68
uint32_t len
Length.
Definition: ena.h:14
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC2(...)
Definition: compiler.h:522
uint8_t data[48]
Additional event data.
Definition: ena.h:22
struct hv_post_message posted
Posted message.
Definition: hyperv.h:195
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
void * memset(void *dest, int character, size_t len) __nonnull
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:288

References assert(), cpu_to_le32, data, DBGC, DBGC2, DBGC2_HDA, EHV, HV_POST_MESSAGE, len, memcpy(), memset(), hv_hypervisor::message, msg(), NULL, hv_message_buffer::posted, rc, status, strerror(), and type.

◆ hv_wait_for_message()

int hv_wait_for_message ( struct hv_hypervisor hv,
unsigned int  sintx 
)

Wait for received message.

Parameters
hvHyper-V hypervisor
sintxSynthetic interrupt number
Return values
rcReturn status code

Definition at line 486 of file hyperv.c.

486  {
487  struct hv_message *msg = &hv->message->received;
488  struct hv_message *src = &hv->synic.message[sintx];
489  unsigned int retries;
490  size_t len;
491 
492  /* Wait for message to arrive */
493  for ( retries = 0 ; retries < HV_MESSAGE_MAX_WAIT_MS ; retries++ ) {
494 
495  /* Check for message */
496  if ( src->type ) {
497 
498  /* Copy message */
499  memset ( msg, 0, sizeof ( *msg ) );
500  len = src->len;
501  assert ( len <= sizeof ( *msg ) );
502  memcpy ( msg, src,
503  ( offsetof ( typeof ( *msg ), data ) + len ) );
504  DBGC2 ( hv, "HV %p SINT%d received message type "
505  "%#08x:\n", hv, sintx,
506  le32_to_cpu ( msg->type ) );
507  DBGC2_HDA ( hv, 0, msg->data, len );
508 
509  /* Consume message */
510  src->type = 0;
511 
512  return 0;
513  }
514 
515  /* Trigger message delivery */
516  wrmsr ( HV_X64_MSR_EOM, 0 );
517 
518  /* Delay */
519  mdelay ( 1 );
520  }
521 
522  DBGC ( hv, "HV %p SINT%d timed out waiting for message\n",
523  hv, sintx );
524  return -ETIMEDOUT;
525 }
#define le32_to_cpu(value)
Definition: byteswap.h:113
static void const void * src
Definition: crypto.h:244
#define DBGC(...)
Definition: compiler.h:505
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
struct hv_message received
Received message.
Definition: hyperv.h:197
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define DBGC2_HDA(...)
Definition: compiler.h:523
A received message.
Definition: hyperv.h:100
struct hv_message * message
Message page.
Definition: hyperv.h:187
#define HV_X64_MSR_EOM
SynIC end of message MSR.
Definition: hyperv.h:58
union hv_message_buffer * message
Message buffer.
Definition: hyperv.h:209
void mdelay(unsigned long msecs)
Delay for a fixed number of milliseconds.
Definition: timer.c:78
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
uint8_t data[48]
Additional event data.
Definition: ena.h:22
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition: acpi.c:45
#define HV_MESSAGE_MAX_WAIT_MS
Maximum time to wait for a message response.
Definition: hyperv.c:54
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669
struct hv_synic synic
Synthetic interrupt controller (SynIC)
Definition: hyperv.h:207
void * memset(void *dest, int character, size_t len) __nonnull
static void msg(unsigned int row, const char *fmt,...)
Print message centred on specified row.
Definition: settings_ui.c:288

References assert(), data, DBGC, DBGC2, DBGC2_HDA, ETIMEDOUT, HV_MESSAGE_MAX_WAIT_MS, HV_X64_MSR_EOM, le32_to_cpu, len, mdelay(), memcpy(), memset(), hv_synic::message, hv_hypervisor::message, msg(), offsetof, hv_message_buffer::received, src, hv_hypervisor::synic, and typeof().

Referenced by vmbus_wait_for_any_message().

◆ hv_signal_event()

int hv_signal_event ( struct hv_hypervisor hv,
unsigned int  id,
unsigned int  flag 
)

Signal event.

Parameters
hvHyper-V hypervisor
idConnection ID
flagFlag number
Return values
rcReturn status code

Definition at line 535 of file hyperv.c.

536  {
537  struct hv_signal_event *event = &hv->message->signalled;
538  int status;
539  int rc;
540 
541  /* Construct event */
542  memset ( event, 0, sizeof ( *event ) );
543  event->id = cpu_to_le32 ( id );
544  event->flag = cpu_to_le16 ( flag );
545 
546  /* Signal event */
547  if ( ( status = hv_call ( hv, HV_SIGNAL_EVENT, event, NULL ) ) != 0 ) {
548  rc = -EHV ( status );
549  DBGC ( hv, "HV %p could not signal event to %#08x: %s\n",
550  hv, id, strerror ( rc ) );
551  return rc;
552  }
553 
554  return 0;
555 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
A signalled event.
Definition: hyperv.h:119
uint8_t status
Status.
Definition: ena.h:16
struct hv_signal_event signalled
Signalled event.
Definition: hyperv.h:199
#define cpu_to_le32(value)
Definition: byteswap.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define HV_SIGNAL_EVENT
Signal event.
Definition: hyperv.h:116
union hv_message_buffer * message
Message buffer.
Definition: hyperv.h:209
#define EHV(status)
Convert a Hyper-V status code to an iPXE status code.
Definition: hyperv.c:68
#define cpu_to_le16(value)
Definition: byteswap.h:106
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
uint16_t flag
Flag number.
Definition: hyperv.h:14
void * memset(void *dest, int character, size_t len) __nonnull

References cpu_to_le16, cpu_to_le32, DBGC, EHV, flag, HV_SIGNAL_EVENT, memset(), hv_hypervisor::message, NULL, rc, hv_message_buffer::signalled, status, and strerror().

Variable Documentation

◆ id

Connection ID.

Definition at line 12 of file hyperv.h.

◆ reserved

uint16_t reserved

Padding.

Reserved.

Definition at line 14 of file hyperv.h.

◆ type

uint32_t type

Type.

Definition at line 16 of file hyperv.h.

◆ len

uint8_t len

Length of message.

Definition at line 18 of file hyperv.h.

Referenced by hv_pfn_count().

◆ data

uint8_t data[240]

Message.

Definition at line 20 of file hyperv.h.

Referenced by hv_pfn_count().

◆ flags

uint32_t flags

Flags.

Event flags.

Definition at line 16 of file hyperv.h.

◆ origin

uint64_t origin

◆ flag

uint16_t flag

◆ pending

uint32_t pending

◆ armed

uint32_t armed

Armed events.

Definition at line 14 of file hyperv.h.

◆ reserved_a

uint8_t reserved_a[4]

Reserved.

Definition at line 14 of file hyperv.h.

◆ trigger

struct hv_monitor_trigger trigger[4]

Trigger groups.

Definition at line 16 of file hyperv.h.

Referenced by vmbus_signal_monitor().

◆ reserved_b

uint8_t reserved_b[536]

Reserved.

Definition at line 18 of file hyperv.h.

◆ latency

uint16 latency[4][32]

Latencies.

Definition at line 20 of file hyperv.h.

◆ reserved_c

uint8_t reserved_c[256]

Reserved.

Definition at line 22 of file hyperv.h.

◆ param

struct hv_monitor_parameter param[4][32]

◆ reserved_d

uint8_t reserved_d[1984]

Reserved.

Definition at line 26 of file hyperv.h.

◆ __attribute__