mirror of
https://github.com/crash-utility/crash
synced 2025-02-23 00:46:48 +00:00
Fix for the swap offset calculation in the x86_64 "vm -p", "pte", and
user-space "vtop" commands. The swap offset bits in an x86_64 PTE were changed in Linux 4.6, and then again in Linux 4.18.1 with the new L1TF security patchset. Without the patch, the offset value in the later kernels, or in older kernels with an L1TF backport, show an incorrect swap offset value. (anderson@redhat.com)
This commit is contained in:
parent
4ae70cc811
commit
3fcb69b9ae
7
defs.h
7
defs.h
@ -3478,8 +3478,8 @@ struct arm64_stackframe {
|
||||
|
||||
#define SWP_TYPE(entry) (((entry) >> 1) & 0x3f)
|
||||
#define SWP_OFFSET(entry) ((entry) >> 8)
|
||||
#define __swp_type(entry) SWP_TYPE(entry)
|
||||
#define __swp_offset(entry) SWP_OFFSET(entry)
|
||||
#define __swp_type(entry) x86_64_swp_type(entry)
|
||||
#define __swp_offset(entry) x86_64_swp_offset(entry)
|
||||
|
||||
#define TIF_SIGPENDING (2)
|
||||
|
||||
@ -5725,6 +5725,8 @@ void x86_64_dump_machdep_table(ulong);
|
||||
ulong x86_64_PTOV(ulong);
|
||||
ulong x86_64_VTOP(ulong);
|
||||
int x86_64_IS_VMALLOC_ADDR(ulong);
|
||||
ulong x86_64_swp_type(ulong);
|
||||
ulong x86_64_swp_offset(ulong);
|
||||
void x86_64_display_idt_table(void);
|
||||
#define display_idt_table() x86_64_display_idt_table()
|
||||
long x86_64_exception_frame(ulong, ulong, char *, struct bt_info *, FILE *);
|
||||
@ -5864,6 +5866,7 @@ struct machine_specific {
|
||||
#define VM_5LEVEL (0x2000)
|
||||
#define ORC (0x4000)
|
||||
#define KPTI (0x8000)
|
||||
#define L1TF (0x10000)
|
||||
|
||||
#define VM_FLAGS (VM_ORIG|VM_2_6_11|VM_XEN|VM_XEN_RHEL4|VM_5LEVEL)
|
||||
|
||||
|
56
x86_64.c
56
x86_64.c
@ -89,6 +89,7 @@ static void x86_64_init_kernel_pgd(void);
|
||||
static void x86_64_cpu_pda_init(void);
|
||||
static void x86_64_per_cpu_init(void);
|
||||
static void x86_64_ist_init(void);
|
||||
static void x86_64_l1tf_init(void);
|
||||
static void x86_64_irq_stack_gap_init(void);
|
||||
static void x86_64_entry_trampoline_init(void);
|
||||
static void x86_64_post_init(void);
|
||||
@ -694,6 +695,7 @@ x86_64_init(int when)
|
||||
x86_64_framepointer_init();
|
||||
x86_64_ORC_init();
|
||||
x86_64_thread_return_init();
|
||||
x86_64_l1tf_init();
|
||||
|
||||
if (THIS_KERNEL_VERSION >= LINUX(2,6,28))
|
||||
machdep->machspec->page_protnone = _PAGE_GLOBAL;
|
||||
@ -774,6 +776,8 @@ x86_64_dump_machdep_table(ulong arg)
|
||||
fprintf(fp, "%sRANDOMIZED", others++ ? "|" : "");
|
||||
if (machdep->flags & KPTI)
|
||||
fprintf(fp, "%sKPTI", others++ ? "|" : "");
|
||||
if (machdep->flags & L1TF)
|
||||
fprintf(fp, "%sL1TF", others++ ? "|" : "");
|
||||
fprintf(fp, ")\n");
|
||||
|
||||
fprintf(fp, " kvbase: %lx\n", machdep->kvbase);
|
||||
@ -1504,6 +1508,17 @@ x86_64_irq_stack_gap_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check kernel version and/or backport for L1TF
|
||||
*/
|
||||
static void
|
||||
x86_64_l1tf_init(void)
|
||||
{
|
||||
if (THIS_KERNEL_VERSION >= LINUX(4,18,1) ||
|
||||
kernel_symbol_exists("l1tf_mitigation"))
|
||||
machdep->flags |= L1TF;
|
||||
}
|
||||
|
||||
static void
|
||||
x86_64_post_init(void)
|
||||
{
|
||||
@ -9062,4 +9077,45 @@ x86_64_in_kpti_entry_stack(int cpu, ulong rsp)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Original:
|
||||
*
|
||||
* #define SWP_TYPE(entry) (((entry) >> 1) & 0x3f)
|
||||
* #define SWP_OFFSET(entry) ((entry) >> 8)
|
||||
*
|
||||
* 4.8:
|
||||
* | OFFSET (14-63) | TYPE (9-13) |0|X|X|X| X| X|X|X|0|
|
||||
*
|
||||
* l1tf:
|
||||
* | ... | 11| 10| 9|8|7|6|5| 4| 3|2| 1|0| <- bit number
|
||||
* | ... |SW3|SW2|SW1|G|L|D|A|CD|WT|U| W|P| <- bit names
|
||||
* | TYPE (59-63) | ~OFFSET (9-58) |0|0|X|X| X| X|X|SD|0| <- swp entry
|
||||
*/
|
||||
|
||||
|
||||
ulong
|
||||
x86_64_swp_type(ulong entry)
|
||||
{
|
||||
if (machdep->flags & L1TF)
|
||||
return(entry >> 59);
|
||||
|
||||
if (THIS_KERNEL_VERSION >= LINUX(4,8,0))
|
||||
return((entry >> 9) & 0x1f);
|
||||
|
||||
return SWP_TYPE(entry);
|
||||
}
|
||||
|
||||
ulong
|
||||
x86_64_swp_offset(ulong entry)
|
||||
{
|
||||
if (machdep->flags & L1TF)
|
||||
return((~entry << 5) >> 14);
|
||||
|
||||
if (THIS_KERNEL_VERSION >= LINUX(4,8,0))
|
||||
return(entry >> 14);
|
||||
|
||||
return SWP_OFFSET(entry);
|
||||
}
|
||||
|
||||
#endif /* X86_64 */
|
||||
|
Loading…
Reference in New Issue
Block a user