iPXE
hvm.c File Reference

Xen HVM driver. More...

#include <stdint.h>
#include <stdio.h>
#include <string.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)
 FILE_SECBOOT (PERMITTED)
static int hvm_cpuid_base (struct hvm_device *hvm)
 Get CPUID base.
static int hvm_map_hypercall (struct hvm_device *hvm)
 Map hypercall page(s)
static void hvm_unmap_hypercall (struct hvm_device *hvm)
 Unmap hypercall page(s)
static void * hvm_ioremap (struct hvm_device *hvm, unsigned int space, size_t len)
 Allocate and map MMIO space.
static void hvm_iounmap (struct hvm_device *hvm, void *mmio, size_t len)
 Unmap MMIO space.
static int hvm_map_shared_info (struct hvm_device *hvm)
 Map shared info page.
static void hvm_unmap_shared_info (struct hvm_device *hvm)
 Unmap shared info page.
static int hvm_map_grant (struct hvm_device *hvm)
 Map grant table.
static void hvm_unmap_grant (struct hvm_device *hvm)
 Unmap grant table.
static int hvm_map_xenstore (struct hvm_device *hvm)
 Map XenStore.
static void hvm_unmap_xenstore (struct hvm_device *hvm)
 Unmap XenStore.
static int hvm_probe (struct pci_device *pci)
 Probe PCI device.
static void hvm_remove (struct pci_device *pci)
 Remove PCI device.
 REQUIRING_SYMBOL (hvm_driver)
 REQUIRE_OBJECT (netfront)

Variables

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

Detailed Description

Xen HVM driver.

Definition in file hvm.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ hvm_cpuid_base()

int hvm_cpuid_base ( struct hvm_device * hvm)
static

Get CPUID base.

Parameters
hvmHVM device
Return values
rcReturn status code

Definition at line 55 of file hvm.c.

55 {
56 struct {
60 } __attribute__ (( packed )) signature;
63 uint32_t discard_eax;
64 uint32_t discard_ebx;
67
68 /* Scan for magic signature */
70 base += HVM_CPUID_STEP ) {
71 cpuid ( base, 0, &discard_eax, &signature.ebx, &signature.ecx,
72 &signature.edx );
74 sizeof ( signature ) ) == 0 ) {
75 hvm->cpuid_base = base;
76 cpuid ( ( base + HVM_CPUID_VERSION ), 0, &version,
77 &discard_ebx, &discard_ecx, &discard_edx );
78 DBGC2 ( hvm, "HVM using CPUID base %#08x (v%d.%d)\n",
79 base, ( version >> 16 ), ( version & 0xffff ) );
80 return 0;
81 }
82 }
83
84 DBGC ( hvm, "HVM could not find hypervisor\n" );
85 return -ENODEV;
86}
u8 signature
CPU signature.
Definition CIB_PRM.h:7
uint32_t discard_edx
Definition hyperv.h:32
uint32_t discard_ecx
Definition hyperv.h:31
unsigned int uint32_t
Definition stdint.h:12
u32 version
Driver version.
Definition ath9k_hw.c:1985
static uint32_t uint32_t uint32_t * ebx
Definition cpuid.h:90
static uint32_t uint32_t uint32_t uint32_t * ecx
Definition cpuid.h:91
static uint32_t uint32_t uint32_t uint32_t uint32_t * edx
Definition cpuid.h:91
#define DBGC2(...)
Definition compiler.h:522
#define DBGC(...)
Definition compiler.h:505
#define ENODEV
No such device.
Definition errno.h:510
#define HVM_CPUID_MAGIC
Magic signature.
Definition hvm.h:28
#define HVM_CPUID_STEP
Increment between CPUID bases.
Definition hvm.h:25
#define HVM_CPUID_MIN
Minimum CPUID base.
Definition hvm.h:19
#define HVM_CPUID_VERSION
Get Xen version.
Definition hvm.h:31
#define HVM_CPUID_MAX
Maximum CPUID base.
Definition hvm.h:22
#define __attribute__(x)
Definition compiler.h:10
uint32_t base
Base.
Definition librm.h:3
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115
uint32_t cpuid_base
CPUID base.
Definition hvm.h:46

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()

int hvm_map_hypercall ( struct hvm_device * hvm)
static

Map hypercall page(s)

Parameters
hvmHVM device
Return values
rcReturn status code

Definition at line 94 of file hvm.c.

94 {
95 uint32_t pages;
96 uint32_t msr;
99 physaddr_t hypercall_phys;
102 int xenrc;
103 int rc;
104
105 /* Get number of hypercall pages and MSR to use */
106 cpuid ( ( hvm->cpuid_base + HVM_CPUID_PAGES ), 0, &pages, &msr,
108
109 /* Allocate pages */
110 hvm->hypercall_len = ( pages * PAGE_SIZE );
112 if ( ! hvm->xen.hypercall ) {
113 DBGC ( hvm, "HVM could not allocate %d hypercall page(s)\n",
114 pages );
115 return -ENOMEM;
116 }
117 hypercall_phys = virt_to_phys ( hvm->xen.hypercall );
118 DBGC2 ( hvm, "HVM hypercall page(s) at [%#08lx,%#08lx) via MSR %#08x\n",
119 hypercall_phys, ( hypercall_phys + hvm->hypercall_len ), msr );
120
121 /* Write to MSR */
122 wrmsr ( msr, hypercall_phys );
123
124 /* Check that hypercall mechanism is working */
125 version = xenver_version ( &hvm->xen );
126 if ( ( xenrc = xenver_extraversion ( &hvm->xen, &extraversion ) ) != 0){
127 rc = -EXEN ( xenrc );
128 DBGC ( hvm, "HVM could not get extraversion: %s\n",
129 strerror ( rc ) );
130 return rc;
131 }
132 DBGC2 ( hvm, "HVM found Xen version %d.%d%s\n",
133 ( version >> 16 ), ( version & 0xffff ) , extraversion );
134
135 return 0;
136}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
unsigned long physaddr_t
Definition stdint.h:20
#define ENOMEM
Not enough space.
Definition errno.h:535
#define HVM_CPUID_PAGES
Get number of hypercall pages.
Definition hvm.h:34
#define PAGE_SIZE
Page size.
Definition io.h:28
#define EXEN(xenrc)
Convert a Xen status code to an iPXE status code.
Definition xen.h:87
void * malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition malloc.c:707
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
size_t hypercall_len
Length of hypercall table.
Definition hvm.h:48
struct xen_hypervisor xen
Xen hypervisor.
Definition hvm.h:42
struct xen_hypercall * hypercall
Hypercall table.
Definition xen.h:53
char xen_extraversion_t[16]
Definition version.h:31
static xen_extraversion_t * extraversion
Definition xenver.h:38

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, and hvm_device::xen.

Referenced by hvm_probe().

◆ hvm_unmap_hypercall()

void hvm_unmap_hypercall ( struct hvm_device * hvm)
static

Unmap hypercall page(s)

Parameters
hvmHVM device

Definition at line 143 of file hvm.c.

143 {
144
145 /* Free pages */
146 free_phys ( hvm->xen.hypercall, hvm->hypercall_len );
147}
void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition malloc.c:723

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

Referenced by hvm_probe(), and hvm_remove().

◆ hvm_ioremap()

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 157 of file hvm.c.

158 {
159 struct xen_add_to_physmap add;
161 unsigned int pages = ( len / PAGE_SIZE );
162 physaddr_t mmio_phys;
163 unsigned int i;
164 void *mmio;
165 int xenrc;
166 int rc;
167
168 /* Sanity check */
169 assert ( ( len % PAGE_SIZE ) == 0 );
170
171 /* Check for available space */
172 if ( ( hvm->mmio_offset + len ) > hvm->mmio_len ) {
173 DBGC ( hvm, "HVM could not allocate %zd bytes of MMIO space "
174 "(%zd of %zd remaining)\n", len,
175 ( hvm->mmio_len - hvm->mmio_offset ), hvm->mmio_len );
176 goto err_no_space;
177 }
178
179 /* Map this space */
180 mmio = pci_ioremap ( hvm->pci, ( hvm->mmio + hvm->mmio_offset ), len );
181 if ( ! mmio ) {
182 DBGC ( hvm, "HVM could not map MMIO space [%08lx,%08lx)\n",
183 ( hvm->mmio + hvm->mmio_offset ),
184 ( hvm->mmio + hvm->mmio_offset + len ) );
185 goto err_ioremap;
186 }
187 mmio_phys = virt_to_phys ( mmio );
188
189 /* Add to physical address space */
190 for ( i = 0 ; i < pages ; i++ ) {
191 add.domid = DOMID_SELF;
192 add.idx = i;
193 add.space = space;
194 add.gpfn = ( ( mmio_phys / PAGE_SIZE ) + i );
195 if ( ( xenrc = xenmem_add_to_physmap ( &hvm->xen, &add ) ) !=0){
196 rc = -EXEN ( xenrc );
197 DBGC ( hvm, "HVM could not add space %d idx %d at "
198 "[%08lx,%08lx): %s\n", space, i,
199 ( mmio_phys + ( i * PAGE_SIZE ) ),
200 ( mmio_phys + ( ( i + 1 ) * PAGE_SIZE ) ),
201 strerror ( rc ) );
202 goto err_add_to_physmap;
203 }
204 }
205
206 /* Update offset */
207 hvm->mmio_offset += len;
208
209 return mmio;
210
211 i = pages;
212 err_add_to_physmap:
213 for ( i-- ; ( signed int ) i >= 0 ; i-- ) {
214 remove.domid = DOMID_SELF;
215 add.gpfn = ( ( mmio_phys / PAGE_SIZE ) + i );
216 xenmem_remove_from_physmap ( &hvm->xen, &remove );
217 }
218 iounmap ( mmio );
219 err_ioremap:
220 err_no_space:
221 return NULL;
222}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
ring len
Length.
Definition dwmac.h:226
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 DOMID_SELF
Definition xen.h:581
unsigned long mmio
MMIO base address.
Definition hvm.h:50
size_t mmio_len
Length of MMIO address space.
Definition hvm.h:54
size_t mmio_offset
Current offset within MMIO address space.
Definition hvm.h:52
struct pci_device * pci
PCI device.
Definition hvm.h:44
static struct xen_remove_from_physmap * remove
Definition xenmem.h:40
static struct xen_add_to_physmap * add
Definition xenmem.h:25

References add, assert, DBGC, 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(), and hvm_device::xen.

Referenced by hvm_map_grant(), and hvm_map_shared_info().

◆ hvm_iounmap()

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 231 of file hvm.c.

231 {
233 physaddr_t mmio_phys = virt_to_phys ( mmio );
234 unsigned int pages = ( len / PAGE_SIZE );
235 unsigned int i;
236 int xenrc;
237 int rc;
238
239 /* Unmap this space */
240 iounmap ( mmio );
241
242 /* Remove from physical address space */
243 for ( i = 0 ; i < pages ; i++ ) {
244 remove.domid = DOMID_SELF;
245 remove.gpfn = ( ( mmio_phys / PAGE_SIZE ) + i );
246 if ( ( xenrc = xenmem_remove_from_physmap ( &hvm->xen,
247 &remove ) ) != 0 ) {
248 rc = -EXEN ( xenrc );
249 DBGC ( hvm, "HVM could not remove space [%08lx,%08lx): "
250 "%s\n", ( mmio_phys + ( i * PAGE_SIZE ) ),
251 ( mmio_phys + ( ( i + 1 ) * PAGE_SIZE ) ),
252 strerror ( rc ) );
253 /* Nothing we can do about this */
254 }
255 }
256}

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

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

◆ hvm_map_shared_info()

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 264 of file hvm.c.

264 {
265 physaddr_t shared_info_phys;
266 int rc;
267
268 /* Map shared info page */
270 PAGE_SIZE );
271 if ( ! hvm->xen.shared ) {
272 rc = -ENOMEM;
273 goto err_alloc;
274 }
275 shared_info_phys = virt_to_phys ( hvm->xen.shared );
276 DBGC2 ( hvm, "HVM shared info page at [%#08lx,%#08lx)\n",
277 shared_info_phys, ( shared_info_phys + PAGE_SIZE ) );
278
279 /* Sanity check */
280 DBGC2 ( hvm, "HVM wallclock time is %d\n",
281 readl ( &hvm->xen.shared->wc_sec ) );
282
283 return 0;
284
285 hvm_iounmap ( hvm, hvm->xen.shared, PAGE_SIZE );
286 err_alloc:
287 return rc;
288}
static void hvm_iounmap(struct hvm_device *hvm, void *mmio, size_t len)
Unmap MMIO space.
Definition hvm.c:231
static void * hvm_ioremap(struct hvm_device *hvm, unsigned int space, size_t len)
Allocate and map MMIO space.
Definition hvm.c:157
#define XENMAPSPACE_shared_info
Definition memory.h:212
uint32_t wc_sec
Definition xen.h:794
struct shared_info * shared
Shared info page.
Definition xen.h:55
#define readl
Definition w89c840.c:157

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

