On 2023/12/08 0:54, Alexander Gordeev wrote: > Rework VTOP and PTOV macros to reflect the future > uncoupling of physical and virtual address spaces > in kernel. Existing versions are not affected. > > Signed-off-by: Alexander Gordeev <agordeev@xxxxxxxxxxxxx> For the series with the 3/3 v3, Acked-by: Kazuhito Hagio <k-hagio-ab@xxxxxxx> Thanks, Kazu > --- > defs.h | 20 +++++- > s390x.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 2 files changed, 228 insertions(+), 4 deletions(-) > > diff --git a/defs.h b/defs.h > index 5218a94..20237b7 100644 > --- a/defs.h > +++ b/defs.h > @@ -4564,9 +4564,9 @@ struct efi_memory_desc_t { > #define _64BIT_ > #define MACHINE_TYPE "S390X" > > -#define PTOV(X) ((unsigned long)(X)+(machdep->kvbase)) > -#define VTOP(X) ((unsigned long)(X)-(machdep->kvbase)) > -#define IS_VMALLOC_ADDR(X) (vt->vmalloc_start && (ulong)(X) >= vt->vmalloc_start) > +#define PTOV(X) s390x_PTOV((ulong)(X)) > +#define VTOP(X) s390x_VTOP((ulong)(X)) > +#define IS_VMALLOC_ADDR(X) s390x_IS_VMALLOC_ADDR(X) > #define PTRS_PER_PTE 512 > #define PTRS_PER_PMD 1024 > #define PTRS_PER_PGD 2048 > @@ -6827,7 +6827,21 @@ void get_s390_panicmsg(char *); > * s390x.c > */ > #ifdef S390X > + > +struct machine_specific > +{ > + ulong (*virt_to_phys)(ulong vaddr); > + ulong (*phys_to_virt)(ulong paddr); > + int (*is_vmalloc_addr)(ulong vaddr); > + ulong __kaslr_offset_phys; > + ulong amode31_start; > + ulong amode31_end; > +}; > + > void s390x_init(int); > +ulong s390x_PTOV(ulong); > +ulong s390x_VTOP(ulong); > +int s390x_IS_VMALLOC_ADDR(ulong); > void s390x_dump_machdep_table(ulong); > #define display_idt_table() \ > error(FATAL, "-d option is not applicable to S390X architecture\n") > diff --git a/s390x.c b/s390x.c > index 4024d84..54b4ebc 100644 > --- a/s390x.c > +++ b/s390x.c > @@ -47,6 +47,7 @@ > #define S390X_PSW_MASK_PSTATE 0x0001000000000000UL > > #define S390X_LC_VMCORE_INFO 0xe0c > +#define S390X_LC_OS_INFO 0xe18 > > /* > * Flags for Region and Segment table entries. > @@ -168,6 +169,19 @@ static struct line_number_hook s390x_line_number_hooks[]; > static int s390x_is_uvaddr(ulong, struct task_context *); > static int s390x_get_kvaddr_ranges(struct vaddr_range *); > static int set_s390x_max_physmem_bits(void); > +static ulong s390x_generic_VTOP(ulong vaddr); > +static ulong s390x_generic_PTOV(ulong paddr); > +static int s390x_generic_IS_VMALLOC_ADDR(ulong vaddr); > +static ulong s390x_vr_VTOP(ulong vaddr); > +static ulong s390x_vr_PTOV(ulong paddr); > +static int s390x_vr_IS_VMALLOC_ADDR(ulong vaddr); > +static int s390x_vr_is_kvaddr(ulong); > + > +struct machine_specific s390x_machine_specific = { > + .virt_to_phys = s390x_generic_VTOP, > + .phys_to_virt = s390x_generic_PTOV, > + .is_vmalloc_addr = s390x_generic_IS_VMALLOC_ADDR, > +}; > > /* > * struct lowcore name (old: "_lowcore", new: "lowcore") > @@ -546,6 +560,191 @@ static void s390x_check_kaslr(void) > free(vmcoreinfo); > } > > +#define OS_INFO_VERSION_MAJOR 1 > +#define OS_INFO_VERSION_MINOR 1 > + > +#define OS_INFO_VMCOREINFO 0 > +#define OS_INFO_REIPL_BLOCK 1 > +#define OS_INFO_FLAGS_ENTRY 2 > +#define OS_INFO_RESERVED 3 > +#define OS_INFO_IDENTITY_BASE 4 > +#define OS_INFO_KASLR_OFFSET 5 > +#define OS_INFO_KASLR_OFF_PHYS 6 > +#define OS_INFO_VMEMMAP 7 > +#define OS_INFO_AMODE31_START 8 > +#define OS_INFO_AMODE31_END 9 > + > +struct os_info_entry { > + union { > + __u64 addr; > + __u64 val; > + }; > + __u64 size; > + __u32 csum; > +} __attribute__((packed)); > + > +struct os_info { > + __u64 magic; > + __u32 csum; > + __u16 version_major; > + __u16 version_minor; > + __u64 crashkernel_addr; > + __u64 crashkernel_size; > + struct os_info_entry entry[10]; > + __u8 reserved[3864]; > +} __attribute__((packed)); > + > +struct vm_info { > + __u64 __identity_base; > + __u64 __kaslr_offset; > + __u64 __kaslr_offset_phys; > + __u64 amode31_start; > + __u64 amode31_end; > +}; > + > +static bool > +vmcoreinfo_read_u64(const char *key, __u64 *val) > +{ > + char *string; > + > + string = pc->read_vmcoreinfo(key); > + if (string) { > + *val = strtoul(string, NULL, 16); > + free(string); > + return true; > + } > + > + return false; > +} > + > +static bool vmcoreinfo_read_vm_info(struct vm_info *_vm_info) > +{ > + struct vm_info vm_info; > + > + if (!vmcoreinfo_read_u64("IDENTITYBASE", &vm_info.__identity_base) || > + !vmcoreinfo_read_u64("KERNELOFFSET", &vm_info.__kaslr_offset) || > + !vmcoreinfo_read_u64("KERNELOFFPHYS", &vm_info.__kaslr_offset_phys) || > + !vmcoreinfo_read_u64("SAMODE31", &vm_info.amode31_start) || > + !vmcoreinfo_read_u64("EAMODE31", &vm_info.amode31_end)) > + return false; > + > + *_vm_info = vm_info; > + > + return true; > +} > + > +static bool os_info_read_vm_info(struct vm_info *vm_info) > +{ > + struct os_info os_info; > + ulong addr; > + > + if (!readmem(S390X_LC_OS_INFO, PHYSADDR, &addr, > + sizeof(addr), "s390x os_info ptr", > + QUIET|RETURN_ON_ERROR)) > + return false; > + > + if (addr == 0) > + return true; > + > + if (!readmem(addr, PHYSADDR, &os_info, > + offsetof(struct os_info, reserved), "s390x os_info header", > + QUIET|RETURN_ON_ERROR)) > + return false; > + > + vm_info->__identity_base = os_info.entry[OS_INFO_IDENTITY_BASE].val; > + vm_info->__kaslr_offset = os_info.entry[OS_INFO_KASLR_OFFSET].val; > + vm_info->__kaslr_offset_phys = os_info.entry[OS_INFO_KASLR_OFF_PHYS].val; > + vm_info->amode31_start = os_info.entry[OS_INFO_AMODE31_START].val; > + vm_info->amode31_end = os_info.entry[OS_INFO_AMODE31_END].val; > + > + return true; > +} > + > +static bool vm_info_empty(struct vm_info *vm_info) > +{ > + return !vm_info->__kaslr_offset; > +} > + > +static bool s390x_init_vm(void) > +{ > + struct vm_info vm_info; > + > + if (pc->flags & PROC_KCORE) { > + if (!vmcoreinfo_read_vm_info(&vm_info)) > + return true; > + } else { > + if (!os_info_read_vm_info(&vm_info)) > + return false; > + } > + if (vm_info_empty(&vm_info)) > + return true; > + > + machdep->identity_map_base = vm_info.__identity_base; > + machdep->kvbase = vm_info.__kaslr_offset; > + machdep->machspec->__kaslr_offset_phys = vm_info.__kaslr_offset_phys; > + machdep->machspec->amode31_start = vm_info.amode31_start; > + machdep->machspec->amode31_end = vm_info.amode31_end; > + > + machdep->is_kvaddr = s390x_vr_is_kvaddr; > + machdep->machspec->virt_to_phys = s390x_vr_VTOP; > + machdep->machspec->phys_to_virt = s390x_vr_PTOV; > + machdep->machspec->is_vmalloc_addr = s390x_vr_IS_VMALLOC_ADDR; > + > + return true; > +} > + > +static ulong s390x_generic_VTOP(ulong vaddr) > +{ > + return vaddr - machdep->kvbase; > +} > + > +static ulong s390x_generic_PTOV(ulong paddr) > +{ > + return paddr + machdep->kvbase; > +} > + > +static int s390x_generic_IS_VMALLOC_ADDR(ulong vaddr) > +{ > + return vt->vmalloc_start && vaddr >= vt->vmalloc_start; > +} > + > +static ulong s390x_vr_VTOP(ulong vaddr) > +{ > + if (vaddr < LOWCORE_SIZE) > + return vaddr; > + if ((vaddr < machdep->machspec->amode31_end) && > + (vaddr >= machdep->machspec->amode31_start)) > + return vaddr; > + if (vaddr < machdep->kvbase) > + return vaddr - machdep->identity_map_base; > + return vaddr - machdep->kvbase + machdep->machspec->__kaslr_offset_phys; > +} > + > +static ulong s390x_vr_PTOV(ulong paddr) > +{ > + return paddr + machdep->identity_map_base; > +} > + > +static int s390x_vr_IS_VMALLOC_ADDR(ulong vaddr) > +{ > + return (vaddr >= vt->vmalloc_start && vaddr < machdep->kvbase); > +} > + > +ulong s390x_VTOP(ulong vaddr) > +{ > + return machdep->machspec->virt_to_phys(vaddr); > +} > + > +ulong s390x_PTOV(ulong paddr) > +{ > + return machdep->machspec->phys_to_virt(paddr); > +} > + > +int s390x_IS_VMALLOC_ADDR(ulong vaddr) > +{ > + return machdep->machspec->is_vmalloc_addr(vaddr); > +} > + > /* > * Do all necessary machine-specific setup here. This is called several > * times during initialization. > @@ -560,6 +759,7 @@ s390x_init(int when) > machdep->process_elf_notes = s390x_process_elf_notes; > break; > case PRE_SYMTAB: > + machdep->machspec = &s390x_machine_specific; > machdep->verify_symbol = s390x_verify_symbol; > if (pc->flags & KERNEL_DEBUG_QUERY) > return; > @@ -587,6 +787,8 @@ s390x_init(int when) > machdep->kvbase = 0; > machdep->identity_map_base = 0; > machdep->is_kvaddr = generic_is_kvaddr; > + if (!s390x_init_vm()) > + error(FATAL, "cannot initialize VM parameters."); > machdep->is_uvaddr = s390x_is_uvaddr; > machdep->eframe_search = s390x_eframe_search; > machdep->back_trace = s390x_back_trace_cmd; > @@ -681,7 +883,9 @@ s390x_dump_machdep_table(ulong arg) > fprintf(fp, " dis_filter: s390x_dis_filter()\n"); > fprintf(fp, " cmd_mach: s390x_cmd_mach()\n"); > fprintf(fp, " get_smp_cpus: s390x_get_smp_cpus()\n"); > - fprintf(fp, " is_kvaddr: generic_is_kvaddr()\n"); > + fprintf(fp, " is_kvaddr: %s()\n", machdep->is_kvaddr == s390x_vr_is_kvaddr ? > + "s390x_vr_is_kvaddr" : > + "generic_is_kvaddr"); > fprintf(fp, " is_uvaddr: s390x_is_uvaddr()\n"); > fprintf(fp, " verify_paddr: generic_verify_paddr()\n"); > fprintf(fp, " get_kvaddr_ranges: s390x_get_kvaddr_ranges()\n"); > @@ -702,6 +906,12 @@ s390x_dump_machdep_table(ulong arg) > fprintf(fp, " machspec: %lx\n", (ulong)machdep->machspec); > } > > +static int > +s390x_vr_is_kvaddr(ulong vaddr) > +{ > + return (vaddr < LOWCORE_SIZE) || (vaddr >= machdep->identity_map_base); > +} > + > /* > * Check if address is in context's address space > */ -- Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ Contribution Guidelines: https://github.com/crash-utility/crash/wiki