s390x: vmalloc support
v3 cover s390x: vmalloc support
This series implements
- detection of installed physical memory
- setup of the physical allocator
- setup of the MMU / page tables / DAT
- setup of the virtual allocator
The CPU now runs with DAT enabled. I added a small test to make sure malloc() indeed works and uses virtual adresses. Also, the sieve test is added.
While at it, fix the TEST BLOCK test on newer compilers.
Tested with upsteam QEMU TCG and KVM. However, to pass under TCG a fix is necessary ("[PATCH v1] s390x/tcg: fix disabling/enabling DAT").
v2 -> v3:
- split up configure_dat() to make use of two functions extract_psw_mask() and load_psw_mask(), it is now much cleaner and we might need these functions in the future.
- Minor cleanups / comment fixes
David Hildenbrand (11):
s390x: fix TEST BLOCK tests
s390x: use highest addresses for PGM_ADDRESSING errors
s390x: set initital stack pointer to stackptr, not stacktop
s390x: add missing sclp definitions from QEMU
s390x: rename sclp_setup() to sclp_ascii_setup()
s390x: detect installed memory
s390x: initialize the physical allocator
s390x: add vmalloc support
s390x: enable DAT in PGM interrupt handler
s390x: add test for (v)malloc
s390x: add sieve test
lib/s390x/asm/arch_def.h | 58 ++++++++++++ lib/s390x/asm/interrupt.h | 1 + lib/s390x/asm/page.h | 24 +++++ lib/s390x/asm/pgtable.h | 224 ++++++++++++++++++++++++++++++++++++++++++++++ lib/s390x/interrupt.c | 11 +++ lib/s390x/io.c | 3 +- lib/s390x/mmu.c | 108 ++++++++++++++++++++++ lib/s390x/sclp-ascii.c | 6 +- lib/s390x/sclp.c | 72 +++++++++++++++ lib/s390x/sclp.h | 112 ++++++++++++++++++++++- s390x/Makefile | 7 ++ s390x/cstart64.S | 2 +- s390x/intercept.c | 14 +-- s390x/selftest.c | 31 ++++++- s390x/sieve.c | 59 ++++++++++++ s390x/unittests.cfg | 6 ++ 16 files changed, 723 insertions(+), 15 deletions(-) create mode 100644 lib/s390x/asm/pgtable.h create mode 100644 lib/s390x/mmu.c create mode 100644 lib/s390x/sclp.c create mode 100644 s390x/sieve.c
Signature · 1 line
2.14.3
PATCH v3 1/11 s390x: fix TEST BLOCK tests
While new compilers like
s390x-linux-gnu-gcc (GCC) 7.2.1 20170915 (Red Hat Cross 7.2.1-1) Complain, that R1 is missing, old compilers like gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16)
will complain that R1 is not valid.
Let's just specify the instruction explicitly.
--- s390x/intercept.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
s390x/intercept.c +3 -3
@@ -139,7 +139,7 @@ static void test_testblock(void) asmvolatile (" lghi %%r0,0\n" -" tb %1\n" +" .insn rre,0xb22c0000,0,%1\n" " ipm %0\n" " srl %0,28\n" : "=d" (cc)
@@ -150,12 +150,12 @@ static void test_testblock(void)expect_pgm_int ();low_prot_enable (); - asmvolatile (" tb %0 " : :"r" (4096 )); + asmvolatile (" .insn rre,0xb22c0000,0,%0\n" : :"r" (4096 ));low_prot_disable ();check_pgm_int_code (PGM_INT_CODE_PROTECTION );expect_pgm_int (); - asmvolatile (" tb %0 " : :"r" (-4096 )); + asmvolatile (" .insn rre,0xb22c0000,0,%0\n" : :"r" (-4096 ));check_pgm_int_code (PGM_INT_CODE_ADDRESSING ); }
Signature · 1 line
2.14.3
PATCH v3 2/11 s390x: use highest addresses for PGM_ADDRESSING errors
In reply to David HildenbrandWithout the L, we get 32 bit addresses, resulting in different memory addresses. This is necessary for enabling the MMU.
--- s390x/intercept.c | 10 +++++----- s390x/selftest.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-)
s390x/intercept.c +5 -5
@@ -46,7 +46,7 @@ static void test_stpx(void)check_pgm_int_code (PGM_INT_CODE_SPECIFICATION );expect_pgm_int (); - asmvolatile (" stpx 0(%0) " : :"r" (-8 )); + asmvolatile (" stpx 0(%0) " : :"r" (-8L ));check_pgm_int_code (PGM_INT_CODE_ADDRESSING ); }
@@ -78,7 +78,7 @@ static void test_spx(void)check_pgm_int_code (PGM_INT_CODE_SPECIFICATION );expect_pgm_int (); - asmvolatile (" spx 0(%0) " : :"r" (-8 )); + asmvolatile (" spx 0(%0) " : :"r" (-8L ));check_pgm_int_code (PGM_INT_CODE_ADDRESSING ); }
@@ -101,7 +101,7 @@ static void test_stap(void)check_pgm_int_code (PGM_INT_CODE_SPECIFICATION );expect_pgm_int (); - asmvolatile ("stap 0(%0)\n" : :"r" (-8 )); + asmvolatile ("stap 0(%0)\n" : :"r" (-8L ));check_pgm_int_code (PGM_INT_CODE_ADDRESSING ); }
@@ -126,7 +126,7 @@ static void test_stidp(void)check_pgm_int_code (PGM_INT_CODE_SPECIFICATION );expect_pgm_int (); - asmvolatile ("stidp 0(%0)\n" : :"r" (-8 )); + asmvolatile ("stidp 0(%0)\n" : :"r" (-8L ));check_pgm_int_code (PGM_INT_CODE_ADDRESSING ); }
@@ -155,7 +155,7 @@ static void test_testblock(void)check_pgm_int_code (PGM_INT_CODE_PROTECTION );expect_pgm_int (); - asmvolatile (" .insn rre,0xb22c0000,0,%0\n" : :"r" (-4096 )); + asmvolatile (" .insn rre,0xb22c0000,0,%0\n" : :"r" (-4096L ));check_pgm_int_code (PGM_INT_CODE_ADDRESSING ); }
s390x/selftest.c +1 -1
@@ -33,7 +33,7 @@ static void test_pgm_int(void)check_pgm_int_code (PGM_INT_CODE_OPERATION );expect_pgm_int (); - asmvolatile (" stg %0,0(%0)\n" : :"r" (-1 )); + asmvolatile (" stg %0,0(%0)\n" : :"r" (-1L ));check_pgm_int_code (PGM_INT_CODE_ADDRESSING ); }
Signature · 1 line
2.14.3
PATCH v3 3/11 s390x: set initital stack pointer to stackptr, not stacktop
In reply to David Hildenbrand... was wrong from the beginning and remained unnoticed until we started playing with dynamic memory allocation.
--- s390x/cstart64.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
s390x/cstart64.S +1 -1
@@ -18,7 +18,7 @@ .globl start start: /* setup stack */ - larl %r15, stacktop + larl %r15, stackptr /* setup initial PSW mask + control registers*/ larl %r1, initital_psw lpswe 0(%r1)
Signature · 1 line
2.14.3
PATCH v3 4/11 s390x: add missing sclp definitions from QEMU
In reply to David HildenbrandCopy all missing definitions from QEMU (include/hw/s390x/sclp.h). We cannot simply replace the file, as some ASCII definitions are missing in the QEMU file (defined somewhere else in QEMU).
Convert QEMU_PACKED accordingly and copy the copyright statement.
--- lib/s390x/sclp.h | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-)
lib/s390x/sclp.h +106 -1
@@ -1,8 +1,13 @@/* -* SCLP ASCII access driver +* SCLP definitions * +* Based on the file pc-bios/s390-ccw/sclp.h from QEMU * Copyright (c) 2013 Alexander Graf <[email protected]> * +* and based on the file include/hw/s390x/sclp.h from QEMU +* Copyright IBM, Corp. 2012 +* Author: Christian Borntraeger <[email protected]> +* * This work is licensed under the terms of the GNU GPL, version 2 or (at * your option) any later version. See the COPYING file in the top-level * directory.
@@ -11,21 +16,51 @@#ifndef SCLP_H #define SCLP_H +#define SCLP_CMD_CODE_MASK 0xffff00ff +/* SCLP command codes */ #define SCLP_CMDW_READ_SCP_INFO 0x00020001#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 +#define SCLP_READ_STORAGE_ELEMENT_INFO 0x00040001 +#define SCLP_ATTACH_STORAGE_ELEMENT 0x00080001 +#define SCLP_ASSIGN_STORAGE 0x000D0001#define SCLP_CMD_READ_EVENT_DATA 0x00770005#define SCLP_CMD_WRITE_EVENT_DATA 0x00760005#define SCLP_CMD_READ_EVENT_DATA 0x00770005#define SCLP_CMD_WRITE_EVENT_DATA 0x00760005#define SCLP_CMD_WRITE_EVENT_MASK 0x00780005 +/* SCLP Memory hotplug codes */ +#define SCLP_FC_ASSIGN_ATTACH_READ_STOR 0xE00000000000ULL +#define SCLP_STARTING_SUBINCREMENT_ID 0x10001 +#define SCLP_INCREMENT_UNIT 0x10000 +#define MAX_AVAIL_SLOTS 32 +#define MAX_STORAGE_INCREMENTS 1020 + +/* CPU hotplug SCLP codes */ +#define SCLP_HAS_CPU_INFO 0x0C00000000000000ULL +#define SCLP_CMDW_READ_CPU_INFO 0x00010001 +#define SCLP_CMDW_CONFIGURE_CPU 0x00110001 +#define SCLP_CMDW_DECONFIGURE_CPU 0x00100001 + +/* SCLP PCI codes */ +#define SCLP_HAS_IOA_RECONFIG 0x0000000040000000ULL +#define SCLP_CMDW_CONFIGURE_IOA 0x001a0001 +#define SCLP_CMDW_DECONFIGURE_IOA 0x001b0001 +#define SCLP_RECONFIG_PCI_ATYPE 2 +/* SCLP response codes */ #define SCLP_RC_NORMAL_READ_COMPLETION 0x0010#define SCLP_RC_NORMAL_COMPLETION 0x0020 +#define SCLP_RC_SCCB_BOUNDARY_VIOLATION 0x0100 +#define SCLP_RC_NO_ACTION_REQUIRED 0x0120#define SCLP_RC_INVALID_SCLP_COMMAND 0x01f0#define SCLP_RC_CONTAINED_EQUIPMENT_CHECK 0x0340#define SCLP_RC_INSUFFICIENT_SCCB_LENGTH 0x0300 +#define SCLP_RC_STANDBY_READ_COMPLETION 0x0410 +#define SCLP_RC_ADAPTER_IN_RESERVED_STATE 0x05f0 +#define SCLP_RC_ADAPTER_TYPE_NOT_RECOGNIZED 0x06f0 +#define SCLP_RC_ADAPTER_ID_NOT_RECOGNIZED 0x09f0#define SCLP_RC_INVALID_FUNCTION 0x40f0#define SCLP_RC_NO_EVENT_BUFFERS_STORED 0x60f0#define SCLP_RC_INVALID_SELECTION_MASK 0x70f0
@@ -50,13 +85,83 @@ typedef struct SCCBHeader { } __attribute__((packed)) SCCBHeader;#define SCCB_DATA_LEN (SCCB_SIZE - sizeof(SCCBHeader)) +#define SCCB_CPU_FEATURE_LEN 6 + +/* CPU information */ +typedef struct CPUEntry { +uint8_t address; +uint8_t reserved0; +uint8_t features[SCCB_CPU_FEATURE_LEN ]; +uint8_t reserved2[6 ]; +uint8_t type; +uint8_t reserved1; +} __attribute__((packed))CPUEntry ;typedef struct ReadInfo {SCCBHeader h;uint16_t rnmax;uint8_t rnsize; +uint8_t _reserved1[16 -11 ];/* 11-15 */ +uint16_t entries_cpu;/* 16-17 */ +uint16_t offset_cpu;/* 18-19 */ +uint8_t _reserved2[24 -20 ];/* 20-23 */ +uint8_t loadparm[8 ];/* 24-31 */ +uint8_t _reserved3[48 -32 ];/* 32-47 */ +uint64_t facilities;/* 48-55 */ +uint8_t _reserved0[76 -56 ];/* 56-75 */ +uint32_t ibc_val; +uint8_t conf_char[99 -80 ];/* 80-98 */ +uint8_t mha_pow; +uint32_t rnsize2; +uint64_t rnmax2; +uint8_t _reserved6[116 -112 ];/* 112-115 */ +uint8_t conf_char_ext[120 -116 ];/* 116-119 */ +uint16_t highest_cpu; +uint8_t _reserved5[124 -122 ];/* 122-123 */ +uint32_t hmfai; +struct CPUEntry entries[0 ]; } __attribute__((packed))ReadInfo ; +typedef struct ReadCpuInfo { +SCCBHeader h; +uint16_t nr_configured;/* 8-9 */ +uint16_t offset_configured;/* 10-11 */ +uint16_t nr_standby;/* 12-13 */ +uint16_t offset_standby;/* 14-15 */ +uint8_t reserved0[24 -16 ];/* 16-23 */ +struct CPUEntry entries[0 ]; +} __attribute__((packed))ReadCpuInfo ; + +typedef struct ReadStorageElementInfo { +SCCBHeader h; +uint16_t max_id; +uint16_t assigned; +uint16_t standby; +uint8_t _reserved0[16 -14 ];/* 14-15 */ +uint32_t entries[0 ]; +} __attribute__((packed))ReadStorageElementInfo ; + +typedef struct AttachStorageElement { +SCCBHeader h; +uint8_t _reserved0[10 -8 ];/* 8-9 */ +uint16_t assigned; +uint8_t _reserved1[16 -12 ];/* 12-15 */ +uint32_t entries[0 ]; +} __attribute__((packed))AttachStorageElement ; + +typedef struct AssignStorage { +SCCBHeader h; +uint16_t rn; +} __attribute__((packed))AssignStorage ; + +typedef struct IoaCfgSccb { +SCCBHeader header; +uint8_t atype; +uint8_t reserved1; +uint16_t reserved2; +uint32_t aid; +} __attribute__((packed))IoaCfgSccb ; + typedef struct SCCB { SCCBHeader h; char data[SCCB_DATA_LEN];
Signature · 1 line
2.14.3
PATCH v3 5/11 s390x: rename sclp_setup() to sclp_ascii_setup()
In reply to David HildenbrandWe'll be introducing some other sclp related files including setup functions soon. Also allow to call sclp_service_call() from these (including reusing the buffer).
--- lib/s390x/io.c | 2 +- lib/s390x/sclp-ascii.c | 6 +++--- lib/s390x/sclp.h | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-)
lib/s390x/io.c +1 -1
@@ -42,7 +42,7 @@ void setup() {setup_args_progname (ipl_args);setup_facilities (); -sclp_setup (); +sclp_ascii_setup (); }void exit (int code)
lib/s390x/sclp-ascii.c +3 -3
@@ -13,10 +13,10 @@#include <asm/page.h> #include "sclp.h" -static char _sccb[PAGE_SIZE] __attribute__((__aligned__(4096))); +char _sccb[PAGE_SIZE] __attribute__((__aligned__(4096)));/* Perform service call. Return 0 on success, non-zero otherwise. */ -static int sclp_service_call (unsigned int command,void *sccb) +int sclp_service_call (unsigned int command,void *sccb) {int cc;
@@ -47,7 +47,7 @@ static void sclp_set_write_mask(void)sclp_service_call (SCLP_CMD_WRITE_EVENT_MASK , sccb); } -void sclp_setup (void ) +void sclp_ascii_setup (void ) {sclp_set_write_mask (); }
lib/s390x/sclp.h +3 -1
@@ -207,7 +207,9 @@ typedef struct ReadEventData {uint32_t mask; } __attribute__((packed)) ReadEventData; -void sclp_setup (void ); +void sclp_ascii_setup (void );void sclp_print (const char *str); +extern char _sccb[]; +int sclp_service_call (unsigned int command,void *sccb);#endif /* SCLP_H */
Signature · 1 line
2.14.3
PATCH v3 6/11 s390x: detect installed memory
In reply to David HildenbrandUnfortunately, there is no easy way to simply read out the amount of installed memory. We have to probe (via TEST PROTECTION) for installed memory in a given range.
--- lib/s390x/asm/arch_def.h | 12 ++++++++++ lib/s390x/asm/interrupt.h | 1 + lib/s390x/interrupt.c | 11 +++++++++ lib/s390x/io.c | 1 + lib/s390x/sclp.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++ lib/s390x/sclp.h | 1 + s390x/Makefile | 1 + 7 files changed, 85 insertions(+) create mode 100644 lib/s390x/sclp.c
lib/s390x/asm/arch_def.h +12 -0
@@ -151,4 +151,16 @@ struct cpuid { uint64_t reserved : 15; }; +static inline int tprot (unsigned long addr) +{ +int cc; + + asmvolatile ( +" tprot 0(%1),0\n" +" ipm %0\n" +" srl %0,28\n" + :"=d" (cc) :"a" (addr) :"cc" ); +return cc; +} +#endif
lib/s390x/asm/interrupt.h +1 -0
@@ -13,6 +13,7 @@void handle_pgm_int (void );void expect_pgm_int (void ); +uint16_t clear_pgm_int (void );void check_pgm_int_code (uint16_t code);/* Activate low-address protection */
lib/s390x/interrupt.c +11 -0
@@ -23,6 +23,17 @@ void expect_pgm_int(void)mb (); } +uint16_t clear_pgm_int (void ) +{ +uint16_t code; + +mb (); + code = lc->pgm_int_code; + lc->pgm_int_code =0 ; + pgm_int_expected = false; +return code; +} +void check_pgm_int_code (uint16_t code) {mb ();
lib/s390x/io.c +1 -0
@@ -43,6 +43,7 @@ void setup()setup_args_progname (ipl_args);setup_facilities ();sclp_ascii_setup (); +sclp_memory_setup (); }void exit (int code)
lib/s390x/sclp.c new file +58 -0
58 lines not on this page · raw message
lib/s390x/sclp.h +1 -0
@@ -211,5 +211,6 @@ void sclp_ascii_setup(void);void sclp_print (const char *str);extern char _sccb[];int sclp_service_call (unsigned int command,void *sccb); +void sclp_memory_setup (void );#endif /* SCLP_H */
s390x/Makefile +1 -0
@@ -24,6 +24,7 @@ cflatobjs += lib/util.o cflatobjs += lib/alloc_phys.o cflatobjs += lib/s390x/io.o cflatobjs += lib/s390x/stack.o +cflatobjs += lib/s390x/sclp.o cflatobjs += lib/s390x/sclp-ascii.o cflatobjs += lib/s390x/interrupt.o
Signature · 1 line
2.14.3
PATCH v3 7/11 s390x: initialize the physical allocator
In reply to David HildenbrandWe now have the range of free memory, let's initialize the physical allocator. It is now possible to use use malloc and memalign, based on the early-ops. alloc_pages() cannot be used yet (as it has to be initialized via free_pages() - e.g. via setup_vm() - first)
--- lib/s390x/sclp.c | 12 ++++++++++++ s390x/Makefile | 3 +++ 2 files changed, 15 insertions(+)
lib/s390x/sclp.c +12 -0
@@ -15,11 +15,21 @@#include <asm/arch_def.h> #include <asm/interrupt.h> #include "sclp.h" +#include <alloc_phys.h> + +extern unsigned long stacktop;static uint64_t storage_increment_size;static uint64_t max_ram_size;static uint64_t ram_size; +static void mem_init (phys_addr_t mem_end) +{ +phys_addr_t freemem_start = (phys_addr_t)&stacktop &PAGE_MASK ; + +phys_alloc_init (freemem_start, mem_end - freemem_start); +} +void sclp_memory_setup (void ) {ReadInfo *ri = (void *)_sccb;
@@ -55,4 +65,6 @@ void sclp_memory_setup(void)break ; ram_size += storage_increment_size; } + +mem_init (ram_size); }
s390x/Makefile +3 -0
@@ -21,6 +21,9 @@ asm-offsets = lib/$(ARCH)/asm-offsets.h include $(SRCDIR)/scripts/asm-offsets.mak cflatobjs += lib/util.o +cflatobjs += lib/alloc.o +cflatobjs += lib/alloc_phys.o +cflatobjs += lib/alloc_page.o cflatobjs += lib/alloc_phys.o cflatobjs += lib/s390x/io.o cflatobjs += lib/s390x/stack.o
Signature · 1 line
2.14.3
Re: [PATCH kvm-unit-tests v3 07/11] s390x: initialize the physical allocator
Quoted 20 lines · David Hildenbrand
We now have the range of free memory, let's initialize the physical allocator. It is now possible to use use malloc and memalign, based on the early-ops.
alloc_pages()cannot be used yet (as it has to be initialized viafree_pages()- e.g. viasetup_vm()- first)Signed-off-by David Hildenbrand <[email protected]>--- lib/s390x/sclp.c | 12 ++++++++++++ s390x/Makefile | 3 +++ 2 files changed, 15 insertions(+)lib/s390x/sclp.c +1
-0@@ -15,11 +15,21 @@#include <asm/arch_def.h> #include <asm/interrupt.h> #include "sclp.h" +#include <alloc_phys.h>
lib/s390x/sclp.c line 28
Quoted 10 lines
lib/s390x/sclp.c +5
-0+ +extern unsigned long stacktop;static uint64_t storage_increment_size;static uint64_t max_ram_size;static uint64_t ram_size; +static void mem_init (phys_addr_t mem_end) +{ +phys_addr_t freemem_start = (phys_addr_t)&stacktop &PAGE_MASK ;
Should be ok since stacktop should be aligned. Otherwise this should maybe better be (stacktop + PAGE_SIZE - 1) & PAGE_MASK ?
Thomas
Re: [PATCH kvm-unit-tests v3 07/11] s390x: initialize the physical allocator
Quoted 28 lines · Thomas Huth
Quoted 27 lines · David Hildenbrand
We now have the range of free memory, let's initialize the physical allocator. It is now possible to use use malloc and memalign, based on the early-ops.
alloc_pages()cannot be used yet (as it has to be initialized viafree_pages()- e.g. viasetup_vm()- first)Signed-off-by David Hildenbrand <[email protected]>--- lib/s390x/sclp.c | 12 ++++++++++++ s390x/Makefile | 3 +++ 2 files changed, 15 insertions(+)lib/s390x/sclp.c +3
-0@@ -15,11 +15,21 @@#include <asm/arch_def.h> #include <asm/interrupt.h> #include "sclp.h" +#include <alloc_phys.h> + +extern unsigned long stacktop;static uint64_t storage_increment_size;static uint64_t max_ram_size;static uint64_t ram_size;
Quoted 7 lines
lib/s390x/sclp.c line 28
Quoted 3 lines
lib/s390x/sclp.c +3
-0+static void mem_init (phys_addr_t mem_end) +{ +phys_addr_t freemem_start = (phys_addr_t)&stacktop &PAGE_MASK ;Should be ok since stacktop should be aligned. Otherwise this should maybe better be (stacktop +
PAGE_SIZE- 1) &PAGE_MASK?
Either that or drop the "& PAGE_MASK". But guess this doesn't really make a difference right now. Thanks!
Quoted 2 lines
Thomas
Signature · 3 lines
Thanks, David / dhildenb
PATCH v3 8/11 s390x: add vmalloc support
In reply to David HildenbrandTo use virtual addresses, we have to
- build page tables with identity mapping
- setup the primary ASCE in cr1
- enable DAT in the PSW
Not using the Linux definitions/implementation as they contain too much software defined stuff / things we don't need.
Written from scratch. Tried to stick to the general Linux naming schemes.
As we currently don't invalidate anything except page table entries, it is sufficient to only use ipte for now.
--- lib/s390x/asm/arch_def.h | 46 ++++++++++ lib/s390x/asm/page.h | 24 +++++ lib/s390x/asm/pgtable.h | 224 +++++++++++++++++++++++++++++++++++++++++++++++ lib/s390x/mmu.c | 104 ++++++++++++++++++++++ lib/s390x/sclp.c | 2 + s390x/Makefile | 2 + 6 files changed, 402 insertions(+) create mode 100644 lib/s390x/asm/pgtable.h create mode 100644 lib/s390x/mmu.c
lib/s390x/asm/arch_def.h +46 -0
@@ -15,6 +15,8 @@ struct psw {uint64_t addr; }; +#define PSW_MASK_DAT 0x0400000000000000UL +struct lowcore {uint8_t pad_0x0000[0x0080 -0x0000 ];/* 0x0000 */ uint32_t ext_int_param;/* 0x0080 */
@@ -163,4 +165,48 @@ static inline int tprot(unsigned long addr)return cc; } +static inline void lctlg (int cr,uint64_t value) +{ + asmvolatile ( +" lctlg %1,%1,%0\n" + : :"Q" (value),"i" (cr)); +} + +static inline uint64_t stctg (int cr) +{ +uint64_t value; + + asmvolatile ( +" stctg %1,%1,%0\n" + :"=Q" (value) :"i" (cr) :"memory" ); +return value; +} + +static inline uint64_t extract_psw_mask (void ) +{ +uint32_t mask_upper =0 , mask_lower =0 ; + + asmvolatile ( +" epsw %0,%1\n" + :"+r" (mask_upper),"+r" (mask_lower) : : ); + +return (uint64_t ) mask_upper <<32 | mask_lower; +} + +static inline void load_psw_mask (uint64_t mask) +{ +struct psw psw = { + .mask = mask, + .addr =0 , + }; +uint64_t tmp =0 ; + + asmvolatile ( +" larl %0,0f\n" +" stg %0,8(%1)\n" +" lpswe 0(%1)\n" +"0:\n" + :"+r" (tmp) :"a" (&psw) :"memory" ,"cc" ); +} +#endif
lib/s390x/asm/page.h +24 -0
@@ -13,4 +13,28 @@#include <asm-generic/page.h> +typedef uint64_t pgdval_t ;/* Region-1 table entry */ +typedef uint64_t p4dval_t ;/* Region-2 table entry*/ +typedef uint64_t pudval_t ;/* Region-3 table entry */ +typedef uint64_t pmdval_t ;/* Segment table entry */ +typedef uint64_t pteval_t ;/* Page table entry */ + +typedef struct {pgdval_t pgd; }pgd_t ; +typedef struct {p4dval_t p4d; }p4d_t ; +typedef struct {pudval_t pud; }pud_t ; +typedef struct {pmdval_t pmd; }pmd_t ; +typedef struct {pteval_t pte; }pte_t ; + +#define pgd_val (x) ((x).pgd) +#define p4d_val (x) ((x).p4d) +#define pud_val (x) ((x).pud) +#define pmd_val (x) ((x).pmd) +#define pte_val (x) ((x).pte) + +#define __pgd (x) ((pgd_t) { (x) } ) +#define __p4d (x) ((p4d_t) { (x) } ) +#define __pud (x) ((pud_t) { (x) } ) +#define __pmd (x) ((pmd_t) { (x) } ) +#define __pte (x) ((pte_t) { (x) } ) +#endif
lib/s390x/asm/pgtable.h new file +224 -0
224 lines not on this page · raw message
lib/s390x/mmu.c new file +104 -0
104 lines not on this page · raw message
lib/s390x/sclp.c +2 -0
@@ -28,6 +28,8 @@ static void mem_init(phys_addr_t mem_end)phys_addr_t freemem_start = (phys_addr_t)&stacktop &PAGE_MASK ;phys_alloc_init (freemem_start, mem_end - freemem_start); + +setup_vm (); }void sclp_memory_setup (void )
s390x/Makefile +2 -0
@@ -24,12 +24,14 @@ cflatobjs += lib/util.o cflatobjs += lib/alloc.o cflatobjs += lib/alloc_phys.o cflatobjs += lib/alloc_page.o +cflatobjs += lib/vmalloc.o cflatobjs += lib/alloc_phys.o cflatobjs += lib/s390x/io.o cflatobjs += lib/s390x/stack.o cflatobjs += lib/s390x/sclp.o cflatobjs += lib/s390x/sclp-ascii.o cflatobjs += lib/s390x/interrupt.o +cflatobjs += lib/s390x/mmu.o OBJDIRS += lib/s390x
Signature · 1 line
2.14.3
PATCH v3 9/11 s390x: enable DAT in PGM interrupt handler
In reply to David HildenbrandConfigure it in setup_vm().
--- lib/s390x/mmu.c | 4 ++++ 1 file changed, 4 insertions(+)
lib/s390x/mmu.c +4 -0
@@ -30,6 +30,7 @@ void configure_dat(int enable)static void mmu_enable (pgd_t *pgtable) { +struct lowcore *lc =NULL ;const uint64_t asce =__pa (pgtable) |ASCE_DT_REGION1 |REGION_TABLE_LENGTH ;
@@ -39,6 +40,9 @@ static void mmu_enable(pgd_t *pgtable)/* enable dat (primary == 0 set as default) */ configure_dat (1 ); + +/* we can now also use DAT unconditionally in our PGM handler */ + lc->pgm_new_psw.mask |=PSW_MASK_DAT ; }static pteval_t *get_pte (pgd_t *pgtable,uintptr_t vaddr)
Signature · 1 line
2.14.3
PATCH v3 10/11 s390x: add test for (v)malloc
In reply to David HildenbrandLet's test if basic allocation works and we get virtual addresses.
--- s390x/selftest.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
s390x/selftest.c +29 -0
@@ -10,7 +10,10 @@*/ #include <libcflat.h> #include <util.h> +#include <alloc.h> #include <asm/interrupt.h> +#include <asm/barrier.h> +#include <asm/pgtable.h> static void test_fp (void ) {
@@ -37,6 +40,31 @@ static void test_pgm_int(void)check_pgm_int_code (PGM_INT_CODE_ADDRESSING ); } +static void test_malloc (void ) +{ +int *tmp =malloc (sizeof (int )); +int *tmp2 =malloc (sizeof (int )); + + *tmp =123456789 ; + *tmp2 =123456789 ; +mb (); + +report ("malloc: got vaddr" , (uintptr_t )tmp &0xf000000000000000ul ); +report ("malloc: access works" , *tmp ==123456789 ); +report ("malloc: got 2nd vaddr" , (uintptr_t )tmp2 &0xf000000000000000ul ); +report ("malloc: access works" , (*tmp2 ==123456789 )); +report ("malloc: addresses differ" , tmp != tmp2); + +expect_pgm_int (); +configure_dat (0 ); + *tmp =987654321 ; +configure_dat (1 ); +check_pgm_int_code (PGM_INT_CODE_ADDRESSING ); + +free (tmp); +free (tmp2); +} +int main (int argc,char **argv) {report_prefix_push ("selftest" );
@@ -49,6 +77,7 @@ int main(int argc, char**argv)test_fp ();test_pgm_int (); +test_malloc ();return report_summary (); }
Signature · 1 line
2.14.3
PATCH v3 11/11 s390x: add sieve test
In reply to David HildenbrandCopied from x86/sieve.c. Modifications:
- proper code formatting.
- as setup_vm() is already called, temporarily disable DAT.
The test takes fairly long, especially because we only have 128MB of ram and allocate 3 times in a row ~100mb of virtual memory.
--- s390x/Makefile | 1 + s390x/sieve.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 6 ++++++ 3 files changed, 66 insertions(+) create mode 100644 s390x/sieve.c
s390x/Makefile +1 -0
@@ -1,6 +1,7 @@ tests = $(TEST_DIR)/selftest.elf tests += $(TEST_DIR)/intercept.elf tests += $(TEST_DIR)/emulator.elf +tests += $(TEST_DIR)/sieve.elf all: directories test_cases
s390x/sieve.c new file +59 -0
59 lines not on this page · raw message
s390x/unittests.cfg +6 -0
@@ -28,3 +28,9 @@ file = intercept.elf [emulator] file = emulator.elf + +[sieve] +file = sieve.elf +groups = selftest +# can take fairly long even on KVM guests +timeout = 600
Signature · 1 line
2.14.3
Re: [PATCH kvm-unit-tests v3 11/11] s390x: add sieve test
Quoted 6 lines · David Hildenbrand
Copied from
x86/sieve.c. Modifications:
- proper code formatting.
- assetup_vm()is already called, temporarily disable DAT.The test takes fairly long, especially because we only have 128MB of ram and allocate 3 times in a row ~100mb of virtual memory.
Does it make sense to change the memory size in the unittests.cfg file? e.g. via extra_params?
Quoted 101 lines
Signed-off-by David Hildenbrand <[email protected]>--- s390x/Makefile | 1 + s390x/sieve.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++ s390x/unittests.cfg | 6 ++++++ 3 files changed, 66 insertions(+) create mode 100644 s390x/sieve.cs390x/Makefile +1
-0@@ -1,6 +1,7 @@ tests = $(TEST_DIR)/selftest.elf tests += $(TEST_DIR)/intercept.elf tests += $(TEST_DIR)/emulator.elf +tests += $(TEST_DIR)/sieve.elf all: directories test_casess390x/sieve.c new file +59
-0@@ -0,0 +1,59 @@ +/* +* Copied from x86/sieve.c +*/ + +#include <libcflat.h> +#include <alloc.h> +#include <asm/pgtable.h> + +int sieve (char * data,int size) +{ +int i, j, r =0 ; + +for (i =0 ; i < size; ++i) + data[i] =1 ; + + data[0 ] = data[1 ] =0 ; + +for (i =2 ; i < size; ++i) +if (data[i]) { + ++r; +for (j = i *2 ; j < size; j += i) + data[j] =0 ; + } +return r; +} + +void test_sieve (const char *msg,char *data,int size) +{ +int r; + +printf ("%s:" , msg); + r =sieve (data, size); +printf ("%d out of %d\n" , r, size); +} + +#define STATIC_SIZE 1000000 +#define VSIZE 100000000 +char static_data[STATIC_SIZE ]; + +int main () +{ +void *v; +int i; + +printf ("starting sieve\n" ); + +configure_dat (0 ); +test_sieve ("static" , static_data,STATIC_SIZE ); +configure_dat (1 ); + +test_sieve ("mapped" , static_data,STATIC_SIZE ); +for (i =0 ; i <3 ; ++i) { + v =malloc (VSIZE ); +test_sieve ("virtual" , v,VSIZE ); +free (v); + } + +return 0 ; +}s390x/unittests.cfg +6
-0@@ -28,3 +28,9 @@ file = intercept.elf [emulator] file = emulator.elf + +[sieve] +file = sieve.elf +groups = selftest +# can take fairly long even on KVM guests +timeout = 600
Paolo Bonzini
maintainerRe: [PATCH kvm-unit-tests v3 11/11] s390x: add sieve test
Quoted 4 lines · Christian Borntraeger
Quoted 2 lines
The test takes fairly long, especially because we only have 128MB of ram and allocate 3 times in a row ~100mb of virtual memory.
Does it make sense to change the memory size in the unittests.cfg file? e.g. via
extra_params?
The test takes 5 seconds on x86 KVM and about a minute on TCG (lots of TLB misses). Maybe it's an s390-specific bug in the test?
Thanks,
Paolo
Re: [PATCH kvm-unit-tests v3 11/11] s390x: add sieve test
Quoted 8 lines · Paolo Bonzini
Quoted 4 lines · Christian Borntraeger
Quoted 2 lines
The test takes fairly long, especially because we only have 128MB of ram and allocate 3 times in a row ~100mb of virtual memory.
Does it make sense to change the memory size in the unittests.cfg file? e.g. via
extra_params?The test takes 5 seconds on x86 KVM and about a minute on TCG (lots of TLB misses). Maybe it's an s390-specific bug in the test?
Under TCG: 1m 6,823s
I have to idea how long it takes under LPAR. Right now, I only have a z/VM based system available, so we are already using nested virtualization (implemented by z/VM). I expect things to be slow :)
Will try to find a LPAR to test with ...
Quoted 5 lines
Thanks,
Paolo
Signature · 3 lines
Thanks, David / dhildenb
Re: [PATCH kvm-unit-tests v3 11/11] s390x: add sieve test
Quoted 10 lines · David Hildenbrand
Quoted 8 lines · Paolo Bonzini
Quoted 4 lines · Christian Borntraeger
Quoted 2 lines
The test takes fairly long, especially because we only have 128MB of ram and allocate 3 times in a row ~100mb of virtual memory.
Does it make sense to change the memory size in the unittests.cfg file? e.g. via
extra_params?The test takes 5 seconds on x86 KVM and about a minute on TCG (lots of TLB misses). Maybe it's an s390-specific bug in the test?
Quoted 8 lines
Under TCG: 1m 6,823s
I have to idea how long it takes under LPAR. Right now, I only have a z/VM based system available, so we are already using nested virtualization (implemented by z/VM). I expect things to be slow :)
Will try to find a LPAR to test with ...
LPAR: 0m 6.552s
z/VM: > 6m
So I don't think its a BUG. It's really nested virtualization kicking in.
Signature · 3 lines
Thanks, David / dhildenb
Paolo Bonzini
maintainerRe: [PATCH kvm-unit-tests v3 11/11] s390x: add sieve test
Quoted 17 lines · David Hildenbrand
Quoted 16 lines · David Hildenbrand
Quoted 8 lines · Paolo Bonzini
Quoted 4 lines · Christian Borntraeger
Quoted 2 lines
The test takes fairly long, especially because we only have 128MB of ram and allocate 3 times in a row ~100mb of virtual memory.
Does it make sense to change the memory size in the unittests.cfg file? e.g. via
extra_params?The test takes 5 seconds on x86 KVM and about a minute on TCG (lots of TLB misses). Maybe it's an s390-specific bug in the test?
Under TCG: 1m 6,823s
I have to idea how long it takes under LPAR. Right now, I only have a z/VM based system available, so we are already using nested virtualization (implemented by z/VM). I expect things to be slow :)
Quoted 7 lines
Quoted 2 lines
Will try to find a LPAR to test with ...
LPAR: 0m 6.552s
z/VM: > 6mSo I don't think its a BUG. It's really nested virtualization kicking in.
Whoa. How does KVM-on-KVM-on-LPAR fare?
I'll change the comment to
# can take fairly long when KVM is nested inside z/VM
Thanks,
Paolo
Re: [PATCH kvm-unit-tests v3 11/11] s390x: add sieve test
Quoted 21 lines · Paolo Bonzini
Quoted 20 lines · David Hildenbrand
Quoted 18 lines · David Hildenbrand
Quoted 8 lines · Paolo Bonzini
Quoted 4 lines · Christian Borntraeger
Quoted 2 lines
The test takes fairly long, especially because we only have 128MB of ram and allocate 3 times in a row ~100mb of virtual memory.
Does it make sense to change the memory size in the unittests.cfg file? e.g. via
extra_params?The test takes 5 seconds on x86 KVM and about a minute on TCG (lots of TLB misses). Maybe it's an s390-specific bug in the test?
Under TCG: 1m 6,823s
I have to idea how long it takes under LPAR. Right now, I only have a z/VM based system available, so we are already using nested virtualization (implemented by z/VM). I expect things to be slow :)
Will try to find a LPAR to test with ...
Quoted 6 lines
Quoted 4 lines
LPAR: 0m 6.552s
z/VM: > 6mSo I don't think its a BUG. It's really nested virtualization kicking in.
Whoa. How does KVM-on-KVM-on-LPAR fare?
We do a lot of IPTE calls, which flush the TLB on all CPUs.
But I think this could also be because the z/VM machine I am running on is simply overloaded. But of course also because our nested virt implementation in KVM is better ;)
Just tried nested under KVM (KVM-on-KVM-on-LPAR):
real 0m 9.411s
Quoted 9 lines
I'll change the comment to
# can take fairly long when KVM is nested inside z/VMThanks,
Paolo
Signature · 3 lines
Thanks, David / dhildenb
Re: [PATCH kvm-unit-tests v3 11/11] s390x: add sieve test
Quoted 27 lines · David Hildenbrand
Quoted 26 lines · Paolo Bonzini
Quoted 24 lines · David Hildenbrand
Quoted 10 lines · David Hildenbrand
Quoted 8 lines · Paolo Bonzini
Quoted 4 lines · Christian Borntraeger
Quoted 2 lines
The test takes fairly long, especially because we only have 128MB of ram and allocate 3 times in a row ~100mb of virtual memory.
Does it make sense to change the memory size in the unittests.cfg file? e.g. via
extra_params?The test takes 5 seconds on x86 KVM and about a minute on TCG (lots of TLB misses). Maybe it's an s390-specific bug in the test?
Quoted 8 lines
Under TCG: 1m 6,823s
I have to idea how long it takes under LPAR. Right now, I only have a z/VM based system available, so we are already using nested virtualization (implemented by z/VM). I expect things to be slow :)
Will try to find a LPAR to test with ...
LPAR: 0m 6.552s
z/VM: > 6mSo I don't think its a BUG. It's really nested virtualization kicking in.
Quoted 7 lines
Quoted 1 line
Whoa. How does KVM-on-KVM-on-LPAR fare?
We do a lot of IPTE calls, which flush the TLB on all CPUs.
But I think this could also be because the z/VM machine I am running on is simply overloaded. But of course also because our nested virt implementation in KVM is better ;)
Just double checked, as we are not reusing virtual addresses, we are not issuing any IPTE instructions right now. So also no TLB flushes. This makes it very strange why z/VM performs (for me reproducible) that bad.
Quoted 16 lines
Just tried nested under KVM (KVM-on-KVM-on-LPAR):
real 0m 9.411s
Quoted 9 lines
I'll change the comment to
# can take fairly long when KVM is nested inside z/VMThanks,
Paolo
Signature · 3 lines
Thanks, David / dhildenb
Re: [PATCH kvm-unit-tests v3 11/11] s390x: add sieve test
In reply to Christian BorntraegerQuoted 11 lines · Christian Borntraeger
Quoted 6 lines · David Hildenbrand
Copied from
x86/sieve.c. Modifications:
- proper code formatting.
- assetup_vm()is already called, temporarily disable DAT.The test takes fairly long, especially because we only have 128MB of ram and allocate 3 times in a row ~100mb of virtual memory.
Does it make sense to change the memory size in the unittests.cfg file? e.g. via
extra_params?
As the long runtime only seems to be a problem when running nested under z/VM, I don't think this should be a problem.
Signature · 3 lines
Thanks, David / dhildenb
Quoted 12 lines · David Hildenbrand
This series implements
- detection of installed physical memory
- setup of the physical allocator
- setup of the MMU / page tables / DAT
- setup of the virtual allocatorThe CPU now runs with DAT enabled. I added a small test to make sure
malloc()indeed works and uses virtual adresses. Also, the sieve test is added.While at it, fix the TEST BLOCK test on newer compilers.
Quoted 8 lines
Tested with upsteam QEMU TCG and KVM. However, to pass under TCG a fix is necessary ("[PATCH v1] s390x/tcg: fix disabling/enabling DAT").
v2 -> v3:
- split upconfigure_dat()to make use of two functionsextract_psw_mask()andload_psw_mask(), it is now much cleaner and we might need these functions in the future.
- Minor cleanups / comment fixes
Applied, thanks. Happy that the arm/x86 code generalized decently to s390!
Paolo
Quoted 37 lines
David Hildenbrand (11):
s390x: fix TEST BLOCK tests
s390x: use highest addresses forPGM_ADDRESSINGerrors
s390x: set initital stack pointer to stackptr, not stacktop
s390x: add missing sclp definitions from QEMU
s390x: renamesclp_setup()tosclp_ascii_setup()
s390x: detect installed memory
s390x: initialize the physical allocator
s390x: add vmalloc support
s390x: enable DAT in PGM interrupt handler
s390x: add test for (v)malloc
s390x: add sieve testlib/s390x/asm/arch_def.h | 58 ++++++++++++ lib/s390x/asm/interrupt.h | 1 + lib/s390x/asm/page.h | 24 +++++ lib/s390x/asm/pgtable.h | 224 ++++++++++++++++++++++++++++++++++++++++++++++ lib/s390x/interrupt.c | 11 +++ lib/s390x/io.c | 3 +- lib/s390x/mmu.c | 108 ++++++++++++++++++++++ lib/s390x/sclp-ascii.c | 6 +- lib/s390x/sclp.c | 72 +++++++++++++++ lib/s390x/sclp.h | 112 ++++++++++++++++++++++- s390x/Makefile | 7 ++ s390x/cstart64.S | 2 +- s390x/intercept.c | 14 +-- s390x/selftest.c | 31 ++++++- s390x/sieve.c | 59 ++++++++++++ s390x/unittests.cfg | 6 ++ 16 files changed, 723 insertions(+), 15 deletions(-) create mode 100644 lib/s390x/asm/pgtable.h create mode 100644 lib/s390x/mmu.c create mode 100644 lib/s390x/sclp.c create mode 100644 s390x/sieve.c