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