Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libnvmm Change the map/unmap functions, again.
details: https://anonhg.NetBSD.org/src/rev/8233fb891635
branches: trunk
changeset: 995222:8233fb891635
user: maxv <maxv%NetBSD.org@localhost>
date: Wed Dec 12 10:42:34 2018 +0000
description:
Change the map/unmap functions, again.
diffstat:
lib/libnvmm/libnvmm.c | 147 ++++++++++++++++++++++---------------------------
1 files changed, 66 insertions(+), 81 deletions(-)
diffs (199 lines):
diff -r 50fd215afdf5 -r 8233fb891635 lib/libnvmm/libnvmm.c
--- a/lib/libnvmm/libnvmm.c Wed Dec 12 10:25:29 2018 +0000
+++ b/lib/libnvmm/libnvmm.c Wed Dec 12 10:42:34 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: libnvmm.c,v 1.3 2018/11/29 19:55:20 maxv Exp $ */
+/* $NetBSD: libnvmm.c,v 1.4 2018/12/12 10:42:34 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -57,89 +57,40 @@
/* -------------------------------------------------------------------------- */
-static int
-__area_unmap(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
- size_t size)
-{
- struct nvmm_ioc_gpa_unmap args;
- int ret;
-
- args.machid = mach->machid;
- args.gpa = gpa;
- args.size = size;
-
- ret = ioctl(nvmm_fd, NVMM_IOC_GPA_UNMAP, &args);
- if (ret == -1)
- return -1;
-
- ret = munmap((void *)hva, size);
-
- return ret;
-}
-
-static int
-__area_dig_hole(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
+static bool
+__area_isvalid(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
size_t size)
{
area_list_t *areas = mach->areas;
- area_t *ent, *tmp, *nxt;
- size_t diff;
+ area_t *ent;
- LIST_FOREACH_SAFE(ent, areas, list, nxt) {
- /* Case 1. */
- if ((gpa < ent->gpa) && (gpa + size > ent->gpa)) {
- diff = (gpa + size) - ent->gpa;
- if (__area_unmap(mach, ent->hva, ent->gpa, diff) == -1) {
- return -1;
- }
- ent->gpa += diff;
- ent->hva += diff;
- ent->size -= diff;
+ LIST_FOREACH(ent, areas, list) {
+ /* Collision on HVA */
+ if (hva >= ent->hva && hva < ent->hva + ent->size) {
+ return false;
+ }
+ if (hva + size >= ent->hva &&
+ hva + size < ent->hva + ent->size) {
+ return false;
+ }
+ if (hva <= ent->hva && hva + size >= ent->hva + ent->size) {
+ return false;
}
- /* Case 2. */
- if ((gpa >= ent->gpa) && (gpa + size <= ent->gpa + ent->size)) {
- /* First half. */
- tmp = malloc(sizeof(*tmp));
- tmp->gpa = ent->gpa;
- tmp->hva = ent->hva;
- tmp->size = (gpa - ent->gpa);
- LIST_INSERT_BEFORE(ent, tmp, list);
- /* Second half. */
- ent->gpa += tmp->size;
- ent->hva += tmp->size;
- ent->size -= tmp->size;
- diff = size;
- if (__area_unmap(mach, ent->hva, ent->gpa, diff) == -1) {
- return -1;
- }
- ent->gpa += diff;
- ent->hva += diff;
- ent->size -= diff;
+ /* Collision on GPA */
+ if (gpa >= ent->gpa && gpa < ent->gpa + ent->size) {
+ return false;
}
-
- /* Case 3. */
- if ((gpa < ent->gpa + ent->size) &&
- (gpa + size > ent->gpa + ent->size)) {
- diff = (ent->gpa + ent->size) - gpa;
- if (__area_unmap(mach, hva, gpa, diff) == -1) {
- return -1;
- }
- ent->size -= diff;
+ if (gpa + size >= ent->gpa &&
+ gpa + size < ent->gpa + ent->size) {
+ return false;
}
-
- /* Case 4. */
- if ((gpa < ent->gpa + ent->size) &&
- (gpa + size > ent->gpa + ent->size)) {
- if (__area_unmap(mach, ent->hva, ent->gpa, ent->size) == -1) {
- return -1;
- }
- LIST_REMOVE(ent, list);
- free(ent);
+ if (gpa <= ent->gpa && gpa + size >= ent->gpa + ent->size) {
+ return false;
}
}
- return 0;
+ return true;
}
static int
@@ -147,7 +98,11 @@
{
area_list_t *areas = mach->areas;
area_t *area;
- int ret;
+
+ if (!__area_isvalid(mach, hva, gpa, size)) {
+ errno = EINVAL;
+ return -1;
+ }
area = malloc(sizeof(*area));
if (area == NULL)
@@ -156,14 +111,27 @@
area->hva = hva;
area->size = size;
- ret = __area_dig_hole(mach, hva, gpa, size);
- if (ret == -1) {
- free(area);
- return -1;
+ LIST_INSERT_HEAD(areas, area, list);
+
+ return 0;
+}
+
+static int
+__area_delete(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
+ size_t size)
+{
+ area_list_t *areas = mach->areas;
+ area_t *ent, *nxt;
+
+ LIST_FOREACH_SAFE(ent, areas, list, nxt) {
+ if (hva == ent->hva && gpa == ent->gpa && size == ent->size) {
+ LIST_REMOVE(ent, list);
+ free(ent);
+ return 0;
+ }
}
- LIST_INSERT_HEAD(areas, area, list);
- return 0;
+ return -1;
}
static void
@@ -450,11 +418,28 @@
nvmm_gpa_unmap(struct nvmm_machine *mach, uintptr_t hva, gpaddr_t gpa,
size_t size)
{
+ struct nvmm_ioc_gpa_unmap args;
+ int ret;
+
if (nvmm_init() == -1) {
return -1;
}
- return __area_dig_hole(mach, hva, gpa, size);
+ ret = __area_delete(mach, hva, gpa, size);
+ if (ret == -1)
+ return -1;
+
+ args.machid = mach->machid;
+ args.gpa = gpa;
+ args.size = size;
+
+ ret = ioctl(nvmm_fd, NVMM_IOC_GPA_UNMAP, &args);
+ if (ret == -1)
+ return -1;
+
+ ret = munmap((void *)hva, size);
+
+ return ret;
}
/*
Home |
Main Index |
Thread Index |
Old Index