cregit-Linux how code gets into the kernel

Release 4.15 kernel/panic.c

Directory: kernel
 *  linux/kernel/panic.c
 *  Copyright (C) 1991, 1992  Linus Torvalds

 * This function is used through-out the kernel (including mm and fs)
 * to indicate a major problem.
#include <linux/debug_locks.h>
#include <linux/sched/debug.h>
#include <linux/interrupt.h>
#include <linux/kmsg_dump.h>
#include <linux/kallsyms.h>
#include <linux/notifier.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/ftrace.h>
#include <linux/reboot.h>
#include <linux/delay.h>
#include <linux/kexec.h>
#include <linux/sched.h>
#include <linux/sysrq.h>
#include <linux/init.h>
#include <linux/nmi.h>
#include <linux/console.h>
#include <linux/bug.h>
#include <linux/ratelimit.h>
#include <linux/debugfs.h>
#include <asm/sections.h>

#define PANIC_TIMER_STEP 100

#define PANIC_BLINK_SPD 18

int panic_on_oops = CONFIG_PANIC_ON_OOPS_VALUE;

static unsigned long tainted_mask;

static int pause_on_oops;

static int pause_on_oops_flag;
static DEFINE_SPINLOCK(pause_on_oops_lock);

bool crash_kexec_post_notifiers;

int panic_on_warn __read_mostly;

int panic_timeout = CONFIG_PANIC_TIMEOUT;




static long no_blink(int state) { return 0; }


Tamuki Shoichi12100.00%1100.00%

/* Returns how long it waited in ms */ long (*panic_blink)(int state); EXPORT_SYMBOL(panic_blink); /* * Stop ourself in panic -- architecture code may override this */
void __weak panic_smp_self_stop(void) { while (1) cpu_relax(); }


Michael Holzheu15100.00%1100.00%

/* * Stop ourselves in NMI context if another CPU has already panicked. Arch code * may override this to prepare for crash dumping, e.g. save regs info. */
void __weak nmi_panic_self_stop(struct pt_regs *regs) { panic_smp_self_stop(); }


Hidehiro Kawai14100.00%1100.00%

/* * Stop other CPUs in panic. Architecture dependent code may override this * with more suitable version. For example, if the architecture supports * crash dump, it should save registers of each stopped CPU and disable * per-CPU features such as virtualization extensions. */
void __weak crash_smp_send_stop(void) { static int cpus_stopped; /* * This function can be called twice in panic path, but obviously * we execute this only once. */ if (cpus_stopped) return; /* * Note smp_send_stop is the usual smp shutdown function, which * unfortunately means it may not be hardened to work in a panic * situation. */ smp_send_stop(); cpus_stopped = 1; }


Hidehiro Kawai26100.00%1100.00%

atomic_t panic_cpu = ATOMIC_INIT(PANIC_CPU_INVALID); /* * A variant of panic() called from NMI context. We return if we've already * panicked on this CPU. If another CPU already panicked, loop in * nmi_panic_self_stop() which can provide architecture dependent code such * as saving register state for crash dump. */
void nmi_panic(struct pt_regs *regs, const char *msg) { int old_cpu, cpu; cpu = raw_smp_processor_id(); old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, cpu); if (old_cpu == PANIC_CPU_INVALID) panic("%s", msg); else if (old_cpu != cpu) nmi_panic_self_stop(regs); }


Hidehiro Kawai62100.00%1100.00%

