git: d4f91b6d25cb - stable/15 - amd64: add wrmsr_early_safe(9)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 01 Oct 2025 03:13:11 UTC
The branch stable/15 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=d4f91b6d25cbae9658035f86ee15e454141fae8e
commit d4f91b6d25cbae9658035f86ee15e454141fae8e
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-09-18 21:55:19 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-10-01 03:00:08 +0000
amd64: add wrmsr_early_safe(9)
(cherry picked from commit a319696875451229f492b6c15e58a0ac54dbcda1)
---
sys/amd64/amd64/machdep.c | 33 +++++++++++++++++++++++++++++++++
sys/amd64/amd64/support.S | 16 ++++++++++++++++
sys/amd64/include/md_var.h | 4 ++++
3 files changed, 53 insertions(+)
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 9ff60439d1ec..2fce1a7e64b6 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1822,6 +1822,39 @@ clear_pcb_flags(struct pcb *pcb, const u_int flags)
: "cc", "memory");
}
+extern const char wrmsr_early_safe_gp_handler[];
+static struct region_descriptor wrmsr_early_safe_orig_efi_idt;
+
+void
+wrmsr_early_safe_start(void)
+{
+ struct region_descriptor efi_idt;
+ struct gate_descriptor *gpf_descr;
+
+ 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;
+}
+
+void
+wrmsr_early_safe_end(void)
+{
+ struct gate_descriptor *gpf_descr;
+
+ lidt(&wrmsr_early_safe_orig_efi_idt);
+
+ gpf_descr = &idt0[IDT_GP];
+ memset(gpf_descr, 0, sizeof(*gpf_descr));
+}
+
#ifdef KDB
/*
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S
index 870cd255abb7..27694a95653c 100644
--- a/sys/amd64/amd64/support.S
+++ b/sys/amd64/amd64/support.S
@@ -1565,6 +1565,22 @@ msr_onfault:
POP_FRAME_POINTER
ret
+ENTRY(wrmsr_early_safe)
+ 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
+ movl $EFAULT,%eax
+ movq $wrmsr_early_faulted,(%rsp)
+ iretq
+
/*
* void pmap_pti_pcid_invalidate(uint64_t ucr3, uint64_t kcr3);
* Invalidates address space addressed by ucr3, then returns to kcr3.
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
index b6ddc6eaaebe..b6d8c469cdf6 100644
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -99,6 +99,10 @@ void get_fpcontext(struct thread *td, struct __mcontext *mcp,
int set_fpcontext(struct thread *td, struct __mcontext *mcp,
char *xfpustate, size_t xfpustate_len);
+void wrmsr_early_safe_start(void);
+void wrmsr_early_safe_end(void);
+int wrmsr_early_safe(u_int msr, uint64_t data);
+
#endif /* !_MACHINE_MD_VAR_H_ */
#endif /* __i386__ */