summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
authorJohn Levon <john.levon@joyent.com>2020-08-13 15:27:11 +0100
committerGitHub <noreply@github.com>2020-08-13 15:27:11 +0100
commite63d036fd36b5642d5e199f7d9895d8d4eda6072 (patch)
tree0c177a62e8bd3796a7b530b7520fb0a4e7d0cd56 /usr/src/uts
parenta8ff5009e5f7ea544c79b60ea65577f19304ff0b (diff)
parent09f210323354e07890b312da9b4f5e33ae6b6df5 (diff)
downloadillumos-joyent-sasinfo.tar.gz
Merge branch 'master' into sasinfosasinfo
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/brand/lx/os/lx_brand.c25
-rw-r--r--usr/src/uts/i86pc/io/vmm/vm/vm_glue.h5
-rw-r--r--usr/src/uts/i86pc/io/vmm/vmm_sol_dev.c32
-rw-r--r--usr/src/uts/i86pc/io/vmm/vmm_sol_vm.c10
4 files changed, 49 insertions, 23 deletions
diff --git a/usr/src/uts/common/brand/lx/os/lx_brand.c b/usr/src/uts/common/brand/lx/os/lx_brand.c
index c7e5351778..31bb86cce1 100644
--- a/usr/src/uts/common/brand/lx/os/lx_brand.c
+++ b/usr/src/uts/common/brand/lx/os/lx_brand.c
@@ -26,6 +26,7 @@
/*
* Copyright 2020 Joyent, Inc.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
/*
@@ -1876,23 +1877,35 @@ lx_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
(void) lx_start_nfs_lockd();
return (0);
- case B_BLOCK_ALL_SIGS:
+ case B_BLOCK_ALL_SIGS: {
+ uint_t result = 0;
+
mutex_enter(&p->p_lock);
pd = ptolxproc(p);
- pd->l_block_all_signals++;
+ /*
+ * This is used to block handling of all signals during vfork()
+ * or clone(LX_CLONE_VFORK) emulation to match Linux semantics
+ * and prevent the parent's signal handlers being called before
+ * they are properly reset.
+ */
+ if (pd->l_block_all_signals != 0) {
+ result = set_errno(EAGAIN);
+ } else {
+ pd->l_block_all_signals = 1;
+ }
mutex_exit(&p->p_lock);
- return (0);
+ return (result);
+ }
case B_UNBLOCK_ALL_SIGS: {
- uint_t result;
+ uint_t result = 0;
mutex_enter(&p->p_lock);
pd = ptolxproc(p);
if (pd->l_block_all_signals == 0) {
result = set_errno(EINVAL);
} else {
- pd->l_block_all_signals--;
- result = 0;
+ pd->l_block_all_signals = 0;
}
mutex_exit(&p->p_lock);
return (result);
diff --git a/usr/src/uts/i86pc/io/vmm/vm/vm_glue.h b/usr/src/uts/i86pc/io/vmm/vm/vm_glue.h
index f894fcaf68..436b8e9691 100644
--- a/usr/src/uts/i86pc/io/vmm/vm/vm_glue.h
+++ b/usr/src/uts/i86pc/io/vmm/vm/vm_glue.h
@@ -12,6 +12,7 @@
/*
* Copyright 2019 Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
*/
#ifndef _VM_GLUE_
@@ -76,8 +77,8 @@ struct vm_page {
};
/* Illumos-specific functions for setup and operation */
-int vm_segmap_obj(struct vmspace *, vm_object_t, struct as *, caddr_t *,
- uint_t, uint_t, uint_t);
+int vm_segmap_obj(vm_object_t, off_t, size_t, struct as *, caddr_t *, uint_t,
+ uint_t, uint_t);
int vm_segmap_space(struct vmspace *, off_t, struct as *, caddr_t *, off_t,
uint_t, uint_t, uint_t);
void *vmspace_find_kva(struct vmspace *, uintptr_t, size_t);
diff --git a/usr/src/uts/i86pc/io/vmm/vmm_sol_dev.c b/usr/src/uts/i86pc/io/vmm/vmm_sol_dev.c
index 95a146661c..2f84ac5e95 100644
--- a/usr/src/uts/i86pc/io/vmm/vmm_sol_dev.c
+++ b/usr/src/uts/i86pc/io/vmm/vmm_sol_dev.c
@@ -14,6 +14,7 @@
* Copyright 2015 Pluribus Networks Inc.
* Copyright 2019 Joyent, Inc.
* Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
+ * Copyright 2020 Oxide Computer Company
*/
#include <sys/types.h>
@@ -184,25 +185,30 @@ vmmdev_devmem_create(vmm_softc_t *sc, struct vm_memseg *mseg, const char *name)
}
static boolean_t
-vmmdev_devmem_segid(vmm_softc_t *sc, off_t off, off_t len, int *segidp)
+vmmdev_devmem_segid(vmm_softc_t *sc, off_t off, off_t len, int *segidp,
+ off_t *map_offp)
{
list_t *dl = &sc->vmm_devmem_list;
vmm_devmem_entry_t *de = NULL;
+ const off_t map_end = off + len;
VERIFY(off >= VM_DEVMEM_START);
- for (de = list_head(dl); de != NULL; de = list_next(dl, de)) {
- /* XXX: Only hit on direct offset/length matches for now */
- if (de->vde_off == off && de->vde_len == len) {
- break;
- }
- }
- if (de == NULL) {
+ if (map_end < off) {
+ /* No match on overflow */
return (B_FALSE);
}
- *segidp = de->vde_segid;
- return (B_TRUE);
+ for (de = list_head(dl); de != NULL; de = list_next(dl, de)) {
+ const off_t item_end = de->vde_off + de->vde_len;
+
+ if (de->vde_off <= off && item_end >= map_end) {
+ *segidp = de->vde_segid;
+ *map_offp = off - de->vde_off;
+ return (B_TRUE);
+ }
+ }
+ return (B_FALSE);
}
static void
@@ -2076,9 +2082,10 @@ vmm_segmap(dev_t dev, off_t off, struct as *as, caddr_t *addrp, off_t len,
vms = vm_get_vmspace(vm);
if (off >= VM_DEVMEM_START) {
int segid;
+ off_t map_off = 0;
/* Mapping a devmem "device" */
- if (!vmmdev_devmem_segid(sc, off, len, &segid)) {
+ if (!vmmdev_devmem_segid(sc, off, len, &segid, &map_off)) {
err = ENODEV;
goto out;
}
@@ -2086,7 +2093,8 @@ vmm_segmap(dev_t dev, off_t off, struct as *as, caddr_t *addrp, off_t len,
if (err != 0) {
goto out;
}
- err = vm_segmap_obj(vms, vmo, as, addrp, prot, maxprot, flags);
+ err = vm_segmap_obj(vmo, map_off, len, as, addrp, prot, maxprot,
+ flags);
} else {
/* Mapping a part of the guest physical space */
err = vm_segmap_space(vms, off, as, addrp, len, prot, maxprot,
diff --git a/usr/src/uts/i86pc/io/vmm/vmm_sol_vm.c b/usr/src/uts/i86pc/io/vmm/vmm_sol_vm.c
index 9bd55c41f2..bedc338474 100644
--- a/usr/src/uts/i86pc/io/vmm/vmm_sol_vm.c
+++ b/usr/src/uts/i86pc/io/vmm/vmm_sol_vm.c
@@ -12,6 +12,7 @@
/*
* Copyright 2019 Joyent, Inc.
+ * Copyright 2020 Oxide Computer Company
*/
#include <sys/param.h>
@@ -894,12 +895,15 @@ vm_map_wire(vm_map_t map, vm_offset_t start, vm_offset_t end, int flags)
/* Provided custom for bhyve 'devmem' segment mapping */
int
-vm_segmap_obj(struct vmspace *vms, vm_object_t vmo, struct as *as,
+vm_segmap_obj(vm_object_t vmo, off_t map_off, size_t size, struct as *as,
caddr_t *addrp, uint_t prot, uint_t maxprot, uint_t flags)
{
- const size_t size = vmo->vmo_size;
int err;
+ VERIFY(map_off >= 0);
+ VERIFY(size <= vmo->vmo_size);
+ VERIFY((size + map_off) <= vmo->vmo_size);
+
if (vmo->vmo_type != OBJT_DEFAULT) {
/* Only support default objects for now */
return (ENOTSUP);
@@ -911,7 +915,7 @@ vm_segmap_obj(struct vmspace *vms, vm_object_t vmo, struct as *as,
if (err == 0) {
segvmm_crargs_t svma;
- svma.kaddr = vmo->vmo_data;
+ svma.kaddr = (caddr_t)vmo->vmo_data + map_off;
svma.prot = prot;
svma.cookie = vmo;
svma.hold = (segvmm_holdfn_t)vm_object_reference;