iPXE
Functions | Variables
hvm.c File Reference

Xen HVM driver. More...

#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include <ipxe/malloc.h>
#include <ipxe/pci.h>
#include <ipxe/cpuid.h>
#include <ipxe/msr.h>
#include <ipxe/xen.h>
#include <ipxe/xenver.h>
#include <ipxe/xenmem.h>
#include <ipxe/xenstore.h>
#include <ipxe/xenbus.h>
#include <ipxe/xengrant.h>
#include "hvm.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static int hvm_cpuid_base (struct hvm_device *hvm)
 Get CPUID base. More...
 
static int hvm_map_hypercall (struct hvm_device *hvm)
 Map hypercall page(s) More...
 
static void hvm_unmap_hypercall (struct hvm_device *hvm)
 Unmap hypercall page(s) More...
 
static void * hvm_ioremap (struct hvm_device *hvm, unsigned int space, size_t len)
 Allocate and map MMIO space. More...
 
static void hvm_iounmap (struct hvm_device *hvm, void *mmio, size_t len)
 Unmap MMIO space. More...
 
static int hvm_map_shared_info (struct hvm_device *hvm)
 Map shared info page. More...
 
static void hvm_unmap_shared_info (struct hvm_device *hvm)
 Unmap shared info page. More...
 
static int hvm_map_grant (struct hvm_device *hvm)
 Map grant table. More...
 
static void hvm_unmap_grant (struct hvm_device *hvm)
 Unmap grant table. More...
 
static int hvm_map_xenstore (struct hvm_device *hvm)
 Map XenStore. More...
 
static void hvm_unmap_xenstore (struct hvm_device *hvm)
 Unmap XenStore. More...
 
static int hvm_probe (struct pci_device *pci)
 Probe PCI device. More...
 
static void hvm_remove (struct pci_device *pci)
 Remove PCI device. More...
 
 REQUIRING_SYMBOL (hvm_driver)
 
 REQUIRE_OBJECT (netfront)
 

Variables

static struct pci_device_id hvm_ids []
 PCI device IDs. More...
 
struct pci_driver hvm_driver __pci_driver
 PCI driver. More...
 

Detailed Description

Xen HVM driver.

Definition in file hvm.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ hvm_cpuid_base()

static int hvm_cpuid_base ( struct hvm_device hvm)
static

Get CPUID base.

Parameters
hvmHVM device
Return values
rcReturn status code

Definition at line 53 of file hvm.c.

53  {
54  struct {
55  uint32_t ebx;
56  uint32_t ecx;
57  uint32_t edx;
58  } __attribute__ (( packed )) signature;
59  uint32_t base;
61  uint32_t discard_eax;
62  uint32_t discard_ebx;
65 
66  /* Scan for magic signature */
67  for ( base = HVM_CPUID_MIN ; base <= HVM_CPUID_MAX ;
68  base += HVM_CPUID_STEP ) {
69  cpuid ( base, 0, &discard_eax, &signature.ebx, &signature.ecx,
70  &signature.edx );
72  sizeof ( signature ) ) == 0 ) {
73  hvm->cpuid_base = base;
74  cpuid ( ( base + HVM_CPUID_VERSION ), 0, &version,
75  &discard_ebx, &discard_ecx, &discard_edx );
76  DBGC2 ( hvm, "HVM using CPUID base %#08x (v%d.%d)\n",
77  base, ( version >> 16 ), ( version & 0xffff ) );
78  return 0;
79  }
80  }
81 
82  DBGC ( hvm, "HVM could not find hypervisor\n" );
83  return -ENODEV;
84 }
#define __attribute__(x)
Definition: compiler.h:10
#define HVM_CPUID_VERSION
Get Xen version.
Definition: hvm.h:30
#define DBGC(...)
Definition: compiler.h:505
#define HVM_CPUID_MAGIC
Magic signature.
Definition: hvm.h:27
#define HVM_CPUID_MIN
Minimum CPUID base.
Definition: hvm.h:18
static const void * base
Base address.
Definition: crypto.h:335
static uint32_t uint32_t uint32_t * ebx
Definition: cpuid.h:86
uint32_t discard_edx
Definition: hyperv.h:32
static uint32_t uint32_t uint32_t uint32_t * ecx
Definition: cpuid.h:86
static uint32_t uint32_t uint32_t uint32_t uint32_t * edx
Definition: cpuid.h:87
#define ENODEV
No such device.
Definition: errno.h:509
#define HVM_CPUID_STEP
Increment between CPUID bases.
Definition: hvm.h:24
uint32_t discard_ecx
Definition: hyperv.h:31
unsigned int uint32_t
Definition: stdint.h:12
u32 version
Driver version.
Definition: ath9k_hw.c:1983
#define DBGC2(...)
Definition: compiler.h:522
#define HVM_CPUID_MAX
Maximum CPUID base.
Definition: hvm.h:21
u8 signature
Signature.
Definition: CIB_PRM.h:35
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
uint32_t cpuid_base
CPUID base.
Definition: hvm.h:45

