x86/mm: Expand the exception table logic to allow new handling options
Huge amounts of help from Andy Lutomirski and Borislav Petkov to produce this. Andy provided the inspiration to add classes to the exception table with a clever bit-squeezing trick, Boris pointed out how much cleaner it would all be if we just had a new field. Linus Torvalds blessed the expansion with: ' I'd rather not be clever in order to save just a tiny amount of space in the exception table, which isn't really criticial for anybody. ' The third field is another relative function pointer, this one to a handler that executes the actions. We start out with three handlers: 1: Legacy - just jumps the to fixup IP 2: Fault - provide the trap number in %ax to the fixup code 3: Cleaned up legacy for the uaccess error hack Signed-off-by: Tony Luck <tony.luck@intel.com> Reviewed-by: Borislav Petkov <bp@suse.de> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/f6af78fcbd348cf4939875cfda9c19689b5e50b8.1455732970.git.tony.luck@intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
061f817eb6
commit
548acf1923
8 changed files with 177 additions and 58 deletions
|
@ -209,6 +209,35 @@ static int compare_relative_table(const void *a, const void *b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void x86_sort_relative_table(char *extab_image, int image_size)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (i < image_size) {
|
||||
uint32_t *loc = (uint32_t *)(extab_image + i);
|
||||
|
||||
w(r(loc) + i, loc);
|
||||
w(r(loc + 1) + i + 4, loc + 1);
|
||||
w(r(loc + 2) + i + 8, loc + 2);
|
||||
|
||||
i += sizeof(uint32_t) * 3;
|
||||
}
|
||||
|
||||
qsort(extab_image, image_size / 12, 12, compare_relative_table);
|
||||
|
||||
i = 0;
|
||||
while (i < image_size) {
|
||||
uint32_t *loc = (uint32_t *)(extab_image + i);
|
||||
|
||||
w(r(loc) - i, loc);
|
||||
w(r(loc + 1) - (i + 4), loc + 1);
|
||||
w(r(loc + 2) - (i + 8), loc + 2);
|
||||
|
||||
i += sizeof(uint32_t) * 3;
|
||||
}
|
||||
}
|
||||
|
||||
static void sort_relative_table(char *extab_image, int image_size)
|
||||
{
|
||||
int i;
|
||||
|
@ -281,6 +310,9 @@ do_file(char const *const fname)
|
|||
break;
|
||||
case EM_386:
|
||||
case EM_X86_64:
|
||||
custom_sort = x86_sort_relative_table;
|
||||
break;
|
||||
|
||||
case EM_S390:
|
||||
custom_sort = sort_relative_table;
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue