x86: for wrmsr_early_safe(), catch all exceptions, not only #GP

Reviewed by:	olce
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D57264
This commit is contained in:
Konstantin Belousov
2026-05-27 11:21:10 +03:00
parent 95fc64cc29
commit 0a02a47fd9
2 changed files with 18 additions and 13 deletions
+15 -9
View File
@@ -1827,29 +1827,35 @@ wrmsr_early_safe_start(void)
{
struct region_descriptor efi_idt;
struct gate_descriptor *gpf_descr;
int i;
sidt(&wrmsr_early_safe_orig_efi_idt);
efi_idt.rd_limit = 32 * sizeof(idt0[0]);
efi_idt.rd_base = (uintptr_t)idt0;
lidt(&efi_idt);
gpf_descr = &idt0[IDT_GP];
gpf_descr->gd_looffset = (uintptr_t)wrmsr_early_safe_gp_handler;
gpf_descr->gd_hioffset = (uintptr_t)wrmsr_early_safe_gp_handler >> 16;
gpf_descr->gd_selector = rcs();
gpf_descr->gd_type = SDT_SYSTGT;
gpf_descr->gd_p = 1;
/* Setup handler for all possible exceptions. */
for (i = 0; i < 32; i++) {
gpf_descr = &idt0[i];
gpf_descr->gd_looffset =
(uintptr_t)wrmsr_early_safe_gp_handler;
gpf_descr->gd_hioffset =
(uintptr_t)wrmsr_early_safe_gp_handler >> 16;
gpf_descr->gd_selector = rcs();
gpf_descr->gd_type = SDT_SYSTGT;
gpf_descr->gd_p = 1;
}
}
void
wrmsr_early_safe_end(void)
{
struct gate_descriptor *gpf_descr;
int i;
lidt(&wrmsr_early_safe_orig_efi_idt);
gpf_descr = &idt0[IDT_GP];
memset_early(gpf_descr, 0, sizeof(*gpf_descr));
for (i = 0; i < 32; i++)
memset_early(&idt0[i], 0, sizeof(idt0[0]));
}
int
+3 -4
View File
@@ -1566,20 +1566,19 @@ msr_onfault:
ret
ENTRY(wrmsr_early_safe)
movq %rsp,%r11
movl %edi,%ecx
movl %esi,%eax
sarq $32,%rsi
movl %esi,%edx
wrmsr
xorl %eax,%eax
wrmsr_early_faulted:
ret
ENTRY(wrmsr_early_safe_gp_handler)
addq $8,%rsp
movq %r11,%rsp
movl $EFAULT,%eax
movq $wrmsr_early_faulted,(%rsp)
iretq
ret
/*
* void pmap_pti_pcid_invalidate(uint64_t ucr3, uint64_t kcr3);