References __attribute__, base, hvm_device::cpuid_base, DBGC, DBGC2, discard_ecx, discard_edx, ebx, ecx, edx, ENODEV, HVM_CPUID_MAGIC, HVM_CPUID_MAX, HVM_CPUID_MIN, HVM_CPUID_STEP, HVM_CPUID_VERSION, memcmp(), signature, and version.

Referenced by hvm_probe().

◆ hvm_map_hypercall()

static int hvm_map_hypercall ( struct hvm_device hvm)
static

Map hypercall page(s)

Parameters
hvmHVM device
Return values
rcReturn status code

Definition at line 92 of file hvm.c.

92  {
93  uint32_t pages;
94  uint32_t msr;
97  physaddr_t hypercall_phys;
100  int xenrc;
101  int rc;
102 
103  /* Get number of hypercall pages and MSR to use */
104  cpuid ( ( hvm->cpuid_base + HVM_CPUID_PAGES ), 0, &pages, &msr,
106 
107  /* Allocate pages */
108  hvm->hypercall_len = ( pages * PAGE_SIZE );
110  if ( ! hvm->xen.hypercall ) {
111  DBGC ( hvm, "HVM could not allocate %d hypercall page(s)\n",
112  pages );
113  return -ENOMEM;
114  }
115  hypercall_phys = virt_to_phys ( hvm->xen.hypercall );
116  DBGC2 ( hvm, "HVM hypercall page(s) at [%#08lx,%#08lx) via MSR %#08x\n",
117  hypercall_phys, ( hypercall_phys + hvm->hypercall_len ), msr );
118 
119  /* Write to MSR */
120  wrmsr ( msr, hypercall_phys );
121 
122  /* Check that hypercall mechanism is working */
123  version = xenver_version ( &hvm->xen );
124  if ( ( xenrc = xenver_extraversion ( &hvm->xen, &extraversion ) ) != 0){
125  rc = -EXEN ( xenrc );
126  DBGC ( hvm, "HVM could not get extraversion: %s\n",
127  strerror ( rc ) );
128  return rc;
129  }
130  DBGC2 ( hvm, "HVM found Xen version %d.%d%s\n",
131  ( version >> 16 ), ( version & 0xffff ) , extraversion );
132 
133  return 0;
134 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static xen_extraversion_t * extraversion
Definition: xenver.h:37
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
#define DBGC(...)
Definition: compiler.h:505
static void *__malloc malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition: malloc.h:62
#define PAGE_SIZE
Page size.
Definition: io.h:27
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
#define EXEN(xenrc)
Convert a Xen status code to an iPXE status code.
Definition: xen.h:87
#define ENOMEM
Not enough space.
Definition: errno.h:534
uint32_t discard_edx
Definition: hyperv.h:32
struct xen_hypercall * hypercall
Hypercall table.
Definition: xen.h:53
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
size_t hypercall_len
Length of hypercall table.
Definition: hvm.h:47
uint32_t discard_ecx
Definition: hyperv.h:31
unsigned int uint32_t
Definition: stdint.h:12
char xen_extraversion_t[16]
Definition: version.h:26
u32 version
Driver version.
Definition: ath9k_hw.c:1983
unsigned long physaddr_t
Definition: stdint.h:20
#define DBGC2(...)
Definition: compiler.h:522
#define HVM_CPUID_PAGES
Get number of hypercall pages.
Definition: hvm.h:33
uint32_t cpuid_base
CPUID base.
Definition: hvm.h:45

References hvm_device::cpuid_base, DBGC, DBGC2, discard_ecx, discard_edx, ENOMEM, EXEN, extraversion, HVM_CPUID_PAGES, xen_hypervisor::hypercall, hvm_device::hypercall_len, malloc_phys(), PAGE_SIZE, rc, strerror(), version, virt_to_phys(), and hvm_device::xen.

Referenced by hvm_probe().

◆ hvm_unmap_hypercall()

static void hvm_unmap_hypercall ( struct hvm_device hvm)
static

Unmap hypercall page(s)

Parameters
hvmHVM device

Definition at line 141 of file hvm.c.

141  {
142 
143  /* Free pages */
144  free_phys ( hvm->xen.hypercall, hvm->hypercall_len );
145 }
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
struct xen_hypercall * hypercall
Hypercall table.
Definition: xen.h:53
size_t hypercall_len
Length of hypercall table.
Definition: hvm.h:47
static void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition: malloc.h:77

References free_phys(), xen_hypervisor::hypercall, hvm_device::hypercall_len, and hvm_device::xen.

Referenced by hvm_probe(), and hvm_remove().

◆ hvm_ioremap()

static void* hvm_ioremap ( struct hvm_device hvm,
unsigned int  space,
size_t  len 
)
static

Allocate and map MMIO space.

Parameters
hvmHVM device
spaceSource mapping space
lenLength (must be a multiple of PAGE_SIZE)
Return values
mmioMMIO space address, or NULL on error

Definition at line 155 of file hvm.c.

156  {
157  struct xen_add_to_physmap add;
159  unsigned int pages = ( len / PAGE_SIZE );
160  physaddr_t mmio_phys;
161  unsigned int i;
162  void *mmio;
163  int xenrc;
164  int rc;
165 
166  /* Sanity check */
167  assert ( ( len % PAGE_SIZE ) == 0 );
168 
169  /* Check for available space */
170  if ( ( hvm->mmio_offset + len ) > hvm->mmio_len ) {
171  DBGC ( hvm, "HVM could not allocate %zd bytes of MMIO space "
172  "(%zd of %zd remaining)\n", len,
173  ( hvm->mmio_len - hvm->mmio_offset ), hvm->mmio_len );
174  goto err_no_space;
175  }
176 
177  /* Map this space */
178  mmio = pci_ioremap ( hvm->pci, ( hvm->mmio + hvm->mmio_offset ), len );
179  if ( ! mmio ) {
180  DBGC ( hvm, "HVM could not map MMIO space [%08lx,%08lx)\n",
181  ( hvm->mmio + hvm->mmio_offset ),
182  ( hvm->mmio + hvm->mmio_offset + len ) );
183  goto err_ioremap;
184  }
185  mmio_phys = virt_to_phys ( mmio );
186 
187  /* Add to physical address space */
188  for ( i = 0 ; i < pages ; i++ ) {
189  add.domid = DOMID_SELF;
190  add.idx = i;
191  add.space = space;
192  add.gpfn = ( ( mmio_phys / PAGE_SIZE ) + i );
193  if ( ( xenrc = xenmem_add_to_physmap ( &hvm->xen, &add ) ) !=0){
194  rc = -EXEN ( xenrc );
195  DBGC ( hvm, "HVM could not add space %d idx %d at "
196  "[%08lx,%08lx): %s\n", space, i,
197  ( mmio_phys + ( i * PAGE_SIZE ) ),
198  ( mmio_phys + ( ( i + 1 ) * PAGE_SIZE ) ),
199  strerror ( rc ) );
200  goto err_add_to_physmap;
201  }
202  }
203 
204  /* Update offset */
205  hvm->mmio_offset += len;
206 
207  return mmio;
208 
209  i = pages;
210  err_add_to_physmap:
211  for ( i-- ; ( signed int ) i >= 0 ; i-- ) {
213  add.gpfn = ( ( mmio_phys / PAGE_SIZE ) + i );
214  xenmem_remove_from_physmap ( &hvm->xen, &remove );
215  }
216  iounmap ( mmio );
217  err_ioremap:
218  err_no_space:
219  return NULL;
220 }
size_t mmio_offset
Current offset within MMIO address space.
Definition: hvm.h:51
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint64_t add
Additional data length.
Definition: gcm.h:12
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
#define DBGC(...)
Definition: compiler.h:505
#define PAGE_SIZE
Page size.
Definition: io.h:27
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
#define EXEN(xenrc)
Convert a Xen status code to an iPXE status code.
Definition: xen.h:87
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
unsigned long mmio
MMIO base address.
Definition: hvm.h:49
size_t mmio_len
Length of MMIO address space.
Definition: hvm.h:53
static struct xen_remove_from_physmap * remove
Definition: xenmem.h:39
unsigned long physaddr_t
Definition: stdint.h:20
uint32_t len
Length.
Definition: ena.h:14
#define DOMID_SELF
Definition: xen.h:567
void iounmap(volatile const void *io_addr)
Unmap I/O address.
void * pci_ioremap(struct pci_device *pci, unsigned long bus_addr, size_t len)
Map PCI bus address as an I/O address.
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct pci_device * pci
PCI device.
Definition: hvm.h:43

References add, assert(), DBGC, xen_remove_from_physmap::domid, DOMID_SELF, EXEN, iounmap(), len, hvm_device::mmio, hvm_device::mmio_len, hvm_device::mmio_offset, NULL, PAGE_SIZE, hvm_device::pci, pci_ioremap(), rc, remove, strerror(), virt_to_phys(), and hvm_device::xen.

Referenced by hvm_map_grant(), and hvm_map_shared_info().

◆ hvm_iounmap()

static void hvm_iounmap ( struct hvm_device hvm,
void *  mmio,
size_t  len 
)
static

Unmap MMIO space.

Parameters
hvmHVM device
mmioMMIO space address
lenLength (must be a multiple of PAGE_SIZE)

Definition at line 229 of file hvm.c.

229  {
231  physaddr_t mmio_phys = virt_to_phys ( mmio );
232  unsigned int pages = ( len / PAGE_SIZE );
233  unsigned int i;
234  int xenrc;
235  int rc;
236 
237  /* Unmap this space */
238  iounmap ( mmio );
239 
240  /* Remove from physical address space */
241  for ( i = 0 ; i < pages ; i++ ) {
243  remove.gpfn = ( ( mmio_phys / PAGE_SIZE ) + i );
244  if ( ( xenrc = xenmem_remove_from_physmap ( &hvm->xen,
245  &remove ) ) != 0 ) {
246  rc = -EXEN ( xenrc );
247  DBGC ( hvm, "HVM could not remove space [%08lx,%08lx): "
248  "%s\n", ( mmio_phys + ( i * PAGE_SIZE ) ),
249  ( mmio_phys + ( ( i + 1 ) * PAGE_SIZE ) ),
250  strerror ( rc ) );
251  /* Nothing we can do about this */
252  }
253  }
254 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
#define DBGC(...)
Definition: compiler.h:505
#define PAGE_SIZE
Page size.
Definition: io.h:27
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
#define EXEN(xenrc)
Convert a Xen status code to an iPXE status code.
Definition: xen.h:87
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static struct xen_remove_from_physmap * remove
Definition: xenmem.h:39
unsigned long physaddr_t
Definition: stdint.h:20
uint32_t len
Length.
Definition: ena.h:14
#define DOMID_SELF
Definition: xen.h:567
void iounmap(volatile const void *io_addr)
Unmap I/O address.

References DBGC, xen_remove_from_physmap::domid, DOMID_SELF, EXEN, xen_remove_from_physmap::gpfn, iounmap(), len, PAGE_SIZE, rc, remove, strerror(), virt_to_phys(), and hvm_device::xen.

Referenced by hvm_map_shared_info(), hvm_unmap_grant(), and hvm_unmap_shared_info().

◆ hvm_map_shared_info()

static int hvm_map_shared_info ( struct hvm_device hvm)
static

Map shared info page.

Parameters
hvmHVM device
Return values
rcReturn status code

Definition at line 262 of file hvm.c.

262  {
263  physaddr_t shared_info_phys;
264  int rc;
265 
266  /* Map shared info page */
268  PAGE_SIZE );
269  if ( ! hvm->xen.shared ) {
270  rc = -ENOMEM;
271  goto err_alloc;
272  }
273  shared_info_phys = virt_to_phys ( hvm->xen.shared );
274  DBGC2 ( hvm, "HVM shared info page at [%#08lx,%#08lx)\n",
275  shared_info_phys, ( shared_info_phys + PAGE_SIZE ) );
276 
277  /* Sanity check */
278  DBGC2 ( hvm, "HVM wallclock time is %d\n",
279  readl ( &hvm->xen.shared->wc_sec ) );
280 
281  return 0;
282 
283  hvm_iounmap ( hvm, hvm->xen.shared, PAGE_SIZE );
284  err_alloc:
285  return rc;
286 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t wc_sec
Definition: xen.h:776
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
uint32_t readl(volatile uint32_t *io_addr)
Read 32-bit dword from memory-mapped device.
#define PAGE_SIZE
Page size.
Definition: io.h:27
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct shared_info * shared
Shared info page.
Definition: xen.h:55
static void hvm_iounmap(struct hvm_device *hvm, void *mmio, size_t len)
Unmap MMIO space.
Definition: hvm.c:229
unsigned long physaddr_t
Definition: stdint.h:20
static void * hvm_ioremap(struct hvm_device *hvm, unsigned int space, size_t len)
Allocate and map MMIO space.
Definition: hvm.c:155
#define XENMAPSPACE_shared_info
Definition: memory.h:211
#define DBGC2(...)
Definition: compiler.h:522

References DBGC2, ENOMEM, hvm_ioremap(), hvm_iounmap(), PAGE_SIZE, rc, readl(), xen_hypervisor::shared, virt_to_phys(), shared_info::wc_sec, hvm_device::xen, and XENMAPSPACE_shared_info.

Referenced by hvm_probe().

◆ hvm_unmap_shared_info()

static void hvm_unmap_shared_info ( struct hvm_device hvm)
static

Unmap shared info page.

Parameters
hvmHVM device

Definition at line 293 of file hvm.c.

293  {
294 
295  /* Unmap shared info page */
296  hvm_iounmap ( hvm, hvm->xen.shared, PAGE_SIZE );
297 }
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
#define PAGE_SIZE
Page size.
Definition: io.h:27
struct shared_info * shared
Shared info page.
Definition: xen.h:55
static void hvm_iounmap(struct hvm_device *hvm, void *mmio, size_t len)
Unmap MMIO space.
Definition: hvm.c:229

References hvm_iounmap(), PAGE_SIZE, xen_hypervisor::shared, and hvm_device::xen.

Referenced by hvm_probe(), and hvm_remove().

◆ hvm_map_grant()

static int hvm_map_grant ( struct hvm_device hvm)
static

Map grant table.

Parameters
hvmHVM device
Return values
rcReturn status code

Definition at line 305 of file hvm.c.

305  {
306  physaddr_t grant_phys;
307  int rc;
308 
309  /* Initialise grant table */
310  if ( ( rc = xengrant_init ( &hvm->xen ) ) != 0 ) {
311  DBGC ( hvm, "HVM could not initialise grant table: %s\n",
312  strerror ( rc ) );
313  return rc;
314  }
315 
316  /* Map grant table */
318  hvm->xen.grant.len );
319  if ( ! hvm->xen.grant.table )
320  return -ENODEV;
321 
322  grant_phys = virt_to_phys ( hvm->xen.grant.table );
323  DBGC2 ( hvm, "HVM mapped grant table at [%08lx,%08lx)\n",
324  grant_phys, ( grant_phys + hvm->xen.grant.len ) );
325  return 0;
326 }
int xengrant_init(struct xen_hypervisor *xen)
Initialise grant table.
Definition: xengrant.c:70
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
#define DBGC(...)
Definition: compiler.h:505
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
struct grant_entry_v1 * table
Grant table entries.
Definition: xen.h:31
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define ENODEV
No such device.
Definition: errno.h:509
#define XENMAPSPACE_grant_table
Definition: memory.h:212
unsigned long physaddr_t
Definition: stdint.h:20
static void * hvm_ioremap(struct hvm_device *hvm, unsigned int space, size_t len)
Allocate and map MMIO space.
Definition: hvm.c:155
#define DBGC2(...)
Definition: compiler.h:522
struct xen_grant grant
Grant table.
Definition: xen.h:57
size_t len
Total grant table length.
Definition: xen.h:33

References DBGC, DBGC2, ENODEV, xen_hypervisor::grant, hvm_ioremap(), xen_grant::len, rc, strerror(), xen_grant::table, virt_to_phys(), hvm_device::xen, xengrant_init(), and XENMAPSPACE_grant_table.

Referenced by hvm_probe().

◆ hvm_unmap_grant()

static void hvm_unmap_grant ( struct hvm_device hvm)
static

Unmap grant table.

Parameters
hvmHVM device

Definition at line 333 of file hvm.c.

333  {
334 
335  /* Unmap grant table */
336  hvm_iounmap ( hvm, hvm->xen.grant.table, hvm->xen.grant.len );
337 }
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
struct grant_entry_v1 * table
Grant table entries.
Definition: xen.h:31
static void hvm_iounmap(struct hvm_device *hvm, void *mmio, size_t len)
Unmap MMIO space.
Definition: hvm.c:229
struct xen_grant grant
Grant table.
Definition: xen.h:57
size_t len
Total grant table length.
Definition: xen.h:33

References xen_hypervisor::grant, hvm_iounmap(), xen_grant::len, xen_grant::table, and hvm_device::xen.

Referenced by hvm_probe(), and hvm_remove().

◆ hvm_map_xenstore()

static int hvm_map_xenstore ( struct hvm_device hvm)
static

Map XenStore.

Parameters
hvmHVM device
Return values
rcReturn status code

Definition at line 345 of file hvm.c.

345  {
346  uint64_t xenstore_evtchn;
347  uint64_t xenstore_pfn;
348  physaddr_t xenstore_phys;
349  char *name;
350  int xenrc;
351  int rc;
352 
353  /* Get XenStore event channel */
354  if ( ( xenrc = xen_hvm_get_param ( &hvm->xen, HVM_PARAM_STORE_EVTCHN,
355  &xenstore_evtchn ) ) != 0 ) {
356  rc = -EXEN ( xenrc );
357  DBGC ( hvm, "HVM could not get XenStore event channel: %s\n",
358  strerror ( rc ) );
359  return rc;
360  }
361  hvm->xen.store.port = xenstore_evtchn;
362 
363  /* Get XenStore PFN */
364  if ( ( xenrc = xen_hvm_get_param ( &hvm->xen, HVM_PARAM_STORE_PFN,
365  &xenstore_pfn ) ) != 0 ) {
366  rc = -EXEN ( xenrc );
367  DBGC ( hvm, "HVM could not get XenStore PFN: %s\n",
368  strerror ( rc ) );
369  return rc;
370  }
371  xenstore_phys = ( xenstore_pfn * PAGE_SIZE );
372 
373  /* Map XenStore */
374  hvm->xen.store.intf = pci_ioremap ( hvm->pci, xenstore_phys,
375  PAGE_SIZE );
376  if ( ! hvm->xen.store.intf ) {
377  DBGC ( hvm, "HVM could not map XenStore at [%08lx,%08lx)\n",
378  xenstore_phys, ( xenstore_phys + PAGE_SIZE ) );
379  return -ENODEV;
380  }
381  DBGC2 ( hvm, "HVM mapped XenStore at [%08lx,%08lx) with event port "
382  "%d\n", xenstore_phys, ( xenstore_phys + PAGE_SIZE ),
383  hvm->xen.store.port );
384 
385  /* Check that XenStore is working */
386  if ( ( rc = xenstore_read ( &hvm->xen, &name, "name", NULL ) ) != 0 ) {
387  DBGC ( hvm, "HVM could not read domain name: %s\n",
388  strerror ( rc ) );
389  return rc;
390  }
391  DBGC2 ( hvm, "HVM running in domain \"%s\"\n", name );
392  free ( name );
393 
394  return 0;
395 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * name
Definition: ath9k_hw.c:1984
static int xen_hvm_get_param(struct xen_hypervisor *xen, unsigned int index, uint64_t *value)
Get HVM parameter value.
Definition: hvm.h:64
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
#define HVM_PARAM_STORE_EVTCHN
Definition: params.h:80
#define HVM_PARAM_STORE_PFN
Definition: params.h:79
#define DBGC(...)
Definition: compiler.h:505
unsigned long long uint64_t
Definition: stdint.h:13
int xenstore_read(struct xen_hypervisor *xen, char **value,...)
Read XenStore value.
Definition: xenstore.c:371
#define PAGE_SIZE
Page size.
Definition: io.h:27
#define EXEN(xenrc)
Convert a Xen status code to an iPXE status code.
Definition: xen.h:87
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
evtchn_port_t port
Event channel.
Definition: xen.h:47
#define ENODEV
No such device.
Definition: errno.h:509
unsigned long physaddr_t
Definition: stdint.h:20
struct xenstore_domain_interface * intf
XenStore domain interface.
Definition: xen.h:45
#define DBGC2(...)
Definition: compiler.h:522
struct xen_store store
XenStore.
Definition: xen.h:59
void * pci_ioremap(struct pci_device *pci, unsigned long bus_addr, size_t len)
Map PCI bus address as an I/O address.
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct pci_device * pci
PCI device.
Definition: hvm.h:43

References DBGC, DBGC2, ENODEV, EXEN, free, HVM_PARAM_STORE_EVTCHN, HVM_PARAM_STORE_PFN, xen_store::intf, name, NULL, PAGE_SIZE, hvm_device::pci, pci_ioremap(), xen_store::port, rc, xen_hypervisor::store, strerror(), hvm_device::xen, xen_hvm_get_param(), and xenstore_read().

Referenced by hvm_probe().

◆ hvm_unmap_xenstore()

static void hvm_unmap_xenstore ( struct hvm_device hvm)
static

Unmap XenStore.

Parameters
hvmHVM device

Definition at line 402 of file hvm.c.

402  {
403 
404  /* Unmap XenStore */
405  iounmap ( hvm->xen.store.intf );
406 }
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
struct xenstore_domain_interface * intf
XenStore domain interface.
Definition: xen.h:45
void iounmap(volatile const void *io_addr)
Unmap I/O address.
struct xen_store store
XenStore.
Definition: xen.h:59

References xen_store::intf, iounmap(), xen_hypervisor::store, and hvm_device::xen.

Referenced by hvm_probe(), and hvm_remove().

◆ hvm_probe()

static int hvm_probe ( struct pci_device pci)
static

Probe PCI device.

Parameters
pciPCI device
Return values
rcReturn status code

Definition at line 414 of file hvm.c.

414  {
415  struct hvm_device *hvm;
416  int rc;
417 
418  /* Allocate and initialise structure */
419  hvm = zalloc ( sizeof ( *hvm ) );
420  if ( ! hvm ) {
421  rc = -ENOMEM;
422  goto err_alloc;
423  }
424  hvm->pci = pci;
425  hvm->mmio = pci_bar_start ( pci, HVM_MMIO_BAR );
427  DBGC2 ( hvm, "HVM has MMIO space [%08lx,%08lx)\n",
428  hvm->mmio, ( hvm->mmio + hvm->mmio_len ) );
429 
430  /* Fix up PCI device */
432 
433  /* Attach to hypervisor */
434  if ( ( rc = hvm_cpuid_base ( hvm ) ) != 0 )
435  goto err_cpuid_base;
436  if ( ( rc = hvm_map_hypercall ( hvm ) ) != 0 )
437  goto err_map_hypercall;
438  if ( ( rc = hvm_map_shared_info ( hvm ) ) != 0 )
439  goto err_map_shared_info;
440  if ( ( rc = hvm_map_grant ( hvm ) ) != 0 )
441  goto err_map_grant;
442  if ( ( rc = hvm_map_xenstore ( hvm ) ) != 0 )
443  goto err_map_xenstore;
444 
445  /* Probe Xen devices */
446  if ( ( rc = xenbus_probe ( &hvm->xen, &pci->dev ) ) != 0 ) {
447  DBGC ( hvm, "HVM could not probe Xen bus: %s\n",
448  strerror ( rc ) );
449  goto err_xenbus_probe;
450  }
451 
452  pci_set_drvdata ( pci, hvm );
453  return 0;
454 
455  xenbus_remove ( &hvm->xen, &pci->dev );
456  err_xenbus_probe:
457  hvm_unmap_xenstore ( hvm );
458  err_map_xenstore:
459  hvm_unmap_grant ( hvm );
460  err_map_grant:
461  hvm_unmap_shared_info ( hvm );
462  err_map_shared_info:
463  hvm_unmap_hypercall ( hvm );
464  err_map_hypercall:
465  err_cpuid_base:
466  free ( hvm );
467  err_alloc:
468  return rc;
469 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void hvm_unmap_hypercall(struct hvm_device *hvm)
Unmap hypercall page(s)
Definition: hvm.c:141
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
#define DBGC(...)
Definition: compiler.h:505
void adjust_pci_device(struct pci_device *pci)
Enable PCI device.
Definition: pci.c:154
struct device dev
Generic device.
Definition: pci.h:208
#define HVM_MMIO_BAR
PCI MMIO BAR.
Definition: hvm.h:36
int xenbus_probe(struct xen_hypervisor *xen, struct device *parent)
Probe Xen bus.
Definition: xenbus.c:353
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition: pci.h:359
#define ENOMEM
Not enough space.
Definition: errno.h:534
unsigned long pci_bar_start(struct pci_device *pci, unsigned int reg)
Find the start of a PCI BAR.
Definition: pci.c:96
static void hvm_unmap_xenstore(struct hvm_device *hvm)
Unmap XenStore.
Definition: hvm.c:402
static int hvm_map_shared_info(struct hvm_device *hvm)
Map shared info page.
Definition: hvm.c:262
static int hvm_cpuid_base(struct hvm_device *hvm)
Get CPUID base.
Definition: hvm.c:53
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
static int hvm_map_hypercall(struct hvm_device *hvm)
Map hypercall page(s)
Definition: hvm.c:92
unsigned long pci_bar_size(struct pci_device *pci, unsigned int reg)
Find the size of a PCI BAR.
Definition: pciextra.c:92
unsigned long mmio
MMIO base address.
Definition: hvm.h:49
A Xen HVM device.
Definition: hvm.h:39
static int hvm_map_xenstore(struct hvm_device *hvm)
Map XenStore.
Definition: hvm.c:345
size_t mmio_len
Length of MMIO address space.
Definition: hvm.h:53
static void hvm_unmap_grant(struct hvm_device *hvm)
Unmap grant table.
Definition: hvm.c:333
#define DBGC2(...)
Definition: compiler.h:522
void xenbus_remove(struct xen_hypervisor *xen __unused, struct device *parent)
Remove Xen bus.
Definition: xenbus.c:390
static int hvm_map_grant(struct hvm_device *hvm)
Map grant table.
Definition: hvm.c:305
static void hvm_unmap_shared_info(struct hvm_device *hvm)
Unmap shared info page.
Definition: hvm.c:293
struct pci_device * pci
PCI device.
Definition: hvm.h:43

References adjust_pci_device(), DBGC, DBGC2, pci_device::dev, ENOMEM, free, hvm_cpuid_base(), hvm_map_grant(), hvm_map_hypercall(), hvm_map_shared_info(), hvm_map_xenstore(), HVM_MMIO_BAR, hvm_unmap_grant(), hvm_unmap_hypercall(), hvm_unmap_shared_info(), hvm_unmap_xenstore(), hvm_device::mmio, hvm_device::mmio_len, hvm_device::pci, pci_bar_size(), pci_bar_start(), pci_set_drvdata(), rc, strerror(), hvm_device::xen, xenbus_probe(), xenbus_remove(), and zalloc().

◆ hvm_remove()

static void hvm_remove ( struct pci_device pci)
static

Remove PCI device.

Parameters
pciPCI device

Definition at line 476 of file hvm.c.

476  {
477  struct hvm_device *hvm = pci_get_drvdata ( pci );
478 
479  xenbus_remove ( &hvm->xen, &pci->dev );
480  hvm_unmap_xenstore ( hvm );
481  hvm_unmap_grant ( hvm );
482  hvm_unmap_shared_info ( hvm );
483  hvm_unmap_hypercall ( hvm );
484  free ( hvm );
485 }
static void hvm_unmap_hypercall(struct hvm_device *hvm)
Unmap hypercall page(s)
Definition: hvm.c:141
struct xen_hypervisor xen
Xen hypervisor.
Definition: hvm.h:41
struct device dev
Generic device.
Definition: pci.h:208
static void hvm_unmap_xenstore(struct hvm_device *hvm)
Unmap XenStore.
Definition: hvm.c:402
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
A Xen HVM device.
Definition: hvm.h:39
static void hvm_unmap_grant(struct hvm_device *hvm)
Unmap grant table.
Definition: hvm.c:333
static void * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition: pci.h:369
void xenbus_remove(struct xen_hypervisor *xen __unused, struct device *parent)
Remove Xen bus.
Definition: xenbus.c:390
static void hvm_unmap_shared_info(struct hvm_device *hvm)
Unmap shared info page.
Definition: hvm.c:293
struct pci_device * pci
PCI device.
Definition: hvm.h:43

References pci_device::dev, free, hvm_unmap_grant(), hvm_unmap_hypercall(), hvm_unmap_shared_info(), hvm_unmap_xenstore(), hvm_device::pci, pci_get_drvdata(), hvm_device::xen, and xenbus_remove().

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( hvm_driver  )

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( netfront  )

Variable Documentation

◆ hvm_ids

struct pci_device_id hvm_ids[]
static
Initial value:
= {
PCI_ROM ( 0x5853, 0x0001, "hvm", "hvm", 0 ),
PCI_ROM ( 0x5853, 0x0002, "hvm2", "hvm2", 0 ),
}
#define PCI_ROM(_vendor, _device, _name, _description, _data)
Definition: pci.h:303

PCI device IDs.

Definition at line 488 of file hvm.c.

◆ __pci_driver

struct pci_driver hvm_driver __pci_driver
Initial value:
= {
.ids = hvm_ids,
.id_count = ( sizeof ( hvm_ids ) / sizeof ( hvm_ids[0] ) ),
.probe = hvm_probe,
}
static void hvm_remove(struct pci_device *pci)
Remove PCI device.
Definition: hvm.c:476
static struct pci_device_id hvm_ids[]
PCI device IDs.
Definition: hvm.c:488
static int hvm_probe(struct pci_device *pci)
Probe PCI device.
Definition: hvm.c:414
static struct xen_remove_from_physmap * remove
Definition: xenmem.h:39

PCI driver.

Definition at line 494 of file hvm.c.