EXPORT_SYMBOL(nmi_panic); /** * panic - halt the system * @fmt: The text string to print * * Display a message, then perform cleanups. * * This function never returns. */
void panic(const char *fmt, ...) { static char buf[1024]; va_list args; long i, i_next = 0; int state = 0; int old_cpu, this_cpu; bool _crash_kexec_post_notifiers = crash_kexec_post_notifiers; /* * Disable local interrupts. This will prevent panic_smp_self_stop * from deadlocking the first cpu that invokes the panic, since * there is nothing to prevent an interrupt handler (that runs * after setting panic_cpu) from invoking panic() again. */ local_irq_disable(); /* * It's possible to come here directly from a panic-assertion and * not have preempt disabled. Some functions called from here want * preempt to be disabled. No point enabling it later though... * * Only one CPU is allowed to execute the panic code from here. For * multiple parallel invocations of panic, all other CPUs either * stop themself or will wait until they are stopped by the 1st CPU * with smp_send_stop(). * * `old_cpu == PANIC_CPU_INVALID' means this is the 1st CPU which * comes here, so go ahead. * `old_cpu == this_cpu' means we came from nmi_panic() which sets * panic_cpu to this CPU. In this case, this is also the 1st CPU. */ this_cpu = raw_smp_processor_id(); old_cpu = atomic_cmpxchg(&panic_cpu, PANIC_CPU_INVALID, this_cpu); if (old_cpu != PANIC_CPU_INVALID && old_cpu != this_cpu) panic_smp_self_stop(); console_verbose(); bust_spinlocks(1); va_start(args, fmt); vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); pr_emerg("Kernel panic - not syncing: %s\n", buf); #ifdef CONFIG_DEBUG_BUGVERBOSE /* * Avoid nested stack-dumping if a panic occurs during oops processing */ if (!test_taint(TAINT_DIE) && oops_in_progress <= 1) dump_stack(); #endif /* * If we have crashed and we have a crash kernel loaded let it handle * everything else. * If we want to run this after calling panic_notifiers, pass * the "crash_kexec_post_notifiers" option to the kernel. * * Bypass the panic_cpu check and call __crash_kexec directly. */ if (!_crash_kexec_post_notifiers) { printk_safe_flush_on_panic(); __crash_kexec(NULL); /* * Note smp_send_stop is the usual smp shutdown function, which * unfortunately means it may not be hardened to work in a * panic situation. */ smp_send_stop(); } else { /* * If we want to do crash dump after notifier calls and * kmsg_dump, we will need architecture dependent extra * works in addition to stopping other CPUs. */ crash_smp_send_stop(); } /* * Run any panic handlers, including those that might need to * add information to the kmsg dump output. */ atomic_notifier_call_chain(&panic_notifier_list, 0, buf); /* Call flush even twice. It tries harder with a single online CPU */ printk_safe_flush_on_panic(); kmsg_dump(KMSG_DUMP_PANIC); /* * If you doubt kdump always works fine in any situation, * "crash_kexec_post_notifiers" offers you a chance to run * panic_notifiers and dumping kmsg before kdump. * Note: since some panic_notifiers can make crashed kernel * more unstable, it can increase risks of the kdump failure too. * * Bypass the panic_cpu check and call __crash_kexec directly. */ if (_crash_kexec_post_notifiers) __crash_kexec(NULL); bust_spinlocks(0); /* * We may have ended up stopping the CPU holding the lock (in * smp_send_stop()) while still having some valuable data in the console * buffer. Try to acquire the lock then release it regardless of the * result. The release will also print the buffers out. Locks debug * should be disabled to avoid reporting bad unlock balance when * panic() is not being callled from OOPS. */ debug_locks_off(); console_flush_on_panic(); if (!panic_blink) panic_blink = no_blink; if (panic_timeout > 0) { /* * Delay timeout seconds before rebooting the machine. * We can't use the "normal" timers since we just panicked. */ pr_emerg("Rebooting in %d seconds..\n", panic_timeout); for (i = 0; i < panic_timeout * 1000; i += PANIC_TIMER_STEP) { touch_nmi_watchdog(); if (i >= i_next) { i += panic_blink(state ^= 1); i_next = i + 3600 / PANIC_BLINK_SPD; } mdelay(PANIC_TIMER_STEP); } } if (panic_timeout != 0) { /* * This will not be a clean reboot, with everything * shutting down. But if there is a chance of * rebooting the system it will be rebooted. */ emergency_restart(); } #ifdef __sparc__ { extern int stop_a_enabled; /* Make sure the user can actually press Stop-A (L1-A) */ stop_a_enabled = 1; pr_emerg("Press Stop-A (L1-A) from sun keyboard or send break\n" "twice on console to return to the boot prom\n"); } #endif #if defined(CONFIG_S390) { unsigned long caller; caller = (unsigned long)__builtin_return_address(0); disabled_wait(caller); } #endif pr_emerg("---[ end Kernel panic - not syncing: %s\n", buf); local_irq_enable(); for (i = 0; ; i += PANIC_TIMER_STEP) { touch_softlockup_watchdog(); if (i >= i_next) { i += panic_blink(state ^= 1); i_next = i + 3600 / PANIC_BLINK_SPD; } mdelay(PANIC_TIMER_STEP); } }


