iPXE
|
Hyper-V driver. More...
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <byteswap.h>
#include <pic8259.h>
#include <ipxe/malloc.h>
#include <ipxe/device.h>
#include <ipxe/timer.h>
#include <ipxe/quiesce.h>
#include <ipxe/cpuid.h>
#include <ipxe/msr.h>
#include <ipxe/hyperv.h>
#include <ipxe/vmbus.h>
#include "hyperv.h"
Go to the source code of this file.
Macros | |
#define | HV_MESSAGE_MAX_WAIT_MS 1000 |
Maximum time to wait for a message response. More... | |
#define | HV_TIMER_HZ 10000000 |
Hyper-V timer frequency (fixed 10Mhz) More... | |
#define | HV_TIMER_SHIFT 18 |
Hyper-V timer scale factor (used to avoid 64-bit division) More... | |
#define | EHV(status) EPLATFORM ( EINFO_EPLATFORM, (status) ) |
Convert a Hyper-V status code to an iPXE status code. More... | |
Functions | |
FILE_LICENCE (GPL2_OR_LATER_OR_UBDL) | |
int | hv_alloc_pages (struct hv_hypervisor *hv,...) |
Allocate zeroed pages. More... | |
void | hv_free_pages (struct hv_hypervisor *hv,...) |
Free pages. More... | |
static int | hv_alloc_message (struct hv_hypervisor *hv) |
Allocate message buffer. More... | |
static void | hv_free_message (struct hv_hypervisor *hv) |
Free message buffer. More... | |
static int | hv_check_hv (void) |
Check whether or not we are running in Hyper-V. More... | |
static int | hv_check_features (struct hv_hypervisor *hv) |
Check required features. More... | |
static int | hv_check_uefi (struct hv_hypervisor *hv) |
Check that Gen 2 UEFI firmware is not running. More... | |
static void | hv_map_hypercall (struct hv_hypervisor *hv) |
Map hypercall page. More... | |
static void | hv_unmap_hypercall (struct hv_hypervisor *hv) |
Unmap hypercall page. More... | |
static void | hv_map_synic (struct hv_hypervisor *hv) |
Map synthetic interrupt controller. More... | |
static void | hv_unmap_synic_no_scontrol (struct hv_hypervisor *hv) |
Unmap synthetic interrupt controller, leaving SCONTROL untouched. More... | |
static void | hv_unmap_synic (struct hv_hypervisor *hv) |
Unmap synthetic interrupt controller. More... | |
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... | |
static int | hv_probe (struct root_device *rootdev) |
Probe root device. More... | |
static void | hv_remove (struct root_device *rootdev) |
Remove root device. More... | |
static void | hv_quiesce (void) |
Quiesce system. More... | |
static void | hv_unquiesce (void) |
Unquiesce system. More... | |
static int | hv_timer_probe (void) |
Probe timer. More... | |
static unsigned long | hv_currticks (void) |
Get current system time in ticks. More... | |
static void | hv_udelay (unsigned long usecs) |
Delay for a fixed number of microseconds. More... | |
struct timer hv_timer | __timer (TIMER_PREFERRED) |
Hyper-V timer. More... | |
REQUIRING_SYMBOL (hv_root_device) | |
REQUIRE_OBJECT (netvsc) | |
Variables | |
static struct root_driver | hv_root_driver |
Hyper-V root device driver. More... | |
struct root_device hv_root_device | __root_device |
Hyper-V root device. More... | |
struct quiescer hv_quiescer | __quiescer |
Hyper-V quiescer. More... | |
Hyper-V driver.
Definition in file hyperv.c.
#define HV_MESSAGE_MAX_WAIT_MS 1000 |
#define HV_TIMER_HZ 10000000 |
#define HV_TIMER_SHIFT 18 |
#define EHV | ( | status | ) | EPLATFORM ( EINFO_EPLATFORM, (status) ) |
FILE_LICENCE | ( | GPL2_OR_LATER_OR_UBDL | ) |
int hv_alloc_pages | ( | struct hv_hypervisor * | hv, |
... | |||
) |
Allocate zeroed pages.
hv | Hyper-V hypervisor |
... | Page addresses to fill in, terminated by NULL |
rc | Return status code |
Definition at line 78 of file hyperv.c.
References ENOMEM, free_phys(), malloc_phys(), memset(), NULL, PAGE_SIZE, va_arg, va_end, and va_start.
Referenced by hv_probe(), and vmbus_probe().
void hv_free_pages | ( | struct hv_hypervisor * | hv, |
... | |||
) |
Free pages.
hv | Hyper-V hypervisor |
... | Page addresses, terminated by NULL |
Definition at line 113 of file hyperv.c.
References free_phys(), NULL, PAGE_SIZE, va_arg, va_end, and va_start.
Referenced by hv_probe(), hv_remove(), vmbus_probe(), and vmbus_remove().
|
static |
Allocate message buffer.
hv | Hyper-V hypervisor |
rc | Return status code |
Definition at line 129 of file hyperv.c.
References ENOMEM, malloc_phys(), and hv_hypervisor::message.
Referenced by hv_probe().
|
static |
Free message buffer.
hv | Hyper-V hypervisor |
Definition at line 147 of file hyperv.c.
References free_phys(), and hv_hypervisor::message.
Referenced by hv_probe(), and hv_remove().
|
static |
Check whether or not we are running in Hyper-V.
rc | Return status code |
Definition at line 158 of file hyperv.c.
References CPUID_FEATURES_INTEL_ECX_HYPERVISOR, DBGC, discard_ecx, discard_edx, ENODEV, features, HV_CPUID_INTERFACE_ID, HV_INTERFACE_ID, and x86_features().
Referenced by hv_probe(), and hv_timer_probe().
|
static |
Check required features.
hv | Hyper-V hypervisor |
rc | Return status code |
Definition at line 190 of file hyperv.c.
References DBGC, discard_ecx, discard_edx, EACCES, ENODEV, HV_CPUID_FEATURES, HV_FEATURES_AVAIL_HYPERCALL_MSR, HV_FEATURES_AVAIL_SYNIC_MSR, HV_FEATURES_PERM_POST_MESSAGES, and HV_FEATURES_PERM_SIGNAL_EVENTS.
Referenced by hv_probe().
|
static |
Check that Gen 2 UEFI firmware is not running.
hv | Hyper-V hypervisor |
rc | Return status code |
We must not steal ownership from the Gen 2 UEFI firmware, since doing so will cause an immediate crash. Avoid this by checking for the guest OS identity known to be used by the Gen 2 UEFI firmware.
Definition at line 233 of file hyperv.c.
References DBGC, ENOTSUP, HV_GUEST_OS_ID_UEFI, and HV_X64_MSR_GUEST_OS_ID.
Referenced by hv_probe().
|
static |
Map hypercall page.
hv | Hyper-V hypervisor |
Definition at line 251 of file hyperv.c.
References __attribute__, DBGC, DBGC2, discard_ecx, discard_edx, ebx, ecx, edx, HV_CPUID_HYPERVISOR_ID, HV_CPUID_VENDOR_ID, HV_GUEST_OS_ID_IPXE, HV_HYPERCALL_ENABLE, HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, hypercall, hv_hypervisor::hypercall, PAGE_SIZE, vendor_id, version, and virt_to_phys().
Referenced by hv_probe(), and hv_unquiesce().
|
static |
Unmap hypercall page.
hv | Hyper-V hypervisor |
Definition at line 300 of file hyperv.c.
References DBGC2, HV_HYPERCALL_ENABLE, HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, hypercall, and PAGE_SIZE.
Referenced by hv_probe(), hv_quiesce(), and hv_remove().
|
static |
Map synthetic interrupt controller.
hv | Hyper-V hypervisor |
Definition at line 321 of file hyperv.c.
References DBGC2, hv_synic::event, HV_SCONTROL_ENABLE, HV_SIEFP_ENABLE, HV_SIMP_ENABLE, HV_X64_MSR_SCONTROL, HV_X64_MSR_SIEFP, HV_X64_MSR_SIMP, memset(), hv_synic::message, PAGE_SIZE, hv_hypervisor::synic, and virt_to_phys().
Referenced by hv_probe(), and hv_unquiesce().
|
static |
Unmap synthetic interrupt controller, leaving SCONTROL untouched.
hv | Hyper-V hypervisor |
Definition at line 356 of file hyperv.c.
References DBGC2, HV_SIEFP_ENABLE, HV_SIMP_ENABLE, HV_X64_MSR_SIEFP, HV_X64_MSR_SIMP, and PAGE_SIZE.
Referenced by hv_quiesce(), and hv_unmap_synic().
|
static |
Unmap synthetic interrupt controller.
hv | Hyper-V hypervisor |
Definition at line 378 of file hyperv.c.
References DBGC2, HV_SCONTROL_ENABLE, hv_unmap_synic_no_scontrol(), and HV_X64_MSR_SCONTROL.
Referenced by hv_probe(), and hv_remove().
void hv_enable_sint | ( | struct hv_hypervisor * | hv, |
unsigned int | sintx | ||
) |
Enable synthetic interrupt.
hv | Hyper-V hypervisor |
sintx | Synthetic interrupt number |
Definition at line 397 of file hyperv.c.
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().
void hv_disable_sint | ( | struct hv_hypervisor * | hv, |
unsigned int | sintx | ||
) |
Disable synthetic interrupt.
hv | Hyper-V hypervisor |
sintx | Synthetic interrupt number |
Definition at line 423 of file hyperv.c.
References DBGC2, HV_SINT_AUTO_EOI, HV_SINT_MASKED, and HV_X64_MSR_SINT.
Referenced by hv_quiesce(), vmbus_probe(), and vmbus_remove().
int hv_post_message | ( | struct hv_hypervisor * | hv, |
unsigned int | id, | ||
unsigned int | type, | ||
const void * | data, | ||
size_t | len | ||
) |
Post message.
hv | Hyper-V hypervisor |
id | Connection ID |
type | Message type |
data | Message |
len | Length of message |
rc | Return status code |
Definition at line 449 of file hyperv.c.
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.
int hv_wait_for_message | ( | struct hv_hypervisor * | hv, |
unsigned int | sintx | ||
) |
Wait for received message.
hv | Hyper-V hypervisor |
sintx | Synthetic interrupt number |
rc | Return status code |
Definition at line 486 of file hyperv.c.
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().
int hv_signal_event | ( | struct hv_hypervisor * | hv, |
unsigned int | id, | ||
unsigned int | flag | ||
) |
Signal event.
hv | Hyper-V hypervisor |
id | Connection ID |
flag | Flag number |
rc | Return status code |
Definition at line 535 of file hyperv.c.
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().
|
static |
Probe root device.
rootdev | Root device |
rc | Return status code |
Definition at line 563 of file hyperv.c.
References root_device::dev, ENOMEM, hv_synic::event, free, hv_alloc_message(), hv_alloc_pages(), hv_check_features(), hv_check_hv(), hv_check_uefi(), hv_free_message(), hv_free_pages(), hv_map_hypercall(), hv_map_synic(), hv_unmap_hypercall(), hv_unmap_synic(), hv_hypervisor::hypercall, hv_synic::message, NULL, rc, rootdev_set_drvdata(), hv_hypervisor::synic, vmbus_probe(), vmbus_remove(), and zalloc().
|
static |
Remove root device.
rootdev | Root device |
Definition at line 630 of file hyperv.c.
References root_device::dev, hv_synic::event, free, hv_free_message(), hv_free_pages(), hv_unmap_hypercall(), hv_unmap_synic(), hv_hypervisor::hypercall, hv_synic::message, NULL, rootdev_get_drvdata(), rootdev_set_drvdata(), hv_hypervisor::synic, and vmbus_remove().
|
static |
Quiesce system.
Definition at line 659 of file hyperv.c.
References DBGC, hv_disable_sint(), HV_SINT_MAX, hv_unmap_hypercall(), hv_unmap_synic_no_scontrol(), and rootdev_get_drvdata().
|
static |
Unquiesce system.
Definition at line 704 of file hyperv.c.
References DBGC, hv_map_hypercall(), hv_map_synic(), HV_SIMP_ENABLE, HV_X64_MSR_SIMP, rc, rootdev_get_drvdata(), strerror(), and vmbus_reset().
|
static |
Probe timer.
rc | Return status code |
Definition at line 754 of file hyperv.c.
References DBGC, discard_ecx, discard_edx, ENODEV, hv_check_hv(), HV_CPUID_FEATURES, HV_FEATURES_AVAIL_TIME_REF_COUNT_MSR, HV_INTERFACE_ID, and rc.
|
static |
Get current system time in ticks.
ticks | Current time, in ticks |
Definition at line 781 of file hyperv.c.
References HV_TIMER_HZ, HV_TIMER_SHIFT, HV_X64_MSR_TIME_REF_COUNT, and TICKS_PER_SEC.
|
static |
Delay for a fixed number of microseconds.
usecs | Number of microseconds for which to delay |
Definition at line 795 of file hyperv.c.
References HV_TIMER_HZ, HV_X64_MSR_TIME_REF_COUNT, and start.
struct timer hv_timer __timer | ( | TIMER_PREFERRED | ) |
Hyper-V timer.
REQUIRING_SYMBOL | ( | hv_root_device | ) |
REQUIRE_OBJECT | ( | netvsc | ) |
|
static |
Hyper-V root device driver.
struct root_device hv_root_device __root_device |
Hyper-V root device.
struct quiescer hv_quiescer __quiescer |
Hyper-V quiescer.