cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ioasm.c (5171B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Channel subsystem I/O instructions.
      4 */
      5
      6#include <linux/export.h>
      7
      8#include <asm/asm-extable.h>
      9#include <asm/chpid.h>
     10#include <asm/schid.h>
     11#include <asm/crw.h>
     12
     13#include "ioasm.h"
     14#include "orb.h"
     15#include "cio.h"
     16#include "cio_inject.h"
     17
     18static inline int __stsch(struct subchannel_id schid, struct schib *addr)
     19{
     20	unsigned long r1 = *(unsigned int *)&schid;
     21	int ccode = -EIO;
     22
     23	asm volatile(
     24		"	lgr	1,%[r1]\n"
     25		"	stsch	%[addr]\n"
     26		"0:	ipm	%[cc]\n"
     27		"	srl	%[cc],28\n"
     28		"1:\n"
     29		EX_TABLE(0b, 1b)
     30		: [cc] "+&d" (ccode), [addr] "=Q" (*addr)
     31		: [r1] "d" (r1)
     32		: "cc", "1");
     33	return ccode;
     34}
     35
     36int stsch(struct subchannel_id schid, struct schib *addr)
     37{
     38	int ccode;
     39
     40	ccode = __stsch(schid, addr);
     41	trace_s390_cio_stsch(schid, addr, ccode);
     42
     43	return ccode;
     44}
     45EXPORT_SYMBOL(stsch);
     46
     47static inline int __msch(struct subchannel_id schid, struct schib *addr)
     48{
     49	unsigned long r1 = *(unsigned int *)&schid;
     50	int ccode = -EIO;
     51
     52	asm volatile(
     53		"	lgr	1,%[r1]\n"
     54		"	msch	%[addr]\n"
     55		"0:	ipm	%[cc]\n"
     56		"	srl	%[cc],28\n"
     57		"1:\n"
     58		EX_TABLE(0b, 1b)
     59		: [cc] "+&d" (ccode)
     60		: [r1] "d" (r1), [addr] "Q" (*addr)
     61		: "cc", "1");
     62	return ccode;
     63}
     64
     65int msch(struct subchannel_id schid, struct schib *addr)
     66{
     67	int ccode;
     68
     69	ccode = __msch(schid, addr);
     70	trace_s390_cio_msch(schid, addr, ccode);
     71
     72	return ccode;
     73}
     74
     75static inline int __tsch(struct subchannel_id schid, struct irb *addr)
     76{
     77	unsigned long r1 = *(unsigned int *)&schid;
     78	int ccode;
     79
     80	asm volatile(
     81		"	lgr	1,%[r1]\n"
     82		"	tsch	%[addr]\n"
     83		"	ipm	%[cc]\n"
     84		"	srl	%[cc],28"
     85		: [cc] "=&d" (ccode), [addr] "=Q" (*addr)
     86		: [r1] "d" (r1)
     87		: "cc", "1");
     88	return ccode;
     89}
     90
     91int tsch(struct subchannel_id schid, struct irb *addr)
     92{
     93	int ccode;
     94
     95	ccode = __tsch(schid, addr);
     96	trace_s390_cio_tsch(schid, addr, ccode);
     97
     98	return ccode;
     99}
    100
    101static inline int __ssch(struct subchannel_id schid, union orb *addr)
    102{
    103	unsigned long r1 = *(unsigned int *)&schid;
    104	int ccode = -EIO;
    105
    106	asm volatile(
    107		"	lgr	1,%[r1]\n"
    108		"	ssch	%[addr]\n"
    109		"0:	ipm	%[cc]\n"
    110		"	srl	%[cc],28\n"
    111		"1:\n"
    112		EX_TABLE(0b, 1b)
    113		: [cc] "+&d" (ccode)
    114		: [r1] "d" (r1), [addr] "Q" (*addr)
    115		: "cc", "memory", "1");
    116	return ccode;
    117}
    118
    119int ssch(struct subchannel_id schid, union orb *addr)
    120{
    121	int ccode;
    122
    123	ccode = __ssch(schid, addr);
    124	trace_s390_cio_ssch(schid, addr, ccode);
    125
    126	return ccode;
    127}
    128EXPORT_SYMBOL(ssch);
    129
    130static inline int __csch(struct subchannel_id schid)
    131{
    132	unsigned long r1 = *(unsigned int *)&schid;
    133	int ccode;
    134
    135	asm volatile(
    136		"	lgr	1,%[r1]\n"
    137		"	csch\n"
    138		"	ipm	%[cc]\n"
    139		"	srl	%[cc],28\n"
    140		: [cc] "=&d" (ccode)
    141		: [r1] "d" (r1)
    142		: "cc", "1");
    143	return ccode;
    144}
    145
    146int csch(struct subchannel_id schid)
    147{
    148	int ccode;
    149
    150	ccode = __csch(schid);
    151	trace_s390_cio_csch(schid, ccode);
    152
    153	return ccode;
    154}
    155EXPORT_SYMBOL(csch);
    156
    157int tpi(struct tpi_info *addr)
    158{
    159	int ccode;
    160
    161	asm volatile(
    162		"	tpi	%[addr]\n"
    163		"	ipm	%[cc]\n"
    164		"	srl	%[cc],28"
    165		: [cc] "=&d" (ccode), [addr] "=Q" (*addr)
    166		:
    167		: "cc");
    168	trace_s390_cio_tpi(addr, ccode);
    169
    170	return ccode;
    171}
    172
    173int chsc(void *chsc_area)
    174{
    175	typedef struct { char _[4096]; } addr_type;
    176	int cc = -EIO;
    177
    178	asm volatile(
    179		"	.insn	rre,0xb25f0000,%[chsc_area],0\n"
    180		"0:	ipm	%[cc]\n"
    181		"	srl	%[cc],28\n"
    182		"1:\n"
    183		EX_TABLE(0b, 1b)
    184		: [cc] "+&d" (cc), "+m" (*(addr_type *)chsc_area)
    185		: [chsc_area] "d" (chsc_area)
    186		: "cc");
    187	trace_s390_cio_chsc(chsc_area, cc);
    188
    189	return cc;
    190}
    191EXPORT_SYMBOL(chsc);
    192
    193static inline int __rsch(struct subchannel_id schid)
    194{
    195	unsigned long r1 = *(unsigned int *)&schid;
    196	int ccode;
    197
    198	asm volatile(
    199		"	lgr	1,%[r1]\n"
    200		"	rsch\n"
    201		"	ipm	%[cc]\n"
    202		"	srl	%[cc],28\n"
    203		: [cc] "=&d" (ccode)
    204		: [r1] "d" (r1)
    205		: "cc", "memory", "1");
    206	return ccode;
    207}
    208
    209int rsch(struct subchannel_id schid)
    210{
    211	int ccode;
    212
    213	ccode = __rsch(schid);
    214	trace_s390_cio_rsch(schid, ccode);
    215
    216	return ccode;
    217}
    218
    219static inline int __hsch(struct subchannel_id schid)
    220{
    221	unsigned long r1 = *(unsigned int *)&schid;
    222	int ccode;
    223
    224	asm volatile(
    225		"	lgr	1,%[r1]\n"
    226		"	hsch\n"
    227		"	ipm	%[cc]\n"
    228		"	srl	%[cc],28\n"
    229		: [cc] "=&d" (ccode)
    230		: [r1] "d" (r1)
    231		: "cc", "1");
    232	return ccode;
    233}
    234
    235int hsch(struct subchannel_id schid)
    236{
    237	int ccode;
    238
    239	ccode = __hsch(schid);
    240	trace_s390_cio_hsch(schid, ccode);
    241
    242	return ccode;
    243}
    244EXPORT_SYMBOL(hsch);
    245
    246static inline int __xsch(struct subchannel_id schid)
    247{
    248	unsigned long r1 = *(unsigned int *)&schid;
    249	int ccode;
    250
    251	asm volatile(
    252		"	lgr	1,%[r1]\n"
    253		"	xsch\n"
    254		"	ipm	%[cc]\n"
    255		"	srl	%[cc],28\n"
    256		: [cc] "=&d" (ccode)
    257		: [r1] "d" (r1)
    258		: "cc", "1");
    259	return ccode;
    260}
    261
    262int xsch(struct subchannel_id schid)
    263{
    264	int ccode;
    265
    266	ccode = __xsch(schid);
    267	trace_s390_cio_xsch(schid, ccode);
    268
    269	return ccode;
    270}
    271
    272static inline int __stcrw(struct crw *crw)
    273{
    274	int ccode;
    275
    276	asm volatile(
    277		"	stcrw	%[crw]\n"
    278		"	ipm	%[cc]\n"
    279		"	srl	%[cc],28\n"
    280		: [cc] "=&d" (ccode), [crw] "=Q" (*crw)
    281		:
    282		: "cc");
    283	return ccode;
    284}
    285
    286static inline int _stcrw(struct crw *crw)
    287{
    288#ifdef CONFIG_CIO_INJECT
    289	if (static_branch_unlikely(&cio_inject_enabled)) {
    290		if (stcrw_get_injected(crw) == 0)
    291			return 0;
    292	}
    293#endif
    294
    295	return __stcrw(crw);
    296}
    297
    298int stcrw(struct crw *crw)
    299{
    300	int ccode;
    301
    302	ccode = _stcrw(crw);
    303	trace_s390_cio_stcrw(crw, ccode);
    304
    305	return ccode;
    306}