Linus Torvalds (pre-git)10325.37%816.33%
Tamuki Shoichi9122.41%12.04%
Hidehiro Kawai5012.32%48.16%
Ingo Molnar297.14%36.12%
Andrew Morton225.42%24.08%
Andi Kleen102.46%24.08%
Fabian Frederick102.46%12.04%
Hugh Dickins81.97%12.04%
Masami Hiramatsu81.97%12.04%
Jason Wessel71.72%12.04%
Kees Cook61.48%12.04%
Petr Mladek61.48%12.04%
Vitaly Kuznetsov61.48%24.08%
Linus Torvalds51.23%12.04%
Eric W. Biedermann51.23%24.08%
Michael Holzheu51.23%12.04%
Aaro Koskinen51.23%12.04%
Anton Blanchard40.99%24.08%
Daisuke Hatayama30.74%12.04%
Seiji Aguchi30.74%12.04%
Vikram Mulukutla30.74%12.04%
Alexander Nyberg30.74%12.04%
Jan Beulich30.74%12.04%
Sergey Senozhatsky20.49%12.04%
Vijay Kumar20.49%12.04%
Alan Stern10.25%12.04%
Jiri Slaby10.25%12.04%
Martin Schwidefsky10.25%12.04%
Tejun Heo10.25%12.04%
Tom 'spot' Callaway10.25%12.04%
Christian Bornträger10.25%12.04%
Jeff Dike10.25%12.04%

EXPORT_SYMBOL(panic); /* * TAINT_FORCED_RMMOD could be a per-module flag but the module * is being removed anyway. */ const struct taint_flag taint_flags[TAINT_FLAGS_COUNT] = { { 'P', 'G', true }, /* TAINT_PROPRIETARY_MODULE */ { 'F', ' ', true }, /* TAINT_FORCED_MODULE */ { 'S', ' ', false }, /* TAINT_CPU_OUT_OF_SPEC */ { 'R', ' ', false }, /* TAINT_FORCED_RMMOD */ { 'M', ' ', false }, /* TAINT_MACHINE_CHECK */ { 'B', ' ', false }, /* TAINT_BAD_PAGE */ { 'U', ' ', false }, /* TAINT_USER */ { 'D', ' ', false }, /* TAINT_DIE */ { 'A', ' ', false }, /* TAINT_OVERRIDDEN_ACPI_TABLE */ { 'W', ' ', false }, /* TAINT_WARN */ { 'C', ' ', true }, /* TAINT_CRAP */ { 'I', ' ', false }, /* TAINT_FIRMWARE_WORKAROUND */ { 'O', ' ', true }, /* TAINT_OOT_MODULE */ { 'E', ' ', true }, /* TAINT_UNSIGNED_MODULE */ { 'L', ' ', false }, /* TAINT_SOFTLOCKUP */ { 'K', ' ', true }, /* TAINT_LIVEPATCH */ { 'X', ' ', true }, /* TAINT_AUX */ }; /** * print_tainted - return a string to represent the kernel taint state. * * 'P' - Proprietary module has been loaded. * 'F' - Module has been forcibly loaded. * 'S' - SMP with CPUs not designed for SMP. * 'R' - User forced a module unload. * 'M' - System experienced a machine check exception. * 'B' - System has hit bad_page. * 'U' - Userspace-defined naughtiness. * 'D' - Kernel has oopsed before * 'A' - ACPI table overridden. * 'W' - Taint on warning. * 'C' - modules from drivers/staging are loaded. * 'I' - Working around severe firmware bug. * 'O' - Out-of-tree module has been loaded. * 'E' - Unsigned module has been loaded. * 'L' - A soft lockup has previously occurred. * 'K' - Kernel has been live patched. * 'X' - Auxiliary taint, for distros' use. * * The string is overwritten by the next call to print_tainted(). */
const char *print_tainted(void) { static char buf[TAINT_FLAGS_COUNT + sizeof("Tainted: ")]; if (tainted_mask) { char *s; int i; s = buf + sprintf(buf, "Tainted: "); for (i = 0; i < TAINT_FLAGS_COUNT; i++) { const struct taint_flag *t = &taint_flags[i]; *s++ = test_bit(i, &tainted_mask) ? t->c_true : t->c_false; } *s = 0; } else snprintf(buf, sizeof(buf), "Not tainted"); return buf; }


