* [PATCH 0/2] s390x: uncouple physical and virtual memory spaces
@ 2023-11-29 12:50 Alexander Gordeev
2023-11-29 12:50 ` [PATCH 1/2] s390x: fix virtual vs physical address confusion Alexander Gordeev
2023-11-29 12:50 ` [PATCH 2/2] s390x: uncouple virtual and physical address spaces Alexander Gordeev
0 siblings, 2 replies; 7+ messages in thread
From: Alexander Gordeev @ 2023-11-29 12:50 UTC (permalink / raw)
To: kexec
Hi all,
Currently physical and virtual addresses are the same on S390X,
but in the future it is going to be uncoupled just like on any
other architecture. This series supports that feature, but it
does not impact the current and older kernel versions.
Patch 1 is basically NOP and only fix semantics.
Patch 2 uses the feature if it is available in kernel.
Thanks!
Alexander Gordeev (2):
s390x: fix virtual vs physical address confusion
s390x: uncouple virtual and physical address spaces
arch/s390x.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++---
makedumpfile.c | 2 +
makedumpfile.h | 12 +++-
3 files changed, 155 insertions(+), 8 deletions(-)
--
2.40.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] s390x: fix virtual vs physical address confusion
2023-11-29 12:50 [PATCH 0/2] s390x: uncouple physical and virtual memory spaces Alexander Gordeev
@ 2023-11-29 12:50 ` Alexander Gordeev
2023-11-29 12:50 ` [PATCH 2/2] s390x: uncouple virtual and physical address spaces Alexander Gordeev
1 sibling, 0 replies; 7+ messages in thread
From: Alexander Gordeev @ 2023-11-29 12:50 UTC (permalink / raw)
To: kexec
Physical and virtual addresses are the same on S390X.
That led to misuse of readmem() address type.
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
---
arch/s390x.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/arch/s390x.c b/arch/s390x.c
index c4fed6f..a01f164 100644
--- a/arch/s390x.c
+++ b/arch/s390x.c
@@ -167,7 +167,7 @@ _kl_rsg_table_deref_s390x(unsigned long vaddr, unsigned long table,
return 0;
}
- if (!readmem(VADDR, table + offset, &entry, sizeof(entry))) {
+ if (!readmem(PADDR, table + offset, &entry, sizeof(entry))) {
if (level)
ERRMSG("Can't read region table %d entry\n", level);
else
@@ -201,7 +201,7 @@ static ulong _kl_pg_table_deref_s390x(unsigned long vaddr, unsigned long table)
unsigned long offset, entry;
offset = pte_offset(vaddr);
- readmem(VADDR, table + offset, &entry, sizeof(entry));
+ readmem(PADDR, table + offset, &entry, sizeof(entry));
/*
* Check if the page table entry could be read and doesn't have
* the reserved bit set.
@@ -227,17 +227,22 @@ static unsigned long long
vtop_s390x(unsigned long vaddr)
{
unsigned long long paddr = NOT_PADDR;
+ unsigned long long swapper_pg_dir;
unsigned long table, entry;
int level, len;
- if (SYMBOL(swapper_pg_dir) == NOT_FOUND_SYMBOL) {
+ swapper_pg_dir = SYMBOL(swapper_pg_dir);
+ if (swapper_pg_dir == NOT_FOUND_SYMBOL) {
ERRMSG("Can't get the symbol of swapper_pg_dir.\n");
return NOT_PADDR;
}
- table = SYMBOL(swapper_pg_dir);
+ table = vaddr_to_paddr(swapper_pg_dir);
/* Read the first entry to find the number of page table levels. */
- readmem(VADDR, table, &entry, sizeof(entry));
+ if (!readmem(PADDR, table, &entry, sizeof(entry))) {
+ ERRMSG("Can't read swapper_pg_dir entry.\n");
+ return NOT_PADDR;
+ }
level = TABLE_LEVEL(entry);
len = TABLE_LENGTH(entry);
--
2.40.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] s390x: uncouple virtual and physical address spaces
2023-11-29 12:50 [PATCH 0/2] s390x: uncouple physical and virtual memory spaces Alexander Gordeev
2023-11-29 12:50 ` [PATCH 1/2] s390x: fix virtual vs physical address confusion Alexander Gordeev
@ 2023-11-29 12:50 ` Alexander Gordeev
2023-12-05 7:24 ` HAGIO KAZUHITO(萩尾 一仁)
1 sibling, 1 reply; 7+ messages in thread
From: Alexander Gordeev @ 2023-11-29 12:50 UTC (permalink / raw)
To: kexec
Rework vaddr_to_paddr() and paddr_to_vaddr() 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@linux.ibm.com>
---
arch/s390x.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++-
makedumpfile.c | 2 +
makedumpfile.h | 12 ++++-
3 files changed, 145 insertions(+), 3 deletions(-)
diff --git a/arch/s390x.c b/arch/s390x.c
index a01f164..8ba2267 100644
--- a/arch/s390x.c
+++ b/arch/s390x.c
@@ -59,6 +59,69 @@
#define rsg_offset(x, y) (rsg_index( x, y) * sizeof(unsigned long))
#define pte_offset(x) (pte_index(x) * sizeof(unsigned long))
+#define LOWCORE_SIZE 0x2000
+
+#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));
+
+#define S390X_LC_OS_INFO 0x0e18
+
+struct s390_ops {
+ unsigned long long (*virt_to_phys)(unsigned long vaddr);
+ unsigned long (*phys_to_virt)(unsigned long long paddr);
+};
+
+static unsigned long long vaddr_to_paddr_s390x_legacy(unsigned long vaddr);
+static unsigned long long vaddr_to_paddr_s390x_vr(unsigned long vaddr);
+static unsigned long paddr_to_vaddr_s390x_legacy(unsigned long long paddr);
+static unsigned long paddr_to_vaddr_s390x_vr(unsigned long long paddr);
+
+struct s390_ops s390_ops = {
+ .virt_to_phys = vaddr_to_paddr_s390x_legacy,
+ .phys_to_virt = paddr_to_vaddr_s390x_legacy,
+};
+
+unsigned long long vaddr_to_paddr_s390x(unsigned long vaddr)
+{
+ return s390_ops.virt_to_phys(vaddr);
+}
+
+unsigned long paddr_to_vaddr_s390x(unsigned long long paddr)
+{
+ return s390_ops.phys_to_virt(paddr);
+}
+
int
set_s390x_max_physmem_bits(void)
{
@@ -88,12 +151,53 @@ set_s390x_max_physmem_bits(void)
return FALSE;
}
+static int s390x_init_vm(void)
+{
+ struct os_info os_info;
+ ulong addr;
+
+ if (!readmem(PADDR, S390X_LC_OS_INFO, &addr,
+ sizeof(addr)) || !addr) {
+ ERRMSG("Can't get s390x os_info ptr.\n");
+ return FALSE;
+ }
+
+ if (addr == 0)
+ return TRUE;
+
+ if (!readmem(PADDR, addr, &os_info, offsetof(struct os_info, reserved))) {
+ ERRMSG("Can't get os_info header.\n");
+ return FALSE;
+ }
+
+ if (!os_info.entry[OS_INFO_KASLR_OFFSET].val)
+ return TRUE;
+
+ MSG("The -vr kernel detected.\n");
+
+ info->identity_map_base = os_info.entry[OS_INFO_IDENTITY_BASE].val;
+ info->kvbase = os_info.entry[OS_INFO_KASLR_OFFSET].val;
+ info->__kaslr_offset_phys = os_info.entry[OS_INFO_KASLR_OFF_PHYS].val;
+ info->vmemmap_start = os_info.entry[OS_INFO_VMEMMAP].val;
+ info->amode31_start = os_info.entry[OS_INFO_AMODE31_START].val;
+ info->amode31_end = os_info.entry[OS_INFO_AMODE31_END].val;
+
+ s390_ops.virt_to_phys = vaddr_to_paddr_s390x_vr;
+ s390_ops.phys_to_virt = paddr_to_vaddr_s390x_vr;
+
+ return TRUE;
+}
+
+
int
get_machdep_info_s390x(void)
{
unsigned long vmalloc_start;
char *term_str = getenv("TERM");
+ if (!s390x_init_vm())
+ return FALSE;
+
if (term_str && strcmp(term_str, "dumb") == 0)
/* '\r' control character is ignored on "dumb" terminal. */
flag_ignore_r_char = 1;
@@ -295,8 +399,8 @@ vtop_s390x(unsigned long vaddr)
return paddr;
}
-unsigned long long
-vaddr_to_paddr_s390x(unsigned long vaddr)
+static unsigned long long
+vaddr_to_paddr_s390x_legacy(unsigned long vaddr)
{
unsigned long long paddr;
@@ -320,6 +424,32 @@ vaddr_to_paddr_s390x(unsigned long vaddr)
return paddr;
}
+static unsigned long long
+vaddr_to_paddr_s390x_vr(unsigned long vaddr)
+{
+ if (vaddr < LOWCORE_SIZE)
+ return vaddr;
+ if ((vaddr < info->amode31_end) && (vaddr >= info->amode31_start))
+ return vaddr;
+ if (vaddr < info->vmemmap_start)
+ return vaddr - info->identity_map_base;
+ if (vaddr >= info->kvbase)
+ return vaddr - info->kvbase + info->__kaslr_offset_phys;
+ return vtop_s390x(vaddr);
+}
+
+unsigned long
+paddr_to_vaddr_s390x_legacy(unsigned long long paddr)
+{
+ return (unsigned long)paddr_to_vaddr_general(paddr);
+}
+
+unsigned long
+paddr_to_vaddr_s390x_vr(unsigned long long paddr)
+{
+ return info->identity_map_base + (unsigned long)paddr;
+}
+
struct addr_check {
unsigned long addr;
int found;
diff --git a/makedumpfile.c b/makedumpfile.c
index a6ec9d4..568889b 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -1654,6 +1654,7 @@ get_symbol_info(void)
SYMBOL_INIT(max_pfn, "max_pfn");
SYMBOL_INIT(modules, "modules");
SYMBOL_INIT(high_memory, "high_memory");
+ SYMBOL_INIT(__kernel_base, "__kernel_base");
SYMBOL_INIT(linux_banner, "linux_banner");
SYMBOL_INIT(bios_cpu_apicid, "bios_cpu_apicid");
SYMBOL_INIT(x86_bios_cpu_apicid, "x86_bios_cpu_apicid");
@@ -2819,6 +2820,7 @@ read_vmcoreinfo(void)
READ_SYMBOL("log_next_idx", log_next_idx);
READ_SYMBOL("max_pfn", max_pfn);
READ_SYMBOL("high_memory", high_memory);
+ READ_SYMBOL("__kernel_base", __kernel_base);
READ_SYMBOL("node_remap_start_vaddr", node_remap_start_vaddr);
READ_SYMBOL("node_remap_end_vaddr", node_remap_end_vaddr);
READ_SYMBOL("node_remap_start_pfn", node_remap_start_pfn);
diff --git a/makedumpfile.h b/makedumpfile.h
index 59a809c..81e2daf 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -1235,6 +1235,7 @@ unsigned long long vaddr_to_paddr_ppc(unsigned long vaddr);
#ifdef __s390x__ /* s390x */
int get_machdep_info_s390x(void);
unsigned long long vaddr_to_paddr_s390x(unsigned long vaddr);
+unsigned long paddr_to_vaddr_s390x(unsigned long long paddr);
int is_iomem_phys_addr_s390x(unsigned long addr);
#define find_vmemmap() stub_false()
#define get_phys_base() stub_true()
@@ -1242,7 +1243,7 @@ int is_iomem_phys_addr_s390x(unsigned long addr);
#define get_versiondep_info() stub_true()
#define get_kaslr_offset(X) get_kaslr_offset_general(X)
#define vaddr_to_paddr(X) vaddr_to_paddr_s390x(X)
-#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
+#define paddr_to_vaddr(X) paddr_to_vaddr_s390x(X)
#define is_phys_addr(X) is_iomem_phys_addr_s390x(X)
#define arch_crashkernel_mem_size() stub_false()
#endif /* s390x */
@@ -1760,6 +1761,14 @@ struct DumpInfo {
pthread_mutex_t current_pfn_mutex;
pthread_mutex_t page_data_mutex;
pthread_mutex_t filter_mutex;
+
+#ifdef __s390x__ /* s390x */
+ unsigned long identity_map_base;
+ unsigned long kvbase;
+ unsigned long __kaslr_offset_phys;
+ unsigned long amode31_start;
+ unsigned long amode31_end;
+#endif
};
extern struct DumpInfo *info;
@@ -1869,6 +1878,7 @@ struct symbol_table {
* vmalloc_start address on s390x arch
*/
unsigned long long high_memory;
+ unsigned long long __kernel_base;
/*
* for sadump
--
2.40.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] s390x: uncouple virtual and physical address spaces
2023-11-29 12:50 ` [PATCH 2/2] s390x: uncouple virtual and physical address spaces Alexander Gordeev
@ 2023-12-05 7:24 ` HAGIO KAZUHITO(萩尾 一仁)
2023-12-05 15:01 ` Alexander Gordeev
0 siblings, 1 reply; 7+ messages in thread
From: HAGIO KAZUHITO(萩尾 一仁) @ 2023-12-05 7:24 UTC (permalink / raw)
To: Alexander Gordeev, kexec@lists.infradead.org
On 2023/11/29 21:50, Alexander Gordeev wrote:
> Rework vaddr_to_paddr() and paddr_to_vaddr() 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@linux.ibm.com>
> ---
> arch/s390x.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++-
> makedumpfile.c | 2 +
> makedumpfile.h | 12 ++++-
> 3 files changed, 145 insertions(+), 3 deletions(-)
>
> diff --git a/arch/s390x.c b/arch/s390x.c
> index a01f164..8ba2267 100644
> --- a/arch/s390x.c
> +++ b/arch/s390x.c
> @@ -59,6 +59,69 @@
> #define rsg_offset(x, y) (rsg_index( x, y) * sizeof(unsigned long))
> #define pte_offset(x) (pte_index(x) * sizeof(unsigned long))
>
> +#define LOWCORE_SIZE 0x2000
> +
> +#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));
are the __u* types defined on s390x? at least make with TARGET=s390xx
on x86_64 by my test fails.
$ make LINKTYPE=dynamic TARGET=s390xx
...
cc -g -O2 -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
-D_LARGEFILE64_SOURCE -D__s390x__ -U__x86_64__ -c -o ./arch/s390x.o
arch/s390x.c
arch/s390x.c:80:3: error: unknown type name '__u64'
__u64 addr;
^~~~~
arch/s390x.c:81:3: error: unknown type name '__u64'
__u64 val;
^~~~~
...
make: *** [Makefile:111: arch/s390x.o] Error 1
("s390xx" is strange but Makefile needs it somehow...)
> +
> +#define S390X_LC_OS_INFO 0x0e18
> +
> +struct s390_ops {
> + unsigned long long (*virt_to_phys)(unsigned long vaddr);
> + unsigned long (*phys_to_virt)(unsigned long long paddr);
> +};
> +
> +static unsigned long long vaddr_to_paddr_s390x_legacy(unsigned long vaddr);
> +static unsigned long long vaddr_to_paddr_s390x_vr(unsigned long vaddr);
> +static unsigned long paddr_to_vaddr_s390x_legacy(unsigned long long paddr);
> +static unsigned long paddr_to_vaddr_s390x_vr(unsigned long long paddr);
> +
> +struct s390_ops s390_ops = {
> + .virt_to_phys = vaddr_to_paddr_s390x_legacy,
> + .phys_to_virt = paddr_to_vaddr_s390x_legacy,
> +};
> +
> +unsigned long long vaddr_to_paddr_s390x(unsigned long vaddr)
> +{
> + return s390_ops.virt_to_phys(vaddr);
> +}
> +
> +unsigned long paddr_to_vaddr_s390x(unsigned long long paddr)
> +{
> + return s390_ops.phys_to_virt(paddr);
> +}
> +
> int
> set_s390x_max_physmem_bits(void)
> {
> @@ -88,12 +151,53 @@ set_s390x_max_physmem_bits(void)
> return FALSE;
> }
>
> +static int s390x_init_vm(void)
> +{
> + struct os_info os_info;
> + ulong addr;
> +
> + if (!readmem(PADDR, S390X_LC_OS_INFO, &addr,
> + sizeof(addr)) || !addr) {
> + ERRMSG("Can't get s390x os_info ptr.\n");
> + return FALSE;
> + }
> +
> + if (addr == 0)
> + return TRUE;
> +
> + if (!readmem(PADDR, addr, &os_info, offsetof(struct os_info, reserved))) {
> + ERRMSG("Can't get os_info header.\n");
> + return FALSE;
> + }
> +
> + if (!os_info.entry[OS_INFO_KASLR_OFFSET].val)
> + return TRUE;
> +
> + MSG("The -vr kernel detected.\n");
> +
> + info->identity_map_base = os_info.entry[OS_INFO_IDENTITY_BASE].val;
> + info->kvbase = os_info.entry[OS_INFO_KASLR_OFFSET].val;
> + info->__kaslr_offset_phys = os_info.entry[OS_INFO_KASLR_OFF_PHYS].val;
> + info->vmemmap_start = os_info.entry[OS_INFO_VMEMMAP].val;
> + info->amode31_start = os_info.entry[OS_INFO_AMODE31_START].val;
> + info->amode31_end = os_info.entry[OS_INFO_AMODE31_END].val;
> +
> + s390_ops.virt_to_phys = vaddr_to_paddr_s390x_vr;
> + s390_ops.phys_to_virt = paddr_to_vaddr_s390x_vr;
> +
> + return TRUE;
> +}
> +
> +
> int
> get_machdep_info_s390x(void)
> {
> unsigned long vmalloc_start;
> char *term_str = getenv("TERM");
>
> + if (!s390x_init_vm())
> + return FALSE;
> +
> if (term_str && strcmp(term_str, "dumb") == 0)
> /* '\r' control character is ignored on "dumb" terminal. */
> flag_ignore_r_char = 1;
> @@ -295,8 +399,8 @@ vtop_s390x(unsigned long vaddr)
> return paddr;
> }
>
> -unsigned long long
> -vaddr_to_paddr_s390x(unsigned long vaddr)
> +static unsigned long long
> +vaddr_to_paddr_s390x_legacy(unsigned long vaddr)
> {
> unsigned long long paddr;
>
> @@ -320,6 +424,32 @@ vaddr_to_paddr_s390x(unsigned long vaddr)
> return paddr;
> }
>
> +static unsigned long long
> +vaddr_to_paddr_s390x_vr(unsigned long vaddr)
> +{
> + if (vaddr < LOWCORE_SIZE)
> + return vaddr;
> + if ((vaddr < info->amode31_end) && (vaddr >= info->amode31_start))
> + return vaddr;
> + if (vaddr < info->vmemmap_start)
> + return vaddr - info->identity_map_base;
> + if (vaddr >= info->kvbase)
> + return vaddr - info->kvbase + info->__kaslr_offset_phys;
> + return vtop_s390x(vaddr);
> +}
> +
> +unsigned long
> +paddr_to_vaddr_s390x_legacy(unsigned long long paddr)
> +{
> + return (unsigned long)paddr_to_vaddr_general(paddr);
> +}
> +
> +unsigned long
> +paddr_to_vaddr_s390x_vr(unsigned long long paddr)
> +{
> + return info->identity_map_base + (unsigned long)paddr;
> +}
> +
> struct addr_check {
> unsigned long addr;
> int found;
> diff --git a/makedumpfile.c b/makedumpfile.c
> index a6ec9d4..568889b 100644
> --- a/makedumpfile.c
> +++ b/makedumpfile.c
> @@ -1654,6 +1654,7 @@ get_symbol_info(void)
> SYMBOL_INIT(max_pfn, "max_pfn");
> SYMBOL_INIT(modules, "modules");
> SYMBOL_INIT(high_memory, "high_memory");
> + SYMBOL_INIT(__kernel_base, "__kernel_base");
> SYMBOL_INIT(linux_banner, "linux_banner");
> SYMBOL_INIT(bios_cpu_apicid, "bios_cpu_apicid");
> SYMBOL_INIT(x86_bios_cpu_apicid, "x86_bios_cpu_apicid");
> @@ -2819,6 +2820,7 @@ read_vmcoreinfo(void)
> READ_SYMBOL("log_next_idx", log_next_idx);
> READ_SYMBOL("max_pfn", max_pfn);
> READ_SYMBOL("high_memory", high_memory);
> + READ_SYMBOL("__kernel_base", __kernel_base);
> READ_SYMBOL("node_remap_start_vaddr", node_remap_start_vaddr);
> READ_SYMBOL("node_remap_end_vaddr", node_remap_end_vaddr);
> READ_SYMBOL("node_remap_start_pfn", node_remap_start_pfn);
> diff --git a/makedumpfile.h b/makedumpfile.h
> index 59a809c..81e2daf 100644
> --- a/makedumpfile.h
> +++ b/makedumpfile.h
> @@ -1235,6 +1235,7 @@ unsigned long long vaddr_to_paddr_ppc(unsigned long vaddr);
> #ifdef __s390x__ /* s390x */
> int get_machdep_info_s390x(void);
> unsigned long long vaddr_to_paddr_s390x(unsigned long vaddr);
> +unsigned long paddr_to_vaddr_s390x(unsigned long long paddr);
> int is_iomem_phys_addr_s390x(unsigned long addr);
> #define find_vmemmap() stub_false()
> #define get_phys_base() stub_true()
> @@ -1242,7 +1243,7 @@ int is_iomem_phys_addr_s390x(unsigned long addr);
> #define get_versiondep_info() stub_true()
> #define get_kaslr_offset(X) get_kaslr_offset_general(X)
> #define vaddr_to_paddr(X) vaddr_to_paddr_s390x(X)
> -#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
> +#define paddr_to_vaddr(X) paddr_to_vaddr_s390x(X)
> #define is_phys_addr(X) is_iomem_phys_addr_s390x(X)
> #define arch_crashkernel_mem_size() stub_false()
> #endif /* s390x */
> @@ -1760,6 +1761,14 @@ struct DumpInfo {
> pthread_mutex_t current_pfn_mutex;
> pthread_mutex_t page_data_mutex;
> pthread_mutex_t filter_mutex;
> +
> +#ifdef __s390x__ /* s390x */
> + unsigned long identity_map_base;
> + unsigned long kvbase;
> + unsigned long __kaslr_offset_phys;
> + unsigned long amode31_start;
> + unsigned long amode31_end;
> +#endif
> };
> extern struct DumpInfo *info;
>
> @@ -1869,6 +1878,7 @@ struct symbol_table {
> * vmalloc_start address on s390x arch
> */
> unsigned long long high_memory;
> + unsigned long long __kernel_base;
Is SYMBOL(__kernel_base) not used? If it will be introduced and used
later, please add it at that time.
Thanks,
Kazu
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] s390x: uncouple virtual and physical address spaces
2023-12-05 7:24 ` HAGIO KAZUHITO(萩尾 一仁)
@ 2023-12-05 15:01 ` Alexander Gordeev
2023-12-05 15:01 ` [PATCH v2 " Alexander Gordeev
0 siblings, 1 reply; 7+ messages in thread
From: Alexander Gordeev @ 2023-12-05 15:01 UTC (permalink / raw)
To: HAGIO KAZUHITO(萩尾 一仁)
Cc: kexec@lists.infradead.org
On Tue, Dec 05, 2023 at 07:24:56AM +0000, HAGIO KAZUHITO(萩尾 一仁) wrote:
Hi HAGIO!
...
> > +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));
>
> are the __u* types defined on s390x? at least make with TARGET=s390xx
> on x86_64 by my test fails.
It does not fail for s390x, but it should not be there anyway, indeed.
I will post v2 as a follow-up to this mail.
> $ make LINKTYPE=dynamic TARGET=s390xx
> ...
> cc -g -O2 -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
> -D_LARGEFILE64_SOURCE -D__s390x__ -U__x86_64__ -c -o ./arch/s390x.o
> arch/s390x.c
> arch/s390x.c:80:3: error: unknown type name '__u64'
> __u64 addr;
> ^~~~~
> arch/s390x.c:81:3: error: unknown type name '__u64'
> __u64 val;
> ^~~~~
> ...
> make: *** [Makefile:111: arch/s390x.o] Error 1
>
> ("s390xx" is strange but Makefile needs it somehow...)
...
> > @@ -1869,6 +1878,7 @@ struct symbol_table {
> > * vmalloc_start address on s390x arch
> > */
> > unsigned long long high_memory;
> > + unsigned long long __kernel_base;
>
> Is SYMBOL(__kernel_base) not used? If it will be introduced and used
> later, please add it at that time.
That is a leftover. Removed in v2.
> Thanks,
> Kazu
Thanks, Kazu!
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 2/2] s390x: uncouple virtual and physical address spaces
2023-12-05 15:01 ` Alexander Gordeev
@ 2023-12-05 15:01 ` Alexander Gordeev
2023-12-06 4:56 ` HAGIO KAZUHITO(萩尾 一仁)
0 siblings, 1 reply; 7+ messages in thread
From: Alexander Gordeev @ 2023-12-05 15:01 UTC (permalink / raw)
To: HAGIO KAZUHITO(萩尾 一仁)
Cc: kexec@lists.infradead.org
Rework vaddr_to_paddr() and paddr_to_vaddr() 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@linux.ibm.com>
---
arch/s390x.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++-
makedumpfile.h | 11 +++-
2 files changed, 142 insertions(+), 3 deletions(-)
diff --git a/arch/s390x.c b/arch/s390x.c
index a01f164..4a993be 100644
--- a/arch/s390x.c
+++ b/arch/s390x.c
@@ -59,6 +59,69 @@
#define rsg_offset(x, y) (rsg_index( x, y) * sizeof(unsigned long))
#define pte_offset(x) (pte_index(x) * sizeof(unsigned long))
+#define LOWCORE_SIZE 0x2000
+
+#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 {
+ uint64_t addr;
+ uint64_t val;
+ };
+ uint64_t size;
+ uint32_t csum;
+} __attribute__((packed));
+
+struct os_info {
+ uint64_t magic;
+ uint32_t csum;
+ uint16_t version_major;
+ uint16_t version_minor;
+ uint64_t crashkernel_addr;
+ uint64_t crashkernel_size;
+ struct os_info_entry entry[10];
+ uint8_t reserved[3864];
+} __attribute__((packed));
+
+#define S390X_LC_OS_INFO 0x0e18
+
+struct s390_ops {
+ unsigned long long (*virt_to_phys)(unsigned long vaddr);
+ unsigned long (*phys_to_virt)(unsigned long long paddr);
+};
+
+static unsigned long long vaddr_to_paddr_s390x_legacy(unsigned long vaddr);
+static unsigned long long vaddr_to_paddr_s390x_vr(unsigned long vaddr);
+static unsigned long paddr_to_vaddr_s390x_legacy(unsigned long long paddr);
+static unsigned long paddr_to_vaddr_s390x_vr(unsigned long long paddr);
+
+struct s390_ops s390_ops = {
+ .virt_to_phys = vaddr_to_paddr_s390x_legacy,
+ .phys_to_virt = paddr_to_vaddr_s390x_legacy,
+};
+
+unsigned long long vaddr_to_paddr_s390x(unsigned long vaddr)
+{
+ return s390_ops.virt_to_phys(vaddr);
+}
+
+unsigned long paddr_to_vaddr_s390x(unsigned long long paddr)
+{
+ return s390_ops.phys_to_virt(paddr);
+}
+
int
set_s390x_max_physmem_bits(void)
{
@@ -88,12 +151,53 @@ set_s390x_max_physmem_bits(void)
return FALSE;
}
+static int s390x_init_vm(void)
+{
+ struct os_info os_info;
+ ulong addr;
+
+ if (!readmem(PADDR, S390X_LC_OS_INFO, &addr,
+ sizeof(addr)) || !addr) {
+ ERRMSG("Can't get s390x os_info ptr.\n");
+ return FALSE;
+ }
+
+ if (addr == 0)
+ return TRUE;
+
+ if (!readmem(PADDR, addr, &os_info, offsetof(struct os_info, reserved))) {
+ ERRMSG("Can't get os_info header.\n");
+ return FALSE;
+ }
+
+ if (!os_info.entry[OS_INFO_KASLR_OFFSET].val)
+ return TRUE;
+
+ MSG("The -vr kernel detected.\n");
+
+ info->identity_map_base = os_info.entry[OS_INFO_IDENTITY_BASE].val;
+ info->kvbase = os_info.entry[OS_INFO_KASLR_OFFSET].val;
+ info->__kaslr_offset_phys = os_info.entry[OS_INFO_KASLR_OFF_PHYS].val;
+ info->vmemmap_start = os_info.entry[OS_INFO_VMEMMAP].val;
+ info->amode31_start = os_info.entry[OS_INFO_AMODE31_START].val;
+ info->amode31_end = os_info.entry[OS_INFO_AMODE31_END].val;
+
+ s390_ops.virt_to_phys = vaddr_to_paddr_s390x_vr;
+ s390_ops.phys_to_virt = paddr_to_vaddr_s390x_vr;
+
+ return TRUE;
+}
+
+
int
get_machdep_info_s390x(void)
{
unsigned long vmalloc_start;
char *term_str = getenv("TERM");
+ if (!s390x_init_vm())
+ return FALSE;
+
if (term_str && strcmp(term_str, "dumb") == 0)
/* '\r' control character is ignored on "dumb" terminal. */
flag_ignore_r_char = 1;
@@ -295,8 +399,8 @@ vtop_s390x(unsigned long vaddr)
return paddr;
}
-unsigned long long
-vaddr_to_paddr_s390x(unsigned long vaddr)
+static unsigned long long
+vaddr_to_paddr_s390x_legacy(unsigned long vaddr)
{
unsigned long long paddr;
@@ -320,6 +424,32 @@ vaddr_to_paddr_s390x(unsigned long vaddr)
return paddr;
}
+static unsigned long long
+vaddr_to_paddr_s390x_vr(unsigned long vaddr)
+{
+ if (vaddr < LOWCORE_SIZE)
+ return vaddr;
+ if ((vaddr < info->amode31_end) && (vaddr >= info->amode31_start))
+ return vaddr;
+ if (vaddr < info->vmemmap_start)
+ return vaddr - info->identity_map_base;
+ if (vaddr >= info->kvbase)
+ return vaddr - info->kvbase + info->__kaslr_offset_phys;
+ return vtop_s390x(vaddr);
+}
+
+unsigned long
+paddr_to_vaddr_s390x_legacy(unsigned long long paddr)
+{
+ return (unsigned long)paddr_to_vaddr_general(paddr);
+}
+
+unsigned long
+paddr_to_vaddr_s390x_vr(unsigned long long paddr)
+{
+ return info->identity_map_base + (unsigned long)paddr;
+}
+
struct addr_check {
unsigned long addr;
int found;
diff --git a/makedumpfile.h b/makedumpfile.h
index 59a809c..f1619c5 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -1235,6 +1235,7 @@ unsigned long long vaddr_to_paddr_ppc(unsigned long vaddr);
#ifdef __s390x__ /* s390x */
int get_machdep_info_s390x(void);
unsigned long long vaddr_to_paddr_s390x(unsigned long vaddr);
+unsigned long paddr_to_vaddr_s390x(unsigned long long paddr);
int is_iomem_phys_addr_s390x(unsigned long addr);
#define find_vmemmap() stub_false()
#define get_phys_base() stub_true()
@@ -1242,7 +1243,7 @@ int is_iomem_phys_addr_s390x(unsigned long addr);
#define get_versiondep_info() stub_true()
#define get_kaslr_offset(X) get_kaslr_offset_general(X)
#define vaddr_to_paddr(X) vaddr_to_paddr_s390x(X)
-#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
+#define paddr_to_vaddr(X) paddr_to_vaddr_s390x(X)
#define is_phys_addr(X) is_iomem_phys_addr_s390x(X)
#define arch_crashkernel_mem_size() stub_false()
#endif /* s390x */
@@ -1760,6 +1761,14 @@ struct DumpInfo {
pthread_mutex_t current_pfn_mutex;
pthread_mutex_t page_data_mutex;
pthread_mutex_t filter_mutex;
+
+#ifdef __s390x__ /* s390x */
+ unsigned long identity_map_base;
+ unsigned long kvbase;
+ unsigned long __kaslr_offset_phys;
+ unsigned long amode31_start;
+ unsigned long amode31_end;
+#endif
};
extern struct DumpInfo *info;
--
2.40.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 2/2] s390x: uncouple virtual and physical address spaces
2023-12-05 15:01 ` [PATCH v2 " Alexander Gordeev
@ 2023-12-06 4:56 ` HAGIO KAZUHITO(萩尾 一仁)
0 siblings, 0 replies; 7+ messages in thread
From: HAGIO KAZUHITO(萩尾 一仁) @ 2023-12-06 4:56 UTC (permalink / raw)
To: Alexander Gordeev; +Cc: kexec@lists.infradead.org
On 2023/12/06 0:01, Alexander Gordeev wrote:
> Rework vaddr_to_paddr() and paddr_to_vaddr() 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@linux.ibm.com>
Thank you for the v2, applied.
Kazu
> ---
> arch/s390x.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++-
> makedumpfile.h | 11 +++-
> 2 files changed, 142 insertions(+), 3 deletions(-)
>
> diff --git a/arch/s390x.c b/arch/s390x.c
> index a01f164..4a993be 100644
> --- a/arch/s390x.c
> +++ b/arch/s390x.c
> @@ -59,6 +59,69 @@
> #define rsg_offset(x, y) (rsg_index( x, y) * sizeof(unsigned long))
> #define pte_offset(x) (pte_index(x) * sizeof(unsigned long))
>
> +#define LOWCORE_SIZE 0x2000
> +
> +#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 {
> + uint64_t addr;
> + uint64_t val;
> + };
> + uint64_t size;
> + uint32_t csum;
> +} __attribute__((packed));
> +
> +struct os_info {
> + uint64_t magic;
> + uint32_t csum;
> + uint16_t version_major;
> + uint16_t version_minor;
> + uint64_t crashkernel_addr;
> + uint64_t crashkernel_size;
> + struct os_info_entry entry[10];
> + uint8_t reserved[3864];
> +} __attribute__((packed));
> +
> +#define S390X_LC_OS_INFO 0x0e18
> +
> +struct s390_ops {
> + unsigned long long (*virt_to_phys)(unsigned long vaddr);
> + unsigned long (*phys_to_virt)(unsigned long long paddr);
> +};
> +
> +static unsigned long long vaddr_to_paddr_s390x_legacy(unsigned long vaddr);
> +static unsigned long long vaddr_to_paddr_s390x_vr(unsigned long vaddr);
> +static unsigned long paddr_to_vaddr_s390x_legacy(unsigned long long paddr);
> +static unsigned long paddr_to_vaddr_s390x_vr(unsigned long long paddr);
> +
> +struct s390_ops s390_ops = {
> + .virt_to_phys = vaddr_to_paddr_s390x_legacy,
> + .phys_to_virt = paddr_to_vaddr_s390x_legacy,
> +};
> +
> +unsigned long long vaddr_to_paddr_s390x(unsigned long vaddr)
> +{
> + return s390_ops.virt_to_phys(vaddr);
> +}
> +
> +unsigned long paddr_to_vaddr_s390x(unsigned long long paddr)
> +{
> + return s390_ops.phys_to_virt(paddr);
> +}
> +
> int
> set_s390x_max_physmem_bits(void)
> {
> @@ -88,12 +151,53 @@ set_s390x_max_physmem_bits(void)
> return FALSE;
> }
>
> +static int s390x_init_vm(void)
> +{
> + struct os_info os_info;
> + ulong addr;
> +
> + if (!readmem(PADDR, S390X_LC_OS_INFO, &addr,
> + sizeof(addr)) || !addr) {
> + ERRMSG("Can't get s390x os_info ptr.\n");
> + return FALSE;
> + }
> +
> + if (addr == 0)
> + return TRUE;
> +
> + if (!readmem(PADDR, addr, &os_info, offsetof(struct os_info, reserved))) {
> + ERRMSG("Can't get os_info header.\n");
> + return FALSE;
> + }
> +
> + if (!os_info.entry[OS_INFO_KASLR_OFFSET].val)
> + return TRUE;
> +
> + MSG("The -vr kernel detected.\n");
> +
> + info->identity_map_base = os_info.entry[OS_INFO_IDENTITY_BASE].val;
> + info->kvbase = os_info.entry[OS_INFO_KASLR_OFFSET].val;
> + info->__kaslr_offset_phys = os_info.entry[OS_INFO_KASLR_OFF_PHYS].val;
> + info->vmemmap_start = os_info.entry[OS_INFO_VMEMMAP].val;
> + info->amode31_start = os_info.entry[OS_INFO_AMODE31_START].val;
> + info->amode31_end = os_info.entry[OS_INFO_AMODE31_END].val;
> +
> + s390_ops.virt_to_phys = vaddr_to_paddr_s390x_vr;
> + s390_ops.phys_to_virt = paddr_to_vaddr_s390x_vr;
> +
> + return TRUE;
> +}
> +
> +
> int
> get_machdep_info_s390x(void)
> {
> unsigned long vmalloc_start;
> char *term_str = getenv("TERM");
>
> + if (!s390x_init_vm())
> + return FALSE;
> +
> if (term_str && strcmp(term_str, "dumb") == 0)
> /* '\r' control character is ignored on "dumb" terminal. */
> flag_ignore_r_char = 1;
> @@ -295,8 +399,8 @@ vtop_s390x(unsigned long vaddr)
> return paddr;
> }
>
> -unsigned long long
> -vaddr_to_paddr_s390x(unsigned long vaddr)
> +static unsigned long long
> +vaddr_to_paddr_s390x_legacy(unsigned long vaddr)
> {
> unsigned long long paddr;
>
> @@ -320,6 +424,32 @@ vaddr_to_paddr_s390x(unsigned long vaddr)
> return paddr;
> }
>
> +static unsigned long long
> +vaddr_to_paddr_s390x_vr(unsigned long vaddr)
> +{
> + if (vaddr < LOWCORE_SIZE)
> + return vaddr;
> + if ((vaddr < info->amode31_end) && (vaddr >= info->amode31_start))
> + return vaddr;
> + if (vaddr < info->vmemmap_start)
> + return vaddr - info->identity_map_base;
> + if (vaddr >= info->kvbase)
> + return vaddr - info->kvbase + info->__kaslr_offset_phys;
> + return vtop_s390x(vaddr);
> +}
> +
> +unsigned long
> +paddr_to_vaddr_s390x_legacy(unsigned long long paddr)
> +{
> + return (unsigned long)paddr_to_vaddr_general(paddr);
> +}
> +
> +unsigned long
> +paddr_to_vaddr_s390x_vr(unsigned long long paddr)
> +{
> + return info->identity_map_base + (unsigned long)paddr;
> +}
> +
> struct addr_check {
> unsigned long addr;
> int found;
> diff --git a/makedumpfile.h b/makedumpfile.h
> index 59a809c..f1619c5 100644
> --- a/makedumpfile.h
> +++ b/makedumpfile.h
> @@ -1235,6 +1235,7 @@ unsigned long long vaddr_to_paddr_ppc(unsigned long vaddr);
> #ifdef __s390x__ /* s390x */
> int get_machdep_info_s390x(void);
> unsigned long long vaddr_to_paddr_s390x(unsigned long vaddr);
> +unsigned long paddr_to_vaddr_s390x(unsigned long long paddr);
> int is_iomem_phys_addr_s390x(unsigned long addr);
> #define find_vmemmap() stub_false()
> #define get_phys_base() stub_true()
> @@ -1242,7 +1243,7 @@ int is_iomem_phys_addr_s390x(unsigned long addr);
> #define get_versiondep_info() stub_true()
> #define get_kaslr_offset(X) get_kaslr_offset_general(X)
> #define vaddr_to_paddr(X) vaddr_to_paddr_s390x(X)
> -#define paddr_to_vaddr(X) paddr_to_vaddr_general(X)
> +#define paddr_to_vaddr(X) paddr_to_vaddr_s390x(X)
> #define is_phys_addr(X) is_iomem_phys_addr_s390x(X)
> #define arch_crashkernel_mem_size() stub_false()
> #endif /* s390x */
> @@ -1760,6 +1761,14 @@ struct DumpInfo {
> pthread_mutex_t current_pfn_mutex;
> pthread_mutex_t page_data_mutex;
> pthread_mutex_t filter_mutex;
> +
> +#ifdef __s390x__ /* s390x */
> + unsigned long identity_map_base;
> + unsigned long kvbase;
> + unsigned long __kaslr_offset_phys;
> + unsigned long amode31_start;
> + unsigned long amode31_end;
> +#endif
> };
> extern struct DumpInfo *info;
>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-12-06 4:57 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-29 12:50 [PATCH 0/2] s390x: uncouple physical and virtual memory spaces Alexander Gordeev
2023-11-29 12:50 ` [PATCH 1/2] s390x: fix virtual vs physical address confusion Alexander Gordeev
2023-11-29 12:50 ` [PATCH 2/2] s390x: uncouple virtual and physical address spaces Alexander Gordeev
2023-12-05 7:24 ` HAGIO KAZUHITO(萩尾 一仁)
2023-12-05 15:01 ` Alexander Gordeev
2023-12-05 15:01 ` [PATCH v2 " Alexander Gordeev
2023-12-06 4:56 ` HAGIO KAZUHITO(萩尾 一仁)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox