You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull misc x86 fixes from Ingo Molnar: - topology enumeration fixes - KASAN fix - two entry fixes (not yet the big series related to KASLR) - remove obsolete code - instruction decoder fix - better /dev/mem sanity checks, hopefully working better this time - pkeys fixes - two ACPI fixes - 5-level paging related fixes - UMIP fixes that should make application visible faults more debuggable - boot fix for weird virtualization environment * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits) x86/decoder: Add new TEST instruction pattern x86/PCI: Remove unused HyperTransport interrupt support x86/umip: Fix insn_get_code_seg_params()'s return value x86/boot/KASLR: Remove unused variable x86/entry/64: Add missing irqflags tracing to native_load_gs_index() x86/mm/kasan: Don't use vmemmap_populate() to initialize shadow x86/entry/64: Fix entry_SYSCALL_64_after_hwframe() IRQ tracing x86/pkeys/selftests: Fix protection keys write() warning x86/pkeys/selftests: Rename 'si_pkey' to 'siginfo_pkey' x86/mpx/selftests: Fix up weird arrays x86/pkeys: Update documentation about availability x86/umip: Print a warning into the syslog if UMIP-protected instructions are used x86/smpboot: Fix __max_logical_packages estimate x86/topology: Avoid wasting 128k for package id array perf/x86/intel/uncore: Cache logical pkg id in uncore driver x86/acpi: Reduce code duplication in mp_override_legacy_irq() x86/acpi: Handle SCI interrupts above legacy space gracefully x86/boot: Fix boot failure when SMP MP-table is based at 0 x86/mm: Limit mmap() of /dev/mem to valid physical addresses x86/selftests: Add test for mapping placement for 5-level paging ...
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
#define PAGE_SIZE 4096
|
||||
#define LOW_ADDR ((void *) (1UL << 30))
|
||||
#define HIGH_ADDR ((void *) (1UL << 50))
|
||||
|
||||
struct testcase {
|
||||
void *addr;
|
||||
unsigned long size;
|
||||
unsigned long flags;
|
||||
const char *msg;
|
||||
unsigned int low_addr_required:1;
|
||||
unsigned int keep_mapped:1;
|
||||
};
|
||||
|
||||
static struct testcase testcases[] = {
|
||||
{
|
||||
.addr = NULL,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(NULL)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = LOW_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(LOW_ADDR)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR) again",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_FIXED)",
|
||||
},
|
||||
{
|
||||
.addr = (void*) -1,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void*) -1,
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1) again",
|
||||
},
|
||||
{
|
||||
.addr = (void *)((1UL << 47) - PAGE_SIZE),
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap((1UL << 47), 2 * PAGE_SIZE)",
|
||||
.low_addr_required = 1,
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *)((1UL << 47) - PAGE_SIZE / 2),
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap((1UL << 47), 2 * PAGE_SIZE / 2)",
|
||||
.low_addr_required = 1,
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *)((1UL << 47) - PAGE_SIZE),
|
||||
.size = 2 * PAGE_SIZE,
|
||||
.flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap((1UL << 47) - PAGE_SIZE, 2 * PAGE_SIZE, MAP_FIXED)",
|
||||
},
|
||||
{
|
||||
.addr = NULL,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(NULL, MAP_HUGETLB)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = LOW_ADDR,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(LOW_ADDR, MAP_HUGETLB)",
|
||||
.low_addr_required = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_HUGETLB)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_HUGETLB) again",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = HIGH_ADDR,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap(HIGH_ADDR, MAP_FIXED | MAP_HUGETLB)",
|
||||
},
|
||||
{
|
||||
.addr = (void*) -1,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1, MAP_HUGETLB)",
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void*) -1,
|
||||
.size = 2UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap(-1, MAP_HUGETLB) again",
|
||||
},
|
||||
{
|
||||
.addr = (void *)((1UL << 47) - PAGE_SIZE),
|
||||
.size = 4UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS,
|
||||
.msg = "mmap((1UL << 47), 4UL << 20, MAP_HUGETLB)",
|
||||
.low_addr_required = 1,
|
||||
.keep_mapped = 1,
|
||||
},
|
||||
{
|
||||
.addr = (void *)((1UL << 47) - (2UL << 20)),
|
||||
.size = 4UL << 20,
|
||||
.flags = MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
||||
.msg = "mmap((1UL << 47) - (2UL << 20), 4UL << 20, MAP_FIXED | MAP_HUGETLB)",
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
void *p;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(testcases); i++) {
|
||||
struct testcase *t = testcases + i;
|
||||
|
||||
p = mmap(t->addr, t->size, PROT_NONE, t->flags, -1, 0);
|
||||
|
||||
printf("%s: %p - ", t->msg, p);
|
||||
|
||||
if (p == MAP_FAILED) {
|
||||
printf("FAILED\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (t->low_addr_required && p >= (void *)(1UL << 47))
|
||||
printf("FAILED\n");
|
||||
else
|
||||
printf("OK\n");
|
||||
if (!t->keep_mapped)
|
||||
munmap(p, t->size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -11,7 +11,7 @@ TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_sysc
|
||||
TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \
|
||||
test_FCMOV test_FCOMI test_FISTTP \
|
||||
vdso_restorer
|
||||
TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip
|
||||
TARGETS_C_64BIT_ONLY := fsgsbase sysret_rip 5lvl
|
||||
|
||||
TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY)
|
||||
TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY)
|
||||
|
||||
@@ -52,14 +52,14 @@
|
||||
struct mpx_bd_entry {
|
||||
union {
|
||||
char x[MPX_BOUNDS_DIR_ENTRY_SIZE_BYTES];
|
||||
void *contents[1];
|
||||
void *contents[0];
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
struct mpx_bt_entry {
|
||||
union {
|
||||
char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES];
|
||||
unsigned long contents[1];
|
||||
unsigned long contents[0];
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ static inline void sigsafe_printf(const char *format, ...)
|
||||
if (!dprint_in_signal) {
|
||||
vprintf(format, ap);
|
||||
} else {
|
||||
int ret;
|
||||
int len = vsnprintf(dprint_in_signal_buffer,
|
||||
DPRINT_IN_SIGNAL_BUF_SIZE,
|
||||
format, ap);
|
||||
@@ -39,7 +40,9 @@ static inline void sigsafe_printf(const char *format, ...)
|
||||
*/
|
||||
if (len > DPRINT_IN_SIGNAL_BUF_SIZE)
|
||||
len = DPRINT_IN_SIGNAL_BUF_SIZE;
|
||||
write(1, dprint_in_signal_buffer, len);
|
||||
ret = write(1, dprint_in_signal_buffer, len);
|
||||
if (ret < 0)
|
||||
abort();
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@@ -250,7 +250,7 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext)
|
||||
unsigned long ip;
|
||||
char *fpregs;
|
||||
u32 *pkru_ptr;
|
||||
u64 si_pkey;
|
||||
u64 siginfo_pkey;
|
||||
u32 *si_pkey_ptr;
|
||||
int pkru_offset;
|
||||
fpregset_t fpregset;
|
||||
@@ -292,9 +292,9 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext)
|
||||
si_pkey_ptr = (u32 *)(((u8 *)si) + si_pkey_offset);
|
||||
dprintf1("si_pkey_ptr: %p\n", si_pkey_ptr);
|
||||
dump_mem(si_pkey_ptr - 8, 24);
|
||||
si_pkey = *si_pkey_ptr;
|
||||
pkey_assert(si_pkey < NR_PKEYS);
|
||||
last_si_pkey = si_pkey;
|
||||
siginfo_pkey = *si_pkey_ptr;
|
||||
pkey_assert(siginfo_pkey < NR_PKEYS);
|
||||
last_si_pkey = siginfo_pkey;
|
||||
|
||||
if ((si->si_code == SEGV_MAPERR) ||
|
||||
(si->si_code == SEGV_ACCERR) ||
|
||||
@@ -306,7 +306,7 @@ void signal_handler(int signum, siginfo_t *si, void *vucontext)
|
||||
dprintf1("signal pkru from xsave: %08x\n", *pkru_ptr);
|
||||
/* need __rdpkru() version so we do not do shadow_pkru checking */
|
||||
dprintf1("signal pkru from pkru: %08x\n", __rdpkru());
|
||||
dprintf1("si_pkey from siginfo: %jx\n", si_pkey);
|
||||
dprintf1("pkey from siginfo: %jx\n", siginfo_pkey);
|
||||
*(u64 *)pkru_ptr = 0x00000000;
|
||||
dprintf1("WARNING: set PRKU=0 to allow faulting instruction to continue\n");
|
||||
pkru_faults++;
|
||||
|
||||
Reference in New Issue
Block a user