Andi Kleen8474.34%125.00%
Linus Torvalds2219.47%125.00%
Petr Mladek54.42%125.00%
Larry Finger21.77%125.00%

int test_taint(unsigned flag) { return test_bit(flag, &tainted_mask); }


Andi Kleen17100.00%2100.00%

unsigned long get_taint(void) { return tainted_mask; }


Andi Kleen872.73%150.00%
Andrew Morton327.27%150.00%

/** * add_taint: add a taint flag if not already set. * @flag: one of the TAINT_* constants. * @lockdep_ok: whether lock debugging is still OK. * * If something bad has gone wrong, you'll want @lockdebug_ok = false, but for * some notewortht-but-not-corrupting cases, it can be set to true. */
void add_taint(unsigned flag, enum lockdep_ok lockdep_ok) { if (lockdep_ok == LOCKDEP_NOW_UNRELIABLE && __debug_locks_off()) pr_warn("Disabling lock debugging due to kernel taint\n"); set_bit(flag, &tainted_mask); }


Andi Kleen1132.35%222.22%
Rusty Russell823.53%111.11%
Andrew Morton514.71%111.11%
Frédéric Weisbecker514.71%111.11%
Peter Zijlstra25.88%111.11%
Fabian Frederick12.94%111.11%
Ingo Molnar12.94%111.11%
Arjan van de Ven12.94%111.11%

static void spin_msec(int msecs) { int i; for (i = 0; i < msecs; i++) { touch_nmi_watchdog(); mdelay(1); } }


Andrew Morton35100.00%1100.00%

/* * It just happens that oops_enter() and oops_exit() are identically * implemented... */
static void do_oops_enter_exit(void) { unsigned long flags; static int spin_counter; if (!pause_on_oops) return; spin_lock_irqsave(&pause_on_oops_lock, flags); if (pause_on_oops_flag == 0) { /* This CPU may now print the oops message */ pause_on_oops_flag = 1; } else { /* We need to stall this CPU */ if (!spin_counter) { /* This CPU gets to do the counting */ spin_counter = pause_on_oops; do { spin_unlock(&pause_on_oops_lock); spin_msec(MSEC_PER_SEC); spin_lock(&pause_on_oops_lock); } while (--spin_counter); pause_on_oops_flag = 0; } else { /* This CPU waits for a different one */ while (spin_counter) { spin_unlock(&pause_on_oops_lock); spin_msec(1); spin_lock(&pause_on_oops_lock); } } } spin_unlock_irqrestore(&pause_on_oops_lock, flags); }


Andrew Morton124100.00%1100.00%

/* * Return true if the calling CPU is allowed to print oops-related info. * This is a bit racy.. */
int oops_may_print(void) { return pause_on_oops_flag == 0; }


Andrew Morton12100.00%1100.00%

/* * Called when the architecture enters its oops handler, before it prints * anything. If this is the first CPU to oops, and it's oopsing the first * time then let it proceed. * * This is all enabled by the pause_on_oops kernel boot option. We do all * this to ensure that oopses don't scroll off the screen. It has the * side-effect of preventing later-oopsing CPUs from mucking up the display, * too. * * It turns out that the CPU which is allowed to print ends up pausing for * the right duration, whereas all the other CPUs pause for twice as long: * once in oops_enter(), once in oops_exit(). */
void oops_enter(void) { tracing_off(); /* can't trust the integrity of the kernel anymore: */ debug_locks_off(); do_oops_enter_exit(); }


Andrew Morton1058.82%125.00%
Thomas Gleixner317.65%125.00%
Arjan van de Ven317.65%125.00%
Ingo Molnar15.88%125.00%

/* * 64-bit random ID for oopses: */ static u64 oops_id;
static int init_oops_id(void) { if (!oops_id) get_random_bytes(&oops_id, sizeof(oops_id)); else oops_id++; return 0; }


