Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137150596
D11780.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D11780.diff
View Options
Index: head/sys/amd64/amd64/elf_machdep.c
===================================================================
--- head/sys/amd64/amd64/elf_machdep.c
+++ head/sys/amd64/amd64/elf_machdep.c
@@ -84,6 +84,25 @@
};
INIT_SYSENTVEC(elf64_sysvec, &elf64_freebsd_sysvec);
+void
+amd64_lower_shared_page(struct sysentvec *sv)
+{
+ if (hw_lower_amd64_sharedpage != 0) {
+ sv->sv_maxuser -= PAGE_SIZE;
+ sv->sv_shared_page_base -= PAGE_SIZE;
+ sv->sv_usrstack -= PAGE_SIZE;
+ sv->sv_psstrings -= PAGE_SIZE;
+ }
+}
+
+/*
+ * Do this fixup before INIT_SYSENTVEC (SI_ORDER_ANY) because the latter
+ * uses the value of sv_shared_page_base.
+ */
+SYSINIT(elf64_sysvec_fixup, SI_SUB_EXEC, SI_ORDER_FIRST,
+ (sysinit_cfunc_t) amd64_lower_shared_page,
+ &elf64_freebsd_sysvec);
+
static Elf64_Brandinfo freebsd_brand_info = {
.brand = ELFOSABI_FREEBSD,
.machine = EM_X86_64,
Index: head/sys/amd64/amd64/initcpu.c
===================================================================
--- head/sys/amd64/amd64/initcpu.c
+++ head/sys/amd64/amd64/initcpu.c
@@ -48,6 +48,11 @@
static int hw_instruction_sse;
SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD,
&hw_instruction_sse, 0, "SIMD/MMX2 instructions available in CPU");
+static int lower_sharedpage_init;
+int hw_lower_amd64_sharedpage;
+SYSCTL_INT(_hw, OID_AUTO, lower_amd64_sharedpage, CTLFLAG_RDTUN,
+ &hw_lower_amd64_sharedpage, 0,
+ "Lower sharedpage to work around Ryzen issue with executing code near the top of user memory");
/*
* -1: automatic (default)
* 0: keep enable CLFLUSH
@@ -120,6 +125,28 @@
msr = rdmsr(0xc0011020);
msr |= (uint64_t)1 << 15;
wrmsr(0xc0011020, msr);
+ }
+ }
+
+ /*
+ * Work around a problem on Ryzen that is triggered by executing
+ * code near the top of user memory, in our case the signal
+ * trampoline code in the shared page on amd64.
+ *
+ * This function is executed once for the BSP before tunables take
+ * effect so the value determined here can be overridden by the
+ * tunable. This function is then executed again for each AP and
+ * also on resume. Set a flag the first time so that value set by
+ * the tunable is not overwritten.
+ *
+ * The stepping and/or microcode versions should be checked after
+ * this issue is fixed by AMD so that we don't use this mode if not
+ * needed.
+ */
+ if (lower_sharedpage_init == 0) {
+ lower_sharedpage_init = 1;
+ if (CPUID_TO_FAMILY(cpu_id) == 0x17) {
+ hw_lower_amd64_sharedpage = 1;
}
}
}
Index: head/sys/amd64/include/md_var.h
===================================================================
--- head/sys/amd64/include/md_var.h
+++ head/sys/amd64/include/md_var.h
@@ -34,11 +34,14 @@
#include <x86/x86_var.h>
-extern uint64_t *vm_page_dump;
+extern uint64_t *vm_page_dump;
+extern int hw_lower_amd64_sharedpage;
struct savefpu;
+struct sysentvec;
void amd64_db_resume_dbreg(void);
+void amd64_lower_shared_page(struct sysentvec *);
void amd64_syscall(struct thread *td, int traced);
void doreti_iret(void) __asm(__STRING(doreti_iret));
void doreti_iret_fault(void) __asm(__STRING(doreti_iret_fault));
Index: head/sys/amd64/linux/linux_sysvec.c
===================================================================
--- head/sys/amd64/linux/linux_sysvec.c
+++ head/sys/amd64/linux/linux_sysvec.c
@@ -833,6 +833,8 @@
linux_vdso_install(void *param)
{
+ amd64_lower_shared_page(&elf_linux_sysvec);
+
linux_szsigcode = (&_binary_linux_locore_o_end -
&_binary_linux_locore_o_start);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 22, 6:58 AM (17 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25929973
Default Alt Text
D11780.diff (3 KB)
Attached To
Mode
D11780: Lower shared page for amd64 on Ryzen to work around bug with code near top of user space
Attached
Detach File
Event Timeline
Log In to Comment