Module Name: src
Committed By: maxv
Date: Sun Jun 7 09:45:20 UTC 2020
Modified Files:
src/etc: MAKEDEV.tmpl
src/sys/arch/amd64/conf: ALL GENERIC
src/sys/conf: files majors
src/sys/kern: files.kern subr_pool.c
Added Files:
src/sys/kern: subr_fault.c
src/sys/sys: fault.h
Log Message:
Add fault(4).
To generate a diff of this commit:
cvs rdiff -u -r1.219 -r1.220 src/etc/MAKEDEV.tmpl
cvs rdiff -u -r1.152 -r1.153 src/sys/arch/amd64/conf/ALL
cvs rdiff -u -r1.568 -r1.569 src/sys/arch/amd64/conf/GENERIC
cvs rdiff -u -r1.1267 -r1.1268 src/sys/conf/files
cvs rdiff -u -r1.93 -r1.94 src/sys/conf/majors
cvs rdiff -u -r1.48 -r1.49 src/sys/kern/files.kern
cvs rdiff -u -r0 -r1.1 src/sys/kern/subr_fault.c
cvs rdiff -u -r1.269 -r1.270 src/sys/kern/subr_pool.c
cvs rdiff -u -r0 -r1.1 src/sys/sys/fault.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/etc/MAKEDEV.tmpl
diff -u src/etc/MAKEDEV.tmpl:1.219 src/etc/MAKEDEV.tmpl:1.220
--- src/etc/MAKEDEV.tmpl:1.219 Fri Jun 5 17:20:56 2020
+++ src/etc/MAKEDEV.tmpl Sun Jun 7 09:45:19 2020
@@ -1,5 +1,5 @@
#!/bin/sh -
-# $NetBSD: MAKEDEV.tmpl,v 1.219 2020/06/05 17:20:56 maxv Exp $
+# $NetBSD: MAKEDEV.tmpl,v 1.220 2020/06/07 09:45:19 maxv Exp $
#
# Copyright (c) 2003,2007,2008 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -1761,6 +1761,10 @@ vio9p[0-9]*)
mkdev vio9p$unit c %vio9p_chr% $unit 660
;;
+fault)
+ mkdev fault c %fault_chr% 0
+ ;;
+
nvram)
mkdev nvram c %nvram_chr% 0 644
;;
Index: src/sys/arch/amd64/conf/ALL
diff -u src/sys/arch/amd64/conf/ALL:1.152 src/sys/arch/amd64/conf/ALL:1.153
--- src/sys/arch/amd64/conf/ALL:1.152 Sat May 30 13:35:31 2020
+++ src/sys/arch/amd64/conf/ALL Sun Jun 7 09:45:19 2020
@@ -1,4 +1,4 @@
-# $NetBSD: ALL,v 1.152 2020/05/30 13:35:31 jdolecek Exp $
+# $NetBSD: ALL,v 1.153 2020/06/07 09:45:19 maxv Exp $
# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
#
# ALL machine description file
@@ -17,7 +17,7 @@ include "arch/amd64/conf/std.amd64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
-#ident "ALL-$Revision: 1.152 $"
+#ident "ALL-$Revision: 1.153 $"
maxusers 64 # estimated number of users
@@ -137,6 +137,9 @@ options KASAN
makeoptions KCOV=1
options KCOV
+# Fault Injection Driver.
+options FAULT
+
# Compatibility options
options EXEC_AOUT # required by binaries from before 1.5
options COMPAT_386BSD_MBRPART # recognize old partition ID
Index: src/sys/arch/amd64/conf/GENERIC
diff -u src/sys/arch/amd64/conf/GENERIC:1.568 src/sys/arch/amd64/conf/GENERIC:1.569
--- src/sys/arch/amd64/conf/GENERIC:1.568 Sat May 16 18:31:48 2020
+++ src/sys/arch/amd64/conf/GENERIC Sun Jun 7 09:45:19 2020
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.568 2020/05/16 18:31:48 christos Exp $
+# $NetBSD: GENERIC,v 1.569 2020/06/07 09:45:19 maxv Exp $
#
# GENERIC machine description file
#
@@ -22,7 +22,7 @@ include "arch/amd64/conf/std.amd64"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
-#ident "GENERIC-$Revision: 1.568 $"
+#ident "GENERIC-$Revision: 1.569 $"
maxusers 64 # estimated number of users
@@ -158,6 +158,9 @@ options KDTRACE_HOOKS # kernel DTrace h
#makeoptions KCOV=1
#options KCOV
+# Fault Injection Driver.
+#options FAULT
+
# Compatibility options
# x86_64 never shipped with a.out binaries; the two options below are
# only relevant to 32-bit i386 binaries
Index: src/sys/conf/files
diff -u src/sys/conf/files:1.1267 src/sys/conf/files:1.1268
--- src/sys/conf/files:1.1267 Wed May 20 09:18:25 2020
+++ src/sys/conf/files Sun Jun 7 09:45:19 2020
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.1267 2020/05/20 09:18:25 hkenken Exp $
+# $NetBSD: files,v 1.1268 2020/06/07 09:45:19 maxv Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20171118
@@ -38,6 +38,7 @@ defflag opt_kmsan.h KMSAN_PANIC
defflag KCOV
defflag opt_pool.h POOL_QUARANTINE
defflag opt_pool.h POOL_NOCACHE
+defflag FAULT
defparam opt_copy_symtab.h makeoptions_COPY_SYMTAB
Index: src/sys/conf/majors
diff -u src/sys/conf/majors:1.93 src/sys/conf/majors:1.94
--- src/sys/conf/majors:1.93 Sun Jan 19 20:41:18 2020
+++ src/sys/conf/majors Sun Jun 7 09:45:19 2020
@@ -1,4 +1,4 @@
-# $NetBSD: majors,v 1.93 2020/01/19 20:41:18 riastradh Exp $
+# $NetBSD: majors,v 1.94 2020/06/07 09:45:19 maxv Exp $
#
# Device majors for Machine-Independent drivers.
#
@@ -88,3 +88,4 @@ device-major spi char 347 spi
device-major ipmi char 354 ipmi
device-major vhci char 355 vhci
device-major vio9p char 356 vio9p
+device-major fault char 357 fault
Index: src/sys/kern/files.kern
diff -u src/sys/kern/files.kern:1.48 src/sys/kern/files.kern:1.49
--- src/sys/kern/files.kern:1.48 Sat May 16 18:31:50 2020
+++ src/sys/kern/files.kern Sun Jun 7 09:45:19 2020
@@ -1,4 +1,4 @@
-# $NetBSD: files.kern,v 1.48 2020/05/16 18:31:50 christos Exp $
+# $NetBSD: files.kern,v 1.49 2020/06/07 09:45:19 maxv Exp $
#
# kernel sources
@@ -118,6 +118,7 @@ file kern/subr_emul.c kern
file kern/subr_evcnt.c kern
file kern/subr_exec_fd.c kern
file kern/subr_extent.c kern
+file kern/subr_fault.c fault
file kern/subr_hash.c kern
file kern/subr_humanize.c kern
file kern/subr_interrupt.c kern
Index: src/sys/kern/subr_pool.c
diff -u src/sys/kern/subr_pool.c:1.269 src/sys/kern/subr_pool.c:1.270
--- src/sys/kern/subr_pool.c:1.269 Sat Jun 6 06:42:54 2020
+++ src/sys/kern/subr_pool.c Sun Jun 7 09:45:19 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_pool.c,v 1.269 2020/06/06 06:42:54 maxv Exp $ */
+/* $NetBSD: subr_pool.c,v 1.270 2020/06/07 09:45:19 maxv Exp $ */
/*
* Copyright (c) 1997, 1999, 2000, 2002, 2007, 2008, 2010, 2014, 2015, 2018
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.269 2020/06/06 06:42:54 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.270 2020/06/07 09:45:19 maxv Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@@ -58,6 +58,7 @@ __KERNEL_RCSID(0, "$NetBSD: subr_pool.c,
#include <sys/atomic.h>
#include <sys/asan.h>
#include <sys/msan.h>
+#include <sys/fault.h>
#include <uvm/uvm_extern.h>
@@ -1056,6 +1057,11 @@ pool_get(struct pool *pp, int flags)
ASSERT_SLEEPABLE();
}
+ if (flags & PR_NOWAIT) {
+ if (fault_inject())
+ return NULL;
+ }
+
mutex_enter(&pp->pr_lock);
startover:
/*
@@ -2533,6 +2539,11 @@ pool_cache_get_paddr(pool_cache_t pc, in
ASSERT_SLEEPABLE();
}
+ if (flags & PR_NOWAIT) {
+ if (fault_inject())
+ return NULL;
+ }
+
/* Lock out interrupts and disable preemption. */
s = splvm();
while (/* CONSTCOND */ true) {
Added files:
Index: src/sys/kern/subr_fault.c
diff -u /dev/null src/sys/kern/subr_fault.c:1.1
--- /dev/null Sun Jun 7 09:45:20 2020
+++ src/sys/kern/subr_fault.c Sun Jun 7 09:45:19 2020
@@ -0,0 +1,271 @@
+/* $NetBSD: subr_fault.c,v 1.1 2020/06/07 09:45:19 maxv Exp $ */
+
+/*
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Maxime Villard.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: subr_fault.c,v 1.1 2020/06/07 09:45:19 maxv Exp $");
+
+#include <sys/module.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+
+#include <sys/conf.h>
+#include <sys/types.h>
+#include <sys/specificdata.h>
+#include <sys/kmem.h>
+#include <sys/atomic.h>
+#include <sys/ioccom.h>
+#include <sys/lwp.h>
+#include <sys/fault.h>
+
+typedef struct {
+ volatile bool enabled;
+ volatile unsigned long nth;
+ volatile unsigned long cnt;
+ volatile unsigned long nfaults;
+} fault_t;
+
+static fault_t fault_global __cacheline_aligned = {
+ .enabled = false,
+ .nth = 2,
+ .cnt = 0,
+ .nfaults = 0
+};
+
+static kmutex_t fault_global_lock __cacheline_aligned;
+static specificdata_key_t fault_lwp_key;
+
+/* -------------------------------------------------------------------------- */
+
+bool
+fault_inject(void)
+{
+ volatile unsigned long cnt;
+ fault_t *f;
+
+ if (__predict_false(cold))
+ return false;
+
+ if (__predict_false(atomic_load_acquire(&fault_global.enabled))) {
+ f = &fault_global;
+ } else {
+ f = lwp_getspecific(fault_lwp_key);
+ if (__predict_true(f == NULL))
+ return false;
+ if (__predict_false(!f->enabled))
+ return false;
+ }
+
+ cnt = atomic_inc_ulong_nv(&f->cnt);
+ if (__predict_false(cnt % atomic_load_relaxed(&f->nth) == 0)) {
+ atomic_inc_ulong(&f->nfaults);
+ return true;
+ }
+
+ return false;
+}
+
+/* -------------------------------------------------------------------------- */
+
+static int
+fault_open(dev_t dev, int flag, int mode, struct lwp *l)
+{
+ return 0;
+}
+
+static int
+fault_close(dev_t dev, int flag, int mode, struct lwp *l)
+{
+ return 0;
+}
+
+static int
+fault_ioc_enable(struct fault_ioc_enable *args)
+{
+ fault_t *f;
+
+ if (args->mode != FAULT_MODE_NTH)
+ return EINVAL;
+ if (args->nth < 2)
+ return EINVAL;
+
+ switch (args->scope) {
+ case FAULT_SCOPE_GLOBAL:
+ mutex_enter(&fault_global_lock);
+ if (fault_global.enabled) {
+ mutex_exit(&fault_global_lock);
+ return EEXIST;
+ }
+ atomic_store_relaxed(&fault_global.nth, args->nth);
+ fault_global.cnt = 0;
+ fault_global.nfaults = 0;
+ atomic_store_release(&fault_global.enabled, true);
+ mutex_exit(&fault_global_lock);
+ break;
+ case FAULT_SCOPE_LWP:
+ f = lwp_getspecific(fault_lwp_key);
+ if (f != NULL) {
+ if (f->enabled)
+ return EEXIST;
+ } else {
+ f = kmem_zalloc(sizeof(*f), KM_SLEEP);
+ lwp_setspecific(fault_lwp_key, f);
+ }
+ atomic_store_relaxed(&f->nth, args->nth);
+ f->cnt = 0;
+ f->nfaults = 0;
+ atomic_store_release(&f->enabled, true);
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+fault_ioc_disable(struct fault_ioc_disable *args)
+{
+ fault_t *f;
+
+ switch (args->scope) {
+ case FAULT_SCOPE_GLOBAL:
+ mutex_enter(&fault_global_lock);
+ if (!fault_global.enabled) {
+ mutex_exit(&fault_global_lock);
+ return ENOENT;
+ }
+ atomic_store_release(&fault_global.enabled, false);
+ mutex_exit(&fault_global_lock);
+ break;
+ case FAULT_SCOPE_LWP:
+ f = lwp_getspecific(fault_lwp_key);
+ if (f == NULL)
+ return ENOENT;
+ if (!f->enabled)
+ return ENOENT;
+ atomic_store_release(&f->enabled, false);
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+fault_ioc_getinfo(struct fault_ioc_getinfo *args)
+{
+ fault_t *f;
+
+ switch (args->scope) {
+ case FAULT_SCOPE_GLOBAL:
+ args->nfaults = atomic_load_relaxed(&fault_global.nfaults);
+ break;
+ case FAULT_SCOPE_LWP:
+ f = lwp_getspecific(fault_lwp_key);
+ if (f == NULL)
+ return ENOENT;
+ args->nfaults = atomic_load_relaxed(&f->nfaults);
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+fault_ioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
+{
+ switch (cmd) {
+ case FAULT_IOC_ENABLE:
+ return fault_ioc_enable(addr);
+ case FAULT_IOC_DISABLE:
+ return fault_ioc_disable(addr);
+ case FAULT_IOC_GETINFO:
+ return fault_ioc_getinfo(addr);
+ default:
+ return EINVAL;
+ }
+}
+
+const struct cdevsw fault_cdevsw = {
+ .d_open = fault_open,
+ .d_close = fault_close,
+ .d_read = noread,
+ .d_write = nowrite,
+ .d_ioctl = fault_ioctl,
+ .d_stop = nostop,
+ .d_tty = notty,
+ .d_poll = nopoll,
+ .d_mmap = nommap,
+ .d_kqfilter = nokqfilter,
+ .d_discard = nodiscard,
+ .d_flag = D_OTHER | D_MPSAFE
+};
+
+/* -------------------------------------------------------------------------- */
+
+MODULE(MODULE_CLASS_MISC, fault, NULL);
+
+static void
+fault_lwp_free(void *arg)
+{
+ fault_t *f = (fault_t *)arg;
+
+ if (f == NULL) {
+ return;
+ }
+
+ kmem_free(f, sizeof(*f));
+}
+
+static void
+fault_init(void)
+{
+ mutex_init(&fault_global_lock, MUTEX_DEFAULT, IPL_NONE);
+ lwp_specific_key_create(&fault_lwp_key, fault_lwp_free);
+}
+
+static int
+fault_modcmd(modcmd_t cmd, void *arg)
+{
+ switch (cmd) {
+ case MODULE_CMD_INIT:
+ fault_init();
+ return 0;
+ case MODULE_CMD_FINI:
+ return EINVAL;
+ default:
+ return ENOTTY;
+ }
+}
Index: src/sys/sys/fault.h
diff -u /dev/null src/sys/sys/fault.h:1.1
--- /dev/null Sun Jun 7 09:45:20 2020
+++ src/sys/sys/fault.h Sun Jun 7 09:45:19 2020
@@ -0,0 +1,77 @@
+/* $NetBSD: fault.h,v 1.1 2020/06/07 09:45:19 maxv Exp $ */
+
+/*
+ * Copyright (c) 2020 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Maxime Villard.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_FAULT_H_
+#define _SYS_FAULT_H_
+
+#ifdef _KERNEL_OPT
+#include "opt_fault.h"
+#endif
+
+#if !defined(_KERNEL) || defined(FAULT)
+
+#define FAULT_SCOPE_GLOBAL 0
+#define FAULT_SCOPE_LWP 1
+
+#define FAULT_MODE_NTH 0
+
+struct fault_ioc_enable {
+ int scope;
+ int mode;
+ union {
+ unsigned long nth;
+ };
+};
+
+struct fault_ioc_disable {
+ int scope;
+};
+
+struct fault_ioc_getinfo {
+ int scope;
+ unsigned long nfaults;
+};
+
+#define FAULT_IOC_ENABLE _IOW ('F', 1, struct fault_ioc_enable)
+#define FAULT_IOC_DISABLE _IOW ('F', 2, struct fault_ioc_disable)
+#define FAULT_IOC_GETINFO _IOWR('F', 3, struct fault_ioc_getinfo)
+
+#endif /* !_KERNEL || FAULT */
+
+#ifdef _KERNEL
+#ifdef FAULT
+bool fault_inject(void);
+#else
+#define fault_inject() false
+#endif
+#endif /* _KERNEL */
+
+#endif /* !_SYS_FAULT_H_ */