Arjan van de Ven31100.00%2100.00%

void print_oops_end_marker(void) { init_oops_id(); pr_warn("---[ end trace %016llx ]---\n", (unsigned long long)oops_id); }


Arjan van de Ven1568.18%250.00%
Andrew Morton627.27%125.00%
Fabian Frederick14.55%125.00%

/* * Called when the architecture exits its oops handler, after printing * everything. */
void oops_exit(void) { do_oops_enter_exit(); print_oops_end_marker(); kmsg_dump(KMSG_DUMP_OOPS); }


Arjan van de Ven1372.22%150.00%
Simon Kågström527.78%150.00%

struct warn_args { const char *fmt; va_list args; };
void __warn(const char *file, int line, void *caller, unsigned taint, struct pt_regs *regs, struct warn_args *args) { disable_trace_on_warning(); if (args) pr_warn(CUT_HERE); if (file) pr_warn("WARNING: CPU: %d PID: %d at %s:%d %pS\n", raw_smp_processor_id(), current->pid, file, line, caller); else pr_warn("WARNING: CPU: %d PID: %d at %pS\n", raw_smp_processor_id(), current->pid, caller); if (args) vprintk(args->fmt, args->args); if (panic_on_warn) { /* * This thread may hit another WARN() in the panic path. * Resetting this prevents additional WARN() from panicking the * system on this thread. Other threads are blocked by the * panic_mutex in panic(). */ panic_on_warn = 0; panic("panic_on_warn set ...\n"); } print_modules(); if (regs) show_regs(regs); else dump_stack(); print_oops_end_marker(); /* Just a warning, don't kill lockdep. */ add_taint(taint, LOCKDEP_STILL_OK); }


Arjan van de Ven5036.50%218.18%
Josh Poimboeuf3727.01%19.09%
Prarit Bhargava1611.68%19.09%
Linus Torvalds107.30%19.09%
Alex Thorlton96.57%19.09%
Kees Cook53.65%218.18%
Ben Hutchings42.92%19.09%
Steven Rostedt32.19%19.09%
Rusty Russell32.19%19.09%

void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) { struct warn_args args; args.fmt = fmt; va_start(args.args, fmt); __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, &args); va_end(args.args); }


Linus Torvalds5990.77%133.33%
Josh Poimboeuf46.15%133.33%
Ben Hutchings23.08%133.33%

void warn_slowpath_fmt_taint(const char *file, int line, unsigned taint, const char *fmt, ...) { struct warn_args args; args.fmt = fmt; va_start(args.args, fmt); __warn(file, line, __builtin_return_address(0), taint, NULL, &args); va_end(args.args); }


Ben Hutchings6494.12%150.00%
Josh Poimboeuf45.88%150.00%

void warn_slowpath_null(const char *file, int line) { pr_warn(CUT_HERE); __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL); }


Andi Kleen2055.56%120.00%
Linus Torvalds616.67%120.00%
Kees Cook513.89%120.00%
Josh Poimboeuf38.33%120.00%
Ben Hutchings25.56%120.00%

EXPORT_SYMBOL(warn_slowpath_null); #else
void __warn_printk(const char *fmt, ...) { va_list args; pr_warn(CUT_HERE); va_start(args, fmt); vprintk(fmt, args); va_end(args); }


Kees Cook39100.00%1100.00%

EXPORT_SYMBOL(__warn_printk); #endif #ifdef CONFIG_BUG /* Support resetting WARN*_ONCE state */
static int clear_warn_once_set(void *data, u64 val) { generic_bug_clear_once(); memset(__start_once, 0, __end_once - __start_once); return 0; }


Andi Kleen30100.00%2100.00%

DEFINE_SIMPLE_ATTRIBUTE(clear_warn_once_fops, NULL, clear_warn_once_set, "%lld\n");
static __init int register_warn_debugfs(void) { /* Don't care about failure */ debugfs_create_file("clear_warn_once", 0200, NULL, NULL, &clear_warn_once_fops); return 0; }


Andi Kleen27100.00%2100.00%

