Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.10.11.
 1// SPDX-License-Identifier: GPL-2.0
 2#include <linux/err.h>
 3#include <linux/mm.h>
 4#include <asm/current.h>
 5#include <asm/traps.h>
 6#include <asm/vdso.h>
 7
 8struct vdso_exception_table_entry {
 9	int insn, fixup;
10};
11
12bool fixup_vdso_exception(struct pt_regs *regs, int trapnr,
13			  unsigned long error_code, unsigned long fault_addr)
14{
15	const struct vdso_image *image = current->mm->context.vdso_image;
16	const struct vdso_exception_table_entry *extable;
17	unsigned int nr_entries, i;
18	unsigned long base;
19
20	/*
21	 * Do not attempt to fixup #DB or #BP.  It's impossible to identify
22	 * whether or not a #DB/#BP originated from within an SGX enclave and
23	 * SGX enclaves are currently the only use case for vDSO fixup.
24	 */
25	if (trapnr == X86_TRAP_DB || trapnr == X86_TRAP_BP)
26		return false;
27
28	if (!current->mm->context.vdso)
29		return false;
30
31	base =  (unsigned long)current->mm->context.vdso + image->extable_base;
32	nr_entries = image->extable_len / (sizeof(*extable));
33	extable = image->extable;
34
35	for (i = 0; i < nr_entries; i++) {
36		if (regs->ip == base + extable[i].insn) {
37			regs->ip = base + extable[i].fixup;
38			regs->di = trapnr;
39			regs->si = error_code;
40			regs->dx = fault_addr;
41			return true;
42		}
43	}
44
45	return false;
46}