Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/s390/linux

Pull s390 updates from Martin Schwidefsky:

 - New entropy generation for the pseudo random number generator.

 - Early boot printk output via sclp to help debug crashes on boot. This
   needs to be enabled with a kernel parameter.

 - Add proper no-execute support with a bit in the page table entry.

 - Bug fixes and cleanups.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (65 commits)
  s390/syscall: fix single stepped system calls
  s390/zcrypt: make ap_bus explicitly non-modular
  s390/zcrypt: Removed unneeded debug feature directory creation.
  s390: add missing "do {} while (0)" loop constructs to multiline macros
  s390/mm: add cond_resched call to kernel page table dumper
  s390: get rid of MACHINE_HAS_PFMF and MACHINE_HAS_HPAGE
  s390/mm: make memory_block_size_bytes available for !MEMORY_HOTPLUG
  s390: replace ACCESS_ONCE with READ_ONCE
  s390: Audit and remove any remaining unnecessary uses of module.h
  s390: mm: Audit and remove any unnecessary uses of module.h
  s390: kernel: Audit and remove any unnecessary uses of module.h
  s390/kdump: Use "LINUX" ELF note name instead of "CORE"
  s390: add no-execute support
  s390: report new vector facilities
  s390: use correct input data address for setup_randomness
  s390/sclp: get rid of common response code handling
  s390/sclp: don't add new lines to each printed string
  s390/sclp: make early sclp code readable
  s390/sclp: disable early sclp code as soon as the base sclp driver is active
  s390/sclp: move early printk code to drivers
  ...
  • Loading branch information
Linus Torvalds committed Feb 22, 2017
2 parents 3051bf3 + d24b98e commit ff47d8c
Show file tree
Hide file tree
Showing 103 changed files with 1,253 additions and 1,083 deletions.
5 changes: 4 additions & 1 deletion Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -970,9 +970,10 @@
address. The serial port must already be setup
and configured. Options are not yet supported.

earlyprintk= [X86,SH,BLACKFIN,ARM,M68k]
earlyprintk= [X86,SH,BLACKFIN,ARM,M68k,S390]
earlyprintk=vga
earlyprintk=efi
earlyprintk=sclp
earlyprintk=xen
earlyprintk=serial[,ttySn[,baudrate]]
earlyprintk=serial[,0x...[,baudrate]]
Expand Down Expand Up @@ -1007,6 +1008,8 @@

The xen output can only be used by Xen PV guests.

The sclp output can only be used on s390.

edac_report= [HW,EDAC] Control how to report EDAC event
Format: {"on" | "off" | "force"}
on: enable EDAC to report H/W event. May be overridden
Expand Down
3 changes: 3 additions & 0 deletions arch/s390/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ config S390_PTDUMP
kernel.
If in doubt, say "N"

config EARLY_PRINTK
def_bool y

endmenu
3 changes: 2 additions & 1 deletion arch/s390/boot/compressed/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ KBUILD_CFLAGS += $(call cc-option,-ffreestanding)
GCOV_PROFILE := n
UBSAN_SANITIZE := n

OBJECTS := $(addprefix $(objtree)/arch/s390/kernel/, head.o sclp.o ebcdic.o als.o)
OBJECTS := $(addprefix $(objtree)/arch/s390/kernel/, head.o ebcdic.o als.o)
OBJECTS += $(objtree)/drivers/s390/char/sclp_early_core.o
OBJECTS += $(obj)/head.o $(obj)/misc.o $(obj)/piggy.o

LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup -T
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/boot/compressed/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static unsigned long free_mem_end_ptr;

static int puts(const char *s)
{
_sclp_print_early(s);
sclp_early_printk(s);
return 0;
}

Expand Down
7 changes: 7 additions & 0 deletions arch/s390/crypto/aes_s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/cpufeature.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/fips.h>
#include <crypto/xts.h>
#include <asm/cpacf.h>

Expand Down Expand Up @@ -501,6 +502,12 @@ static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
if (err)
return err;

/* In fips mode only 128 bit or 256 bit keys are valid */
if (fips_enabled && key_len != 32 && key_len != 64) {
tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
return -EINVAL;
}