device_initcall(register_warn_debugfs); #endif #ifdef CONFIG_CC_STACKPROTECTOR /* * Called when gcc's -fstack-protector feature is used, and * gcc detects corruption of the on-stack canary value */
__visible void __stack_chk_fail(void) { panic("stack-protector: Kernel stack is corrupted in: %p\n", __builtin_return_address(0)); }


Arjan van de Ven1161.11%133.33%
Ingo Molnar633.33%133.33%
Andi Kleen15.56%133.33%

EXPORT_SYMBOL(__stack_chk_fail); #endif #ifdef CONFIG_ARCH_HAS_REFCOUNT
void refcount_error_report(struct pt_regs *regs, const char *err) { WARN_RATELIMIT(1, "refcount_t %s at %pB in %s[%d], uid/euid: %u/%u\n", err, (void *)instruction_pointer(regs), current->comm, task_pid_nr(current), from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid())); }


Kees Cook60100.00%1100.00%

#endif core_param(panic, panic_timeout, int, 0644); core_param(pause_on_oops, pause_on_oops, int, 0644); core_param(panic_on_warn, panic_on_warn, int, 0644); core_param(crash_kexec_post_notifiers, crash_kexec_post_notifiers, bool, 0644);
static int __init oops_setup(char *s) { if (!s) return -EINVAL; if (!strcmp(s, "panic")) panic_on_oops = 1; return 0; }


Olaf Hering37100.00%1100.00%

early_param("oops", oops_setup);

Overall Contributors

Andi Kleen31215.85%86.96%
Andrew Morton24412.39%43.48%
Hidehiro Kawai1758.89%65.22%
Arjan van de Ven1567.92%86.96%
Kees Cook1306.60%43.48%
Linus Torvalds1236.25%43.48%
Linus Torvalds (pre-git)1226.20%1311.30%
Tamuki Shoichi1135.74%10.87%
Ben Hutchings894.52%32.61%
Petr Mladek673.40%21.74%
Ingo Molnar552.79%65.22%
Josh Poimboeuf552.79%10.87%
Olaf Hering442.23%10.87%
Rusty Russell351.78%32.61%
Prarit Bhargava311.57%10.87%
Michael Holzheu211.07%10.87%
Masami Hiramatsu150.76%10.87%
Arnaldo Carvalho de Melo120.61%10.87%
Fabian Frederick120.61%10.87%
Borislav Petkov100.51%10.87%
Vitaly Kuznetsov90.46%21.74%
Alex Thorlton90.46%10.87%
Hugh Dickins80.41%10.87%
Simon Kågström80.41%10.87%
Eric W. Biedermann70.36%21.74%
Jason Wessel70.36%10.87%
Seth Jennings60.30%10.87%
Joshua Hunt60.30%10.87%
Steven Rostedt60.30%10.87%
Alan Stern50.25%10.87%
Frédéric Weisbecker50.25%10.87%
Huang Ying50.25%10.87%
Mathieu Desnoyers50.25%10.87%
Aaro Koskinen50.25%10.87%
Nicholas Piggin40.20%21.74%
Anton Blanchard40.20%21.74%
Seiji Aguchi30.15%10.87%
Nur Hussein30.15%10.87%
Daisuke Hatayama30.15%10.87%
Vikram Mulukutla30.15%10.87%
Thomas Gleixner30.15%10.87%
Jan Beulich30.15%10.87%
Alexander Nyberg30.15%10.87%
Theodore Y. Ts'o20.10%10.87%
Kyle McMartin20.10%10.87%
Pavel Emelyanov20.10%10.87%
Peter Zijlstra20.10%10.87%
Jason Baron20.10%10.87%
Sergey Senozhatsky20.10%10.87%
Éric Piel20.10%10.87%
Vijay Kumar20.10%10.87%
Larry Finger20.10%10.87%
Dave Jones20.10%10.87%
Martin Schwidefsky10.05%10.87%
Tejun Heo10.05%10.87%
Jiri Slaby10.05%10.87%
Heiko Carstens10.05%10.87%
Tom 'spot' Callaway10.05%10.87%
Greg Kroah-Hartman10.05%10.87%
Jeff Dike10.05%10.87%
Christian Bornträger10.05%10.87%
Directory: kernel
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.