Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull more s390 updates from Martin Schwidefsky: "Three notable larger changes next to the usual bug fixing: - update the email addresses in MAINTAINERS for the s390 folks to use the simpler linux.ibm.com domain instead of the old linux.vnet.ibm.com - an update for the zcrypt device driver that removes some old and obsolete interfaces and add support for up to 256 crypto adapters - a rework of the IPL aka boot code" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (23 commits) s390: correct nospec auto detection init order s390/zcrypt: Support up to 256 crypto adapters. s390/zcrypt: Remove deprecated zcrypt proc interface. s390/zcrypt: Remove deprecated ioctls. s390/zcrypt: Make ap init functions static. MAINTAINERS: update s390 maintainers email addresses s390/ipl: remove reipl_method and dump_method s390/ipl: correct kdump reipl block checksum calculation s390/ipl: remove non-existing functions declaration s390: assume diag308 set always works s390/ipl: avoid adding scpdata to cmdline during ftp/dvd boot s390/ipl: correct ipl parmblock valid checks s390/ipl: rely on diag308 store to get ipl info s390/ipl: move ipl_flags to ipl.c s390/ipl: get rid of ipl_ssid and ipl_devno s390/ipl: unite diag308 and scsi boot ipl blocks s390/ipl: ensure loadparm valid flag is set s390/qdio: lock device while installing IRQ handler s390/qdio: clear intparm during shutdown s390/ccwgroup: require at least one ccw device ...
This commit is contained in:
commit
6c21e4334a
34
MAINTAINERS
34
MAINTAINERS
@ -5843,7 +5843,7 @@ F: scripts/Makefile.gcc-plugins
|
||||
F: Documentation/gcc-plugins.txt
|
||||
|
||||
GCOV BASED KERNEL PROFILING
|
||||
M: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
M: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
S: Maintained
|
||||
F: kernel/gcov/
|
||||
F: Documentation/dev-tools/gcov.rst
|
||||
@ -7768,7 +7768,7 @@ F: arch/powerpc/kernel/kvm*
|
||||
|
||||
KERNEL VIRTUAL MACHINE for s390 (KVM/s390)
|
||||
M: Christian Borntraeger <borntraeger@de.ibm.com>
|
||||
M: Janosch Frank <frankja@linux.vnet.ibm.com>
|
||||
M: Janosch Frank <frankja@linux.ibm.com>
|
||||
R: David Hildenbrand <david@redhat.com>
|
||||
R: Cornelia Huck <cohuck@redhat.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
@ -12124,16 +12124,16 @@ F: Documentation/s390/
|
||||
F: Documentation/driver-api/s390-drivers.rst
|
||||
|
||||
S390 COMMON I/O LAYER
|
||||
M: Sebastian Ott <sebott@linux.vnet.ibm.com>
|
||||
M: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||
M: Sebastian Ott <sebott@linux.ibm.com>
|
||||
M: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
S: Supported
|
||||
F: drivers/s390/cio/
|
||||
|
||||
S390 DASD DRIVER
|
||||
M: Stefan Haberland <sth@linux.vnet.ibm.com>
|
||||
M: Jan Hoeppner <hoeppner@linux.vnet.ibm.com>
|
||||
M: Stefan Haberland <sth@linux.ibm.com>
|
||||
M: Jan Hoeppner <hoeppner@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
S: Supported
|
||||
@ -12148,8 +12148,8 @@ S: Supported
|
||||
F: drivers/iommu/s390-iommu.c
|
||||
|
||||
S390 IUCV NETWORK LAYER
|
||||
M: Julian Wiedmann <jwi@linux.vnet.ibm.com>
|
||||
M: Ursula Braun <ubraun@linux.vnet.ibm.com>
|
||||
M: Julian Wiedmann <jwi@linux.ibm.com>
|
||||
M: Ursula Braun <ubraun@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
S: Supported
|
||||
@ -12158,15 +12158,15 @@ F: include/net/iucv/
|
||||
F: net/iucv/
|
||||
|
||||
S390 NETWORK DRIVERS
|
||||
M: Julian Wiedmann <jwi@linux.vnet.ibm.com>
|
||||
M: Ursula Braun <ubraun@linux.vnet.ibm.com>
|
||||
M: Julian Wiedmann <jwi@linux.ibm.com>
|
||||
M: Ursula Braun <ubraun@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
S: Supported
|
||||
F: drivers/s390/net/
|
||||
|
||||
S390 PCI SUBSYSTEM
|
||||
M: Sebastian Ott <sebott@linux.vnet.ibm.com>
|
||||
M: Sebastian Ott <sebott@linux.ibm.com>
|
||||
M: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
@ -12176,8 +12176,8 @@ F: drivers/pci/hotplug/s390_pci_hpc.c
|
||||
|
||||
S390 VFIO-CCW DRIVER
|
||||
M: Cornelia Huck <cohuck@redhat.com>
|
||||
M: Dong Jia Shi <bjsdjshi@linux.vnet.ibm.com>
|
||||
M: Halil Pasic <pasic@linux.vnet.ibm.com>
|
||||
M: Dong Jia Shi <bjsdjshi@linux.ibm.com>
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
L: kvm@vger.kernel.org
|
||||
S: Supported
|
||||
@ -12193,8 +12193,8 @@ S: Supported
|
||||
F: drivers/s390/crypto/
|
||||
|
||||
S390 ZFCP DRIVER
|
||||
M: Steffen Maier <maier@linux.vnet.ibm.com>
|
||||
M: Benjamin Block <bblock@linux.vnet.ibm.com>
|
||||
M: Steffen Maier <maier@linux.ibm.com>
|
||||
M: Benjamin Block <bblock@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
S: Supported
|
||||
@ -12630,7 +12630,7 @@ S: Maintained
|
||||
F: drivers/misc/sgi-xp/
|
||||
|
||||
SHARED MEMORY COMMUNICATIONS (SMC) SOCKETS
|
||||
M: Ursula Braun <ubraun@linux.vnet.ibm.com>
|
||||
M: Ursula Braun <ubraun@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
S: Supported
|
||||
@ -14965,7 +14965,7 @@ F: include/uapi/linux/virtio_crypto.h
|
||||
|
||||
VIRTIO DRIVERS FOR S390
|
||||
M: Cornelia Huck <cohuck@redhat.com>
|
||||
M: Halil Pasic <pasic@linux.vnet.ibm.com>
|
||||
M: Halil Pasic <pasic@linux.ibm.com>
|
||||
L: linux-s390@vger.kernel.org
|
||||
L: virtualization@lists.linux-foundation.org
|
||||
L: kvm@vger.kernel.org
|
||||
|
@ -119,34 +119,12 @@ static void error(char *x)
|
||||
asm volatile("lpsw %0" : : "Q" (psw));
|
||||
}
|
||||
|
||||
/*
|
||||
* Safe guard the ipl parameter block against a memory area that will be
|
||||
* overwritten. The validity check for the ipl parameter block is complex
|
||||
* (see cio_get_iplinfo and ipl_save_parameters) but if the pointer to
|
||||
* the ipl parameter block intersects with the passed memory area we can
|
||||
* safely assume that we can read from that memory. In that case just copy
|
||||
* the memory to IPL_PARMBLOCK_ORIGIN even if there is no ipl parameter
|
||||
* block.
|
||||
*/
|
||||
static void check_ipl_parmblock(void *start, unsigned long size)
|
||||
{
|
||||
void *src, *dst;
|
||||
|
||||
src = (void *)(unsigned long) S390_lowcore.ipl_parmblock_ptr;
|
||||
if (src + PAGE_SIZE <= start || src >= start + size)
|
||||
return;
|
||||
dst = (void *) IPL_PARMBLOCK_ORIGIN;
|
||||
memmove(dst, src, PAGE_SIZE);
|
||||
S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
|
||||
}
|
||||
|
||||
unsigned long decompress_kernel(void)
|
||||
{
|
||||
void *output, *kernel_end;
|
||||
|
||||
output = (void *) ALIGN((unsigned long) _end + HEAP_SIZE, PAGE_SIZE);
|
||||
kernel_end = output + SZ__bss_start;
|
||||
check_ipl_parmblock((void *) 0, (unsigned long) kernel_end);
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
/*
|
||||
@ -156,7 +134,6 @@ unsigned long decompress_kernel(void)
|
||||
* current bss section..
|
||||
*/
|
||||
if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) {
|
||||
check_ipl_parmblock(kernel_end, INITRD_SIZE);
|
||||
memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE);
|
||||
INITRD_START = (unsigned long) kernel_end;
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ static void fallback_exit_blk(struct crypto_tfm *tfm)
|
||||
static struct crypto_alg ecb_aes_alg = {
|
||||
.cra_name = "ecb(aes)",
|
||||
.cra_driver_name = "ecb-aes-s390",
|
||||
.cra_priority = 400, /* combo: aes + ecb */
|
||||
.cra_priority = 401, /* combo: aes + ecb + 1 */
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
@ -426,7 +426,7 @@ static int cbc_aes_decrypt(struct blkcipher_desc *desc,
|
||||
static struct crypto_alg cbc_aes_alg = {
|
||||
.cra_name = "cbc(aes)",
|
||||
.cra_driver_name = "cbc-aes-s390",
|
||||
.cra_priority = 400, /* combo: aes + cbc */
|
||||
.cra_priority = 402, /* ecb-aes-s390 + 1 */
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
@ -633,7 +633,7 @@ static void xts_fallback_exit(struct crypto_tfm *tfm)
|
||||
static struct crypto_alg xts_aes_alg = {
|
||||
.cra_name = "xts(aes)",
|
||||
.cra_driver_name = "xts-aes-s390",
|
||||
.cra_priority = 400, /* combo: aes + xts */
|
||||
.cra_priority = 402, /* ecb-aes-s390 + 1 */
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
@ -763,7 +763,7 @@ static int ctr_aes_decrypt(struct blkcipher_desc *desc,
|
||||
static struct crypto_alg ctr_aes_alg = {
|
||||
.cra_name = "ctr(aes)",
|
||||
.cra_driver_name = "ctr-aes-s390",
|
||||
.cra_priority = 400, /* combo: aes + ctr */
|
||||
.cra_priority = 402, /* ecb-aes-s390 + 1 */
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER |
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = 1,
|
||||
|
@ -138,7 +138,7 @@ static int ecb_paes_decrypt(struct blkcipher_desc *desc,
|
||||
static struct crypto_alg ecb_paes_alg = {
|
||||
.cra_name = "ecb(paes)",
|
||||
.cra_driver_name = "ecb-paes-s390",
|
||||
.cra_priority = 400, /* combo: aes + ecb */
|
||||
.cra_priority = 401, /* combo: aes + ecb + 1 */
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_paes_ctx),
|
||||
@ -241,7 +241,7 @@ static int cbc_paes_decrypt(struct blkcipher_desc *desc,
|
||||
static struct crypto_alg cbc_paes_alg = {
|
||||
.cra_name = "cbc(paes)",
|
||||
.cra_driver_name = "cbc-paes-s390",
|
||||
.cra_priority = 400, /* combo: aes + cbc */
|
||||
.cra_priority = 402, /* ecb-paes-s390 + 1 */
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_paes_ctx),
|
||||
@ -377,7 +377,7 @@ static int xts_paes_decrypt(struct blkcipher_desc *desc,
|
||||
static struct crypto_alg xts_paes_alg = {
|
||||
.cra_name = "xts(paes)",
|
||||
.cra_driver_name = "xts-paes-s390",
|
||||
.cra_priority = 400, /* combo: aes + xts */
|
||||
.cra_priority = 402, /* ecb-paes-s390 + 1 */
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = AES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct s390_pxts_ctx),
|
||||
@ -523,7 +523,7 @@ static int ctr_paes_decrypt(struct blkcipher_desc *desc,
|
||||
static struct crypto_alg ctr_paes_alg = {
|
||||
.cra_name = "ctr(paes)",
|
||||
.cra_driver_name = "ctr-paes-s390",
|
||||
.cra_priority = 400, /* combo: aes + ctr */
|
||||
.cra_priority = 402, /* ecb-paes-s390 + 1 */
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = 1,
|
||||
.cra_ctxsize = sizeof(struct s390_paes_ctx),
|
||||
|
@ -20,9 +20,9 @@
|
||||
*/
|
||||
typedef unsigned int ap_qid_t;
|
||||
|
||||
#define AP_MKQID(_card, _queue) (((_card) & 63) << 8 | ((_queue) & 255))
|
||||
#define AP_QID_CARD(_qid) (((_qid) >> 8) & 63)
|
||||
#define AP_QID_QUEUE(_qid) ((_qid) & 255)
|
||||
#define AP_MKQID(_card, _queue) (((_card) & 0xff) << 8 | ((_queue) & 0xff))
|
||||
#define AP_QID_CARD(_qid) (((_qid) >> 8) & 0xff)
|
||||
#define AP_QID_QUEUE(_qid) ((_qid) & 0xff)
|
||||
|
||||
/**
|
||||
* struct ap_queue_status - Holds the AP queue status.
|
||||
|
@ -328,16 +328,6 @@ static inline u8 pathmask_to_pos(u8 mask)
|
||||
void channel_subsystem_reinit(void);
|
||||
extern void css_schedule_reprobe(void);
|
||||
|
||||
extern void reipl_ccw_dev(struct ccw_dev_id *id);
|
||||
|
||||
struct cio_iplinfo {
|
||||
u8 ssid;
|
||||
u16 devno;
|
||||
int is_qdio;
|
||||
};
|
||||
|
||||
extern int cio_get_iplinfo(struct cio_iplinfo *iplinfo);
|
||||
|
||||
/* Function from drivers/s390/cio/chsc.c */
|
||||
int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta);
|
||||
int chsc_sstpi(void *page, void *result, size_t size);
|
||||
|
@ -15,8 +15,6 @@
|
||||
|
||||
#define NSS_NAME_SIZE 8
|
||||
|
||||
#define IPL_PARMBLOCK_ORIGIN 0x2000
|
||||
|
||||
#define IPL_PARM_BLK_FCP_LEN (sizeof(struct ipl_list_hdr) + \
|
||||
sizeof(struct ipl_block_fcp))
|
||||
|
||||
@ -29,10 +27,6 @@
|
||||
|
||||
#define IPL_MAX_SUPPORTED_VERSION (0)
|
||||
|
||||
#define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \
|
||||
IPL_PARMBLOCK_ORIGIN)
|
||||
#define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.len)
|
||||
|
||||
struct ipl_list_hdr {
|
||||
u32 len;
|
||||
u8 reserved1[3];
|
||||
@ -83,33 +77,21 @@ struct ipl_parameter_block {
|
||||
union {
|
||||
struct ipl_block_fcp fcp;
|
||||
struct ipl_block_ccw ccw;
|
||||
char raw[PAGE_SIZE - sizeof(struct ipl_list_hdr)];
|
||||
} ipl_info;
|
||||
} __packed __aligned(PAGE_SIZE);
|
||||
|
||||
/*
|
||||
* IPL validity flags
|
||||
*/
|
||||
extern u32 ipl_flags;
|
||||
|
||||
struct save_area;
|
||||
struct save_area * __init save_area_alloc(bool is_boot_cpu);
|
||||
struct save_area * __init save_area_boot_cpu(void);
|
||||
void __init save_area_add_regs(struct save_area *, void *regs);
|
||||
void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs);
|
||||
|
||||
extern void do_reipl(void);
|
||||
extern void do_halt(void);
|
||||
extern void do_poff(void);
|
||||
extern void ipl_verify_parameters(void);
|
||||
extern void ipl_update_parameters(void);
|
||||
extern void s390_reset_system(void);
|
||||
extern void ipl_store_parameters(void);
|
||||
extern size_t append_ipl_vmparm(char *, size_t);
|
||||
extern size_t append_ipl_scpdata(char *, size_t);
|
||||
|
||||
enum {
|
||||
IPL_DEVNO_VALID = 1,
|
||||
IPL_PARMBLOCK_VALID = 2,
|
||||
};
|
||||
|
||||
enum ipl_type {
|
||||
IPL_TYPE_UNKNOWN = 1,
|
||||
IPL_TYPE_CCW = 2,
|
||||
@ -138,6 +120,7 @@ struct ipl_info
|
||||
|
||||
extern struct ipl_info ipl_info;
|
||||
extern void setup_ipl(void);
|
||||
extern void set_os_info_reipl_block(void);
|
||||
|
||||
/*
|
||||
* DIAG 308 support
|
||||
|
@ -9,6 +9,7 @@
|
||||
extern int nospec_disable;
|
||||
|
||||
void nospec_init_branches(void);
|
||||
void nospec_auto_detect(void);
|
||||
void nospec_revert(s32 *start, s32 *end);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
@ -1,20 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright IBM Corp. 2006
|
||||
* Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
|
||||
*/
|
||||
|
||||
#ifndef _ASM_S390_RESET_H
|
||||
#define _ASM_S390_RESET_H
|
||||
|
||||
#include <linux/list.h>
|
||||
|
||||
struct reset_call {
|
||||
struct list_head list;
|
||||
void (*fn)(void);
|
||||
};
|
||||
|
||||
extern void register_reset_call(struct reset_call *reset);
|
||||
extern void unregister_reset_call(struct reset_call *reset);
|
||||
extern void s390_reset_system(void);
|
||||
#endif /* _ASM_S390_RESET_H */
|
@ -203,9 +203,9 @@ struct ep11_urb {
|
||||
} __attribute__((packed));
|
||||
|
||||
/**
|
||||
* struct zcrypt_device_status
|
||||
* struct zcrypt_device_status_ext
|
||||
* @hwtype: raw hardware type
|
||||
* @qid: 6 bit device index, 8 bit domain
|
||||
* @qid: 8 bit device index, 8 bit domain
|
||||
* @functions: AP device function bit field 'abcdef'
|
||||
* a, b, c = reserved
|
||||
* d = CCA coprocessor
|
||||
@ -214,28 +214,23 @@ struct ep11_urb {
|
||||
* @online online status
|
||||
* @reserved reserved
|
||||
*/
|
||||
struct zcrypt_device_status {
|
||||
struct zcrypt_device_status_ext {
|
||||
unsigned int hwtype:8;
|
||||
unsigned int qid:14;
|
||||
unsigned int qid:16;
|
||||
unsigned int online:1;
|
||||
unsigned int functions:6;
|
||||
unsigned int reserved:3;
|
||||
unsigned int reserved:1;
|
||||
};
|
||||
|
||||
#define MAX_ZDEV_CARDIDS 64
|
||||
#define MAX_ZDEV_DOMAINS 256
|
||||
#define MAX_ZDEV_CARDIDS_EXT 256
|
||||
#define MAX_ZDEV_DOMAINS_EXT 256
|
||||
|
||||
/**
|
||||
* Maximum number of zcrypt devices
|
||||
*/
|
||||
#define MAX_ZDEV_ENTRIES (MAX_ZDEV_CARDIDS * MAX_ZDEV_DOMAINS)
|
||||
/* Maximum number of zcrypt devices */
|
||||
#define MAX_ZDEV_ENTRIES_EXT (MAX_ZDEV_CARDIDS_EXT * MAX_ZDEV_DOMAINS_EXT)
|
||||
|
||||
/**
|
||||
* zcrypt_device_matrix
|
||||
* Device matrix of all zcrypt devices
|
||||
*/
|
||||
struct zcrypt_device_matrix {
|
||||
struct zcrypt_device_status device[MAX_ZDEV_ENTRIES];
|
||||
/* Device matrix of all zcrypt devices */
|
||||
struct zcrypt_device_matrix_ext {
|
||||
struct zcrypt_device_status_ext device[MAX_ZDEV_ENTRIES_EXT];
|
||||
};
|
||||
|
||||
#define AUTOSELECT ((unsigned int)0xFFFFFFFF)
|
||||
@ -270,71 +265,35 @@ struct zcrypt_device_matrix {
|
||||
* ZSENDEP11CPRB
|
||||
* Send an arbitrary EP11 CPRB to an EP11 coprocessor crypto card.
|
||||
*
|
||||
* Z90STAT_STATUS_MASK
|
||||
* Return an 64 element array of unsigned chars for the status of
|
||||
* all devices.
|
||||
* ZCRYPT_DEVICE_STATUS
|
||||
* The given struct zcrypt_device_matrix_ext is updated with
|
||||
* status information for each currently known apqn.
|
||||
*
|
||||
* ZCRYPT_STATUS_MASK
|
||||
* Return an MAX_ZDEV_CARDIDS_EXT element array of unsigned chars for the
|
||||
* status of all devices.
|
||||
* 0x01: PCICA
|
||||
* 0x02: PCICC
|
||||
* 0x03: PCIXCC_MCL2
|
||||
* 0x04: PCIXCC_MCL3
|
||||
* 0x05: CEX2C
|
||||
* 0x06: CEX2A
|
||||
* 0x0d: device is disabled via the proc filesystem
|
||||
* 0x07: CEX3C
|
||||
* 0x08: CEX3A
|
||||
* 0x0a: CEX4
|
||||
* 0x0b: CEX5
|
||||
* 0x0c: CEX6
|
||||
* 0x0d: device is disabled
|
||||
*
|
||||
* Z90STAT_QDEPTH_MASK
|
||||
* Return an 64 element array of unsigned chars for the queue
|
||||
* depth of all devices.
|
||||
* ZCRYPT_QDEPTH_MASK
|
||||
* Return an MAX_ZDEV_CARDIDS_EXT element array of unsigned chars for the
|
||||
* queue depth of all devices.
|
||||
*
|
||||
* Z90STAT_PERDEV_REQCNT
|
||||
* Return an 64 element array of unsigned integers for the number
|
||||
* of successfully completed requests per device since the device
|
||||
* was detected and made available.
|
||||
* ZCRYPT_PERDEV_REQCNT
|
||||
* Return an MAX_ZDEV_CARDIDS_EXT element array of unsigned integers for
|
||||
* the number of successfully completed requests per device since the
|
||||
* device was detected and made available.
|
||||
*
|
||||
* Z90STAT_REQUESTQ_COUNT
|
||||
* Return an integer count of the number of entries waiting to be
|
||||
* sent to a device.
|
||||
*
|
||||
* Z90STAT_PENDINGQ_COUNT
|
||||
* Return an integer count of the number of entries sent to all
|
||||
* devices awaiting the reply.
|
||||
*
|
||||
* Z90STAT_TOTALOPEN_COUNT
|
||||
* Return an integer count of the number of open file handles.
|
||||
*
|
||||
* Z90STAT_DOMAIN_INDEX
|
||||
* Return the integer value of the Cryptographic Domain.
|
||||
*
|
||||
* The following ioctls are deprecated and should be no longer used:
|
||||
*
|
||||
* Z90STAT_TOTALCOUNT
|
||||
* Return an integer count of all device types together.
|
||||
*
|
||||
* Z90STAT_PCICACOUNT
|
||||
* Return an integer count of all PCICAs.
|
||||
*
|
||||
* Z90STAT_PCICCCOUNT
|
||||
* Return an integer count of all PCICCs.
|
||||
*
|
||||
* Z90STAT_PCIXCCMCL2COUNT
|
||||
* Return an integer count of all MCL2 PCIXCCs.
|
||||
*
|
||||
* Z90STAT_PCIXCCMCL3COUNT
|
||||
* Return an integer count of all MCL3 PCIXCCs.
|
||||
*
|
||||
* Z90STAT_CEX2CCOUNT
|
||||
* Return an integer count of all CEX2Cs.
|
||||
*
|
||||
* Z90STAT_CEX2ACOUNT
|
||||
* Return an integer count of all CEX2As.
|
||||
*
|
||||
* ICAZ90STATUS
|
||||
* Return some device driver status in a ica_z90_status struct
|
||||
* This takes an ica_z90_status struct as its arg.
|
||||
*
|
||||
* Z90STAT_PCIXCCCOUNT
|
||||
* Return an integer count of all PCIXCCs (MCL2 + MCL3).
|
||||
* This is DEPRECATED now that MCL3 PCIXCCs are treated differently from
|
||||
* MCL2 PCIXCCs.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -344,22 +303,56 @@ struct zcrypt_device_matrix {
|
||||
#define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0)
|
||||
#define ZSECSENDCPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0)
|
||||
#define ZSENDEP11CPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x04, 0)
|
||||
#define ZDEVICESTATUS _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x4f, 0)
|
||||
|
||||
/* New status calls */
|
||||
#define Z90STAT_TOTALCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x40, int)
|
||||
#define Z90STAT_PCICACOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x41, int)
|
||||
#define Z90STAT_PCICCCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x42, int)
|
||||
#define Z90STAT_PCIXCCMCL2COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4b, int)
|
||||
#define Z90STAT_PCIXCCMCL3COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4c, int)
|
||||
#define Z90STAT_CEX2CCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4d, int)
|
||||
#define Z90STAT_CEX2ACOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4e, int)
|
||||
#define ZCRYPT_DEVICE_STATUS _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x5f, 0)
|
||||
#define ZCRYPT_STATUS_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x58, char[MAX_ZDEV_CARDIDS_EXT])
|
||||
#define ZCRYPT_QDEPTH_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x59, char[MAX_ZDEV_CARDIDS_EXT])
|
||||
#define ZCRYPT_PERDEV_REQCNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x5a, int[MAX_ZDEV_CARDIDS_EXT])
|
||||
|
||||
/*
|
||||
* Only deprecated defines, structs and ioctls below this line.
|
||||
*/
|
||||
|
||||
/* Deprecated: use MAX_ZDEV_CARDIDS_EXT */
|
||||
#define MAX_ZDEV_CARDIDS 64
|
||||
/* Deprecated: use MAX_ZDEV_DOMAINS_EXT */
|
||||
#define MAX_ZDEV_DOMAINS 256
|
||||
|
||||
/* Deprecated: use MAX_ZDEV_ENTRIES_EXT */
|
||||
#define MAX_ZDEV_ENTRIES (MAX_ZDEV_CARDIDS * MAX_ZDEV_DOMAINS)
|
||||
|
||||
/* Deprecated: use struct zcrypt_device_status_ext */
|
||||
struct zcrypt_device_status {
|
||||
unsigned int hwtype:8;
|
||||
unsigned int qid:14;
|
||||
unsigned int online:1;
|
||||
unsigned int functions:6;
|
||||
unsigned int reserved:3;
|
||||
};
|
||||
|
||||
/* Deprecated: use struct zcrypt_device_matrix_ext */
|
||||
struct zcrypt_device_matrix {
|
||||
struct zcrypt_device_status device[MAX_ZDEV_ENTRIES];
|
||||
};
|
||||
|
||||
/* Deprecated: use ZCRYPT_DEVICE_STATUS */
|
||||
#define ZDEVICESTATUS _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x4f, 0)
|
||||
/* Deprecated: use ZCRYPT_STATUS_MASK */
|
||||
#define Z90STAT_STATUS_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x48, char[64])
|
||||
/* Deprecated: use ZCRYPT_QDEPTH_MASK */
|
||||
#define Z90STAT_QDEPTH_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x49, char[64])
|
||||
/* Deprecated: use ZCRYPT_PERDEV_REQCNT */
|
||||
#define Z90STAT_PERDEV_REQCNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4a, int[64])
|
||||
|
||||
/* Deprecated: use sysfs to query these values */
|
||||
#define Z90STAT_REQUESTQ_COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x44, int)
|
||||
#define Z90STAT_PENDINGQ_COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x45, int)
|
||||
#define Z90STAT_TOTALOPEN_COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x46, int)
|
||||
#define Z90STAT_DOMAIN_INDEX _IOR(ZCRYPT_IOCTL_MAGIC, 0x47, int)
|
||||
#define Z90STAT_STATUS_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x48, char[64])
|
||||
#define Z90STAT_QDEPTH_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x49, char[64])
|
||||
#define Z90STAT_PERDEV_REQCNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4a, int[64])
|
||||
|
||||
/*
|
||||
* The ioctl number ranges 0x40 - 0x42 and 0x4b - 0x4e had been used in the
|
||||
* past, don't assign new ioctls for these.
|
||||
*/
|
||||
|
||||
#endif /* __ASM_S390_ZCRYPT_H */
|
||||
|
@ -279,7 +279,7 @@ static int setup_frame32(struct ksignal *ksig, sigset_t *set,
|
||||
if (put_compat_sigset((compat_sigset_t __user *)frame->sc.oldmask,
|
||||
set, sizeof(compat_sigset_t)))
|
||||
return -EFAULT;
|
||||
if (__put_user(ptr_to_compat(&frame->sc), &frame->sc.sregs))
|
||||
if (__put_user(ptr_to_compat(&frame->sregs), &frame->sc.sregs))
|
||||
return -EFAULT;
|
||||
|
||||
/* Store registers needed to create the signal frame */
|
||||
|
@ -342,16 +342,6 @@ static __init void memmove_early(void *dst, const void *src, size_t n)
|
||||
S390_lowcore.program_new_psw = old;
|
||||
}
|
||||
|
||||
static __init noinline void ipl_save_parameters(void)
|
||||
{
|
||||
void *src, *dst;
|
||||
|
||||
src = (void *)(unsigned long) S390_lowcore.ipl_parmblock_ptr;
|
||||
dst = (void *) IPL_PARMBLOCK_ORIGIN;
|
||||
memmove_early(dst, src, PAGE_SIZE);
|
||||
S390_lowcore.ipl_parmblock_ptr = IPL_PARMBLOCK_ORIGIN;
|
||||
}
|
||||
|
||||
static __init noinline void rescue_initrd(void)
|
||||
{
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
@ -421,10 +411,8 @@ static void __init setup_boot_command_line(void)
|
||||
void __init startup_init(void)
|
||||
{
|
||||
reset_tod_clock();
|
||||
ipl_save_parameters();
|
||||
rescue_initrd();
|
||||
clear_bss_section();
|
||||
ipl_verify_parameters();
|
||||
time_early_init();
|
||||
init_kernel_storage_key();
|
||||
lockdep_off();
|
||||
@ -432,7 +420,7 @@ void __init startup_init(void)
|
||||
setup_facility_list();
|
||||
detect_machine_type();
|
||||
setup_arch_string();
|
||||
ipl_update_parameters();
|
||||
ipl_store_parameters();
|
||||
setup_boot_command_line();
|
||||
detect_diag9c();
|
||||
detect_diag44();
|
||||
|
@ -24,9 +24,7 @@
|
||||
#include <asm/smp.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/cpcmd.h>
|
||||
#include <asm/cio.h>
|
||||
#include <asm/ebcdic.h>
|
||||
#include <asm/reset.h>
|
||||
#include <asm/sclp.h>
|
||||
#include <asm/checksum.h>
|
||||
#include <asm/debug.h>
|
||||
@ -119,39 +117,12 @@ static char *dump_type_str(enum dump_type type)
|
||||
}
|
||||
}
|
||||
|
||||
static u8 ipl_ssid;
|
||||
static u16 ipl_devno;
|
||||
u32 ipl_flags;
|
||||
|
||||
enum ipl_method {
|
||||
REIPL_METHOD_CCW_CIO,
|
||||
REIPL_METHOD_CCW_DIAG,
|
||||
REIPL_METHOD_CCW_VM,
|
||||
REIPL_METHOD_FCP_RO_DIAG,
|
||||
REIPL_METHOD_FCP_RW_DIAG,
|
||||
REIPL_METHOD_FCP_RO_VM,
|
||||
REIPL_METHOD_FCP_DUMP,
|
||||
REIPL_METHOD_NSS,
|
||||
REIPL_METHOD_NSS_DIAG,
|
||||
REIPL_METHOD_DEFAULT,
|
||||
};
|
||||
|
||||
enum dump_method {
|
||||
DUMP_METHOD_NONE,
|
||||
DUMP_METHOD_CCW_CIO,
|
||||
DUMP_METHOD_CCW_DIAG,
|
||||
DUMP_METHOD_CCW_VM,
|
||||
DUMP_METHOD_FCP_DIAG,
|
||||
};
|
||||
|
||||
static int diag308_set_works;
|
||||
|
||||
static int ipl_block_valid;
|
||||
static struct ipl_parameter_block ipl_block;
|
||||
|
||||
static int reipl_capabilities = IPL_TYPE_UNKNOWN;
|
||||
|
||||
static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
|
||||
static enum ipl_method reipl_method = REIPL_METHOD_DEFAULT;
|
||||
static struct ipl_parameter_block *reipl_block_fcp;
|
||||
static struct ipl_parameter_block *reipl_block_ccw;
|
||||
static struct ipl_parameter_block *reipl_block_nss;
|
||||
@ -159,7 +130,6 @@ static struct ipl_parameter_block *reipl_block_actual;
|
||||
|
||||
static int dump_capabilities = DUMP_TYPE_NONE;
|
||||
static enum dump_type dump_type = DUMP_TYPE_NONE;
|
||||
static enum dump_method dump_method = DUMP_METHOD_NONE;
|
||||
static struct ipl_parameter_block *dump_block_fcp;
|
||||
static struct ipl_parameter_block *dump_block_ccw;
|
||||
|
||||
@ -260,33 +230,25 @@ static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
|
||||
sys_##_prefix##_##_name##_show, \
|
||||
sys_##_prefix##_##_name##_store)
|
||||
|
||||
static void make_attrs_ro(struct attribute **attrs)
|
||||
{
|
||||
while (*attrs) {
|
||||
(*attrs)->mode = S_IRUGO;
|
||||
attrs++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ipl section
|
||||
*/
|
||||
|
||||
static __init enum ipl_type get_ipl_type(void)
|
||||
{
|
||||
struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
|
||||
if (!ipl_block_valid)
|
||||
return IPL_TYPE_UNKNOWN;
|
||||
|
||||
if (!(ipl_flags & IPL_DEVNO_VALID))
|
||||
return IPL_TYPE_UNKNOWN;
|
||||
if (!(ipl_flags & IPL_PARMBLOCK_VALID))
|
||||
switch (ipl_block.hdr.pbt) {
|
||||
case DIAG308_IPL_TYPE_CCW:
|
||||
return IPL_TYPE_CCW;
|
||||
if (ipl->hdr.version > IPL_MAX_SUPPORTED_VERSION)
|
||||
return IPL_TYPE_UNKNOWN;
|
||||
if (ipl->hdr.pbt != DIAG308_IPL_TYPE_FCP)
|
||||
return IPL_TYPE_UNKNOWN;
|
||||
if (ipl->ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP)
|
||||
return IPL_TYPE_FCP_DUMP;
|
||||
return IPL_TYPE_FCP;
|
||||
case DIAG308_IPL_TYPE_FCP:
|
||||
if (ipl_block.ipl_info.fcp.opt == DIAG308_IPL_OPT_DUMP)
|
||||
return IPL_TYPE_FCP_DUMP;
|
||||
else
|
||||
return IPL_TYPE_FCP;
|
||||
}
|
||||
return IPL_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
struct ipl_info ipl_info;
|
||||
@ -338,7 +300,7 @@ size_t append_ipl_vmparm(char *dest, size_t size)
|
||||
size_t rc;
|
||||
|
||||
rc = 0;
|
||||
if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW))
|
||||
if (ipl_block_valid && ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)
|
||||
rc = reipl_get_ascii_vmparm(dest, size, &ipl_block);
|
||||
else
|
||||
dest[0] = 0;
|
||||
@ -401,7 +363,7 @@ size_t append_ipl_scpdata(char *dest, size_t len)
|
||||
size_t rc;
|
||||
|
||||
rc = 0;
|
||||
if (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP)
|
||||
if (ipl_block_valid && ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP)
|
||||
rc = reipl_append_ascii_scpdata(dest, len, &ipl_block);
|
||||
else
|
||||
dest[0] = 0;
|
||||
@ -415,14 +377,14 @@ static struct kobj_attribute sys_ipl_vm_parm_attr =
|
||||
static ssize_t sys_ipl_device_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *page)
|
||||
{
|
||||
struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
|
||||
|
||||
switch (ipl_info.type) {
|
||||
case IPL_TYPE_CCW:
|
||||
return sprintf(page, "0.%x.%04x\n", ipl_ssid, ipl_devno);
|
||||
return sprintf(page, "0.%x.%04x\n", ipl_block.ipl_info.ccw.ssid,
|
||||
ipl_block.ipl_info.ccw.devno);
|
||||
case IPL_TYPE_FCP:
|
||||
case IPL_TYPE_FCP_DUMP:
|
||||
return sprintf(page, "0.0.%04x\n", ipl->ipl_info.fcp.devno);
|
||||
return sprintf(page, "0.0.%04x\n",
|
||||
ipl_block.ipl_info.fcp.devno);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -435,8 +397,8 @@ static ssize_t ipl_parameter_read(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *attr, char *buf,
|
||||
loff_t off, size_t count)
|
||||
{
|
||||
return memory_read_from_buffer(buf, count, &off, IPL_PARMBLOCK_START,
|
||||
IPL_PARMBLOCK_SIZE);
|
||||
return memory_read_from_buffer(buf, count, &off, &ipl_block,
|
||||
ipl_block.hdr.len);
|
||||
}
|
||||
static struct bin_attribute ipl_parameter_attr =
|
||||
__BIN_ATTR(binary_parameter, S_IRUGO, ipl_parameter_read, NULL,
|
||||
@ -446,8 +408,8 @@ static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *attr, char *buf,
|
||||
loff_t off, size_t count)
|
||||
{
|
||||
unsigned int size = IPL_PARMBLOCK_START->ipl_info.fcp.scp_data_len;
|
||||
void *scp_data = &IPL_PARMBLOCK_START->ipl_info.fcp.scp_data;
|
||||
unsigned int size = ipl_block.ipl_info.fcp.scp_data_len;
|
||||
void *scp_data = &ipl_block.ipl_info.fcp.scp_data;
|
||||
|
||||
return memory_read_from_buffer(buf, count, &off, scp_data, size);
|
||||
}
|
||||
@ -462,14 +424,14 @@ static struct bin_attribute *ipl_fcp_bin_attrs[] = {
|
||||
|
||||
/* FCP ipl device attributes */
|
||||
|
||||
DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n", (unsigned long long)
|
||||
IPL_PARMBLOCK_START->ipl_info.fcp.wwpn);
|
||||
DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n", (unsigned long long)
|
||||
IPL_PARMBLOCK_START->ipl_info.fcp.lun);
|
||||
DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", (unsigned long long)
|
||||
IPL_PARMBLOCK_START->ipl_info.fcp.bootprog);
|
||||
DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long)
|
||||
IPL_PARMBLOCK_START->ipl_info.fcp.br_lba);
|
||||
DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n",
|
||||
(unsigned long long)ipl_block.ipl_info.fcp.wwpn);
|
||||
DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n",
|
||||
(unsigned long long)ipl_block.ipl_info.fcp.lun);
|
||||
DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n",
|
||||
(unsigned long long)ipl_block.ipl_info.fcp.bootprog);
|
||||
DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n",
|
||||
(unsigned long long)ipl_block.ipl_info.fcp.br_lba);
|
||||
|
||||
static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *page)
|
||||
@ -545,10 +507,6 @@ static void __ipl_run(void *unused)
|
||||
{
|
||||
__bpon();
|
||||
diag308(DIAG308_LOAD_CLEAR, NULL);
|
||||
if (MACHINE_IS_VM)
|
||||
__cpcmd("IPL", NULL, 0, NULL);
|
||||
else if (ipl_info.type == IPL_TYPE_CCW)
|
||||
reipl_ccw_dev(&ipl_info.data.ccw.dev_id);
|
||||
}
|
||||
|
||||
static void ipl_run(struct shutdown_trigger *trigger)
|
||||
@ -776,6 +734,7 @@ static ssize_t reipl_generic_loadparm_store(struct ipl_parameter_block *ipb,
|
||||
/* copy and convert to ebcdic */
|
||||
memcpy(ipb->hdr.loadparm, buf, lp_len);
|
||||
ASCEBC(ipb->hdr.loadparm, LOADPARM_LEN);
|
||||
ipb->hdr.flags |= DIAG308_FLAGS_LP_VALID;
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -938,11 +897,10 @@ static struct attribute_group reipl_nss_attr_group = {
|
||||
.attrs = reipl_nss_attrs,
|
||||
};
|
||||
|
||||
static void set_reipl_block_actual(struct ipl_parameter_block *reipl_block)
|
||||
void set_os_info_reipl_block(void)
|
||||
{
|
||||
reipl_block_actual = reipl_block;
|
||||
os_info_entry_add(OS_INFO_REIPL_BLOCK, reipl_block_actual,
|
||||
reipl_block->hdr.len);
|
||||
reipl_block_actual->hdr.len);
|
||||
}
|
||||
|
||||
/* reipl type */
|
||||
@ -954,38 +912,16 @@ static int reipl_set_type(enum ipl_type type)
|
||||
|
||||
switch(type) {
|
||||
case IPL_TYPE_CCW:
|
||||
if (diag308_set_works)
|
||||
reipl_method = REIPL_METHOD_CCW_DIAG;
|
||||
else if (MACHINE_IS_VM)
|
||||
reipl_method = REIPL_METHOD_CCW_VM;
|
||||
else
|
||||
reipl_method = REIPL_METHOD_CCW_CIO;
|
||||
set_reipl_block_actual(reipl_block_ccw);
|
||||
reipl_block_actual = reipl_block_ccw;
|
||||
break;
|
||||
case IPL_TYPE_FCP:
|
||||
if (diag308_set_works)
|
||||
reipl_method = REIPL_METHOD_FCP_RW_DIAG;
|
||||
else if (MACHINE_IS_VM)
|
||||
reipl_method = REIPL_METHOD_FCP_RO_VM;
|
||||
else
|
||||
reipl_method = REIPL_METHOD_FCP_RO_DIAG;
|
||||
set_reipl_block_actual(reipl_block_fcp);
|
||||
break;
|
||||
case IPL_TYPE_FCP_DUMP:
|
||||
reipl_method = REIPL_METHOD_FCP_DUMP;
|
||||
reipl_block_actual = reipl_block_fcp;
|
||||
break;
|
||||
case IPL_TYPE_NSS:
|
||||
if (diag308_set_works)
|
||||
reipl_method = REIPL_METHOD_NSS_DIAG;
|
||||
else
|
||||
reipl_method = REIPL_METHOD_NSS;
|
||||
set_reipl_block_actual(reipl_block_nss);
|
||||
break;
|
||||
case IPL_TYPE_UNKNOWN:
|
||||
reipl_method = REIPL_METHOD_DEFAULT;
|
||||
reipl_block_actual = reipl_block_nss;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
break;
|
||||
}
|
||||
reipl_type = type;
|
||||
return 0;
|
||||
@ -1018,77 +954,25 @@ static struct kobj_attribute reipl_type_attr =
|
||||
static struct kset *reipl_kset;
|
||||
static struct kset *reipl_fcp_kset;
|
||||
|
||||
static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb,
|
||||
const enum ipl_method m)
|
||||
{
|
||||
char loadparm[LOADPARM_LEN + 1] = {};
|
||||
char vmparm[DIAG308_VMPARM_SIZE + 1] = {};
|
||||
char nss_name[NSS_NAME_SIZE + 1] = {};
|
||||
size_t pos = 0;
|
||||
|
||||
reipl_get_ascii_loadparm(loadparm, ipb);
|
||||
reipl_get_ascii_nss_name(nss_name, ipb);
|
||||
reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb);
|
||||
|
||||
switch (m) {
|
||||
case REIPL_METHOD_CCW_VM:
|
||||
pos = sprintf(dst, "IPL %X CLEAR", ipb->ipl_info.ccw.devno);
|
||||
break;
|
||||
case REIPL_METHOD_NSS:
|
||||
pos = sprintf(dst, "IPL %s", nss_name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (strlen(loadparm) > 0)
|
||||
pos += sprintf(dst + pos, " LOADPARM '%s'", loadparm);
|
||||
if (strlen(vmparm) > 0)
|
||||
sprintf(dst + pos, " PARM %s", vmparm);
|
||||
}
|
||||
|
||||
static void __reipl_run(void *unused)
|
||||
{
|
||||
struct ccw_dev_id devid;
|
||||
static char buf[128];
|
||||
|
||||
switch (reipl_method) {
|
||||
case REIPL_METHOD_CCW_CIO:
|
||||
devid.ssid = reipl_block_ccw->ipl_info.ccw.ssid;
|
||||
devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
|
||||
reipl_ccw_dev(&devid);
|
||||
break;
|
||||
case REIPL_METHOD_CCW_VM:
|
||||
get_ipl_string(buf, reipl_block_ccw, REIPL_METHOD_CCW_VM);
|
||||
__cpcmd(buf, NULL, 0, NULL);
|
||||
break;
|
||||
case REIPL_METHOD_CCW_DIAG:
|
||||
switch (reipl_type) {
|
||||
case IPL_TYPE_CCW:
|
||||
diag308(DIAG308_SET, reipl_block_ccw);
|
||||
diag308(DIAG308_LOAD_CLEAR, NULL);
|
||||
break;
|
||||
case REIPL_METHOD_FCP_RW_DIAG:
|
||||
case IPL_TYPE_FCP:
|
||||
diag308(DIAG308_SET, reipl_block_fcp);
|
||||
diag308(DIAG308_LOAD_CLEAR, NULL);
|
||||
break;
|
||||
case REIPL_METHOD_FCP_RO_DIAG:
|
||||
diag308(DIAG308_LOAD_CLEAR, NULL);
|
||||
break;
|
||||
case REIPL_METHOD_FCP_RO_VM:
|
||||
__cpcmd("IPL", NULL, 0, NULL);
|
||||
break;
|
||||
case REIPL_METHOD_NSS_DIAG:
|
||||
case IPL_TYPE_NSS:
|
||||
diag308(DIAG308_SET, reipl_block_nss);
|
||||
diag308(DIAG308_LOAD_CLEAR, NULL);
|
||||
break;
|
||||
case REIPL_METHOD_NSS:
|
||||
get_ipl_string(buf, reipl_block_nss, REIPL_METHOD_NSS);
|
||||
__cpcmd(buf, NULL, 0, NULL);
|
||||
break;
|
||||
case REIPL_METHOD_DEFAULT:
|
||||
if (MACHINE_IS_VM)
|
||||
__cpcmd("IPL", NULL, 0, NULL);
|
||||
case IPL_TYPE_UNKNOWN:
|
||||
diag308(DIAG308_LOAD_CLEAR, NULL);
|
||||
break;
|
||||
case REIPL_METHOD_FCP_DUMP:
|
||||
case IPL_TYPE_FCP_DUMP:
|
||||
break;
|
||||
}
|
||||
disabled_wait((unsigned long) __builtin_return_address(0));
|
||||
@ -1119,7 +1003,7 @@ static void reipl_block_ccw_fill_parms(struct ipl_parameter_block *ipb)
|
||||
ipb->hdr.flags = DIAG308_FLAGS_LP_VALID;
|
||||
|
||||
/* VM PARM */
|
||||
if (MACHINE_IS_VM && diag308_set_works &&
|
||||
if (MACHINE_IS_VM && ipl_block_valid &&
|
||||
(ipl_block.ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID)) {
|
||||
|
||||
ipb->ipl_info.ccw.vm_flags |= DIAG308_VM_FLAGS_VP_VALID;
|
||||
@ -1141,9 +1025,6 @@ static int __init reipl_nss_init(void)
|
||||
if (!reipl_block_nss)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!diag308_set_works)
|
||||
sys_reipl_nss_vmparm_attr.attr.mode = S_IRUGO;
|
||||
|
||||
rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group);
|
||||
if (rc)
|
||||
return rc;
|
||||
@ -1161,24 +1042,16 @@ static int __init reipl_ccw_init(void)
|
||||
if (!reipl_block_ccw)
|
||||
return -ENOMEM;
|
||||
|
||||
if (MACHINE_IS_VM) {
|
||||
if (!diag308_set_works)
|
||||
sys_reipl_ccw_vmparm_attr.attr.mode = S_IRUGO;
|
||||
rc = sysfs_create_group(&reipl_kset->kobj,
|
||||
&reipl_ccw_attr_group_vm);
|
||||
} else {
|
||||
if(!diag308_set_works)
|
||||
sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO;
|
||||
rc = sysfs_create_group(&reipl_kset->kobj,
|
||||
&reipl_ccw_attr_group_lpar);
|
||||
}
|
||||
rc = sysfs_create_group(&reipl_kset->kobj,
|
||||
MACHINE_IS_VM ? &reipl_ccw_attr_group_vm
|
||||
: &reipl_ccw_attr_group_lpar);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
reipl_block_ccw_init(reipl_block_ccw);
|
||||
if (ipl_info.type == IPL_TYPE_CCW) {
|
||||
reipl_block_ccw->ipl_info.ccw.ssid = ipl_ssid;
|
||||
reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
|
||||
reipl_block_ccw->ipl_info.ccw.ssid = ipl_block.ipl_info.ccw.ssid;
|
||||
reipl_block_ccw->ipl_info.ccw.devno = ipl_block.ipl_info.ccw.devno;
|
||||
reipl_block_ccw_fill_parms(reipl_block_ccw);
|
||||
}
|
||||
|
||||
@ -1190,14 +1063,6 @@ static int __init reipl_fcp_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!diag308_set_works) {
|
||||
if (ipl_info.type == IPL_TYPE_FCP) {
|
||||
make_attrs_ro(reipl_fcp_attrs);
|
||||
sys_reipl_fcp_scp_data_attr.attr.mode = S_IRUGO;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
|
||||
if (!reipl_block_fcp)
|
||||
return -ENOMEM;
|
||||
@ -1218,7 +1083,7 @@ static int __init reipl_fcp_init(void)
|
||||
}
|
||||
|
||||
if (ipl_info.type == IPL_TYPE_FCP) {
|
||||
memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE);
|
||||
memcpy(reipl_block_fcp, &ipl_block, sizeof(ipl_block));
|
||||
/*
|
||||
* Fix loadparm: There are systems where the (SCSI) LOADPARM
|
||||
* is invalid in the SCSI IPL parameter block, so take it
|
||||
@ -1340,21 +1205,6 @@ static int dump_set_type(enum dump_type type)
|
||||
{
|
||||
if (!(dump_capabilities & type))
|
||||
return -EINVAL;
|
||||
switch (type) {
|
||||
case DUMP_TYPE_CCW:
|
||||
if (diag308_set_works)
|
||||
dump_method = DUMP_METHOD_CCW_DIAG;
|
||||
else if (MACHINE_IS_VM)
|
||||
dump_method = DUMP_METHOD_CCW_VM;
|
||||
else
|
||||
dump_method = DUMP_METHOD_CCW_CIO;
|
||||
break;
|
||||
case DUMP_TYPE_FCP:
|
||||
dump_method = DUMP_METHOD_FCP_DIAG;
|
||||
break;
|
||||
default:
|
||||
dump_method = DUMP_METHOD_NONE;
|
||||
}
|
||||
dump_type = type;
|
||||
return 0;
|
||||
}
|
||||
@ -1397,25 +1247,11 @@ static void diag308_dump(void *dump_block)
|
||||
|
||||
static void __dump_run(void *unused)
|
||||
{
|
||||
struct ccw_dev_id devid;
|
||||
static char buf[100];
|
||||
|
||||
switch (dump_method) {
|
||||
case DUMP_METHOD_CCW_CIO:
|
||||
devid.ssid = dump_block_ccw->ipl_info.ccw.ssid;
|
||||
devid.devno = dump_block_ccw->ipl_info.ccw.devno;
|
||||
reipl_ccw_dev(&devid);
|
||||
break;
|
||||
case DUMP_METHOD_CCW_VM:
|
||||
sprintf(buf, "STORE STATUS");
|
||||
__cpcmd(buf, NULL, 0, NULL);
|
||||
sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
|
||||
__cpcmd(buf, NULL, 0, NULL);
|
||||
break;
|
||||
case DUMP_METHOD_CCW_DIAG:
|
||||
switch (dump_type) {
|
||||
case DUMP_TYPE_CCW:
|
||||
diag308_dump(dump_block_ccw);
|
||||
break;
|
||||
case DUMP_METHOD_FCP_DIAG:
|
||||
case DUMP_TYPE_FCP:
|
||||
diag308_dump(dump_block_fcp);
|
||||
break;
|
||||
default:
|
||||
@ -1425,7 +1261,7 @@ static void __dump_run(void *unused)
|
||||
|
||||
static void dump_run(struct shutdown_trigger *trigger)
|
||||
{
|
||||
if (dump_method == DUMP_METHOD_NONE)
|
||||
if (dump_type == DUMP_TYPE_NONE)
|
||||
return;
|
||||
smp_send_stop();
|
||||
smp_call_ipl_cpu(__dump_run, NULL);
|
||||
@ -1457,8 +1293,6 @@ static int __init dump_fcp_init(void)
|
||||
|
||||
if (!sclp_ipl_info.has_dump)
|
||||
return 0; /* LDIPL DUMP is not installed */
|
||||
if (!diag308_set_works)
|
||||
return 0;
|
||||
dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
|
||||
if (!dump_block_fcp)
|
||||
return -ENOMEM;
|
||||
@ -1516,18 +1350,9 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
|
||||
dump_run(trigger);
|
||||
}
|
||||
|
||||
static int __init dump_reipl_init(void)
|
||||
{
|
||||
if (!diag308_set_works)
|
||||
return -EOPNOTSUPP;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shutdown_action __refdata dump_reipl_action = {
|
||||
.name = SHUTDOWN_ACTION_DUMP_REIPL_STR,
|
||||
.fn = dump_reipl_run,
|
||||
.init = dump_reipl_init,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1838,10 +1663,8 @@ static int __init s390_ipl_init(void)
|
||||
* case the system is booted from HMC. Fortunately in this case
|
||||
* READ SCP info provides the correct value.
|
||||
*/
|
||||
if (memcmp(sclp_ipl_info.loadparm, str, sizeof(str)) == 0 &&
|
||||
diag308_set_works)
|
||||
memcpy(sclp_ipl_info.loadparm, ipl_block.hdr.loadparm,
|
||||
LOADPARM_LEN);
|
||||
if (memcmp(sclp_ipl_info.loadparm, str, sizeof(str)) == 0 && ipl_block_valid)
|
||||
memcpy(sclp_ipl_info.loadparm, ipl_block.hdr.loadparm, LOADPARM_LEN);
|
||||
shutdown_actions_init();
|
||||
shutdown_triggers_init();
|
||||
return 0;
|
||||
@ -1921,19 +1744,20 @@ static struct notifier_block on_panic_nb = {
|
||||
|
||||
void __init setup_ipl(void)
|
||||
{
|
||||
BUILD_BUG_ON(sizeof(struct ipl_parameter_block) != PAGE_SIZE);
|
||||
|
||||
ipl_info.type = get_ipl_type();
|
||||
switch (ipl_info.type) {
|
||||
case IPL_TYPE_CCW:
|
||||
ipl_info.data.ccw.dev_id.ssid = ipl_ssid;
|
||||
ipl_info.data.ccw.dev_id.devno = ipl_devno;
|
||||
ipl_info.data.ccw.dev_id.ssid = ipl_block.ipl_info.ccw.ssid;
|
||||
ipl_info.data.ccw.dev_id.devno = ipl_block.ipl_info.ccw.devno;
|
||||
break;
|
||||
case IPL_TYPE_FCP:
|
||||
case IPL_TYPE_FCP_DUMP:
|
||||
ipl_info.data.fcp.dev_id.ssid = 0;
|
||||
ipl_info.data.fcp.dev_id.devno =
|
||||
IPL_PARMBLOCK_START->ipl_info.fcp.devno;
|
||||
ipl_info.data.fcp.wwpn = IPL_PARMBLOCK_START->ipl_info.fcp.wwpn;
|
||||
ipl_info.data.fcp.lun = IPL_PARMBLOCK_START->ipl_info.fcp.lun;
|
||||
ipl_info.data.fcp.dev_id.devno = ipl_block.ipl_info.fcp.devno;
|
||||
ipl_info.data.fcp.wwpn = ipl_block.ipl_info.fcp.wwpn;
|
||||
ipl_info.data.fcp.lun = ipl_block.ipl_info.fcp.lun;
|
||||
break;
|
||||
case IPL_TYPE_NSS:
|
||||
case IPL_TYPE_UNKNOWN:
|
||||
@ -1943,85 +1767,21 @@ void __init setup_ipl(void)
|
||||
atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
|
||||
}
|
||||
|
||||
void __init ipl_update_parameters(void)
|
||||
void __init ipl_store_parameters(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = diag308(DIAG308_STORE, &ipl_block);
|
||||
if ((rc == DIAG308_RC_OK) || (rc == DIAG308_RC_NOCONFIG))
|
||||
diag308_set_works = 1;
|
||||
}
|
||||
|
||||
void __init ipl_verify_parameters(void)
|
||||
{
|
||||
struct cio_iplinfo iplinfo;
|
||||
|
||||
if (cio_get_iplinfo(&iplinfo))
|
||||
return;
|
||||
|
||||
ipl_ssid = iplinfo.ssid;
|
||||
ipl_devno = iplinfo.devno;
|
||||
ipl_flags |= IPL_DEVNO_VALID;
|
||||
if (!iplinfo.is_qdio)
|
||||
return;
|
||||
ipl_flags |= IPL_PARMBLOCK_VALID;
|
||||
}
|
||||
|
||||
static LIST_HEAD(rcall);
|
||||
static DEFINE_MUTEX(rcall_mutex);
|
||||
|
||||
void register_reset_call(struct reset_call *reset)
|
||||
{
|
||||
mutex_lock(&rcall_mutex);
|
||||
list_add(&reset->list, &rcall);
|
||||
mutex_unlock(&rcall_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(register_reset_call);
|
||||
|
||||
void unregister_reset_call(struct reset_call *reset)
|
||||
{
|
||||
mutex_lock(&rcall_mutex);
|
||||
list_del(&reset->list);
|
||||
mutex_unlock(&rcall_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_reset_call);
|
||||
|
||||
static void do_reset_calls(void)
|
||||
{
|
||||
struct reset_call *reset;
|
||||
|
||||
if (diag308_set_works) {
|
||||
diag308_reset();
|
||||
return;
|
||||
}
|
||||
list_for_each_entry(reset, &rcall, list)
|
||||
reset->fn();
|
||||
if (rc == DIAG308_RC_OK && ipl_block.hdr.version <= IPL_MAX_SUPPORTED_VERSION)
|
||||
ipl_block_valid = 1;
|
||||
}
|
||||
|
||||
void s390_reset_system(void)
|
||||
{
|
||||
struct lowcore *lc;
|
||||
|
||||
lc = (struct lowcore *)(unsigned long) store_prefix();
|
||||
|
||||
/* Stack for interrupt/machine check handler */
|
||||
lc->panic_stack = S390_lowcore.panic_stack;
|
||||
|
||||
/* Disable prefixing */
|
||||
set_prefix(0);
|
||||
|
||||
/* Disable lowcore protection */
|
||||
__ctl_clear_bit(0,28);
|
||||
|
||||
/* Set new machine check handler */
|
||||
S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
|
||||
S390_lowcore.mcck_new_psw.addr =
|
||||
(unsigned long) s390_base_mcck_handler;
|
||||
|
||||
/* Set new program check handler */
|
||||
S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_DAT;
|
||||
S390_lowcore.program_new_psw.addr =
|
||||
(unsigned long) s390_base_pgm_handler;
|
||||
|
||||
do_reset_calls();
|
||||
__ctl_clear_bit(0, 28);
|
||||
diag308_reset();
|
||||
}
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/reset.h>
|
||||
#include <asm/ipl.h>
|
||||
#include <asm/diag.h>
|
||||
#include <asm/elf.h>
|
||||
@ -253,6 +252,7 @@ void machine_shutdown(void)
|
||||
|
||||
void machine_crash_shutdown(struct pt_regs *regs)
|
||||
{
|
||||
set_os_info_reipl_block();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -72,7 +72,7 @@ static int __init nospectre_v2_setup_early(char *str)
|
||||
}
|
||||
early_param("nospectre_v2", nospectre_v2_setup_early);
|
||||
|
||||
static int __init spectre_v2_auto_early(void)
|
||||
void __init nospec_auto_detect(void)
|
||||
{
|
||||
if (IS_ENABLED(CC_USING_EXPOLINE)) {
|
||||
/*
|
||||
@ -87,11 +87,7 @@ static int __init spectre_v2_auto_early(void)
|
||||
* nobp setting decides what is done, this depends on the
|
||||
* CONFIG_KERNEL_NP option and the nobp/nospec parameters.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
#ifdef CONFIG_EXPOLINE_AUTO
|
||||
early_initcall(spectre_v2_auto_early);
|
||||
#endif
|
||||
|
||||
static int __init spectre_v2_setup_early(char *str)
|
||||
{
|
||||
@ -102,7 +98,7 @@ static int __init spectre_v2_setup_early(char *str)
|
||||
if (str && !strncmp(str, "off", 3))
|
||||
nospec_disable = 1;
|
||||
if (str && !strncmp(str, "auto", 4))
|
||||
spectre_v2_auto_early();
|
||||
nospec_auto_detect();
|
||||
return 0;
|
||||
}
|
||||
early_param("spectre_v2", spectre_v2_setup_early);
|
||||
|
@ -75,90 +75,3 @@ ENTRY(store_status)
|
||||
.align 8
|
||||
.Lclkcmp: .quad 0x0000000000000000
|
||||
.previous
|
||||
|
||||
#
|
||||
# do_reipl_asm
|
||||
# Parameter: r2 = schid of reipl device
|
||||
#
|
||||
|
||||
ENTRY(do_reipl_asm)
|
||||
basr %r13,0
|
||||
.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13)
|
||||
.Lpg1: lgr %r3,%r2
|
||||
larl %r2,.Lstatus
|
||||
brasl %r14,store_status
|
||||
|
||||
.Lstatus: lctlg %c6,%c6,.Lall-.Lpg0(%r13)
|
||||
lgr %r1,%r2
|
||||
mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
|
||||
stsch .Lschib-.Lpg0(%r13)
|
||||
oi .Lschib+5-.Lpg0(%r13),0x84
|
||||
.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01
|
||||
msch .Lschib-.Lpg0(%r13)
|
||||
lghi %r0,5
|
||||
.Lssch: ssch .Liplorb-.Lpg0(%r13)
|
||||
jz .L001
|
||||
brct %r0,.Lssch
|
||||
bas %r14,.Ldisab-.Lpg0(%r13)
|
||||
.L001: mvc __LC_IO_NEW_PSW(16),.Lionew-.Lpg0(%r13)
|
||||
.Ltpi: lpswe .Lwaitpsw-.Lpg0(%r13)
|
||||
.Lcont: c %r1,__LC_SUBCHANNEL_ID
|
||||
jnz .Ltpi
|
||||
clc __LC_IO_INT_PARM(4),.Liplorb-.Lpg0(%r13)
|
||||
jnz .Ltpi
|
||||
tsch .Liplirb-.Lpg0(%r13)
|
||||
tm .Liplirb+9-.Lpg0(%r13),0xbf
|
||||
jz .L002
|
||||
bas %r14,.Ldisab-.Lpg0(%r13)
|
||||
.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3
|
||||
jz .L003
|
||||
bas %r14,.Ldisab-.Lpg0(%r13)
|
||||
.L003: st %r1,__LC_SUBCHANNEL_ID
|
||||
lhi %r1,0 # mode 0 = esa
|
||||
slr %r0,%r0 # set cpuid to zero
|
||||
sigp %r1,%r0,SIGP_SET_ARCHITECTURE # switch to esa mode
|
||||
lpsw 0
|
||||
.Ldisab: sll %r14,1
|
||||
srl %r14,1 # need to kill hi bit to avoid specification exceptions.
|
||||
st %r14,.Ldispsw+12-.Lpg0(%r13)
|
||||
lpswe .Ldispsw-.Lpg0(%r13)
|
||||
.align 8
|
||||
.Lall: .quad 0x00000000ff000000
|
||||
.align 16
|
||||
/*
|
||||
* These addresses have to be 31 bit otherwise
|
||||
* the sigp will throw a specifcation exception
|
||||
* when switching to ESA mode as bit 31 be set
|
||||
* in the ESA psw.
|
||||
* Bit 31 of the addresses has to be 0 for the
|
||||
* 31bit lpswe instruction a fact they appear to have
|
||||
* omitted from the pop.
|
||||
*/
|
||||
.Lnewpsw: .quad 0x0000000080000000
|
||||
.quad .Lpg1
|
||||
.Lpcnew: .quad 0x0000000080000000
|
||||
.quad .Lecs
|
||||
.Lionew: .quad 0x0000000080000000
|
||||
.quad .Lcont
|
||||
.Lwaitpsw: .quad 0x0202000080000000
|
||||
.quad .Ltpi
|
||||
.Ldispsw: .quad 0x0002000080000000
|
||||
.quad 0x0000000000000000
|
||||
.Liplccws: .long 0x02000000,0x60000018
|
||||
.long 0x08000008,0x20000001
|
||||
.Liplorb: .long 0x0049504c,0x0040ff80
|
||||
.long 0x00000000+.Liplccws
|
||||
.Lschib: .long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
.Liplirb: .long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
.long 0x00000000,0x00000000
|
||||
|
@ -29,33 +29,6 @@
|
||||
ENTRY(relocate_kernel)
|
||||
basr %r13,0 # base address
|
||||
.base:
|
||||
stctg %c0,%c15,ctlregs-.base(%r13)
|
||||
stmg %r0,%r15,gprregs-.base(%r13)
|
||||
lghi %r0,3
|
||||
sllg %r0,%r0,31
|
||||
stg %r0,0x1d0(%r0)
|
||||
la %r0,.back_pgm-.base(%r13)
|
||||
stg %r0,0x1d8(%r0)
|
||||
la %r1,load_psw-.base(%r13)
|
||||
mvc 0(8,%r0),0(%r1)
|
||||
la %r0,.back-.base(%r13)
|
||||
st %r0,4(%r0)
|
||||
oi 4(%r0),0x80
|
||||
lghi %r0,0
|
||||
diag %r0,%r0,0x308
|
||||
.back:
|
||||
lhi %r1,1 # mode 1 = esame
|
||||
sigp %r1,%r0,SIGP_SET_ARCHITECTURE # switch to esame mode
|
||||
sam64 # switch to 64 bit addressing mode
|
||||
basr %r13,0
|
||||
.back_base:
|
||||
oi have_diag308-.back_base(%r13),0x01
|
||||
lctlg %c0,%c15,ctlregs-.back_base(%r13)
|
||||
lmg %r0,%r15,gprregs-.back_base(%r13)
|
||||
j .top
|
||||
.back_pgm:
|
||||
lmg %r0,%r15,gprregs-.base(%r13)
|
||||
.top:
|
||||
lghi %r7,PAGE_SIZE # load PAGE_SIZE in r7
|
||||
lghi %r9,PAGE_SIZE # load PAGE_SIZE in r9
|
||||
lg %r5,0(%r2) # read another word for indirection page
|
||||
@ -64,55 +37,36 @@ ENTRY(relocate_kernel)
|
||||
je .indir_check # NO, goto "indir_check"
|
||||
lgr %r6,%r5 # r6 = r5
|
||||
nill %r6,0xf000 # mask it out and...
|
||||
j .top # ...next iteration
|
||||
j .base # ...next iteration
|
||||
.indir_check:
|
||||
tml %r5,0x2 # is it a indirection page?
|
||||
je .done_test # NO, goto "done_test"
|
||||
nill %r5,0xf000 # YES, mask out,
|
||||
lgr %r2,%r5 # move it into the right register,
|
||||
j .top # and read next...
|
||||
j .base # and read next...
|
||||
.done_test:
|
||||
tml %r5,0x4 # is it the done indicator?
|
||||
je .source_test # NO! Well, then it should be the source indicator...
|
||||
j .done # ok, lets finish it here...
|
||||
.source_test:
|
||||
tml %r5,0x8 # it should be a source indicator...
|
||||
je .top # NO, ignore it...
|
||||
je .base # NO, ignore it...
|
||||
lgr %r8,%r5 # r8 = r5
|
||||
nill %r8,0xf000 # masking
|
||||
0: mvcle %r6,%r8,0x0 # copy PAGE_SIZE bytes from r8 to r6 - pad with 0
|
||||
jo 0b
|
||||
j .top
|
||||
j .base
|
||||
.done:
|
||||
sgr %r0,%r0 # clear register r0
|
||||
la %r4,load_psw-.base(%r13) # load psw-address into the register
|
||||
o %r3,4(%r4) # or load address into psw
|
||||
st %r3,4(%r4)
|
||||
mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0
|
||||
tm have_diag308-.base(%r13),0x01
|
||||
jno .no_diag308
|
||||
diag %r0,%r0,0x308
|
||||
.no_diag308:
|
||||
sam31 # 31 bit mode
|
||||
sr %r1,%r1 # erase register r1
|
||||
sr %r2,%r2 # erase register r2
|
||||
sigp %r1,%r2,SIGP_SET_ARCHITECTURE # set cpuid to zero
|
||||
lpsw 0 # hopefully start new kernel...
|
||||
|
||||
.align 8
|
||||
load_psw:
|
||||
.long 0x00080000,0x80000000
|
||||
ctlregs:
|
||||
.rept 16
|
||||
.quad 0
|
||||
.endr
|
||||
gprregs:
|
||||
.rept 16
|
||||
.quad 0
|
||||
.endr
|
||||
have_diag308:
|
||||
.byte 0
|
||||
.align 8
|
||||
relocate_kernel_end:
|
||||
.align 8
|
||||
.globl relocate_kernel_len
|
||||
|
@ -894,6 +894,9 @@ void __init setup_arch(char **cmdline_p)
|
||||
init_mm.end_data = (unsigned long) _edata;
|
||||
init_mm.brk = (unsigned long) _end;
|
||||
|
||||
if (IS_ENABLED(CONFIG_EXPOLINE_AUTO))
|
||||
nospec_auto_detect();
|
||||
|
||||
parse_early_param();
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
/* Deactivate elfcorehdr= kernel parameter */
|
||||
|
@ -323,6 +323,9 @@ int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv,
|
||||
struct ccw_dev_id dev_id;
|
||||
int rc, i;
|
||||
|
||||
if (num_devices < 1)
|
||||
return -EINVAL;
|
||||
|
||||
gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]),
|
||||
GFP_KERNEL);
|
||||
if (!gdev)
|
||||
@ -375,7 +378,7 @@ int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv,
|
||||
goto error;
|
||||
}
|
||||
/* Check if the devices are bound to the required ccw driver. */
|
||||
if (gdev->count && gdrv && gdrv->ccw_driver &&
|
||||
if (gdrv && gdrv->ccw_driver &&
|
||||
gdev->cdev[0]->drv != gdrv->ccw_driver) {
|
||||
rc = -EINVAL;
|
||||
goto error;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <asm/irq.h>
|
||||
#include <asm/irq_regs.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/reset.h>
|
||||
#include <asm/ipl.h>
|
||||
#include <asm/chpid.h>
|
||||
#include <asm/airq.h>
|
||||
@ -767,262 +766,6 @@ void cio_register_early_subchannels(void)
|
||||
}
|
||||
#endif /* CONFIG_CCW_CONSOLE */
|
||||
|
||||
static int
|
||||
__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
|
||||
{
|
||||
int retry, cc;
|
||||
|
||||
cc = 0;
|
||||
for (retry=0;retry<3;retry++) {
|
||||
schib->pmcw.ena = 0;
|
||||
cc = msch(schid, schib);
|
||||
if (cc)
|
||||
return (cc==3?-ENODEV:-EBUSY);
|
||||
if (stsch(schid, schib) || !css_sch_is_valid(schib))
|
||||
return -ENODEV;
|
||||
if (!schib->pmcw.ena)
|
||||
return 0;
|
||||
}
|
||||
return -EBUSY; /* uhm... */
|
||||
}
|
||||
|
||||
static int
|
||||
__clear_io_subchannel_easy(struct subchannel_id schid)
|
||||
{
|
||||
int retry;
|
||||
|
||||
if (csch(schid))
|
||||
return -ENODEV;
|
||||
for (retry=0;retry<20;retry++) {
|
||||
struct tpi_info ti;
|
||||
|
||||
if (tpi(&ti)) {
|
||||
tsch(ti.schid, this_cpu_ptr(&cio_irb));
|
||||
if (schid_equal(&ti.schid, &schid))
|
||||
return 0;
|
||||
}
|
||||
udelay_simple(100);
|
||||
}
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static void __clear_chsc_subchannel_easy(void)
|
||||
{
|
||||
/* It seems we can only wait for a bit here :/ */
|
||||
udelay_simple(100);
|
||||
}
|
||||
|
||||
static int pgm_check_occured;
|
||||
|
||||
static void cio_reset_pgm_check_handler(void)
|
||||
{
|
||||
pgm_check_occured = 1;
|
||||
}
|
||||
|
||||
static int stsch_reset(struct subchannel_id schid, struct schib *addr)
|
||||
{
|
||||
int rc;
|
||||
|
||||
pgm_check_occured = 0;
|
||||
s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
|
||||
rc = stsch(schid, addr);
|
||||
s390_base_pgm_handler_fn = NULL;
|
||||
|
||||
/* The program check handler could have changed pgm_check_occured. */
|
||||
barrier();
|
||||
|
||||
if (pgm_check_occured)
|
||||
return -EIO;
|
||||
else
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
|
||||
{
|
||||
struct schib schib;
|
||||
|
||||
if (stsch_reset(schid, &schib))
|
||||
return -ENXIO;
|
||||
if (!schib.pmcw.ena)
|
||||
return 0;
|
||||
switch(__disable_subchannel_easy(schid, &schib)) {
|
||||
case 0:
|
||||
case -ENODEV:
|
||||
break;
|
||||
default: /* -EBUSY */
|
||||
switch (schib.pmcw.st) {
|
||||
case SUBCHANNEL_TYPE_IO:
|
||||
if (__clear_io_subchannel_easy(schid))
|
||||
goto out; /* give up... */
|
||||
break;
|
||||
case SUBCHANNEL_TYPE_CHSC:
|
||||
__clear_chsc_subchannel_easy();
|
||||
break;
|
||||
default:
|
||||
/* No default clear strategy */
|
||||
break;
|
||||
}
|
||||
stsch(schid, &schib);
|
||||
__disable_subchannel_easy(schid, &schib);
|
||||
}
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static atomic_t chpid_reset_count;
|
||||
|
||||
static void s390_reset_chpids_mcck_handler(void)
|
||||
{
|
||||
struct crw crw;
|
||||
union mci mci;
|
||||
|
||||
/* Check for pending channel report word. */
|
||||
mci.val = S390_lowcore.mcck_interruption_code;
|
||||
if (!mci.cp)
|
||||
return;
|
||||
/* Process channel report words. */
|
||||
while (stcrw(&crw) == 0) {
|
||||
/* Check for responses to RCHP. */
|
||||
if (crw.slct && crw.rsc == CRW_RSC_CPATH)
|
||||
atomic_dec(&chpid_reset_count);
|
||||
}
|
||||
}
|
||||
|
||||
#define RCHP_TIMEOUT (30 * USEC_PER_SEC)
|
||||
static void css_reset(void)
|
||||
{
|
||||
int i, ret;
|
||||
unsigned long long timeout;
|
||||
struct chp_id chpid;
|
||||
|
||||
/* Reset subchannels. */
|
||||
for_each_subchannel(__shutdown_subchannel_easy, NULL);
|
||||
/* Reset channel paths. */
|
||||
s390_base_mcck_handler_fn = s390_reset_chpids_mcck_handler;
|
||||
/* Enable channel report machine checks. */
|
||||
__ctl_set_bit(14, 28);
|
||||
/* Temporarily reenable machine checks. */
|
||||
local_mcck_enable();
|
||||
chp_id_init(&chpid);
|
||||
for (i = 0; i <= __MAX_CHPID; i++) {
|
||||
chpid.id = i;
|
||||
ret = rchp(chpid);
|
||||
if ((ret == 0) || (ret == 2))
|
||||
/*
|
||||
* rchp either succeeded, or another rchp is already
|
||||
* in progress. In either case, we'll get a crw.
|
||||
*/
|
||||
atomic_inc(&chpid_reset_count);
|
||||
}
|
||||
/* Wait for machine check for all channel paths. */
|
||||
timeout = get_tod_clock_fast() + (RCHP_TIMEOUT << 12);
|
||||
while (atomic_read(&chpid_reset_count) != 0) {
|
||||
if (get_tod_clock_fast() > timeout)
|
||||
break;
|
||||
cpu_relax();
|
||||
}
|
||||
/* Disable machine checks again. */
|
||||
local_mcck_disable();
|
||||
/* Disable channel report machine checks. */
|
||||
__ctl_clear_bit(14, 28);
|
||||
s390_base_mcck_handler_fn = NULL;
|
||||
}
|
||||
|
||||
static struct reset_call css_reset_call = {
|
||||
.fn = css_reset,
|
||||
};
|
||||
|
||||
static int __init init_css_reset_call(void)
|
||||
{
|
||||
atomic_set(&chpid_reset_count, 0);
|
||||
register_reset_call(&css_reset_call);
|
||||
return 0;
|
||||
}
|
||||
|
||||
arch_initcall(init_css_reset_call);
|
||||
|
||||
struct sch_match_id {
|
||||
struct subchannel_id schid;
|
||||
struct ccw_dev_id devid;
|
||||
int rc;
|
||||
};
|
||||
|
||||
static int __reipl_subchannel_match(struct subchannel_id schid, void *data)
|
||||
{
|
||||
struct schib schib;
|
||||
struct sch_match_id *match_id = data;
|
||||
|
||||
if (stsch_reset(schid, &schib))
|
||||
return -ENXIO;
|
||||
if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv &&
|
||||
(schib.pmcw.dev == match_id->devid.devno) &&
|
||||
(schid.ssid == match_id->devid.ssid)) {
|
||||
match_id->schid = schid;
|
||||
match_id->rc = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reipl_find_schid(struct ccw_dev_id *devid,
|
||||
struct subchannel_id *schid)
|
||||
{
|
||||
struct sch_match_id match_id;
|
||||
|
||||
match_id.devid = *devid;
|
||||
match_id.rc = -ENODEV;
|
||||
for_each_subchannel(__reipl_subchannel_match, &match_id);
|
||||
if (match_id.rc == 0)
|
||||
*schid = match_id.schid;
|
||||
return match_id.rc;
|
||||
}
|
||||
|
||||
extern void do_reipl_asm(__u32 schid);
|
||||
|
||||
/* Make sure all subchannels are quiet before we re-ipl an lpar. */
|
||||
void reipl_ccw_dev(struct ccw_dev_id *devid)
|
||||
{
|
||||
struct subchannel_id uninitialized_var(schid);
|
||||
|
||||
s390_reset_system();
|
||||
if (reipl_find_schid(devid, &schid) != 0)
|
||||
panic("IPL Device not found\n");
|
||||
do_reipl_asm(*((__u32*)&schid));
|
||||
}
|
||||
|
||||
int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo)
|
||||
{
|
||||
static struct chsc_sda_area sda_area __initdata;
|
||||
struct subchannel_id schid;
|
||||
struct schib schib;
|
||||
|
||||
schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id;
|
||||
if (!schid.one)
|
||||
return -ENODEV;
|
||||
|
||||
if (schid.ssid) {
|
||||
/*
|
||||
* Firmware should have already enabled MSS but whoever started
|
||||
* the kernel might have initiated a channel subsystem reset.
|
||||
* Ensure that MSS is enabled.
|
||||
*/
|
||||
memset(&sda_area, 0, sizeof(sda_area));
|
||||
if (__chsc_enable_facility(&sda_area, CHSC_SDA_OC_MSS))
|
||||
return -ENODEV;
|
||||
}
|
||||
if (stsch(schid, &schib))
|
||||
return -ENODEV;
|
||||
if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
|
||||
return -ENODEV;
|
||||
if (!schib.pmcw.dnv)
|
||||
return -ENODEV;
|
||||
|
||||
iplinfo->ssid = schid.ssid;
|
||||
iplinfo->devno = schib.pmcw.dev;
|
||||
iplinfo->is_qdio = schib.pmcw.qf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* cio_tm_start_key - perform start function
|
||||
* @sch: subchannel on which to perform the start function
|
||||
|
@ -183,30 +183,6 @@ int chsc(void *chsc_area)
|
||||
}
|
||||
EXPORT_SYMBOL(chsc);
|
||||
|
||||
static inline int __rchp(struct chp_id chpid)
|
||||
{
|
||||
register struct chp_id reg1 asm ("1") = chpid;
|
||||
int ccode;
|
||||
|
||||
asm volatile(
|
||||
" lr 1,%1\n"
|
||||
" rchp\n"
|
||||
" ipm %0\n"
|
||||
" srl %0,28"
|
||||
: "=d" (ccode) : "d" (reg1) : "cc");
|
||||
return ccode;
|
||||
}
|
||||
|
||||
int rchp(struct chp_id chpid)
|
||||
{
|
||||
int ccode;
|
||||
|
||||
ccode = __rchp(chpid);
|
||||
trace_s390_cio_rchp(chpid, ccode);
|
||||
|
||||
return ccode;
|
||||
}
|
||||
|
||||
static inline int __rsch(struct subchannel_id schid)
|
||||
{
|
||||
register struct subchannel_id reg1 asm("1") = schid;
|
||||
|
@ -20,7 +20,6 @@ int ssch(struct subchannel_id schid, union orb *addr);
|
||||
int csch(struct subchannel_id schid);
|
||||
int tpi(struct tpi_info *addr);
|
||||
int chsc(void *chsc_area);
|
||||
int rchp(struct chp_id chpid);
|
||||
int rsch(struct subchannel_id schid);
|
||||
int hsch(struct subchannel_id schid);
|
||||
int xsch(struct subchannel_id schid);
|
||||
|
@ -1207,8 +1207,10 @@ no_cleanup:
|
||||
qdio_shutdown_thinint(irq_ptr);
|
||||
|
||||
/* restore interrupt handler */
|
||||
if ((void *)cdev->handler == (void *)qdio_int_handler)
|
||||
if ((void *)cdev->handler == (void *)qdio_int_handler) {
|
||||
cdev->handler = irq_ptr->orig_handler;
|
||||
cdev->private->intparm = 0;
|
||||
}
|
||||
spin_unlock_irq(get_ccwdev_lock(cdev));
|
||||
|
||||
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
|
||||
|
@ -507,8 +507,10 @@ int qdio_setup_irq(struct qdio_initialize *init_data)
|
||||
irq_ptr->aqueue = *ciw;
|
||||
|
||||
/* set new interrupt handler */
|
||||
spin_lock_irq(get_ccwdev_lock(irq_ptr->cdev));
|
||||
irq_ptr->orig_handler = init_data->cdev->handler;
|
||||
init_data->cdev->handler = qdio_int_handler;
|
||||
spin_unlock_irq(get_ccwdev_lock(irq_ptr->cdev));
|
||||
return 0;
|
||||
out_err:
|
||||
qdio_release_memory(irq_ptr);
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <asm/reset.h>
|
||||
#include <asm/airq.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <asm/isc.h>
|
||||
@ -1197,26 +1196,7 @@ static void ap_config_timeout(struct timer_list *unused)
|
||||
queue_work(system_long_wq, &ap_scan_work);
|
||||
}
|
||||
|
||||
static void ap_reset_all(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < AP_DOMAINS; i++) {
|
||||
if (!ap_test_config_domain(i))
|
||||
continue;
|
||||
for (j = 0; j < AP_DEVICES; j++) {
|
||||
if (!ap_test_config_card_id(j))
|
||||
continue;
|
||||
ap_rapq(AP_MKQID(j, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static struct reset_call ap_reset_call = {
|
||||
.fn = ap_reset_all,
|
||||
};
|
||||
|
||||
int __init ap_debug_init(void)
|
||||
static int __init ap_debug_init(void)
|
||||
{
|
||||
ap_dbf_info = debug_register("ap", 1, 1,
|
||||
DBF_MAX_SPRINTF_ARGS * sizeof(long));
|
||||
@ -1226,17 +1206,12 @@ int __init ap_debug_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ap_debug_exit(void)
|
||||
{
|
||||
debug_unregister(ap_dbf_info);
|
||||
}
|
||||
|
||||
/**
|
||||
* ap_module_init(): The module initialization code.
|
||||
*
|
||||
* Initializes the module.
|
||||
*/
|
||||
int __init ap_module_init(void)
|
||||
static int __init ap_module_init(void)
|
||||
{
|
||||
int max_domain_id;
|
||||
int rc, i;
|
||||
@ -1274,8 +1249,6 @@ int __init ap_module_init(void)
|
||||
ap_airq_flag = (rc == 0);
|
||||
}
|
||||
|
||||
register_reset_call(&ap_reset_call);
|
||||
|
||||
/* Create /sys/bus/ap. */
|
||||
rc = bus_register(&ap_bus_type);
|
||||
if (rc)
|
||||
@ -1331,7 +1304,6 @@ out_bus:
|
||||
bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
|
||||
bus_unregister(&ap_bus_type);
|
||||
out:
|
||||
unregister_reset_call(&ap_reset_call);
|
||||
if (ap_using_interrupts())
|
||||
unregister_adapter_interrupt(&ap_airq);
|
||||
kfree(ap_configuration);
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <linux/types.h>
|
||||
#include <asm/ap.h>
|
||||
|
||||
#define AP_DEVICES 64 /* Number of AP devices. */
|
||||
#define AP_DEVICES 256 /* Number of AP devices. */
|
||||
#define AP_DOMAINS 256 /* Number of AP domains. */
|
||||
#define AP_RESET_TIMEOUT (HZ*0.7) /* Time in ticks for reset timeouts. */
|
||||
#define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */
|
||||
@ -240,7 +240,4 @@ void ap_queue_resume(struct ap_device *ap_dev);
|
||||
struct ap_card *ap_card_create(int id, int queue_depth, int raw_device_type,
|
||||
int comp_device_type, unsigned int functions);
|
||||
|
||||
int ap_module_init(void);
|
||||
void ap_module_exit(void);
|
||||
|
||||
#endif /* _AP_BUS_H_ */
|
||||
|
@ -23,7 +23,4 @@
|
||||
|
||||
extern debug_info_t *ap_dbf_info;
|
||||
|
||||
int ap_debug_init(void);
|
||||
void ap_debug_exit(void);
|
||||
|
||||
#endif /* AP_DEBUG_H */
|
||||
|
@ -889,7 +889,7 @@ int pkey_findcard(const struct pkey_seckey *seckey,
|
||||
u16 *pcardnr, u16 *pdomain, int verify)
|
||||
{
|
||||
struct secaeskeytoken *t = (struct secaeskeytoken *) seckey;
|
||||
struct zcrypt_device_matrix *device_matrix;
|
||||
struct zcrypt_device_status_ext *device_status;
|
||||
u16 card, dom;
|
||||
u64 mkvp[2];
|
||||
int i, rc, oi = -1;
|
||||
@ -899,18 +899,19 @@ int pkey_findcard(const struct pkey_seckey *seckey,
|
||||
return -EINVAL;
|
||||
|
||||
/* fetch status of all crypto cards */
|
||||
device_matrix = kmalloc(sizeof(struct zcrypt_device_matrix),
|
||||
device_status = kmalloc(MAX_ZDEV_ENTRIES_EXT
|
||||
* sizeof(struct zcrypt_device_status_ext),
|
||||
GFP_KERNEL);
|
||||
if (!device_matrix)
|
||||
if (!device_status)
|
||||
return -ENOMEM;
|
||||
zcrypt_device_status_mask(device_matrix);
|
||||
zcrypt_device_status_mask_ext(device_status);
|
||||
|
||||
/* walk through all crypto cards */
|
||||
for (i = 0; i < MAX_ZDEV_ENTRIES; i++) {
|
||||
card = AP_QID_CARD(device_matrix->device[i].qid);
|
||||
dom = AP_QID_QUEUE(device_matrix->device[i].qid);
|
||||
if (device_matrix->device[i].online &&
|
||||
device_matrix->device[i].functions & 0x04) {
|
||||
for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
|
||||
card = AP_QID_CARD(device_status[i].qid);
|
||||
dom = AP_QID_QUEUE(device_status[i].qid);
|
||||
if (device_status[i].online &&
|
||||
device_status[i].functions & 0x04) {
|
||||
/* an enabled CCA Coprocessor card */
|
||||
/* try cached mkvp */
|
||||
if (mkvp_cache_fetch(card, dom, mkvp) == 0 &&
|
||||
@ -930,14 +931,14 @@ int pkey_findcard(const struct pkey_seckey *seckey,
|
||||
mkvp_cache_scrub(card, dom);
|
||||
}
|
||||
}
|
||||
if (i >= MAX_ZDEV_ENTRIES) {
|
||||
if (i >= MAX_ZDEV_ENTRIES_EXT) {
|
||||
/* nothing found, so this time without cache */
|
||||
for (i = 0; i < MAX_ZDEV_ENTRIES; i++) {
|
||||
if (!(device_matrix->device[i].online &&
|
||||
device_matrix->device[i].functions & 0x04))
|
||||
for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
|
||||
if (!(device_status[i].online &&
|
||||
device_status[i].functions & 0x04))
|
||||
continue;
|
||||
card = AP_QID_CARD(device_matrix->device[i].qid);
|
||||
dom = AP_QID_QUEUE(device_matrix->device[i].qid);
|
||||
card = AP_QID_CARD(device_status[i].qid);
|
||||
dom = AP_QID_QUEUE(device_status[i].qid);
|
||||
/* fresh fetch mkvp from adapter */
|
||||
if (fetch_mkvp(card, dom, mkvp) == 0) {
|
||||
mkvp_cache_update(card, dom, mkvp);
|
||||
@ -947,13 +948,13 @@ int pkey_findcard(const struct pkey_seckey *seckey,
|
||||
oi = i;
|
||||
}
|
||||
}
|
||||
if (i >= MAX_ZDEV_ENTRIES && oi >= 0) {
|
||||
if (i >= MAX_ZDEV_ENTRIES_EXT && oi >= 0) {
|
||||
/* old mkvp matched, use this card then */
|
||||
card = AP_QID_CARD(device_matrix->device[oi].qid);
|
||||
dom = AP_QID_QUEUE(device_matrix->device[oi].qid);
|
||||
card = AP_QID_CARD(device_status[oi].qid);
|
||||
dom = AP_QID_QUEUE(device_status[oi].qid);
|
||||
}
|
||||
}
|
||||
if (i < MAX_ZDEV_ENTRIES || oi >= 0) {
|
||||
if (i < MAX_ZDEV_ENTRIES_EXT || oi >= 0) {
|
||||
if (pcardnr)
|
||||
*pcardnr = card;
|
||||
if (pdomain)
|
||||
@ -962,7 +963,7 @@ int pkey_findcard(const struct pkey_seckey *seckey,
|
||||
} else
|
||||
rc = -ENODEV;
|
||||
|
||||
kfree(device_matrix);
|
||||
kfree(device_status);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(pkey_findcard);
|
||||
|
@ -18,8 +18,6 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/atomic.h>
|
||||
@ -607,19 +605,24 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void zcrypt_device_status_mask(struct zcrypt_device_matrix *matrix)
|
||||
static void zcrypt_device_status_mask(struct zcrypt_device_status *devstatus)
|
||||
{
|
||||
struct zcrypt_card *zc;
|
||||
struct zcrypt_queue *zq;
|
||||
struct zcrypt_device_status *stat;
|
||||
int card, queue;
|
||||
|
||||
memset(devstatus, 0, MAX_ZDEV_ENTRIES
|
||||
* sizeof(struct zcrypt_device_status));
|
||||
|
||||
memset(matrix, 0, sizeof(*matrix));
|
||||
spin_lock(&zcrypt_list_lock);
|
||||
for_each_zcrypt_card(zc) {
|
||||
for_each_zcrypt_queue(zq, zc) {
|
||||
stat = matrix->device;
|
||||
stat += AP_QID_CARD(zq->queue->qid) * MAX_ZDEV_DOMAINS;
|
||||
stat += AP_QID_QUEUE(zq->queue->qid);
|
||||
card = AP_QID_CARD(zq->queue->qid);
|
||||
if (card >= MAX_ZDEV_CARDIDS)
|
||||
continue;
|
||||
queue = AP_QID_QUEUE(zq->queue->qid);
|
||||
stat = &devstatus[card * AP_DOMAINS + queue];
|
||||
stat->hwtype = zc->card->ap_dev.device_type;
|
||||
stat->functions = zc->card->functions >> 26;
|
||||
stat->qid = zq->queue->qid;
|
||||
@ -628,40 +631,70 @@ void zcrypt_device_status_mask(struct zcrypt_device_matrix *matrix)
|
||||
}
|
||||
spin_unlock(&zcrypt_list_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(zcrypt_device_status_mask);
|
||||
|
||||
static void zcrypt_status_mask(char status[AP_DEVICES])
|
||||
void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus)
|
||||
{
|
||||
struct zcrypt_card *zc;
|
||||
struct zcrypt_queue *zq;
|
||||
struct zcrypt_device_status_ext *stat;
|
||||
int card, queue;
|
||||
|
||||
memset(devstatus, 0, MAX_ZDEV_ENTRIES_EXT
|
||||
* sizeof(struct zcrypt_device_status_ext));
|
||||
|
||||
memset(status, 0, sizeof(char) * AP_DEVICES);
|
||||
spin_lock(&zcrypt_list_lock);
|
||||
for_each_zcrypt_card(zc) {
|
||||
for_each_zcrypt_queue(zq, zc) {
|
||||
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
|
||||
card = AP_QID_CARD(zq->queue->qid);
|
||||
queue = AP_QID_QUEUE(zq->queue->qid);
|
||||
stat = &devstatus[card * AP_DOMAINS + queue];
|
||||
stat->hwtype = zc->card->ap_dev.device_type;
|
||||
stat->functions = zc->card->functions >> 26;
|
||||
stat->qid = zq->queue->qid;
|
||||
stat->online = zq->online ? 0x01 : 0x00;
|
||||
}
|
||||
}
|
||||
spin_unlock(&zcrypt_list_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(zcrypt_device_status_mask_ext);
|
||||
|
||||
static void zcrypt_status_mask(char status[], size_t max_adapters)
|
||||
{
|
||||
struct zcrypt_card *zc;
|
||||
struct zcrypt_queue *zq;
|
||||
int card;
|
||||
|
||||
memset(status, 0, max_adapters);
|
||||
spin_lock(&zcrypt_list_lock);
|
||||
for_each_zcrypt_card(zc) {
|
||||
for_each_zcrypt_queue(zq, zc) {
|
||||
card = AP_QID_CARD(zq->queue->qid);
|
||||
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index
|
||||
|| card >= max_adapters)
|
||||
continue;
|
||||
status[AP_QID_CARD(zq->queue->qid)] =
|
||||
zc->online ? zc->user_space_type : 0x0d;
|
||||
status[card] = zc->online ? zc->user_space_type : 0x0d;
|
||||
}
|
||||
}
|
||||
spin_unlock(&zcrypt_list_lock);
|
||||
}
|
||||
|
||||
static void zcrypt_qdepth_mask(char qdepth[AP_DEVICES])
|
||||
static void zcrypt_qdepth_mask(char qdepth[], size_t max_adapters)
|
||||
{
|
||||
struct zcrypt_card *zc;
|
||||
struct zcrypt_queue *zq;
|
||||
int card;
|
||||
|
||||
memset(qdepth, 0, sizeof(char) * AP_DEVICES);
|
||||
memset(qdepth, 0, max_adapters);
|
||||
spin_lock(&zcrypt_list_lock);
|
||||
local_bh_disable();
|
||||
for_each_zcrypt_card(zc) {
|
||||
for_each_zcrypt_queue(zq, zc) {
|
||||
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
|
||||
card = AP_QID_CARD(zq->queue->qid);
|
||||
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index
|
||||
|| card >= max_adapters)
|
||||
continue;
|
||||
spin_lock(&zq->queue->lock);
|
||||
qdepth[AP_QID_CARD(zq->queue->qid)] =
|
||||
qdepth[card] =
|
||||
zq->queue->pendingq_count +
|
||||
zq->queue->requestq_count;
|
||||
spin_unlock(&zq->queue->lock);
|
||||
@ -671,21 +704,23 @@ static void zcrypt_qdepth_mask(char qdepth[AP_DEVICES])
|
||||
spin_unlock(&zcrypt_list_lock);
|
||||
}
|
||||
|
||||
static void zcrypt_perdev_reqcnt(int reqcnt[AP_DEVICES])
|
||||
static void zcrypt_perdev_reqcnt(int reqcnt[], size_t max_adapters)
|
||||
{
|
||||
struct zcrypt_card *zc;
|
||||
struct zcrypt_queue *zq;
|
||||
int card;
|
||||
|
||||
memset(reqcnt, 0, sizeof(int) * AP_DEVICES);
|
||||
memset(reqcnt, 0, sizeof(int) * max_adapters);
|
||||
spin_lock(&zcrypt_list_lock);
|
||||
local_bh_disable();
|
||||
for_each_zcrypt_card(zc) {
|
||||
for_each_zcrypt_queue(zq, zc) {
|
||||
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
|
||||
card = AP_QID_CARD(zq->queue->qid);
|
||||
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index
|
||||
|| card >= max_adapters)
|
||||
continue;
|
||||
spin_lock(&zq->queue->lock);
|
||||
reqcnt[AP_QID_CARD(zq->queue->qid)] =
|
||||
zq->queue->total_request_count;
|
||||
reqcnt[card] = zq->queue->total_request_count;
|
||||
spin_unlock(&zq->queue->lock);
|
||||
}
|
||||
}
|
||||
@ -739,60 +774,10 @@ static int zcrypt_requestq_count(void)
|
||||
return requestq_count;
|
||||
}
|
||||
|
||||
static int zcrypt_count_type(int type)
|
||||
{
|
||||
struct zcrypt_card *zc;
|
||||
struct zcrypt_queue *zq;
|
||||
int device_count;
|
||||
|
||||
device_count = 0;
|
||||
spin_lock(&zcrypt_list_lock);
|
||||
for_each_zcrypt_card(zc) {
|
||||
if (zc->card->id != type)
|
||||
continue;
|
||||
for_each_zcrypt_queue(zq, zc) {
|
||||
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
|
||||
continue;
|
||||
device_count++;
|
||||
}
|
||||
}
|
||||
spin_unlock(&zcrypt_list_lock);
|
||||
return device_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* zcrypt_ica_status(): Old, depracted combi status call.
|
||||
*
|
||||
* Old, deprecated combi status call.
|
||||
*/
|
||||
static long zcrypt_ica_status(struct file *filp, unsigned long arg)
|
||||
{
|
||||
struct ica_z90_status *pstat;
|
||||
int ret;
|
||||
|
||||
pstat = kzalloc(sizeof(*pstat), GFP_KERNEL);
|
||||
if (!pstat)
|
||||
return -ENOMEM;
|
||||
pstat->totalcount = zcrypt_device_count;
|
||||
pstat->leedslitecount = zcrypt_count_type(ZCRYPT_PCICA);
|
||||
pstat->leeds2count = zcrypt_count_type(ZCRYPT_PCICC);
|
||||
pstat->requestqWaitCount = zcrypt_requestq_count();
|
||||
pstat->pendingqWaitCount = zcrypt_pendingq_count();
|
||||
pstat->totalOpenCount = atomic_read(&zcrypt_open_count);
|
||||
pstat->cryptoDomain = ap_domain_index;
|
||||
zcrypt_status_mask(pstat->status);
|
||||
zcrypt_qdepth_mask(pstat->qdepth);
|
||||
ret = 0;
|
||||
if (copy_to_user((void __user *) arg, pstat, sizeof(*pstat)))
|
||||
ret = -EFAULT;
|
||||
kfree(pstat);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case ICARSAMODEXPO: {
|
||||
@ -871,48 +856,48 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
|
||||
return -EFAULT;
|
||||
return rc;
|
||||
}
|
||||
case ZDEVICESTATUS: {
|
||||
struct zcrypt_device_matrix *device_status;
|
||||
case ZCRYPT_DEVICE_STATUS: {
|
||||
struct zcrypt_device_status_ext *device_status;
|
||||
size_t total_size = MAX_ZDEV_ENTRIES_EXT
|
||||
* sizeof(struct zcrypt_device_status_ext);
|
||||
|
||||
device_status = kzalloc(sizeof(struct zcrypt_device_matrix),
|
||||
GFP_KERNEL);
|
||||
device_status = kzalloc(total_size, GFP_KERNEL);
|
||||
if (!device_status)
|
||||
return -ENOMEM;
|
||||
|
||||
zcrypt_device_status_mask(device_status);
|
||||
|
||||
zcrypt_device_status_mask_ext(device_status);
|
||||
if (copy_to_user((char __user *) arg, device_status,
|
||||
sizeof(struct zcrypt_device_matrix))) {
|
||||
kfree(device_status);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
total_size))
|
||||
rc = -EFAULT;
|
||||
kfree(device_status);
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
case Z90STAT_STATUS_MASK: {
|
||||
case ZCRYPT_STATUS_MASK: {
|
||||
char status[AP_DEVICES];
|
||||
zcrypt_status_mask(status);
|
||||
if (copy_to_user((char __user *) arg, status,
|
||||
sizeof(char) * AP_DEVICES))
|
||||
|
||||
zcrypt_status_mask(status, AP_DEVICES);
|
||||
if (copy_to_user((char __user *) arg, status, sizeof(status)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
case Z90STAT_QDEPTH_MASK: {
|
||||
case ZCRYPT_QDEPTH_MASK: {
|
||||
char qdepth[AP_DEVICES];
|
||||
zcrypt_qdepth_mask(qdepth);
|
||||
if (copy_to_user((char __user *) arg, qdepth,
|
||||
sizeof(char) * AP_DEVICES))
|
||||
|
||||
zcrypt_qdepth_mask(qdepth, AP_DEVICES);
|
||||
if (copy_to_user((char __user *) arg, qdepth, sizeof(qdepth)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
case Z90STAT_PERDEV_REQCNT: {
|
||||
int reqcnt[AP_DEVICES];
|
||||
zcrypt_perdev_reqcnt(reqcnt);
|
||||
if (copy_to_user((int __user *) arg, reqcnt,
|
||||
sizeof(int) * AP_DEVICES))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
case ZCRYPT_PERDEV_REQCNT: {
|
||||
int *reqcnt;
|
||||
|
||||
reqcnt = kcalloc(AP_DEVICES, sizeof(int), GFP_KERNEL);
|
||||
if (!reqcnt)
|
||||
return -ENOMEM;
|
||||
zcrypt_perdev_reqcnt(reqcnt, AP_DEVICES);
|
||||
if (copy_to_user((int __user *) arg, reqcnt, sizeof(reqcnt)))
|
||||
rc = -EFAULT;
|
||||
kfree(reqcnt);
|
||||
return rc;
|
||||
}
|
||||
case Z90STAT_REQUESTQ_COUNT:
|
||||
return put_user(zcrypt_requestq_count(), (int __user *) arg);
|
||||
@ -924,38 +909,54 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
|
||||
case Z90STAT_DOMAIN_INDEX:
|
||||
return put_user(ap_domain_index, (int __user *) arg);
|
||||
/*
|
||||
* Deprecated ioctls. Don't add another device count ioctl,
|
||||
* you can count them yourself in the user space with the
|
||||
* output of the Z90STAT_STATUS_MASK ioctl.
|
||||
* Deprecated ioctls
|
||||
*/
|
||||
case ICAZ90STATUS:
|
||||
return zcrypt_ica_status(filp, arg);
|
||||
case Z90STAT_TOTALCOUNT:
|
||||
return put_user(zcrypt_device_count, (int __user *) arg);
|
||||
case Z90STAT_PCICACOUNT:
|
||||
return put_user(zcrypt_count_type(ZCRYPT_PCICA),
|
||||
(int __user *) arg);
|
||||
case Z90STAT_PCICCCOUNT:
|
||||
return put_user(zcrypt_count_type(ZCRYPT_PCICC),
|
||||
(int __user *) arg);
|
||||
case Z90STAT_PCIXCCMCL2COUNT:
|
||||
return put_user(zcrypt_count_type(ZCRYPT_PCIXCC_MCL2),
|
||||
(int __user *) arg);
|
||||
case Z90STAT_PCIXCCMCL3COUNT:
|
||||
return put_user(zcrypt_count_type(ZCRYPT_PCIXCC_MCL3),
|
||||
(int __user *) arg);
|
||||
case Z90STAT_PCIXCCCOUNT:
|
||||
return put_user(zcrypt_count_type(ZCRYPT_PCIXCC_MCL2) +
|
||||
zcrypt_count_type(ZCRYPT_PCIXCC_MCL3),
|
||||
(int __user *) arg);
|
||||
case Z90STAT_CEX2CCOUNT:
|
||||
return put_user(zcrypt_count_type(ZCRYPT_CEX2C),
|
||||
(int __user *) arg);
|
||||
case Z90STAT_CEX2ACOUNT:
|
||||
return put_user(zcrypt_count_type(ZCRYPT_CEX2A),
|
||||
(int __user *) arg);
|
||||
case ZDEVICESTATUS: {
|
||||
/* the old ioctl supports only 64 adapters */
|
||||
struct zcrypt_device_status *device_status;
|
||||
size_t total_size = MAX_ZDEV_ENTRIES
|
||||
* sizeof(struct zcrypt_device_status);
|
||||
|
||||
device_status = kzalloc(total_size, GFP_KERNEL);
|
||||
if (!device_status)
|
||||
return -ENOMEM;
|
||||
zcrypt_device_status_mask(device_status);
|
||||
if (copy_to_user((char __user *) arg, device_status,
|
||||
total_size))
|
||||
rc = -EFAULT;
|
||||
kfree(device_status);
|
||||
return rc;
|
||||
}
|
||||
case Z90STAT_STATUS_MASK: {
|
||||
/* the old ioctl supports only 64 adapters */
|
||||
char status[MAX_ZDEV_CARDIDS];
|
||||
|
||||
zcrypt_status_mask(status, MAX_ZDEV_CARDIDS);
|
||||
if (copy_to_user((char __user *) arg, status, sizeof(status)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
case Z90STAT_QDEPTH_MASK: {
|
||||
/* the old ioctl supports only 64 adapters */
|
||||
char qdepth[MAX_ZDEV_CARDIDS];
|
||||
|
||||
zcrypt_qdepth_mask(qdepth, MAX_ZDEV_CARDIDS);
|
||||
if (copy_to_user((char __user *) arg, qdepth, sizeof(qdepth)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
case Z90STAT_PERDEV_REQCNT: {
|
||||
/* the old ioctl supports only 64 adapters */
|
||||
int reqcnt[MAX_ZDEV_CARDIDS];
|
||||
|
||||
zcrypt_perdev_reqcnt(reqcnt, MAX_ZDEV_CARDIDS);
|
||||
if (copy_to_user((int __user *) arg, reqcnt, sizeof(reqcnt)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
/* unknown ioctl number */
|
||||
default:
|
||||
/* unknown ioctl number */
|
||||
ZCRYPT_DBF(DBF_DEBUG, "unknown ioctl 0x%08x\n", cmd);
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
}
|
||||
@ -1152,201 +1153,6 @@ static struct miscdevice zcrypt_misc_device = {
|
||||
.fops = &zcrypt_fops,
|
||||
};
|
||||
|
||||
/*
|
||||
* Deprecated /proc entry support.
|
||||
*/
|
||||
static struct proc_dir_entry *zcrypt_entry;
|
||||
|
||||
static void sprintcl(struct seq_file *m, unsigned char *addr, unsigned int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
seq_printf(m, "%01x", (unsigned int) addr[i]);
|
||||
seq_putc(m, ' ');
|
||||
}
|
||||
|
||||
static void sprintrw(struct seq_file *m, unsigned char *addr, unsigned int len)
|
||||
{
|
||||
int inl, c, cx;
|
||||
|
||||
seq_printf(m, " ");
|
||||
inl = 0;
|
||||
for (c = 0; c < (len / 16); c++) {
|
||||
sprintcl(m, addr+inl, 16);
|
||||
inl += 16;
|
||||
}
|
||||
cx = len%16;
|
||||
if (cx) {
|
||||
sprintcl(m, addr+inl, cx);
|
||||
inl += cx;
|
||||
}
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
|
||||
static void sprinthx(unsigned char *title, struct seq_file *m,
|
||||
unsigned char *addr, unsigned int len)
|
||||
{
|
||||
int inl, r, rx;
|
||||
|
||||
seq_printf(m, "\n%s\n", title);
|
||||
inl = 0;
|
||||
for (r = 0; r < (len / 64); r++) {
|
||||
sprintrw(m, addr+inl, 64);
|
||||
inl += 64;
|
||||
}
|
||||
rx = len % 64;
|
||||
if (rx) {
|
||||
sprintrw(m, addr+inl, rx);
|
||||
inl += rx;
|
||||
}
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
|
||||
static void sprinthx4(unsigned char *title, struct seq_file *m,
|
||||
unsigned int *array, unsigned int len)
|
||||
{
|
||||
seq_printf(m, "\n%s\n", title);
|
||||
seq_hex_dump(m, " ", DUMP_PREFIX_NONE, 32, 4, array, len, false);
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
|
||||
static int zcrypt_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
char workarea[sizeof(int) * AP_DEVICES];
|
||||
|
||||
seq_printf(m, "\nzcrypt version: %d.%d.%d\n",
|
||||
ZCRYPT_VERSION, ZCRYPT_RELEASE, ZCRYPT_VARIANT);
|
||||
seq_printf(m, "Cryptographic domain: %d\n", ap_domain_index);
|
||||
seq_printf(m, "Total device count: %d\n", zcrypt_device_count);
|
||||
seq_printf(m, "PCICA count: %d\n", zcrypt_count_type(ZCRYPT_PCICA));
|
||||
seq_printf(m, "PCICC count: %d\n", zcrypt_count_type(ZCRYPT_PCICC));
|
||||
seq_printf(m, "PCIXCC MCL2 count: %d\n",
|
||||
zcrypt_count_type(ZCRYPT_PCIXCC_MCL2));
|
||||
seq_printf(m, "PCIXCC MCL3 count: %d\n",
|
||||
zcrypt_count_type(ZCRYPT_PCIXCC_MCL3));
|
||||
seq_printf(m, "CEX2C count: %d\n", zcrypt_count_type(ZCRYPT_CEX2C));
|
||||
seq_printf(m, "CEX2A count: %d\n", zcrypt_count_type(ZCRYPT_CEX2A));
|
||||
seq_printf(m, "CEX3C count: %d\n", zcrypt_count_type(ZCRYPT_CEX3C));
|
||||
seq_printf(m, "CEX3A count: %d\n", zcrypt_count_type(ZCRYPT_CEX3A));
|
||||
seq_printf(m, "requestq count: %d\n", zcrypt_requestq_count());
|
||||
seq_printf(m, "pendingq count: %d\n", zcrypt_pendingq_count());
|
||||
seq_printf(m, "Total open handles: %d\n\n",
|
||||
atomic_read(&zcrypt_open_count));
|
||||
zcrypt_status_mask(workarea);
|
||||
sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) "
|
||||
"4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A 7=CEX3C 8=CEX3A",
|
||||
m, workarea, AP_DEVICES);
|
||||
zcrypt_qdepth_mask(workarea);
|
||||
sprinthx("Waiting work element counts", m, workarea, AP_DEVICES);
|
||||
zcrypt_perdev_reqcnt((int *) workarea);
|
||||
sprinthx4("Per-device successfully completed request counts",
|
||||
m, (unsigned int *) workarea, AP_DEVICES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zcrypt_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, zcrypt_proc_show, NULL);
|
||||
}
|
||||
|
||||
static void zcrypt_disable_card(int index)
|
||||
{
|
||||
struct zcrypt_card *zc;
|
||||
struct zcrypt_queue *zq;
|
||||
|
||||
spin_lock(&zcrypt_list_lock);
|
||||
for_each_zcrypt_card(zc) {
|
||||
for_each_zcrypt_queue(zq, zc) {
|
||||
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
|
||||
continue;
|
||||
zq->online = 0;
|
||||
ap_flush_queue(zq->queue);
|
||||
}
|
||||
}
|
||||
spin_unlock(&zcrypt_list_lock);
|
||||
}
|
||||
|
||||
static void zcrypt_enable_card(int index)
|
||||
{
|
||||
struct zcrypt_card *zc;
|
||||
struct zcrypt_queue *zq;
|
||||
|
||||
spin_lock(&zcrypt_list_lock);
|
||||
for_each_zcrypt_card(zc) {
|
||||
for_each_zcrypt_queue(zq, zc) {
|
||||
if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
|
||||
continue;
|
||||
zq->online = 1;
|
||||
ap_flush_queue(zq->queue);
|
||||
}
|
||||
}
|
||||
spin_unlock(&zcrypt_list_lock);
|
||||
}
|
||||
|
||||
static ssize_t zcrypt_proc_write(struct file *file, const char __user *buffer,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
unsigned char *lbuf, *ptr;
|
||||
size_t local_count;
|
||||
int j;
|
||||
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
|
||||
#define LBUFSIZE 1200UL
|
||||
lbuf = kmalloc(LBUFSIZE, GFP_KERNEL);
|
||||
if (!lbuf)
|
||||
return 0;
|
||||
|
||||
local_count = min(LBUFSIZE - 1, count);
|
||||
if (copy_from_user(lbuf, buffer, local_count) != 0) {
|
||||
kfree(lbuf);
|
||||
return -EFAULT;
|
||||
}
|
||||
lbuf[local_count] = '\0';
|
||||
|
||||
ptr = strstr(lbuf, "Online devices");
|
||||
if (!ptr)
|
||||
goto out;
|
||||
ptr = strstr(ptr, "\n");
|
||||
if (!ptr)
|
||||
goto out;
|
||||
ptr++;
|
||||
|
||||
if (strstr(ptr, "Waiting work element counts") == NULL)
|
||||
goto out;
|
||||
|
||||
for (j = 0; j < 64 && *ptr; ptr++) {
|
||||
/*
|
||||
* '0' for no device, '1' for PCICA, '2' for PCICC,
|
||||
* '3' for PCIXCC_MCL2, '4' for PCIXCC_MCL3,
|
||||
* '5' for CEX2C and '6' for CEX2A'
|
||||
* '7' for CEX3C and '8' for CEX3A
|
||||
*/
|
||||
if (*ptr >= '0' && *ptr <= '8')
|
||||
j++;
|
||||
else if (*ptr == 'd' || *ptr == 'D')
|
||||
zcrypt_disable_card(j++);
|
||||
else if (*ptr == 'e' || *ptr == 'E')
|
||||
zcrypt_enable_card(j++);
|
||||
else if (*ptr != ' ' && *ptr != '\t')
|
||||
break;
|
||||
}
|
||||
out:
|
||||
kfree(lbuf);
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations zcrypt_proc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = zcrypt_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
.write = zcrypt_proc_write,
|
||||
};
|
||||
|
||||
static int zcrypt_rng_device_count;
|
||||
static u32 *zcrypt_rng_buffer;
|
||||
static int zcrypt_rng_buffer_index;
|
||||
@ -1448,27 +1254,15 @@ int __init zcrypt_api_init(void)
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
atomic_set(&zcrypt_rescan_req, 0);
|
||||
|
||||
/* Register the request sprayer. */
|
||||
rc = misc_register(&zcrypt_misc_device);
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
|
||||
/* Set up the proc file system */
|
||||
zcrypt_entry = proc_create("driver/z90crypt", 0644, NULL,
|
||||
&zcrypt_proc_fops);
|
||||
if (!zcrypt_entry) {
|
||||
rc = -ENOMEM;
|
||||
goto out_misc;
|
||||
}
|
||||
|
||||
zcrypt_msgtype6_init();
|
||||
zcrypt_msgtype50_init();
|
||||
return 0;
|
||||
|
||||
out_misc:
|
||||
misc_deregister(&zcrypt_misc_device);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
@ -1480,7 +1274,6 @@ out:
|
||||
*/
|
||||
void __exit zcrypt_api_exit(void)
|
||||
{
|
||||
remove_proc_entry("driver/z90crypt", NULL);
|
||||
misc_deregister(&zcrypt_misc_device);
|
||||
zcrypt_msgtype6_exit();
|
||||
zcrypt_msgtype50_exit();
|
||||
|
@ -21,30 +21,6 @@
|
||||
#include <asm/zcrypt.h>
|
||||
#include "ap_bus.h"
|
||||
|
||||
/* deprecated status calls */
|
||||
#define ICAZ90STATUS _IOR(ZCRYPT_IOCTL_MAGIC, 0x10, struct ica_z90_status)
|
||||
#define Z90STAT_PCIXCCCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x43, int)
|
||||
|
||||
/**
|
||||
* This structure is deprecated and the corresponding ioctl() has been
|
||||
* replaced with individual ioctl()s for each piece of data!
|
||||
*/
|
||||
struct ica_z90_status {
|
||||
int totalcount;
|
||||
int leedslitecount; // PCICA
|
||||
int leeds2count; // PCICC
|
||||
// int PCIXCCCount; is not in struct for backward compatibility
|
||||
int requestqWaitCount;
|
||||
int pendingqWaitCount;
|
||||
int totalOpenCount;
|
||||
int cryptoDomain;
|
||||
// status: 0=not there, 1=PCICA, 2=PCICC, 3=PCIXCC_MCL2, 4=PCIXCC_MCL3,
|
||||
// 5=CEX2C
|
||||
unsigned char status[64];
|
||||
// qdepth: # work elements waiting for each device
|
||||
unsigned char qdepth[64];
|
||||
};
|
||||
|
||||
/**
|
||||
* device type for an actual device is either PCICA, PCICC, PCIXCC_MCL2,
|
||||
* PCIXCC_MCL3, CEX2C, or CEX2A
|
||||
@ -179,6 +155,6 @@ struct zcrypt_ops *zcrypt_msgtype(unsigned char *, int);
|
||||
int zcrypt_api_init(void);
|
||||
void zcrypt_api_exit(void);
|
||||
long zcrypt_send_cprb(struct ica_xcRB *xcRB);
|
||||
void zcrypt_device_status_mask(struct zcrypt_device_matrix *devstatus);
|
||||
void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus);
|
||||
|
||||
#endif /* _ZCRYPT_API_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user