Referenced by hvm_probe().

◆ hvm_unmap_shared_info()

void hvm_unmap_shared_info ( struct hvm_device * hvm)
static

Unmap shared info page.

Parameters
hvmHVM device

Definition at line 295 of file hvm.c.

295 {
296
297 /* Unmap shared info page */
298 hvm_iounmap ( hvm, hvm->xen.shared, PAGE_SIZE );
299}

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

Referenced by hvm_probe(), and hvm_remove().

◆ hvm_map_grant()

int hvm_map_grant ( struct hvm_device * hvm)
static

Map grant table.

Parameters
hvmHVM device
Return values
rcReturn status code

Definition at line 307 of file hvm.c.

307 {
308 physaddr_t grant_phys;
309 int rc;
310
311 /* Initialise grant table */
312 if ( ( rc = xengrant_init ( &hvm->xen ) ) != 0 ) {
313 DBGC ( hvm, "HVM could not initialise grant table: %s\n",
314 strerror ( rc ) );
315 return rc;
316 }
317
318 /* Map grant table */
320 hvm->xen.grant.len );
321 if ( ! hvm->xen.grant.table )
322 return -ENODEV;
323
324 grant_phys = virt_to_phys ( hvm->xen.grant.table );
325 DBGC2 ( hvm, "HVM mapped grant table at [%08lx,%08lx)\n",
326 grant_phys, ( grant_phys + hvm->xen.grant.len ) );
327 return 0;
328}
#define XENMAPSPACE_grant_table
Definition memory.h:213
size_t len
Total grant table length.
Definition xen.h:33
struct grant_entry_v1 * table
Grant table entries.
Definition xen.h:31
struct xen_grant grant
Grant table.
Definition xen.h:57
int xengrant_init(struct xen_hypervisor *xen)
Initialise grant table.
Definition xengrant.c:71

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

