drm/rockchip: vop2: Fix the windows switch between different layers
[drm/drm-misc.git] / arch / x86 / entry / vdso / extable.c
blobafcf5b65beef7e716506851360d932cc0b774ad7
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>
8 struct vdso_exception_table_entry {
9 int insn, fixup;
12 bool fixup_vdso_exception(struct pt_regs *regs, int trapnr,
13 unsigned long error_code, unsigned long fault_addr)
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;
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.
25 if (trapnr == X86_TRAP_DB || trapnr == X86_TRAP_BP)
26 return false;
28 if (!current->mm->context.vdso)
29 return false;
31 base = (unsigned long)current->mm->context.vdso + image->extable_base;
32 nr_entries = image->extable_len / (sizeof(*extable));
33 extable = image->extable;
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;
45 return false;