Page MenuHomeFreeBSD

D52607.id162380.diff
No OneTemporary

D52607.id162380.diff

diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1836,6 +1836,42 @@
: "cc", "memory");
}
+extern const char wrmsr_early_safe_gp_handler[];
+static struct gate_descriptor orig_gpf_descr;
+
+static struct gate_descriptor *
+wrmsr_early_get_gp_descr(void)
+{
+ struct region_descriptor efi_idt;
+ struct gate_descriptor *gpf_descr;
+
+ sidt(&efi_idt);
+ return ((void *)(uintptr_t)(efi_idt.rd_base +
+ sizeof(*gpf_descr) * IDT_GP));
+}
+
+void
+wrmsr_early_safe_start(void)
+{
+ struct gate_descriptor *gpf_descr;
+
+ gpf_descr = wrmsr_early_get_gp_descr();
+ orig_gpf_descr = *gpf_descr;
+
+ memset(gpf_descr, 0, sizeof(*gpf_descr));
+ 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)
+{
+ *wrmsr_early_get_gp_descr() = orig_gpf_descr;
+}
+
#ifdef KDB
/*
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S
--- a/sys/amd64/amd64/support.S
+++ b/sys/amd64/amd64/support.S
@@ -1565,6 +1565,22 @@
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/cpufunc.h b/sys/amd64/include/cpufunc.h
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -863,6 +863,15 @@
__asm __volatile("clac" : : : "cc");
}
+static __inline uint16_t
+rcs(void)
+{
+ uint16_t cs;
+
+ __asm("movw\t%%cs,%0" : "=r" (cs));
+ return (cs);
+}
+
enum {
SGX_ECREATE = 0x0,
SGX_EADD = 0x1,
diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h
--- a/sys/amd64/include/md_var.h
+++ b/sys/amd64/include/md_var.h
@@ -100,6 +100,10 @@
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__ */

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 1, 9:53 PM (2 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30690134
Default Alt Text
D52607.id162380.diff (2 KB)

Event Timeline