Referenced by hvm_probe().

◆ hvm_unmap_grant()

void hvm_unmap_grant ( struct hvm_device * hvm)
static

Unmap grant table.

Parameters
hvmHVM device

Definition at line 335 of file hvm.c.

335 {
336
337 /* Unmap grant table */
338 hvm_iounmap ( hvm, hvm->xen.grant.table, hvm->xen.grant.len );
339}

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()

int hvm_map_xenstore ( struct hvm_device * hvm)
static

Map XenStore.

Parameters
hvmHVM device
Return values
rcReturn status code

Definition at line 347 of file hvm.c.

347 {
348 uint64_t xenstore_evtchn;
349 uint64_t xenstore_pfn;
350 physaddr_t xenstore_phys;
351 char *name;
352 int xenrc;
353 int rc;
354
355 /* Get XenStore event channel */
356 if ( ( xenrc = xen_hvm_get_param ( &hvm->xen, HVM_PARAM_STORE_EVTCHN,
357 &xenstore_evtchn ) ) != 0 ) {
358 rc = -EXEN ( xenrc );
359 DBGC ( hvm, "HVM could not get XenStore event channel: %s\n",
360 strerror ( rc ) );
361 return rc;
362 }
363 hvm->xen.store.port = xenstore_evtchn;
364
365 /* Get XenStore PFN */
366 if ( ( xenrc = xen_hvm_get_param ( &hvm->xen, HVM_PARAM_STORE_PFN,
367 &xenstore_pfn ) ) != 0 ) {
368 rc = -EXEN ( xenrc );
369 DBGC ( hvm, "HVM could not get XenStore PFN: %s\n",
370 strerror ( rc ) );
371 return rc;
372 }
373 xenstore_phys = ( xenstore_pfn * PAGE_SIZE );
374
375 /* Map XenStore */
376 hvm->xen.store.intf = pci_ioremap ( hvm->pci, xenstore_phys,
377 PAGE_SIZE );
378 if ( ! hvm->xen.store.intf ) {
379 DBGC ( hvm, "HVM could not map XenStore at [%08lx,%08lx)\n",
380 xenstore_phys, ( xenstore_phys + PAGE_SIZE ) );
381 return -ENODEV;
382 }
383 DBGC2 ( hvm, "HVM mapped XenStore at [%08lx,%08lx) with event port "
384 "%d\n", xenstore_phys, ( xenstore_phys + PAGE_SIZE ),
385 hvm->xen.store.port );
386
387 /* Check that XenStore is working */
388 if ( ( rc = xenstore_read ( &hvm->xen, &name, "name", NULL ) ) != 0 ) {
389 DBGC ( hvm, "HVM could not read domain name: %s\n",
390 strerror ( rc ) );
391 return rc;
392 }
393 DBGC2 ( hvm, "HVM running in domain \"%s\"\n", name );
394 free ( name );
395
396 return 0;
397}
unsigned long long uint64_t
Definition stdint.h:13
const char * name
Definition ath9k_hw.c:1986
static int xen_hvm_get_param(struct xen_hypervisor *xen, unsigned int index, uint64_t *value)
Get HVM parameter value.
Definition hvm.h:65
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
struct xen_store store
XenStore.
Definition xen.h:59
struct xenstore_domain_interface * intf
XenStore domain interface.
Definition xen.h:45
evtchn_port_t port
Event channel.
Definition xen.h:47
#define HVM_PARAM_STORE_EVTCHN
Definition params.h:81
#define HVM_PARAM_STORE_PFN
Definition params.h:80
int xenstore_read(struct xen_hypervisor *xen, char **value,...)
Read XenStore value.
Definition xenstore.c:372

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()

void hvm_unmap_xenstore ( struct hvm_device * hvm)
static

Unmap XenStore.

Parameters
hvmHVM device

Definition at line 404 of file hvm.c.

404 {
405
406 /* Unmap XenStore */
407 iounmap ( hvm->xen.store.intf );
408}

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

Referenced by hvm_probe(), and hvm_remove().

◆ hvm_probe()

int hvm_probe ( struct pci_device * pci)
static

Probe PCI device.

Parameters
pciPCI device
Return values
rcReturn status code

Definition at line 416 of file hvm.c.

416 {
417 struct hvm_device *hvm;
418 int rc;
419
420 /* Allocate and initialise structure */
421 hvm = zalloc ( sizeof ( *hvm ) );
422 if ( ! hvm ) {
423 rc = -ENOMEM;
424 goto err_alloc;
425 }
426 hvm->pci = pci;
429 DBGC2 ( hvm, "HVM has MMIO space [%08lx,%08lx)\n",
430 hvm->mmio, ( hvm->mmio + hvm->mmio_len ) );
431
432 /* Fix up PCI device */
434
435 /* Attach to hypervisor */
436 if ( ( rc = hvm_cpuid_base ( hvm ) ) != 0 )
437 goto err_cpuid_base;
438 if ( ( rc = hvm_map_hypercall ( hvm ) ) != 0 )
439 goto err_map_hypercall;
440 if ( ( rc = hvm_map_shared_info ( hvm ) ) != 0 )
441 goto err_map_shared_info;
442 if ( ( rc = hvm_map_grant ( hvm ) ) != 0 )
443 goto err_map_grant;
444 if ( ( rc = hvm_map_xenstore ( hvm ) ) != 0 )
445 goto err_map_xenstore;
446
447 /* Probe Xen devices */
448 if ( ( rc = xenbus_probe ( &hvm->xen, &pci->dev ) ) != 0 ) {
449 DBGC ( hvm, "HVM could not probe Xen bus: %s\n",
450 strerror ( rc ) );
451 goto err_xenbus_probe;
452 }
453
454 pci_set_drvdata ( pci, hvm );
455 return 0;
456
457 xenbus_remove ( &hvm->xen, &pci->dev );
458 err_xenbus_probe:
459 hvm_unmap_xenstore ( hvm );
460 err_map_xenstore:
461 hvm_unmap_grant ( hvm );
462 err_map_grant:
463 hvm_unmap_shared_info ( hvm );
464 err_map_shared_info:
465 hvm_unmap_hypercall ( hvm );
466 err_map_hypercall:
467 err_cpuid_base:
468 free ( hvm );
469 err_alloc:
470 return rc;
471}
static void hvm_unmap_grant(struct hvm_device *hvm)
Unmap grant table.
Definition hvm.c:335
static int hvm_map_shared_info(struct hvm_device *hvm)
Map shared info page.
Definition hvm.c:264
static void hvm_unmap_xenstore(struct hvm_device *hvm)
Unmap XenStore.
Definition hvm.c:404
static int hvm_map_grant(struct hvm_device *hvm)
Map grant table.
Definition hvm.c:307
static int hvm_map_hypercall(struct hvm_device *hvm)
Map hypercall page(s)
Definition hvm.c:94
static int hvm_cpuid_base(struct hvm_device *hvm)
Get CPUID base.
Definition hvm.c:55
static void hvm_unmap_shared_info(struct hvm_device *hvm)
Unmap shared info page.
Definition hvm.c:295
static void hvm_unmap_hypercall(struct hvm_device *hvm)
Unmap hypercall page(s)
Definition hvm.c:143
static int hvm_map_xenstore(struct hvm_device *hvm)
Map XenStore.
Definition hvm.c:347
#define HVM_MMIO_BAR
PCI MMIO BAR.
Definition hvm.h:37
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
unsigned long pci_bar_size(struct pci_device *pci, unsigned int reg)
Get the size of a PCI BAR.
Definition pci.c:164
void adjust_pci_device(struct pci_device *pci)
Enable PCI device.
Definition pci.c:241
unsigned long pci_bar_start(struct pci_device *pci, unsigned int reg)
Find the start of a PCI BAR.
Definition pci.c:97
static void pci_set_drvdata(struct pci_device *pci, void *priv)
Set PCI driver-private data.
Definition pci.h:366
A Xen HVM device.
Definition hvm.h:40
struct device dev
Generic device.
Definition pci.h:213
void xenbus_remove(struct xen_hypervisor *xen __unused, struct device *parent)
Remove Xen bus.
Definition xenbus.c:392
int xenbus_probe(struct xen_hypervisor *xen, struct device *parent)
Probe Xen bus.
Definition xenbus.c:355

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()

