diff options
author | royger <royger@FreeBSD.org> | 2015-05-08 14:48:40 +0000 |
---|---|---|
committer | royger <royger@FreeBSD.org> | 2015-05-08 14:48:40 +0000 |
commit | d9a8b7337bd9eac9574477b682f8bba0af827223 (patch) | |
tree | 0df19d243cf9c3b5b078907ca41718eadb489e8f /sys/dev/xen | |
parent | b15170de41044ac77f0d019e6d5bb620d8a0f38f (diff) | |
download | FreeBSD-src-d9a8b7337bd9eac9574477b682f8bba0af827223.zip FreeBSD-src-d9a8b7337bd9eac9574477b682f8bba0af827223.tar.gz |
xen: introduce a newbus function to allocate unused memory
In order to map memory from other domains when running on Xen FreeBSD uses
unused physical memory regions. Until now this memory has been allocated
using bus_alloc_resource, but this is not completely safe as we can end up
using unreclaimed MMIO or ACPI regions.
Fix this by introducing a new newbus method that can be used by Xen drivers
to request for unused memory regions. On amd64 we make sure this memory
comes from regions above 4GB in order to prevent clashes with MMIO/ACPI
regions. On i386 there's nothing we can do, so just fall back to the
previous mechanism.
Sponsored by: Citrix Systems R&D
Tested by: Gustau PĂ©rez <gperez@entel.upc.edu>
Diffstat (limited to 'sys/dev/xen')
-rw-r--r-- | sys/dev/xen/blkback/blkback.c | 11 | ||||
-rw-r--r-- | sys/dev/xen/grant_table/grant_table.c | 5 | ||||
-rw-r--r-- | sys/dev/xen/netback/netback.c | 9 | ||||
-rw-r--r-- | sys/dev/xen/privcmd/privcmd.c | 26 |
4 files changed, 15 insertions, 36 deletions
diff --git a/sys/dev/xen/blkback/blkback.c b/sys/dev/xen/blkback/blkback.c index b647fec..d352242 100644 --- a/sys/dev/xen/blkback/blkback.c +++ b/sys/dev/xen/blkback/blkback.c @@ -2817,9 +2817,8 @@ xbb_free_communication_mem(struct xbb_softc *xbb) { if (xbb->kva != 0) { if (xbb->pseudo_phys_res != NULL) { - bus_release_resource(xbb->dev, SYS_RES_MEMORY, - xbb->pseudo_phys_res_id, - xbb->pseudo_phys_res); + xenmem_free(xbb->dev, xbb->pseudo_phys_res_id, + xbb->pseudo_phys_res); xbb->pseudo_phys_res = NULL; } } @@ -3056,10 +3055,8 @@ xbb_alloc_communication_mem(struct xbb_softc *xbb) * via grant table operations. */ xbb->pseudo_phys_res_id = 0; - xbb->pseudo_phys_res = bus_alloc_resource(xbb->dev, SYS_RES_MEMORY, - &xbb->pseudo_phys_res_id, - 0, ~0, xbb->kva_size, - RF_ACTIVE); + xbb->pseudo_phys_res = xenmem_alloc(xbb->dev, &xbb->pseudo_phys_res_id, + xbb->kva_size); if (xbb->pseudo_phys_res == NULL) { xbb->kva = 0; return (ENOMEM); diff --git a/sys/dev/xen/grant_table/grant_table.c b/sys/dev/xen/grant_table/grant_table.c index ad65fe0..728d64d 100644 --- a/sys/dev/xen/grant_table/grant_table.c +++ b/sys/dev/xen/grant_table/grant_table.c @@ -559,9 +559,8 @@ gnttab_resume(device_t dev) KASSERT(dev != NULL, ("No resume frames and no device provided")); - gnttab_pseudo_phys_res = bus_alloc_resource(dev, - SYS_RES_MEMORY, &gnttab_pseudo_phys_res_id, 0, ~0, - PAGE_SIZE * max_nr_gframes, RF_ACTIVE); + gnttab_pseudo_phys_res = xenmem_alloc(dev, + &gnttab_pseudo_phys_res_id, PAGE_SIZE * max_nr_gframes); if (gnttab_pseudo_phys_res == NULL) panic("Unable to reserve physical memory for gnttab"); resume_frames = rman_get_start(gnttab_pseudo_phys_res); diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c index b5c1c13..2233084 100644 --- a/sys/dev/xen/netback/netback.c +++ b/sys/dev/xen/netback/netback.c @@ -625,8 +625,7 @@ xnb_free_communication_mem(struct xnb_softc *xnb) { if (xnb->kva != 0) { if (xnb->pseudo_phys_res != NULL) { - bus_release_resource(xnb->dev, SYS_RES_MEMORY, - xnb->pseudo_phys_res_id, + xenmem_free(xnb->dev, xnb->pseudo_phys_res_id, xnb->pseudo_phys_res); xnb->pseudo_phys_res = NULL; } @@ -819,10 +818,8 @@ xnb_alloc_communication_mem(struct xnb_softc *xnb) * into this space. */ xnb->pseudo_phys_res_id = 0; - xnb->pseudo_phys_res = bus_alloc_resource(xnb->dev, SYS_RES_MEMORY, - &xnb->pseudo_phys_res_id, - 0, ~0, xnb->kva_size, - RF_ACTIVE); + xnb->pseudo_phys_res = xenmem_alloc(xnb->dev, &xnb->pseudo_phys_res_id, + xnb->kva_size); if (xnb->pseudo_phys_res == NULL) { xnb->kva = 0; return (ENOMEM); diff --git a/sys/dev/xen/privcmd/privcmd.c b/sys/dev/xen/privcmd/privcmd.c index 761fb03..0bf9585 100644 --- a/sys/dev/xen/privcmd/privcmd.c +++ b/sys/dev/xen/privcmd/privcmd.c @@ -141,11 +141,8 @@ retry: free(map->errs, M_PRIVCMD); } - vm_phys_fictitious_unreg_range(map->phys_base_addr, - map->phys_base_addr + map->size * PAGE_SIZE); - - error = bus_release_resource(privcmd_dev, SYS_RES_MEMORY, - map->pseudo_phys_res_id, map->pseudo_phys_res); + error = xenmem_free(privcmd_dev, map->pseudo_phys_res_id, + map->pseudo_phys_res); KASSERT(error == 0, ("Unable to release memory resource: %d", error)); free(map, M_PRIVCMD); @@ -196,36 +193,25 @@ privcmd_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t size, vm_object_t *object, int nprot) { struct privcmd_map *map; - int error; map = malloc(sizeof(*map), M_PRIVCMD, M_WAITOK | M_ZERO); map->size = OFF_TO_IDX(size); map->pseudo_phys_res_id = 0; - map->pseudo_phys_res = bus_alloc_resource(privcmd_dev, SYS_RES_MEMORY, - &map->pseudo_phys_res_id, 0, ~0, size, RF_ACTIVE); + map->pseudo_phys_res = xenmem_alloc(privcmd_dev, + &map->pseudo_phys_res_id, size); if (map->pseudo_phys_res == NULL) { free(map, M_PRIVCMD); return (ENOMEM); } map->phys_base_addr = rman_get_start(map->pseudo_phys_res); - - error = vm_phys_fictitious_reg_range(map->phys_base_addr, - map->phys_base_addr + size, VM_MEMATTR_DEFAULT); - if (error) { - bus_release_resource(privcmd_dev, SYS_RES_MEMORY, - map->pseudo_phys_res_id, map->pseudo_phys_res); - free(map, M_PRIVCMD); - return (error); - } - map->mem = cdev_pager_allocate(map, OBJT_MGTDEVICE, &privcmd_pg_ops, size, nprot, *offset, NULL); if (map->mem == NULL) { - bus_release_resource(privcmd_dev, SYS_RES_MEMORY, - map->pseudo_phys_res_id, map->pseudo_phys_res); + xenmem_free(privcmd_dev, map->pseudo_phys_res_id, + map->pseudo_phys_res); free(map, M_PRIVCMD); return (ENOMEM); } |