linux/arch/x86/boot/compressed/idt_64.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2#include <asm/trap_pf.h>
   3#include <asm/segment.h>
   4#include <asm/trapnr.h>
   5#include "misc.h"
   6
   7static void set_idt_entry(int vector, void (*handler)(void))
   8{
   9        unsigned long address = (unsigned long)handler;
  10        gate_desc entry;
  11
  12        memset(&entry, 0, sizeof(entry));
  13
  14        entry.offset_low    = (u16)(address & 0xffff);
  15        entry.segment       = __KERNEL_CS;
  16        entry.bits.type     = GATE_TRAP;
  17        entry.bits.p        = 1;
  18        entry.offset_middle = (u16)((address >> 16) & 0xffff);
  19        entry.offset_high   = (u32)(address >> 32);
  20
  21        memcpy(&boot_idt[vector], &entry, sizeof(entry));
  22}
  23
  24/* Have this here so we don't need to include <asm/desc.h> */
  25static void load_boot_idt(const struct desc_ptr *dtr)
  26{
  27        asm volatile("lidt %0"::"m" (*dtr));
  28}
  29
  30/* Setup IDT before kernel jumping to  .Lrelocated */
  31void load_stage1_idt(void)
  32{
  33        boot_idt_desc.address = (unsigned long)boot_idt;
  34
  35
  36        if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT))
  37                set_idt_entry(X86_TRAP_VC, boot_stage1_vc);
  38
  39        load_boot_idt(&boot_idt_desc);
  40}
  41
  42/* Setup IDT after kernel jumping to  .Lrelocated */
  43void load_stage2_idt(void)
  44{
  45        boot_idt_desc.address = (unsigned long)boot_idt;
  46
  47        set_idt_entry(X86_TRAP_PF, boot_page_fault);
  48
  49#ifdef CONFIG_AMD_MEM_ENCRYPT
  50        set_idt_entry(X86_TRAP_VC, boot_stage2_vc);
  51#endif
  52
  53        load_boot_idt(&boot_idt_desc);
  54}
  55