void hvm_remove ( struct pci_device * pci)
static

Remove PCI device.

Parameters
pciPCI device

Definition at line 478 of file hvm.c.

478 {
479 struct hvm_device *hvm = pci_get_drvdata ( pci );
480
481 xenbus_remove ( &hvm->xen, &pci->dev );
482 hvm_unmap_xenstore ( hvm );
483 hvm_unmap_grant ( hvm );
484 hvm_unmap_shared_info ( hvm );
485 hvm_unmap_hypercall ( hvm );
486 free ( hvm );
487}
static void * pci_get_drvdata(struct pci_device *pci)
Get PCI driver-private data.
Definition pci.h:376

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:308

PCI device IDs.

Definition at line 490 of file hvm.c.

490 {
491 PCI_ROM ( 0x5853, 0x0001, "hvm", "hvm", 0 ),
492 PCI_ROM ( 0x5853, 0x0002, "hvm2", "hvm2", 0 ),
493};

◆ __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:478
static int hvm_probe(struct pci_device *pci)
Probe PCI device.
Definition hvm.c:416
static struct pci_device_id hvm_ids[]
PCI device IDs.
Definition hvm.c:490

PCI driver.

Definition at line 496 of file hvm.c.

496 {
497 .ids = hvm_ids,
498 .id_count = ( sizeof ( hvm_ids ) / sizeof ( hvm_ids[0] ) ),
499 .probe = hvm_probe,
501};