[PATCH 2/2] s390x: uncouple virtual and physical address spaces

HAGIO KAZUHITO(萩尾 一仁) k-hagio-ab at nec.com
Mon Dec 4 23:24:56 PST 2023


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 at 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


More information about the kexec mailing list