/* Pick the correct function code based on the key length */
fc = (key_len == 32) ? CPACF_KM_XTS_128 :
(key_len == 64) ? CPACF_KM_XTS_256 : 0;
Expand Down
14 changes: 14 additions & 0 deletions arch/s390/crypto/des_s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/cpufeature.h>
#include <linux/crypto.h>
#include <linux/fips.h>
#include <crypto/algapi.h>
#include <crypto/des.h>
#include <asm/cpacf.h>
Expand Down Expand Up @@ -221,6 +222,8 @@ static struct crypto_alg cbc_des_alg = {
* same as DES. Implementers MUST reject keys that exhibit this
* property.
*
* In fips mode additinally check for all 3 keys are unique.
*
*/
static int des3_setkey(struct crypto_tfm *tfm, const u8 *key,
unsigned int key_len)
Expand All @@ -234,6 +237,17 @@ static int des3_setkey(struct crypto_tfm *tfm, const u8 *key,
tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
return -EINVAL;
}

/* in fips mode, ensure k1 != k2 and k2 != k3 and k1 != k3 */
if (fips_enabled &&
!(crypto_memneq(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
crypto_memneq(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
DES_KEY_SIZE) &&
crypto_memneq(key, &key[DES_KEY_SIZE * 2], DES_KEY_SIZE))) {
tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
return -EINVAL;
}

memcpy(ctx->key, key, key_len);
return 0;
}
Expand Down
40 changes: 24 additions & 16 deletions arch/s390/crypto/prng.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,30 @@ static const u8 initial_parm_block[32] __initconst = {

/*** helper functions ***/

/*
* generate_entropy:
* This algorithm produces 64 bytes of entropy data based on 1024
* individual stckf() invocations assuming that each stckf() value
* contributes 0.25 bits of entropy. So the caller gets 256 bit
* entropy per 64 byte or 4 bits entropy per byte.
*/
static int generate_entropy(u8 *ebuf, size_t nbytes)
{
int n, ret = 0;
u8 *pg, *h, hash[32];
u8 *pg, *h, hash[64];

pg = (u8 *) __get_free_page(GFP_KERNEL);
/* allocate 2 pages */
pg = (u8 *) __get_free_pages(GFP_KERNEL, 1);
if (!pg) {
prng_errorflag = PRNG_GEN_ENTROPY_FAILED;
return -ENOMEM;
}

while (nbytes) {
/* fill page with urandom bytes */
get_random_bytes(pg, PAGE_SIZE);
/* exor page with stckf values */
for (n = 0; n < PAGE_SIZE / sizeof(u64); n++) {
/* fill pages with urandom bytes */
get_random_bytes(pg, 2*PAGE_SIZE);
/* exor pages with 1024 stckf values */
for (n = 0; n < 2 * PAGE_SIZE / sizeof(u64); n++) {
u64 *p = ((u64 *)pg) + n;
*p ^= get_tod_clock_fast();
}
Expand All @@ -134,16 +142,16 @@ static int generate_entropy(u8 *ebuf, size_t nbytes)
h = hash;
else
h = ebuf;
/* generate sha256 from this page */
cpacf_kimd(CPACF_KIMD_SHA_256, h, pg, PAGE_SIZE);
/* hash over the filled pages */
cpacf_kimd(CPACF_KIMD_SHA_512, h, pg, 2*PAGE_SIZE);
if (n < sizeof(hash))
memcpy(ebuf, hash, n);
ret += n;
ebuf += n;
nbytes -= n;
}

free_page((unsigned long)pg);
free_pages((unsigned long)pg, 1);
return ret;
}

Expand Down Expand Up @@ -334,7 +342,7 @@ static int __init prng_sha512_selftest(void)
static int __init prng_sha512_instantiate(void)
{
int ret, datalen;
u8 seed[64];
u8 seed[64 + 32 + 16];

pr_debug("prng runs in SHA-512 mode "
"with chunksize=%d and reseed_limit=%u\n",
Expand All @@ -357,12 +365,12 @@ static int __init prng_sha512_instantiate(void)
if (ret)
goto outfree;

/* generate initial seed bytestring, first 48 bytes of entropy */
ret = generate_entropy(seed, 48);
if (ret != 48)
/* generate initial seed bytestring, with 256 + 128 bits entropy */
ret = generate_entropy(seed, 64 + 32);
if (ret != 64 + 32)
goto outfree;
/* followed by 16 bytes of unique nonce */
get_tod_clock_ext(seed + 48);
get_tod_clock_ext(seed + 64 + 32);

/* initial seed of the ppno drng */
cpacf_ppno(CPACF_PPNO_SHA512_DRNG_SEED,
Expand Down Expand Up @@ -395,9 +403,9 @@ static void prng_sha512_deinstantiate(void)
static int prng_sha512_reseed(void)
{
int ret;
u8 seed[32];
u8 seed[64];

/* generate 32 bytes of fresh entropy */
/* fetch 256 bits of fresh entropy */
ret = generate_entropy(seed, sizeof(seed));
if (ret != sizeof(seed))
return ret;
Expand Down
30 changes: 26 additions & 4 deletions arch/s390/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,31 @@
/* Caches aren't brain-dead on the s390. */
#include <asm-generic/cacheflush.h>

int set_memory_ro(unsigned long addr, int numpages);
int set_memory_rw(unsigned long addr, int numpages);
int set_memory_nx(unsigned long addr, int numpages);
int set_memory_x(unsigned long addr, int numpages);
#define SET_MEMORY_RO 1UL
#define SET_MEMORY_RW 2UL
#define SET_MEMORY_NX 4UL
#define SET_MEMORY_X 8UL

int __set_memory(unsigned long addr, int numpages, unsigned long flags);

static inline int set_memory_ro(unsigned long addr, int numpages)
{
return __set_memory(addr, numpages, SET_MEMORY_RO);
}

static inline int set_memory_rw(unsigned long addr, int numpages)
{
return __set_memory(addr, numpages, SET_MEMORY_RW);
}

static inline int set_memory_nx(unsigned long addr, int numpages)
{
return __set_memory(addr, numpages, SET_MEMORY_NX);
}

static inline int set_memory_x(unsigned long addr, int numpages)
{
return __set_memory(addr, numpages, SET_MEMORY_X);
}

#endif /* _S390_CACHEFLUSH_H */
5 changes: 3 additions & 2 deletions arch/s390/include/asm/cpu_mf.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,14 +199,15 @@ static inline int ecctr(u64 ctr, u64 *val)
/* Store CPU counter multiple for the MT utilization counter set */
static inline int stcctm5(u64 num, u64 *val)
{
typedef struct { u64 _[num]; } addrtype;
int cc;

asm volatile (
" .insn rsy,0xeb0000000017,%2,5,%1\n"
" ipm %0\n"
" srl %0,28\n"
: "=d" (cc), "=Q" (*(addrtype *) val) : "d" (num) : "cc");
: "=d" (cc)
: "Q" (*val), "d" (num)
: "cc", "memory");
return cc;
}

Expand Down
12 changes: 7 additions & 5 deletions arch/s390/include/asm/ctl_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

#include <linux/bug.h>

#define __ctl_load(array, low, high) { \
#define __ctl_load(array, low, high) do { \
typedef struct { char _[sizeof(array)]; } addrtype; \
\
BUILD_BUG_ON(sizeof(addrtype) != (high - low + 1) * sizeof(long));\
Expand All @@ -18,17 +18,17 @@
: \
: "Q" (*(addrtype *)(&array)), "i" (low), "i" (high) \
: "memory"); \
}
} while (0)

#define __ctl_store(array, low, high) { \
#define __ctl_store(array, low, high) do { \
typedef struct { char _[sizeof(array)]; } addrtype; \
\
BUILD_BUG_ON(sizeof(addrtype) != (high - low + 1) * sizeof(long));\
asm volatile( \
" stctg %1,%2,%0\n" \
: "=Q" (*(addrtype *)(&array)) \
: "i" (low), "i" (high)); \
}
} while (0)

static inline void __ctl_set_bit(unsigned int cr, unsigned int bit)
{
Expand Down Expand Up @@ -62,7 +62,9 @@ union ctlreg0 {
unsigned long : 4;
unsigned long afp : 1; /* AFP-register control */
unsigned long vx : 1; /* Vector enablement control */
unsigned long : 17;
unsigned long : 7;
unsigned long sssm : 1; /* Service signal subclass mask */
unsigned long : 9;
};
};

Expand Down
2 changes: 2 additions & 0 deletions arch/s390/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@
#define HWCAP_S390_HIGH_GPRS 512
#define HWCAP_S390_TE 1024
#define HWCAP_S390_VXRS 2048
#define HWCAP_S390_VXRS_BCD 4096
#define HWCAP_S390_VXRS_EXT 8192

/* Internal bits, not exposed via elf */
#define HWCAP_INT_SIE 1UL
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/include/asm/hugetlb.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#define is_hugepage_only_range(mm, addr, len) 0
#define hugetlb_free_pgd_range free_pgd_range
#define hugepages_supported() (MACHINE_HAS_HPAGE)
#define hugepages_supported() (MACHINE_HAS_EDAT1)

void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte);
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/include/asm/livepatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#ifndef ASM_LIVEPATCH_H
#define ASM_LIVEPATCH_H

#include <linux/module.h>
#include <asm/ptrace.h>

static inline int klp_check_compiler_support(void)
{
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/include/asm/pci_clp.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ struct clp_rsp_query_pci {
u32 fid; /* pci function id */
u8 bar_size[PCI_BAR_COUNT];
u16 pchid;
u32 bar[PCI_BAR_COUNT];
__le32 bar[PCI_BAR_COUNT];
u8 pfip[CLP_PFIP_NR_SEGMENTS]; /* pci function internal path */
u32 : 16;
u8 fmb_len;
Expand Down
Loading

0 comments on commit ff47d8c

Please sign in to comment.