diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-17 17:04:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-17 17:04:43 -0400 |
commit | d590284419b1d7cc2dc646e9bdde4da19061cf0f (patch) | |
tree | 007a94945a82e3010c1847daeeb8f17d8e988929 | |
parent | 1e24aaabdee9e07f19b09bd305ffc069b0b07371 (diff) | |
parent | 2735913c1079b7dd7ec1d746c13a84ec1b5ea276 (diff) |
Merge tag 's390-5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Vasily Gorbik:
- Add support for IBM z15 machines.
- Add SHA3 and CCA AES cipher key support in zcrypt and pkey
refactoring.
- Move to arch_stack_walk infrastructure for the stack unwinder.
- Various kasan fixes and improvements.
- Various command line parsing fixes.
- Improve decompressor phase debuggability.
- Lift no bss usage restriction for the early code.
- Use refcount_t for reference counters for couple of places in mm
code.
- Logging improvements and return code fix in vfio-ccw code.
- Couple of zpci fixes and minor refactoring.
- Remove some outdated documentation.
- Fix secure boot detection.
- Other various minor code clean ups.
* tag 's390-5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (48 commits)
s390: remove pointless drivers-y in drivers/s390/Makefile
s390/cpum_sf: Fix line length and format string
s390/pci: fix MSI message data
s390: add support for IBM z15 machines
s390/crypto: Support for SHA3 via CPACF (MSA6)
s390/startup: add pgm check info printing
s390/crypto: xts-aes-s390 fix extra run-time crypto self tests finding
vfio-ccw: fix error return code in vfio_ccw_sch_init()
s390: vfio-ap: fix warning reset not completed
s390/base: remove unused s390_base_mcck_handler
s390/sclp: Fix bit checked for has_sipl
s390/zcrypt: fix wrong handling of cca cipher keygenflags
s390/kasan: add kdump support
s390/setup: avoid using strncmp with hardcoded length
s390/sclp: avoid using strncmp with hardcoded length
s390/module: avoid using strncmp with hardcoded length
s390/pci: avoid using strncmp with hardcoded length
s390/kaslr: reserve memory for kasan usage
s390/mem_detect: provide single get_mem_detect_end
s390/cmma: reuse kstrtobool for option value parsing
...
73 files changed, 4047 insertions, 4123 deletions
diff --git a/Documentation/s390/dasd.rst b/Documentation/s390/dasd.rst deleted file mode 100644 index 9e22247285c8..000000000000 --- a/Documentation/s390/dasd.rst +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | ================== | ||
2 | DASD device driver | ||
3 | ================== | ||
4 | |||
5 | S/390's disk devices (DASDs) are managed by Linux via the DASD device | ||
6 | driver. It is valid for all types of DASDs and represents them to | ||
7 | Linux as block devices, namely "dd". Currently the DASD driver uses a | ||
8 | single major number (254) and 4 minor numbers per volume (1 for the | ||
9 | physical volume and 3 for partitions). With respect to partitions see | ||
10 | below. Thus you may have up to 64 DASD devices in your system. | ||
11 | |||
12 | The kernel parameter 'dasd=from-to,...' may be issued arbitrary times | ||
13 | in the kernel's parameter line or not at all. The 'from' and 'to' | ||
14 | parameters are to be given in hexadecimal notation without a leading | ||
15 | 0x. | ||
16 | If you supply kernel parameters the different instances are processed | ||
17 | in order of appearance and a minor number is reserved for any device | ||
18 | covered by the supplied range up to 64 volumes. Additional DASDs are | ||
19 | ignored. If you do not supply the 'dasd=' kernel parameter at all, the | ||
20 | DASD driver registers all supported DASDs of your system to a minor | ||
21 | number in ascending order of the subchannel number. | ||
22 | |||
23 | The driver currently supports ECKD-devices and there are stubs for | ||
24 | support of the FBA and CKD architectures. For the FBA architecture | ||
25 | only some smart data structures are missing to make the support | ||
26 | complete. | ||
27 | We performed our testing on 3380 and 3390 type disks of different | ||
28 | sizes, under VM and on the bare hardware (LPAR), using internal disks | ||
29 | of the multiprise as well as a RAMAC virtual array. Disks exported by | ||
30 | an Enterprise Storage Server (Seascape) should work fine as well. | ||
31 | |||
32 | We currently implement one partition per volume, which is the whole | ||
33 | volume, skipping the first blocks up to the volume label. These are | ||
34 | reserved for IPL records and IBM's volume label to assure | ||
35 | accessibility of the DASD from other OSs. In a later stage we will | ||
36 | provide support of partitions, maybe VTOC oriented or using a kind of | ||
37 | partition table in the label record. | ||
38 | |||
39 | Usage | ||
40 | ===== | ||
41 | |||
42 | -Low-level format (?CKD only) | ||
43 | For using an ECKD-DASD as a Linux harddisk you have to low-level | ||
44 | format the tracks by issuing the BLKDASDFORMAT-ioctl on that | ||
45 | device. This will erase any data on that volume including IBM volume | ||
46 | labels, VTOCs etc. The ioctl may take a `struct format_data *` or | ||
47 | 'NULL' as an argument:: | ||
48 | |||
49 | typedef struct { | ||
50 | int start_unit; | ||
51 | int stop_unit; | ||
52 | int blksize; | ||
53 | } format_data_t; | ||
54 | |||
55 | When a NULL argument is passed to the BLKDASDFORMAT ioctl the whole | ||
56 | disk is formatted to a blocksize of 1024 bytes. Otherwise start_unit | ||
57 | and stop_unit are the first and last track to be formatted. If | ||
58 | stop_unit is -1 it implies that the DASD is formatted from start_unit | ||
59 | up to the last track. blksize can be any power of two between 512 and | ||
60 | 4096. We recommend no blksize lower than 1024 because the ext2fs uses | ||
61 | 1kB blocks anyway and you gain approx. 50% of capacity increasing your | ||
62 | blksize from 512 byte to 1kB. | ||
63 | |||
64 | Make a filesystem | ||
65 | ================= | ||
66 | |||
67 | Then you can mk??fs the filesystem of your choice on that volume or | ||
68 | partition. For reasons of sanity you should build your filesystem on | ||
69 | the partition /dev/dd?1 instead of the whole volume. You only lose 3kB | ||
70 | but may be sure that you can reuse your data after introduction of a | ||
71 | real partition table. | ||
72 | |||
73 | Bugs | ||
74 | ==== | ||
75 | |||
76 | - Performance sometimes is rather low because we don't fully exploit clustering | ||
77 | |||
78 | TODO-List | ||
79 | ========= | ||
80 | |||
81 | - Add IBM'S Disk layout to genhd | ||
82 | - Enhance driver to use more than one major number | ||
83 | - Enable usage as a module | ||
84 | - Support Cache fast write and DASD fast write (ECKD) | ||
diff --git a/Documentation/s390/debugging390.rst b/Documentation/s390/debugging390.rst deleted file mode 100644 index 73ad0b06c666..000000000000 --- a/Documentation/s390/debugging390.rst +++ /dev/null | |||
@@ -1,2613 +0,0 @@ | |||
1 | ============================================= | ||
2 | Debugging on Linux for s/390 & z/Architecture | ||
3 | ============================================= | ||
4 | |||
5 | Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) | ||
6 | |||
7 | Copyright (C) 2000-2001 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
8 | |||
9 | .. Best viewed with fixed width fonts | ||
10 | |||
11 | Overview of Document: | ||
12 | ===================== | ||
13 | This document is intended to give a good overview of how to debug Linux for | ||
14 | s/390 and z/Architecture. It is not intended as a complete reference and not a | ||
15 | tutorial on the fundamentals of C & assembly. It doesn't go into | ||
16 | 390 IO in any detail. It is intended to complement the documents in the | ||
17 | reference section below & any other worthwhile references you get. | ||
18 | |||
19 | It is intended like the Enterprise Systems Architecture/390 Reference Summary | ||
20 | to be printed out & used as a quick cheat sheet self help style reference when | ||
21 | problems occur. | ||
22 | |||
23 | .. Contents | ||
24 | ======== | ||
25 | Register Set | ||
26 | Address Spaces on Intel Linux | ||
27 | Address Spaces on Linux for s/390 & z/Architecture | ||
28 | The Linux for s/390 & z/Architecture Kernel Task Structure | ||
29 | Register Usage & Stackframes on Linux for s/390 & z/Architecture | ||
30 | A sample program with comments | ||
31 | Compiling programs for debugging on Linux for s/390 & z/Architecture | ||
32 | Debugging under VM | ||
33 | s/390 & z/Architecture IO Overview | ||
34 | Debugging IO on s/390 & z/Architecture under VM | ||
35 | GDB on s/390 & z/Architecture | ||
36 | Stack chaining in gdb by hand | ||
37 | Examining core dumps | ||
38 | ldd | ||
39 | Debugging modules | ||
40 | The proc file system | ||
41 | SysRq | ||
42 | References | ||
43 | Special Thanks | ||
44 | |||
45 | Register Set | ||
46 | ============ | ||
47 | The current architectures have the following registers. | ||
48 | |||
49 | 16 General propose registers, 32 bit on s/390 and 64 bit on z/Architecture, | ||
50 | r0-r15 (or gpr0-gpr15), used for arithmetic and addressing. | ||
51 | |||
52 | 16 Control registers, 32 bit on s/390 and 64 bit on z/Architecture, cr0-cr15, | ||
53 | kernel usage only, used for memory management, interrupt control, debugging | ||
54 | control etc. | ||
55 | |||
56 | 16 Access registers (ar0-ar15), 32 bit on both s/390 and z/Architecture, | ||
57 | normally not used by normal programs but potentially could be used as | ||
58 | temporary storage. These registers have a 1:1 association with general | ||
59 | purpose registers and are designed to be used in the so-called access | ||
60 | register mode to select different address spaces. | ||
61 | Access register 0 (and access register 1 on z/Architecture, which needs a | ||
62 | 64 bit pointer) is currently used by the pthread library as a pointer to | ||
63 | the current running threads private area. | ||
64 | |||
65 | 16 64-bit floating point registers (fp0-fp15 ) IEEE & HFP floating | ||
66 | point format compliant on G5 upwards & a Floating point control reg (FPC) | ||
67 | |||
68 | 4 64-bit registers (fp0,fp2,fp4 & fp6) HFP only on older machines. | ||
69 | |||
70 | Note: | ||
71 | Linux (currently) always uses IEEE & emulates G5 IEEE format on older | ||
72 | machines, ( provided the kernel is configured for this ). | ||
73 | |||
74 | |||
75 | The PSW is the most important register on the machine it | ||
76 | is 64 bit on s/390 & 128 bit on z/Architecture & serves the roles of | ||
77 | a program counter (pc), condition code register,memory space designator. | ||
78 | In IBM standard notation I am counting bit 0 as the MSB. | ||
79 | It has several advantages over a normal program counter | ||
80 | in that you can change address translation & program counter | ||
81 | in a single instruction. To change address translation, | ||
82 | e.g. switching address translation off requires that you | ||
83 | have a logical=physical mapping for the address you are | ||
84 | currently running at. | ||
85 | |||
86 | +-------------------------+-------------------------------------------------+ | ||
87 | | Bit | | | ||
88 | +--------+----------------+ Value | | ||
89 | | s/390 | z/Architecture | | | ||
90 | +========+================+=================================================+ | ||
91 | | 0 | 0 | Reserved (must be 0) otherwise specification | | ||
92 | | | | exception occurs. | | ||
93 | +--------+----------------+-------------------------------------------------+ | ||
94 | | 1 | 1 | Program Event Recording 1 PER enabled, | | ||
95 | | | | PER is used to facilitate debugging e.g. | | ||
96 | | | | single stepping. | | ||
97 | +--------+----------------+-------------------------------------------------+ | ||
98 | | 2-4 | 2-4 | Reserved (must be 0). | | ||
99 | +--------+----------------+-------------------------------------------------+ | ||
100 | | 5 | 5 | Dynamic address translation 1=DAT on. | | ||
101 | +--------+----------------+-------------------------------------------------+ | ||
102 | | 6 | 6 | Input/Output interrupt Mask | | ||
103 | +--------+----------------+-------------------------------------------------+ | ||
104 | | 7 | 7 | External interrupt Mask used primarily for | | ||
105 | | | | interprocessor signalling and clock interrupts. | | ||
106 | +--------+----------------+-------------------------------------------------+ | ||
107 | | 8-11 | 8-11 | PSW Key used for complex memory protection | | ||
108 | | | | mechanism (not used under linux) | | ||
109 | +--------+----------------+-------------------------------------------------+ | ||
110 | | 12 | 12 | 1 on s/390 0 on z/Architecture | | ||
111 | +--------+----------------+-------------------------------------------------+ | ||
112 | | 13 | 13 | Machine Check Mask 1=enable machine check | | ||
113 | | | | interrupts | | ||
114 | +--------+----------------+-------------------------------------------------+ | ||
115 | | 14 | 14 | Wait State. Set this to 1 to stop the processor | | ||
116 | | | | except for interrupts and give time to other | | ||
117 | | | | LPARS. Used in CPU idle in the kernel to | | ||
118 | | | | increase overall usage of processor resources. | | ||
119 | +--------+----------------+-------------------------------------------------+ | ||
120 | | 15 | 15 | Problem state (if set to 1 certain instructions | | ||
121 | | | | are disabled). All linux user programs run with | | ||
122 | | | | this bit 1 (useful info for debugging under VM).| | ||
123 | +--------+----------------+-------------------------------------------------+ | ||
124 | | 16-17 | 16-17 | Address Space Control | | ||
125 | | | | | | ||
126 | | | | 00 Primary Space Mode: | | ||
127 | | | | | | ||
128 | | | | The register CR1 contains the primary | | ||
129 | | | | address-space control element (PASCE), which | | ||
130 | | | | points to the primary space region/segment | | ||
131 | | | | table origin. | | ||
132 | | | | | | ||
133 | | | | 01 Access register mode | | ||
134 | | | | | | ||
135 | | | | 10 Secondary Space Mode: | | ||
136 | | | | | | ||
137 | | | | The register CR7 contains the secondary | | ||
138 | | | | address-space control element (SASCE), which | | ||
139 | | | | points to the secondary space region or | | ||
140 | | | | segment table origin. | | ||
141 | | | | | | ||
142 | | | | 11 Home Space Mode: | | ||
143 | | | | | | ||
144 | | | | The register CR13 contains the home space | | ||
145 | | | | address-space control element (HASCE), which | | ||
146 | | | | points to the home space region/segment | | ||
147 | | | | table origin. | | ||
148 | | | | | | ||
149 | | | | See "Address Spaces on Linux for s/390 & | | ||
150 | | | | z/Architecture" below for more information | | ||
151 | | | | about address space usage in Linux. | | ||
152 | +--------+----------------+-------------------------------------------------+ | ||
153 | | 18-19 | 18-19 | Condition codes (CC) | | ||
154 | +--------+----------------+-------------------------------------------------+ | ||
155 | | 20 | 20 | Fixed point overflow mask if 1=FPU exceptions | | ||
156 | | | | for this event occur (normally 0) | | ||
157 | +--------+----------------+-------------------------------------------------+ | ||
158 | | 21 | 21 | Decimal overflow mask if 1=FPU exceptions for | | ||
159 | | | | this event occur (normally 0) | | ||
160 | +--------+----------------+-------------------------------------------------+ | ||
161 | | 22 | 22 | Exponent underflow mask if 1=FPU exceptions | | ||
162 | | | | for this event occur (normally 0) | | ||
163 | +--------+----------------+-------------------------------------------------+ | ||
164 | | 23 | 23 | Significance Mask if 1=FPU exceptions for this | | ||
165 | | | | event occur (normally 0) | | ||
166 | +--------+----------------+-------------------------------------------------+ | ||
167 | | 24-31 | 24-30 | Reserved Must be 0. | | ||
168 | | +----------------+-------------------------------------------------+ | ||
169 | | | 31 | Extended Addressing Mode | | ||
170 | | +----------------+-------------------------------------------------+ | ||
171 | | | 32 | Basic Addressing Mode | | ||
172 | | | | | | ||
173 | | | | Used to set addressing mode:: | | ||
174 | | | | | | ||
175 | | | | +---------+----------+----------+ | | ||
176 | | | | | PSW 31 | PSW 32 | | | | ||
177 | | | | +---------+----------+----------+ | | ||
178 | | | | | 0 | 0 | 24 bit | | | ||
179 | | | | +---------+----------+----------+ | | ||
180 | | | | | 0 | 1 | 31 bit | | | ||
181 | | | | +---------+----------+----------+ | | ||
182 | | | | | 1 | 1 | 64 bit | | | ||
183 | | | | +---------+----------+----------+ | | ||
184 | +--------+----------------+-------------------------------------------------+ | ||
185 | | 32 | | 1=31 bit addressing mode 0=24 bit addressing | | ||
186 | | | | mode (for backward compatibility), linux | | ||
187 | | | | always runs with this bit set to 1 | | ||
188 | +--------+----------------+-------------------------------------------------+ | ||
189 | | 33-64 | | Instruction address. | | ||
190 | | +----------------+-------------------------------------------------+ | ||
191 | | | 33-63 | Reserved must be 0 | | ||
192 | | +----------------+-------------------------------------------------+ | ||
193 | | | 64-127 | Address | | ||
194 | | | | | | ||
195 | | | | - In 24 bits mode bits 64-103=0 bits 104-127 | | ||
196 | | | | Address | | ||
197 | | | | - In 31 bits mode bits 64-96=0 bits 97-127 | | ||
198 | | | | Address | | ||
199 | | | | | | ||
200 | | | | Note: | | ||
201 | | | | unlike 31 bit mode on s/390 bit 96 must be | | ||
202 | | | | zero when loading the address with LPSWE | | ||
203 | | | | otherwise a specification exception occurs, | | ||
204 | | | | LPSW is fully backward compatible. | | ||
205 | +--------+----------------+-------------------------------------------------+ | ||
206 | |||
207 | Prefix Page(s) | ||
208 | -------------- | ||
209 | This per cpu memory area is too intimately tied to the processor not to mention. | ||
210 | It exists between the real addresses 0-4096 on s/390 and between 0-8192 on | ||
211 | z/Architecture and is exchanged with one page on s/390 or two pages on | ||
212 | z/Architecture in absolute storage by the set prefix instruction during Linux | ||
213 | startup. | ||
214 | |||
215 | This page is mapped to a different prefix for each processor in an SMP | ||
216 | configuration (assuming the OS designer is sane of course). | ||
217 | |||
218 | Bytes 0-512 (200 hex) on s/390 and 0-512, 4096-4544, 4604-5119 currently on | ||
219 | z/Architecture are used by the processor itself for holding such information | ||
220 | as exception indications and entry points for exceptions. | ||
221 | |||
222 | Bytes after 0xc00 hex are used by linux for per processor globals on s/390 and | ||
223 | z/Architecture (there is a gap on z/Architecture currently between 0xc00 and | ||
224 | 0x1000, too, which is used by Linux). | ||
225 | |||
226 | The closest thing to this on traditional architectures is the interrupt | ||
227 | vector table. This is a good thing & does simplify some of the kernel coding | ||
228 | however it means that we now cannot catch stray NULL pointers in the | ||
229 | kernel without hard coded checks. | ||
230 | |||
231 | |||
232 | |||
233 | Address Spaces on Intel Linux | ||
234 | ============================= | ||
235 | |||
236 | The traditional Intel Linux is approximately mapped as follows forgive | ||
237 | the ascii art:: | ||
238 | |||
239 | 0xFFFFFFFF 4GB Himem ***************** | ||
240 | * * | ||
241 | * Kernel Space * | ||
242 | * * | ||
243 | ***************** **************** | ||
244 | User Space Himem * User Stack * * * | ||
245 | (typically 0xC0000000 3GB ) ***************** * * | ||
246 | * Shared Libs * * Next Process * | ||
247 | ***************** * to * | ||
248 | * * <== * Run * <== | ||
249 | * User Program * * * | ||
250 | * Data BSS * * * | ||
251 | * Text * * * | ||
252 | * Sections * * * | ||
253 | 0x00000000 ***************** **************** | ||
254 | |||
255 | Now it is easy to see that on Intel it is quite easy to recognise a kernel | ||
256 | address as being one greater than user space himem (in this case 0xC0000000), | ||
257 | and addresses of less than this are the ones in the current running program on | ||
258 | this processor (if an smp box). | ||
259 | |||
260 | If using the virtual machine ( VM ) as a debugger it is quite difficult to | ||
261 | know which user process is running as the address space you are looking at | ||
262 | could be from any process in the run queue. | ||
263 | |||
264 | The limitation of Intels addressing technique is that the linux | ||
265 | kernel uses a very simple real address to virtual addressing technique | ||
266 | of Real Address=Virtual Address-User Space Himem. | ||
267 | This means that on Intel the kernel linux can typically only address | ||
268 | Himem=0xFFFFFFFF-0xC0000000=1GB & this is all the RAM these machines | ||
269 | can typically use. | ||
270 | |||
271 | They can lower User Himem to 2GB or lower & thus be | ||
272 | able to use 2GB of RAM however this shrinks the maximum size | ||
273 | of User Space from 3GB to 2GB they have a no win limit of 4GB unless | ||
274 | they go to 64 Bit. | ||
275 | |||
276 | |||
277 | On 390 our limitations & strengths make us slightly different. | ||
278 | For backward compatibility we are only allowed use 31 bits (2GB) | ||
279 | of our 32 bit addresses, however, we use entirely separate address | ||
280 | spaces for the user & kernel. | ||
281 | |||
282 | This means we can support 2GB of non Extended RAM on s/390, & more | ||
283 | with the Extended memory management swap device & | ||
284 | currently 4TB of physical memory currently on z/Architecture. | ||
285 | |||
286 | |||
287 | Address Spaces on Linux for s/390 & z/Architecture | ||
288 | ================================================== | ||
289 | |||
290 | Our addressing scheme is basically as follows:: | ||
291 | |||
292 | Primary Space Home Space | ||
293 | Himem 0x7fffffff 2GB on s/390 ***************** **************** | ||
294 | currently 0x3ffffffffff (2^42)-1 * User Stack * * * | ||
295 | on z/Architecture. ***************** * * | ||
296 | * Shared Libs * * * | ||
297 | ***************** * * | ||
298 | * * * Kernel * | ||
299 | * User Program * * * | ||
300 | * Data BSS * * * | ||
301 | * Text * * * | ||
302 | * Sections * * * | ||
303 | 0x00000000 ***************** **************** | ||
304 | |||
305 | This also means that we need to look at the PSW problem state bit and the | ||
306 | addressing mode to decide whether we are looking at user or kernel space. | ||
307 | |||
308 | User space runs in primary address mode (or access register mode within | ||
309 | the vdso code). | ||
310 | |||
311 | The kernel usually also runs in home space mode, however when accessing | ||
312 | user space the kernel switches to primary or secondary address mode if | ||
313 | the mvcos instruction is not available or if a compare-and-swap (futex) | ||
314 | instruction on a user space address is performed. | ||
315 | |||
316 | When also looking at the ASCE control registers, this means: | ||
317 | |||
318 | User space: | ||
319 | |||
320 | - runs in primary or access register mode | ||
321 | - cr1 contains the user asce | ||
322 | - cr7 contains the user asce | ||
323 | - cr13 contains the kernel asce | ||
324 | |||
325 | Kernel space: | ||
326 | |||
327 | - runs in home space mode | ||
328 | - cr1 contains the user or kernel asce | ||
329 | |||
330 | - the kernel asce is loaded when a uaccess requires primary or | ||
331 | secondary address mode | ||
332 | |||
333 | - cr7 contains the user or kernel asce, (changed with set_fs()) | ||
334 | - cr13 contains the kernel asce | ||
335 | |||
336 | In case of uaccess the kernel changes to: | ||
337 | |||
338 | - primary space mode in case of a uaccess (copy_to_user) and uses | ||
339 | e.g. the mvcp instruction to access user space. However the kernel | ||
340 | will stay in home space mode if the mvcos instruction is available | ||
341 | - secondary space mode in case of futex atomic operations, so that the | ||
342 | instructions come from primary address space and data from secondary | ||
343 | space | ||
344 | |||
345 | In case of KVM, the kernel runs in home space mode, but cr1 gets switched | ||
346 | to contain the gmap asce before the SIE instruction gets executed. When | ||
347 | the SIE instruction is finished, cr1 will be switched back to contain the | ||
348 | user asce. | ||
349 | |||
350 | |||
351 | Virtual Addresses on s/390 & z/Architecture | ||
352 | =========================================== | ||
353 | |||
354 | A virtual address on s/390 is made up of 3 parts | ||
355 | The SX (segment index, roughly corresponding to the PGD & PMD in Linux | ||
356 | terminology) being bits 1-11. | ||
357 | |||
358 | The PX (page index, corresponding to the page table entry (pte) in Linux | ||
359 | terminology) being bits 12-19. | ||
360 | |||
361 | The remaining bits BX (the byte index are the offset in the page ) | ||
362 | i.e. bits 20 to 31. | ||
363 | |||
364 | On z/Architecture in linux we currently make up an address from 4 parts. | ||
365 | |||
366 | - The region index bits (RX) 0-32 we currently use bits 22-32 | ||
367 | - The segment index (SX) being bits 33-43 | ||
368 | - The page index (PX) being bits 44-51 | ||
369 | - The byte index (BX) being bits 52-63 | ||
370 | |||
371 | Notes: | ||
372 | 1) s/390 has no PMD so the PMD is really the PGD also. | ||
373 | A lot of this stuff is defined in pgtable.h. | ||
374 | |||
375 | 2) Also seeing as s/390's page indexes are only 1k in size | ||
376 | (bits 12-19 x 4 bytes per pte ) we use 1 ( page 4k ) | ||
377 | to make the best use of memory by updating 4 segment indices | ||
378 | entries each time we mess with a PMD & use offsets | ||
379 | 0,1024,2048 & 3072 in this page as for our segment indexes. | ||
380 | On z/Architecture our page indexes are now 2k in size | ||
381 | ( bits 12-19 x 8 bytes per pte ) we do a similar trick | ||
382 | but only mess with 2 segment indices each time we mess with | ||
383 | a PMD. | ||
384 | |||
385 | 3) As z/Architecture supports up to a massive 5-level page table lookup we | ||
386 | can only use 3 currently on Linux ( as this is all the generic kernel | ||
387 | currently supports ) however this may change in future | ||
388 | this allows us to access ( according to my sums ) | ||
389 | 4TB of virtual storage per process i.e. | ||
390 | 4096*512(PTES)*1024(PMDS)*2048(PGD) = 4398046511104 bytes, | ||
391 | enough for another 2 or 3 of years I think :-). | ||
392 | to do this we use a region-third-table designation type in | ||
393 | our address space control registers. | ||
394 | |||
395 | |||
396 | The Linux for s/390 & z/Architecture Kernel Task Structure | ||
397 | ========================================================== | ||
398 | Each process/thread under Linux for S390 has its own kernel task_struct | ||
399 | defined in linux/include/linux/sched.h | ||
400 | The S390 on initialisation & resuming of a process on a cpu sets | ||
401 | the __LC_KERNEL_STACK variable in the spare prefix area for this cpu | ||
402 | (which we use for per-processor globals). | ||
403 | |||
404 | The kernel stack pointer is intimately tied with the task structure for | ||
405 | each processor as follows:: | ||
406 | |||
407 | s/390 | ||
408 | ************************ | ||
409 | * 1 page kernel stack * | ||
410 | * ( 4K ) * | ||
411 | ************************ | ||
412 | * 1 page task_struct * | ||
413 | * ( 4K ) * | ||
414 | 8K aligned ************************ | ||
415 | |||
416 | z/Architecture | ||
417 | ************************ | ||
418 | * 2 page kernel stack * | ||
419 | * ( 8K ) * | ||
420 | ************************ | ||
421 | * 2 page task_struct * | ||
422 | * ( 8K ) * | ||
423 | 16K aligned ************************ | ||
424 | |||
425 | What this means is that we don't need to dedicate any register or global | ||
426 | variable to point to the current running process & can retrieve it with the | ||
427 | following very simple construct for s/390 & one very similar for | ||
428 | z/Architecture:: | ||
429 | |||
430 | static inline struct task_struct * get_current(void) | ||
431 | { | ||
432 | struct task_struct *current; | ||
433 | __asm__("lhi %0,-8192\n\t" | ||
434 | "nr %0,15" | ||
435 | : "=r" (current) ); | ||
436 | return current; | ||
437 | } | ||
438 | |||
439 | i.e. just anding the current kernel stack pointer with the mask -8192. | ||
440 | Thankfully because Linux doesn't have support for nested IO interrupts | ||
441 | & our devices have large buffers can survive interrupts being shut for | ||
442 | short amounts of time we don't need a separate stack for interrupts. | ||
443 | |||
444 | |||
445 | |||
446 | |||
447 | Register Usage & Stackframes on Linux for s/390 & z/Architecture | ||
448 | ================================================================= | ||
449 | Overview: | ||
450 | --------- | ||
451 | This is the code that gcc produces at the top & the bottom of | ||
452 | each function. It usually is fairly consistent & similar from | ||
453 | function to function & if you know its layout you can probably | ||
454 | make some headway in finding the ultimate cause of a problem | ||
455 | after a crash without a source level debugger. | ||
456 | |||
457 | Note: To follow stackframes requires a knowledge of C or Pascal & | ||
458 | limited knowledge of one assembly language. | ||
459 | |||
460 | It should be noted that there are some differences between the | ||
461 | s/390 and z/Architecture stack layouts as the z/Architecture stack layout | ||
462 | didn't have to maintain compatibility with older linkage formats. | ||
463 | |||
464 | Glossary: | ||
465 | --------- | ||
466 | alloca: | ||
467 | This is a built in compiler function for runtime allocation | ||
468 | of extra space on the callers stack which is obviously freed | ||
469 | up on function exit ( e.g. the caller may choose to allocate nothing | ||
470 | of a buffer of 4k if required for temporary purposes ), it generates | ||
471 | very efficient code ( a few cycles ) when compared to alternatives | ||
472 | like malloc. | ||
473 | |||
474 | automatics: | ||
475 | These are local variables on the stack, i.e they aren't in registers & | ||
476 | they aren't static. | ||
477 | |||
478 | back-chain: | ||
479 | This is a pointer to the stack pointer before entering a | ||
480 | framed functions ( see frameless function ) prologue got by | ||
481 | dereferencing the address of the current stack pointer, | ||
482 | i.e. got by accessing the 32 bit value at the stack pointers | ||
483 | current location. | ||
484 | |||
485 | base-pointer: | ||
486 | This is a pointer to the back of the literal pool which | ||
487 | is an area just behind each procedure used to store constants | ||
488 | in each function. | ||
489 | |||
490 | call-clobbered: | ||
491 | The caller probably needs to save these registers if there | ||
492 | is something of value in them, on the stack or elsewhere before making a | ||
493 | call to another procedure so that it can restore it later. | ||
494 | |||
495 | epilogue: | ||
496 | The code generated by the compiler to return to the caller. | ||
497 | |||
498 | frameless-function: | ||
499 | A frameless function in Linux for s390 & z/Architecture is one which doesn't | ||
500 | need more than the register save area (96 bytes on s/390, 160 on z/Architecture) | ||
501 | given to it by the caller. | ||
502 | |||
503 | A frameless function never: | ||
504 | |||
505 | 1) Sets up a back chain. | ||
506 | 2) Calls alloca. | ||
507 | 3) Calls other normal functions | ||
508 | 4) Has automatics. | ||
509 | |||
510 | GOT-pointer: | ||
511 | This is a pointer to the global-offset-table in ELF | ||
512 | ( Executable Linkable Format, Linux'es most common executable format ), | ||
513 | all globals & shared library objects are found using this pointer. | ||
514 | |||
515 | lazy-binding | ||
516 | ELF shared libraries are typically only loaded when routines in the shared | ||
517 | library are actually first called at runtime. This is lazy binding. | ||
518 | |||
519 | procedure-linkage-table | ||
520 | This is a table found from the GOT which contains pointers to routines | ||
521 | in other shared libraries which can't be called to by easier means. | ||
522 | |||
523 | prologue: | ||
524 | The code generated by the compiler to set up the stack frame. | ||
525 | |||
526 | outgoing-args: | ||
527 | This is extra area allocated on the stack of the calling function if the | ||
528 | parameters for the callee's cannot all be put in registers, the same | ||
529 | area can be reused by each function the caller calls. | ||
530 | |||
531 | routine-descriptor: | ||
532 | A COFF executable format based concept of a procedure reference | ||
533 | actually being 8 bytes or more as opposed to a simple pointer to the routine. | ||
534 | This is typically defined as follows: | ||
535 | |||
536 | - Routine Descriptor offset 0=Pointer to Function | ||
537 | - Routine Descriptor offset 4=Pointer to Table of Contents | ||
538 | |||
539 | The table of contents/TOC is roughly equivalent to a GOT pointer. | ||
540 | & it means that shared libraries etc. can be shared between several | ||
541 | environments each with their own TOC. | ||
542 | |||
543 | static-chain: | ||
544 | This is used in nested functions a concept adopted from pascal | ||
545 | by gcc not used in ansi C or C++ ( although quite useful ), basically it | ||
546 | is a pointer used to reference local variables of enclosing functions. | ||
547 | You might come across this stuff once or twice in your lifetime. | ||
548 | |||
549 | e.g. | ||
550 | |||
551 | The function below should return 11 though gcc may get upset & toss warnings | ||
552 | about unused variables:: | ||
553 | |||
554 | int FunctionA(int a) | ||
555 | { | ||
556 | int b; | ||
557 | FunctionC(int c) | ||
558 | { | ||
559 | b=c+1; | ||
560 | } | ||
561 | FunctionC(10); | ||
562 | return(b); | ||
563 | } | ||
564 | |||
565 | |||
566 | s/390 & z/Architecture Register usage | ||
567 | ===================================== | ||
568 | |||
569 | ======== ========================================== =============== | ||
570 | r0 used by syscalls/assembly call-clobbered | ||
571 | r1 used by syscalls/assembly call-clobbered | ||
572 | r2 argument 0 / return value 0 call-clobbered | ||
573 | r3 argument 1 / return value 1 (if long long) call-clobbered | ||
574 | r4 argument 2 call-clobbered | ||
575 | r5 argument 3 call-clobbered | ||
576 | r6 argument 4 saved | ||
577 | r7 pointer-to arguments 5 to ... saved | ||
578 | r8 this & that saved | ||
579 | r9 this & that saved | ||
580 | r10 static-chain ( if nested function ) saved | ||
581 | r11 frame-pointer ( if function used alloca ) saved | ||
582 | r12 got-pointer saved | ||
583 | r13 base-pointer saved | ||
584 | r14 return-address saved | ||
585 | r15 stack-pointer saved | ||
586 | |||
587 | f0 argument 0 / return value ( float/double ) call-clobbered | ||
588 | f2 argument 1 call-clobbered | ||
589 | f4 z/Architecture argument 2 saved | ||
590 | f6 z/Architecture argument 3 saved | ||
591 | ======== ========================================== =============== | ||
592 | |||
593 | The remaining floating points | ||
594 | f1,f3,f5 f7-f15 are call-clobbered. | ||
595 | |||
596 | Notes: | ||
597 | ------ | ||
598 | 1) The only requirement is that registers which are used | ||
599 | by the callee are saved, e.g. the compiler is perfectly | ||
600 | capable of using r11 for purposes other than a frame a | ||
601 | frame pointer if a frame pointer is not needed. | ||
602 | 2) In functions with variable arguments e.g. printf the calling procedure | ||
603 | is identical to one without variable arguments & the same number of | ||
604 | parameters. However, the prologue of this function is somewhat more | ||
605 | hairy owing to it having to move these parameters to the stack to | ||
606 | get va_start, va_arg & va_end to work. | ||
607 | 3) Access registers are currently unused by gcc but are used in | ||
608 | the kernel. Possibilities exist to use them at the moment for | ||
609 | temporary storage but it isn't recommended. | ||
610 | 4) Only 4 of the floating point registers are used for | ||
611 | parameter passing as older machines such as G3 only have only 4 | ||
612 | & it keeps the stack frame compatible with other compilers. | ||
613 | However with IEEE floating point emulation under linux on the | ||
614 | older machines you are free to use the other 12. | ||
615 | 5) A long long or double parameter cannot be have the | ||
616 | first 4 bytes in a register & the second four bytes in the | ||
617 | outgoing args area. It must be purely in the outgoing args | ||
618 | area if crossing this boundary. | ||
619 | 6) Floating point parameters are mixed with outgoing args | ||
620 | on the outgoing args area in the order the are passed in as parameters. | ||
621 | 7) Floating point arguments 2 & 3 are saved in the outgoing args area for | ||
622 | z/Architecture | ||
623 | |||
624 | |||
625 | Stack Frame Layout | ||
626 | ------------------ | ||
627 | |||
628 | ========= ============== ====================================================== | ||
629 | s/390 z/Architecture | ||
630 | ========= ============== ====================================================== | ||
631 | 0 0 back chain ( a 0 here signifies end of back chain ) | ||
632 | 4 8 eos ( end of stack, not used on Linux for S390 used | ||
633 | in other linkage formats ) | ||
634 | 8 16 glue used in other s/390 linkage formats for saved | ||
635 | routine descriptors etc. | ||
636 | 12 24 glue used in other s/390 linkage formats for saved | ||
637 | routine descriptors etc. | ||
638 | 16 32 scratch area | ||
639 | 20 40 scratch area | ||
640 | 24 48 saved r6 of caller function | ||
641 | 28 56 saved r7 of caller function | ||
642 | 32 64 saved r8 of caller function | ||
643 | 36 72 saved r9 of caller function | ||
644 | 40 80 saved r10 of caller function | ||
645 | 44 88 saved r11 of caller function | ||
646 | 48 96 saved r12 of caller function | ||
647 | 52 104 saved r13 of caller function | ||
648 | 56 112 saved r14 of caller function | ||
649 | 60 120 saved r15 of caller function | ||
650 | 64 128 saved f4 of caller function | ||
651 | 72 132 saved f6 of caller function | ||
652 | 80 undefined | ||
653 | 96 160 outgoing args passed from caller to callee | ||
654 | 96+x 160+x possible stack alignment ( 8 bytes desirable ) | ||
655 | 96+x+y 160+x+y alloca space of caller ( if used ) | ||
656 | 96+x+y+z 160+x+y+z automatics of caller ( if used ) | ||
657 | 0 back-chain | ||
658 | ========= ============== ====================================================== | ||
659 | |||
660 | A sample program with comments. | ||
661 | =============================== | ||
662 | |||
663 | Comments on the function test | ||
664 | ----------------------------- | ||
665 | 1) It didn't need to set up a pointer to the constant pool gpr13 as it is not | ||
666 | used ( :-( ). | ||
667 | 2) This is a frameless function & no stack is bought. | ||
668 | 3) The compiler was clever enough to recognise that it could return the | ||
669 | value in r2 as well as use it for the passed in parameter ( :-) ). | ||
670 | 4) The basr ( branch relative & save ) trick works as follows the instruction | ||
671 | has a special case with r0,r0 with some instruction operands is understood as | ||
672 | the literal value 0, some risc architectures also do this ). So now | ||
673 | we are branching to the next address & the address new program counter is | ||
674 | in r13,so now we subtract the size of the function prologue we have executed | ||
675 | the size of the literal pool to get to the top of the literal pool:: | ||
676 | |||
677 | |||
678 | 0040037c int test(int b) | ||
679 | { # Function prologue below | ||
680 | 40037c: 90 de f0 34 stm %r13,%r14,52(%r15) # Save registers r13 & r14 | ||
681 | 400380: 0d d0 basr %r13,%r0 # Set up pointer to constant pool using | ||
682 | 400382: a7 da ff fa ahi %r13,-6 # basr trick | ||
683 | return(5+b); | ||
684 | # Huge main program | ||
685 | 400386: a7 2a 00 05 ahi %r2,5 # add 5 to r2 | ||
686 | |||
687 | # Function epilogue below | ||
688 | 40038a: 98 de f0 34 lm %r13,%r14,52(%r15) # restore registers r13 & 14 | ||
689 | 40038e: 07 fe br %r14 # return | ||
690 | } | ||
691 | |||
692 | Comments on the function main | ||
693 | ----------------------------- | ||
694 | 1) The compiler did this function optimally ( 8-) ):: | ||
695 | |||
696 | Literal pool for main. | ||
697 | 400390: ff ff ff ec .long 0xffffffec | ||
698 | main(int argc,char *argv[]) | ||
699 | { # Function prologue below | ||
700 | 400394: 90 bf f0 2c stm %r11,%r15,44(%r15) # Save necessary registers | ||
701 | 400398: 18 0f lr %r0,%r15 # copy stack pointer to r0 | ||
702 | 40039a: a7 fa ff a0 ahi %r15,-96 # Make area for callee saving | ||
703 | 40039e: 0d d0 basr %r13,%r0 # Set up r13 to point to | ||
704 | 4003a0: a7 da ff f0 ahi %r13,-16 # literal pool | ||
705 | 4003a4: 50 00 f0 00 st %r0,0(%r15) # Save backchain | ||
706 | |||
707 | return(test(5)); # Main Program Below | ||
708 | 4003a8: 58 e0 d0 00 l %r14,0(%r13) # load relative address of test from | ||
709 | # literal pool | ||
710 | 4003ac: a7 28 00 05 lhi %r2,5 # Set first parameter to 5 | ||
711 | 4003b0: 4d ee d0 00 bas %r14,0(%r14,%r13) # jump to test setting r14 as return | ||
712 | # address using branch & save instruction. | ||
713 | |||
714 | # Function Epilogue below | ||
715 | 4003b4: 98 bf f0 8c lm %r11,%r15,140(%r15)# Restore necessary registers. | ||
716 | 4003b8: 07 fe br %r14 # return to do program exit | ||
717 | } | ||
718 | |||
719 | |||
720 | Compiler updates | ||
721 | ---------------- | ||
722 | |||
723 | :: | ||
724 | |||
725 | main(int argc,char *argv[]) | ||
726 | { | ||
727 | 4004fc: 90 7f f0 1c stm %r7,%r15,28(%r15) | ||
728 | 400500: a7 d5 00 04 bras %r13,400508 <main+0xc> | ||
729 | 400504: 00 40 04 f4 .long 0x004004f4 | ||
730 | # compiler now puts constant pool in code to so it saves an instruction | ||
731 | 400508: 18 0f lr %r0,%r15 | ||
732 | 40050a: a7 fa ff a0 ahi %r15,-96 | ||
733 | 40050e: 50 00 f0 00 st %r0,0(%r15) | ||
734 | return(test(5)); | ||
735 | 400512: 58 10 d0 00 l %r1,0(%r13) | ||
736 | 400516: a7 28 00 05 lhi %r2,5 | ||
737 | 40051a: 0d e1 basr %r14,%r1 | ||
738 | # compiler adds 1 extra instruction to epilogue this is done to | ||
739 | # avoid processor pipeline stalls owing to data dependencies on g5 & | ||
740 | # above as register 14 in the old code was needed directly after being loaded | ||
741 | # by the lm %r11,%r15,140(%r15) for the br %14. | ||
742 | 40051c: 58 40 f0 98 l %r4,152(%r15) | ||
743 | 400520: 98 7f f0 7c lm %r7,%r15,124(%r15) | ||
744 | 400524: 07 f4 br %r4 | ||
745 | } | ||
746 | |||
747 | |||
748 | Hartmut ( our compiler developer ) also has been threatening to take out the | ||
749 | stack backchain in optimised code as this also causes pipeline stalls, you | ||
750 | have been warned. | ||
751 | |||
752 | 64 bit z/Architecture code disassembly | ||
753 | -------------------------------------- | ||
754 | |||
755 | If you understand the stuff above you'll understand the stuff | ||
756 | below too so I'll avoid repeating myself & just say that | ||
757 | some of the instructions have g's on the end of them to indicate | ||
758 | they are 64 bit & the stack offsets are a bigger, | ||
759 | the only other difference you'll find between 32 & 64 bit is that | ||
760 | we now use f4 & f6 for floating point arguments on 64 bit:: | ||
761 | |||
762 | 00000000800005b0 <test>: | ||
763 | int test(int b) | ||
764 | { | ||
765 | return(5+b); | ||
766 | 800005b0: a7 2a 00 05 ahi %r2,5 | ||
767 | 800005b4: b9 14 00 22 lgfr %r2,%r2 # downcast to integer | ||
768 | 800005b8: 07 fe br %r14 | ||
769 | 800005ba: 07 07 bcr 0,%r7 | ||
770 | |||
771 | |||
772 | } | ||
773 | |||
774 | 00000000800005bc <main>: | ||
775 | main(int argc,char *argv[]) | ||
776 | { | ||
777 | 800005bc: eb bf f0 58 00 24 stmg %r11,%r15,88(%r15) | ||
778 | 800005c2: b9 04 00 1f lgr %r1,%r15 | ||
779 | 800005c6: a7 fb ff 60 aghi %r15,-160 | ||
780 | 800005ca: e3 10 f0 00 00 24 stg %r1,0(%r15) | ||
781 | return(test(5)); | ||
782 | 800005d0: a7 29 00 05 lghi %r2,5 | ||
783 | # brasl allows jumps > 64k & is overkill here bras would do fune | ||
784 | 800005d4: c0 e5 ff ff ff ee brasl %r14,800005b0 <test> | ||
785 | 800005da: e3 40 f1 10 00 04 lg %r4,272(%r15) | ||
786 | 800005e0: eb bf f0 f8 00 04 lmg %r11,%r15,248(%r15) | ||
787 | 800005e6: 07 f4 br %r4 | ||
788 | } | ||
789 | |||
790 | |||
791 | |||
792 | Compiling programs for debugging on Linux for s/390 & z/Architecture | ||
793 | ==================================================================== | ||
794 | -gdwarf-2 now works it should be considered the default debugging | ||
795 | format for s/390 & z/Architecture as it is more reliable for debugging | ||
796 | shared libraries, normal -g debugging works much better now | ||
797 | Thanks to the IBM java compiler developers bug reports. | ||
798 | |||
799 | This is typically done adding/appending the flags -g or -gdwarf-2 to the | ||
800 | CFLAGS & LDFLAGS variables Makefile of the program concerned. | ||
801 | |||
802 | If using gdb & you would like accurate displays of registers & | ||
803 | stack traces compile without optimisation i.e make sure | ||
804 | that there is no -O2 or similar on the CFLAGS line of the Makefile & | ||
805 | the emitted gcc commands, obviously this will produce worse code | ||
806 | ( not advisable for shipment ) but it is an aid to the debugging process. | ||
807 | |||
808 | This aids debugging because the compiler will copy parameters passed in | ||
809 | in registers onto the stack so backtracing & looking at passed in | ||
810 | parameters will work, however some larger programs which use inline functions | ||
811 | will not compile without optimisation. | ||
812 | |||
813 | Debugging with optimisation has since much improved after fixing | ||
814 | some bugs, please make sure you are using gdb-5.0 or later developed | ||
815 | after Nov'2000. | ||
816 | |||
817 | |||
818 | |||
819 | Debugging under VM | ||
820 | ================== | ||
821 | |||
822 | Notes | ||
823 | ----- | ||
824 | Addresses & values in the VM debugger are always hex never decimal | ||
825 | Address ranges are of the format <HexValue1>-<HexValue2> or | ||
826 | <HexValue1>.<HexValue2> | ||
827 | For example, the address range 0x2000 to 0x3000 can be described as 2000-3000 | ||
828 | or 2000.1000 | ||
829 | |||
830 | The VM Debugger is case insensitive. | ||
831 | |||
832 | VM's strengths are usually other debuggers weaknesses you can get at any | ||
833 | resource no matter how sensitive e.g. memory management resources, change | ||
834 | address translation in the PSW. For kernel hacking you will reap dividends if | ||
835 | you get good at it. | ||
836 | |||
837 | The VM Debugger displays operators but not operands, and also the debugger | ||
838 | displays useful information on the same line as the author of the code probably | ||
839 | felt that it was a good idea not to go over the 80 columns on the screen. | ||
840 | This isn't as unintuitive as it may seem as the s/390 instructions are easy to | ||
841 | decode mentally and you can make a good guess at a lot of them as all the | ||
842 | operands are nibble (half byte aligned). | ||
843 | So if you have an objdump listing by hand, it is quite easy to follow, and if | ||
844 | you don't have an objdump listing keep a copy of the s/390 Reference Summary | ||
845 | or alternatively the s/390 principles of operation next to you. | ||
846 | e.g. even I can guess that | ||
847 | 0001AFF8' LR 180F CC 0 | ||
848 | is a ( load register ) lr r0,r15 | ||
849 | |||
850 | Also it is very easy to tell the length of a 390 instruction from the 2 most | ||
851 | significant bits in the instruction (not that this info is really useful except | ||
852 | if you are trying to make sense of a hexdump of code). | ||
853 | Here is a table | ||
854 | |||
855 | ======================= ================== | ||
856 | Bits Instruction Length | ||
857 | ======================= ================== | ||
858 | 00 2 Bytes | ||
859 | 01 4 Bytes | ||
860 | 10 4 Bytes | ||
861 | 11 6 Bytes | ||
862 | ======================= ================== | ||
863 | |||
864 | The debugger also displays other useful info on the same line such as the | ||
865 | addresses being operated on destination addresses of branches & condition codes. | ||
866 | e.g.:: | ||
867 | |||
868 | 00019736' AHI A7DAFF0E CC 1 | ||
869 | 000198BA' BRC A7840004 -> 000198C2' CC 0 | ||
870 | 000198CE' STM 900EF068 >> 0FA95E78 CC 2 | ||
871 | |||
872 | |||
873 | |||
874 | Useful VM debugger commands | ||
875 | --------------------------- | ||
876 | |||
877 | I suppose I'd better mention this before I start | ||
878 | to list the current active traces do:: | ||
879 | |||
880 | Q TR | ||
881 | |||
882 | there can be a maximum of 255 of these per set | ||
883 | ( more about trace sets later ). | ||
884 | |||
885 | To stop traces issue a:: | ||
886 | |||
887 | TR END. | ||
888 | |||
889 | To delete a particular breakpoint issue:: | ||
890 | |||
891 | TR DEL <breakpoint number> | ||
892 | |||
893 | The PA1 key drops to CP mode so you can issue debugger commands, | ||
894 | Doing alt c (on my 3270 console at least ) clears the screen. | ||
895 | |||
896 | hitting b <enter> comes back to the running operating system | ||
897 | from cp mode ( in our case linux ). | ||
898 | |||
899 | It is typically useful to add shortcuts to your profile.exec file | ||
900 | if you have one ( this is roughly equivalent to autoexec.bat in DOS ). | ||
901 | file here are a few from mine:: | ||
902 | |||
903 | /* this gives me command history on issuing f12 */ | ||
904 | set pf12 retrieve | ||
905 | /* this continues */ | ||
906 | set pf8 imm b | ||
907 | /* goes to trace set a */ | ||
908 | set pf1 imm tr goto a | ||
909 | /* goes to trace set b */ | ||
910 | set pf2 imm tr goto b | ||
911 | /* goes to trace set c */ | ||
912 | set pf3 imm tr goto c | ||
913 | |||
914 | |||
915 | |||
916 | Instruction Tracing | ||
917 | ------------------- | ||
918 | Setting a simple breakpoint:: | ||
919 | |||
920 | TR I PSWA <address> | ||
921 | |||
922 | To debug a particular function try:: | ||
923 | |||
924 | TR I R <function address range> | ||
925 | TR I on its own will single step. | ||
926 | TR I DATA <MNEMONIC> <OPTIONAL RANGE> will trace for particular mnemonics | ||
927 | |||
928 | e.g.:: | ||
929 | |||
930 | TR I DATA 4D R 0197BC.4000 | ||
931 | |||
932 | will trace for BAS'es ( opcode 4D ) in the range 0197BC.4000 | ||
933 | |||
934 | if you were inclined you could add traces for all branch instructions & | ||
935 | suffix them with the run prefix so you would have a backtrace on screen | ||
936 | when a program crashes:: | ||
937 | |||
938 | TR BR <INTO OR FROM> will trace branches into or out of an address. | ||
939 | |||
940 | e.g.:: | ||
941 | |||
942 | TR BR INTO 0 | ||
943 | |||
944 | is often quite useful if a program is getting awkward & deciding | ||
945 | to branch to 0 & crashing as this will stop at the address before in jumps to 0. | ||
946 | |||
947 | :: | ||
948 | |||
949 | TR I R <address range> RUN cmd d g | ||
950 | |||
951 | single steps a range of addresses but stays running & | ||
952 | displays the gprs on each step. | ||
953 | |||
954 | |||
955 | |||
956 | Displaying & modifying Registers | ||
957 | -------------------------------- | ||
958 | D G | ||
959 | will display all the gprs | ||
960 | |||
961 | Adding a extra G to all the commands is necessary to access the full 64 bit | ||
962 | content in VM on z/Architecture. Obviously this isn't required for access | ||
963 | registers as these are still 32 bit. | ||
964 | |||
965 | e.g. | ||
966 | |||
967 | DGG | ||
968 | instead of DG | ||
969 | |||
970 | D X | ||
971 | will display all the control registers | ||
972 | D AR | ||
973 | will display all the access registers | ||
974 | D AR4-7 | ||
975 | will display access registers 4 to 7 | ||
976 | CPU ALL D G | ||
977 | will display the GRPS of all CPUS in the configuration | ||
978 | D PSW | ||
979 | will display the current PSW | ||
980 | st PSW 2000 | ||
981 | will put the value 2000 into the PSW & cause crash your machine. | ||
982 | D PREFIX | ||
983 | displays the prefix offset | ||
984 | |||
985 | |||
986 | Displaying Memory | ||
987 | ----------------- | ||
988 | To display memory mapped using the current PSW's mapping try:: | ||
989 | |||
990 | D <range> | ||
991 | |||
992 | To make VM display a message each time it hits a particular address and | ||
993 | continue try: | ||
994 | |||
995 | D I<range> | ||
996 | will disassemble/display a range of instructions. | ||
997 | |||
998 | ST addr 32 bit word | ||
999 | will store a 32 bit aligned address | ||
1000 | D T<range> | ||
1001 | will display the EBCDIC in an address (if you are that way inclined) | ||
1002 | D R<range> | ||
1003 | will display real addresses ( without DAT ) but with prefixing. | ||
1004 | |||
1005 | There are other complex options to display if you need to get at say home space | ||
1006 | but are in primary space the easiest thing to do is to temporarily | ||
1007 | modify the PSW to the other addressing mode, display the stuff & then | ||
1008 | restore it. | ||
1009 | |||
1010 | |||
1011 | |||
1012 | Hints | ||
1013 | ----- | ||
1014 | If you want to issue a debugger command without halting your virtual machine | ||
1015 | with the PA1 key try prefixing the command with #CP e.g.:: | ||
1016 | |||
1017 | #cp tr i pswa 2000 | ||
1018 | |||
1019 | also suffixing most debugger commands with RUN will cause them not | ||
1020 | to stop just display the mnemonic at the current instruction on the console. | ||
1021 | |||
1022 | If you have several breakpoints you want to put into your program & | ||
1023 | you get fed up of cross referencing with System.map | ||
1024 | you can do the following trick for several symbols. | ||
1025 | |||
1026 | :: | ||
1027 | |||
1028 | grep do_signal System.map | ||
1029 | |||
1030 | which emits the following among other things:: | ||
1031 | |||
1032 | 0001f4e0 T do_signal | ||
1033 | |||
1034 | now you can do:: | ||
1035 | |||
1036 | TR I PSWA 0001f4e0 cmd msg * do_signal | ||
1037 | |||
1038 | This sends a message to your own console each time do_signal is entered. | ||
1039 | ( As an aside I wrote a perl script once which automatically generated a REXX | ||
1040 | script with breakpoints on every kernel procedure, this isn't a good idea | ||
1041 | because there are thousands of these routines & VM can only set 255 breakpoints | ||
1042 | at a time so you nearly had to spend as long pruning the file down as you would | ||
1043 | entering the msgs by hand), however, the trick might be useful for a single | ||
1044 | object file. In the 3270 terminal emulator x3270 there is a very useful option | ||
1045 | in the file menu called "Save Screen In File" - this is very good for keeping a | ||
1046 | copy of traces. | ||
1047 | |||
1048 | From CMS help <command name> will give you online help on a particular command. | ||
1049 | e.g.:: | ||
1050 | |||
1051 | HELP DISPLAY | ||
1052 | |||
1053 | Also CP has a file called profile.exec which automatically gets called | ||
1054 | on startup of CMS ( like autoexec.bat ), keeping on a DOS analogy session | ||
1055 | CP has a feature similar to doskey, it may be useful for you to | ||
1056 | use profile.exec to define some keystrokes. | ||
1057 | |||
1058 | SET PF9 IMM B | ||
1059 | This does a single step in VM on pressing F8. | ||
1060 | |||
1061 | SET PF10 ^ | ||
1062 | This sets up the ^ key. | ||
1063 | which can be used for ^c (ctrl-c),^z (ctrl-z) which can't be typed | ||
1064 | directly into some 3270 consoles. | ||
1065 | |||
1066 | SET PF11 ^- | ||
1067 | This types the starting keystrokes for a sysrq see SysRq below. | ||
1068 | SET PF12 RETRIEVE | ||
1069 | This retrieves command history on pressing F12. | ||
1070 | |||
1071 | |||
1072 | Sometimes in VM the display is set up to scroll automatically this | ||
1073 | can be very annoying if there are messages you wish to look at | ||
1074 | to stop this do | ||
1075 | |||
1076 | TERM MORE 255 255 | ||
1077 | This will nearly stop automatic screen updates, however it will | ||
1078 | cause a denial of service if lots of messages go to the 3270 console, | ||
1079 | so it would be foolish to use this as the default on a production machine. | ||
1080 | |||
1081 | |||
1082 | Tracing particular processes | ||
1083 | ---------------------------- | ||
1084 | The kernel's text segment is intentionally at an address in memory that it will | ||
1085 | very seldom collide with text segments of user programs ( thanks Martin ), | ||
1086 | this simplifies debugging the kernel. | ||
1087 | However it is quite common for user processes to have addresses which collide | ||
1088 | this can make debugging a particular process under VM painful under normal | ||
1089 | circumstances as the process may change when doing a:: | ||
1090 | |||
1091 | TR I R <address range>. | ||
1092 | |||
1093 | Thankfully after reading VM's online help I figured out how to debug | ||
1094 | I particular process. | ||
1095 | |||
1096 | Your first problem is to find the STD ( segment table designation ) | ||
1097 | of the program you wish to debug. | ||
1098 | There are several ways you can do this here are a few | ||
1099 | |||
1100 | Run:: | ||
1101 | |||
1102 | objdump --syms <program to be debugged> | grep main | ||
1103 | |||
1104 | To get the address of main in the program. Then:: | ||
1105 | |||
1106 | tr i pswa <address of main> | ||
1107 | |||
1108 | Start the program, if VM drops to CP on what looks like the entry | ||
1109 | point of the main function this is most likely the process you wish to debug. | ||
1110 | Now do a D X13 or D XG13 on z/Architecture. | ||
1111 | |||
1112 | On 31 bit the STD is bits 1-19 ( the STO segment table origin ) | ||
1113 | & 25-31 ( the STL segment table length ) of CR13. | ||
1114 | |||
1115 | now type:: | ||
1116 | |||
1117 | TR I R STD <CR13's value> 0.7fffffff | ||
1118 | |||
1119 | e.g.:: | ||
1120 | |||
1121 | TR I R STD 8F32E1FF 0.7fffffff | ||
1122 | |||
1123 | Another very useful variation is:: | ||
1124 | |||
1125 | TR STORE INTO STD <CR13's value> <address range> | ||
1126 | |||
1127 | for finding out when a particular variable changes. | ||
1128 | |||
1129 | An alternative way of finding the STD of a currently running process | ||
1130 | is to do the following, ( this method is more complex but | ||
1131 | could be quite convenient if you aren't updating the kernel much & | ||
1132 | so your kernel structures will stay constant for a reasonable period of | ||
1133 | time ). | ||
1134 | |||
1135 | :: | ||
1136 | |||
1137 | grep task /proc/<pid>/status | ||
1138 | |||
1139 | from this you should see something like:: | ||
1140 | |||
1141 | task: 0f160000 ksp: 0f161de8 pt_regs: 0f161f68 | ||
1142 | |||
1143 | This now gives you a pointer to the task structure. | ||
1144 | |||
1145 | Now make:: | ||
1146 | |||
1147 | CC:="s390-gcc -g" kernel/sched.s | ||
1148 | |||
1149 | To get the task_struct stabinfo. | ||
1150 | |||
1151 | ( task_struct is defined in include/linux/sched.h ). | ||
1152 | |||
1153 | Now we want to look at | ||
1154 | task->active_mm->pgd | ||
1155 | |||
1156 | on my machine the active_mm in the task structure stab is | ||
1157 | active_mm:(4,12),672,32 | ||
1158 | |||
1159 | its offset is 672/8=84=0x54 | ||
1160 | |||
1161 | the pgd member in the mm_struct stab is | ||
1162 | pgd:(4,6)=*(29,5),96,32 | ||
1163 | so its offset is 96/8=12=0xc | ||
1164 | |||
1165 | so we'll:: | ||
1166 | |||
1167 | hexdump -s 0xf160054 /dev/mem | more | ||
1168 | |||
1169 | i.e. task_struct+active_mm offset | ||
1170 | to look at the active_mm member:: | ||
1171 | |||
1172 | f160054 0fee cc60 0019 e334 0000 0000 0000 0011 | ||
1173 | |||
1174 | :: | ||
1175 | |||
1176 | hexdump -s 0x0feecc6c /dev/mem | more | ||
1177 | |||
1178 | i.e. active_mm+pgd offset:: | ||
1179 | |||
1180 | feecc6c 0f2c 0000 0000 0001 0000 0001 0000 0010 | ||
1181 | |||
1182 | we get something like | ||
1183 | now do:: | ||
1184 | |||
1185 | TR I R STD <pgd|0x7f> 0.7fffffff | ||
1186 | |||
1187 | i.e. the 0x7f is added because the pgd only | ||
1188 | gives the page table origin & we need to set the low bits | ||
1189 | to the maximum possible segment table length. | ||
1190 | |||
1191 | :: | ||
1192 | |||
1193 | TR I R STD 0f2c007f 0.7fffffff | ||
1194 | |||
1195 | on z/Architecture you'll probably need to do:: | ||
1196 | |||
1197 | TR I R STD <pgd|0x7> 0.ffffffffffffffff | ||
1198 | |||
1199 | to set the TableType to 0x1 & the Table length to 3. | ||
1200 | |||
1201 | |||
1202 | |||
1203 | Tracing Program Exceptions | ||
1204 | -------------------------- | ||
1205 | If you get a crash which says something like | ||
1206 | illegal operation or specification exception followed by a register dump | ||
1207 | You can restart linux & trace these using the tr prog <range or value> trace | ||
1208 | option. | ||
1209 | |||
1210 | |||
1211 | The most common ones you will normally be tracing for is: | ||
1212 | |||
1213 | - 1=operation exception | ||
1214 | - 2=privileged operation exception | ||
1215 | - 4=protection exception | ||
1216 | - 5=addressing exception | ||
1217 | - 6=specification exception | ||
1218 | - 10=segment translation exception | ||
1219 | - 11=page translation exception | ||
1220 | |||
1221 | The full list of these is on page 22 of the current s/390 Reference Summary. | ||
1222 | e.g. | ||
1223 | |||
1224 | tr prog 10 will trace segment translation exceptions. | ||
1225 | |||
1226 | tr prog on its own will trace all program interruption codes. | ||
1227 | |||
1228 | Trace Sets | ||
1229 | ---------- | ||
1230 | On starting VM you are initially in the INITIAL trace set. | ||
1231 | You can do a Q TR to verify this. | ||
1232 | If you have a complex tracing situation where you wish to wait for instance | ||
1233 | till a driver is open before you start tracing IO, but know in your | ||
1234 | heart that you are going to have to make several runs through the code till you | ||
1235 | have a clue whats going on. | ||
1236 | |||
1237 | What you can do is:: | ||
1238 | |||
1239 | TR I PSWA <Driver open address> | ||
1240 | |||
1241 | hit b to continue till breakpoint | ||
1242 | |||
1243 | reach the breakpoint | ||
1244 | |||
1245 | now do your:: | ||
1246 | |||
1247 | TR GOTO B | ||
1248 | TR IO 7c08-7c09 inst int run | ||
1249 | |||
1250 | or whatever the IO channels you wish to trace are & hit b | ||
1251 | |||
1252 | To got back to the initial trace set do:: | ||
1253 | |||
1254 | TR GOTO INITIAL | ||
1255 | |||
1256 | & the TR I PSWA <Driver open address> will be the only active breakpoint again. | ||
1257 | |||
1258 | |||
1259 | Tracing linux syscalls under VM | ||
1260 | ------------------------------- | ||
1261 | Syscalls are implemented on Linux for S390 by the Supervisor call instruction | ||
1262 | (SVC). There 256 possibilities of these as the instruction is made up of a 0xA | ||
1263 | opcode and the second byte being the syscall number. They are traced using the | ||
1264 | simple command:: | ||
1265 | |||
1266 | TR SVC <Optional value or range> | ||
1267 | |||
1268 | the syscalls are defined in linux/arch/s390/include/asm/unistd.h | ||
1269 | e.g. to trace all file opens just do:: | ||
1270 | |||
1271 | TR SVC 5 ( as this is the syscall number of open ) | ||
1272 | |||
1273 | |||
1274 | SMP Specific commands | ||
1275 | --------------------- | ||
1276 | To find out how many cpus you have | ||
1277 | Q CPUS displays all the CPU's available to your virtual machine | ||
1278 | To find the cpu that the current cpu VM debugger commands are being directed at | ||
1279 | do Q CPU to change the current cpu VM debugger commands are being directed at | ||
1280 | do:: | ||
1281 | |||
1282 | CPU <desired cpu no> | ||
1283 | |||
1284 | On a SMP guest issue a command to all CPUs try prefixing the command with cpu | ||
1285 | all. To issue a command to a particular cpu try cpu <cpu number> e.g.:: | ||
1286 | |||
1287 | CPU 01 TR I R 2000.3000 | ||
1288 | |||
1289 | If you are running on a guest with several cpus & you have a IO related problem | ||
1290 | & cannot follow the flow of code but you know it isn't smp related. | ||
1291 | |||
1292 | from the bash prompt issue:: | ||
1293 | |||
1294 | shutdown -h now or halt. | ||
1295 | |||
1296 | do a:: | ||
1297 | |||
1298 | Q CPUS | ||
1299 | |||
1300 | to find out how many cpus you have detach each one of them from cp except | ||
1301 | cpu 0 by issuing a:: | ||
1302 | |||
1303 | DETACH CPU 01-(number of cpus in configuration) | ||
1304 | |||
1305 | & boot linux again. | ||
1306 | |||
1307 | TR SIGP | ||
1308 | will trace inter processor signal processor instructions. | ||
1309 | |||
1310 | DEFINE CPU 01-(number in configuration) | ||
1311 | will get your guests cpus back. | ||
1312 | |||
1313 | |||
1314 | Help for displaying ascii textstrings | ||
1315 | ------------------------------------- | ||
1316 | On the very latest VM Nucleus'es VM can now display ascii | ||
1317 | ( thanks Neale for the hint ) by doing:: | ||
1318 | |||
1319 | D TX<lowaddr>.<len> | ||
1320 | |||
1321 | e.g.:: | ||
1322 | |||
1323 | D TX0.100 | ||
1324 | |||
1325 | Alternatively | ||
1326 | ============= | ||
1327 | Under older VM debuggers (I love EBDIC too) you can use following little | ||
1328 | program which converts a command line of hex digits to ascii text. It can be | ||
1329 | compiled under linux and you can copy the hex digits from your x3270 terminal | ||
1330 | to your xterm if you are debugging from a linuxbox. | ||
1331 | |||
1332 | This is quite useful when looking at a parameter passed in as a text string | ||
1333 | under VM ( unless you are good at decoding ASCII in your head ). | ||
1334 | |||
1335 | e.g. consider tracing an open syscall:: | ||
1336 | |||
1337 | TR SVC 5 | ||
1338 | |||
1339 | We have stopped at a breakpoint:: | ||
1340 | |||
1341 | 000151B0' SVC 0A05 -> 0001909A' CC 0 | ||
1342 | |||
1343 | D 20.8 to check the SVC old psw in the prefix area and see was it from userspace | ||
1344 | (for the layout of the prefix area consult the "Fixed Storage Locations" | ||
1345 | chapter of the s/390 Reference Summary if you have it available). | ||
1346 | |||
1347 | :: | ||
1348 | |||
1349 | V00000020 070C2000 800151B2 | ||
1350 | |||
1351 | The problem state bit wasn't set & it's also too early in the boot sequence | ||
1352 | for it to be a userspace SVC if it was we would have to temporarily switch the | ||
1353 | psw to user space addressing so we could get at the first parameter of the open | ||
1354 | in gpr2. | ||
1355 | |||
1356 | Next do a:: | ||
1357 | |||
1358 | D G2 | ||
1359 | GPR 2 = 00014CB4 | ||
1360 | |||
1361 | Now display what gpr2 is pointing to:: | ||
1362 | |||
1363 | D 00014CB4.20 | ||
1364 | V00014CB4 2F646576 2F636F6E 736F6C65 00001BF5 | ||
1365 | V00014CC4 FC00014C B4001001 E0001000 B8070707 | ||
1366 | |||
1367 | Now copy the text till the first 00 hex ( which is the end of the string | ||
1368 | to an xterm & do hex2ascii on it:: | ||
1369 | |||
1370 | hex2ascii 2F646576 2F636F6E 736F6C65 00 | ||
1371 | |||
1372 | outputs:: | ||
1373 | |||
1374 | Decoded Hex:=/ d e v / c o n s o l e 0x00 | ||
1375 | |||
1376 | We were opening the console device, | ||
1377 | |||
1378 | You can compile the code below yourself for practice :-), | ||
1379 | |||
1380 | :: | ||
1381 | |||
1382 | /* | ||
1383 | * hex2ascii.c | ||
1384 | * a useful little tool for converting a hexadecimal command line to ascii | ||
1385 | * | ||
1386 | * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) | ||
1387 | * (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation. | ||
1388 | */ | ||
1389 | #include <stdio.h> | ||
1390 | |||
1391 | int main(int argc,char *argv[]) | ||
1392 | { | ||
1393 | int cnt1,cnt2,len,toggle=0; | ||
1394 | int startcnt=1; | ||
1395 | unsigned char c,hex; | ||
1396 | |||
1397 | if(argc>1&&(strcmp(argv[1],"-a")==0)) | ||
1398 | startcnt=2; | ||
1399 | printf("Decoded Hex:="); | ||
1400 | for(cnt1=startcnt;cnt1<argc;cnt1++) | ||
1401 | { | ||
1402 | len=strlen(argv[cnt1]); | ||
1403 | for(cnt2=0;cnt2<len;cnt2++) | ||
1404 | { | ||
1405 | c=argv[cnt1][cnt2]; | ||
1406 | if(c>='0'&&c<='9') | ||
1407 | c=c-'0'; | ||
1408 | if(c>='A'&&c<='F') | ||
1409 | c=c-'A'+10; | ||
1410 | if(c>='a'&&c<='f') | ||
1411 | c=c-'a'+10; | ||
1412 | switch(toggle) | ||
1413 | { | ||
1414 | case 0: | ||
1415 | hex=c<<4; | ||
1416 | toggle=1; | ||
1417 | break; | ||
1418 | case 1: | ||
1419 | hex+=c; | ||
1420 | if(hex<32||hex>127) | ||
1421 | { | ||
1422 | if(startcnt==1) | ||
1423 | printf("0x%02X ",(int)hex); | ||
1424 | else | ||
1425 | printf("."); | ||
1426 | } | ||
1427 | else | ||
1428 | { | ||
1429 | printf("%c",hex); | ||
1430 | if(startcnt==1) | ||
1431 | printf(" "); | ||
1432 | } | ||
1433 | toggle=0; | ||
1434 | break; | ||
1435 | } | ||
1436 | } | ||
1437 | } | ||
1438 | printf("\n"); | ||
1439 | } | ||
1440 | |||
1441 | |||
1442 | |||
1443 | |||
1444 | Stack tracing under VM | ||
1445 | ---------------------- | ||
1446 | A basic backtrace | ||
1447 | ----------------- | ||
1448 | |||
1449 | Here are the tricks I use 9 out of 10 times it works pretty well, | ||
1450 | |||
1451 | When your backchain reaches a dead end | ||
1452 | -------------------------------------- | ||
1453 | This can happen when an exception happens in the kernel and the kernel is | ||
1454 | entered twice. If you reach the NULL pointer at the end of the back chain you | ||
1455 | should be able to sniff further back if you follow the following tricks. | ||
1456 | 1) A kernel address should be easy to recognise since it is in | ||
1457 | primary space & the problem state bit isn't set & also | ||
1458 | The Hi bit of the address is set. | ||
1459 | 2) Another backchain should also be easy to recognise since it is an | ||
1460 | address pointing to another address approximately 100 bytes or 0x70 hex | ||
1461 | behind the current stackpointer. | ||
1462 | |||
1463 | |||
1464 | Here is some practice. | ||
1465 | |||
1466 | boot the kernel & hit PA1 at some random time | ||
1467 | |||
1468 | d g to display the gprs, this should display something like:: | ||
1469 | |||
1470 | GPR 0 = 00000001 00156018 0014359C 00000000 | ||
1471 | GPR 4 = 00000001 001B8888 000003E0 00000000 | ||
1472 | GPR 8 = 00100080 00100084 00000000 000FE000 | ||
1473 | GPR 12 = 00010400 8001B2DC 8001B36A 000FFED8 | ||
1474 | |||
1475 | Note that GPR14 is a return address but as we are real men we are going to | ||
1476 | trace the stack. | ||
1477 | display 0x40 bytes after the stack pointer:: | ||
1478 | |||
1479 | V000FFED8 000FFF38 8001B838 80014C8E 000FFF38 | ||
1480 | V000FFEE8 00000000 00000000 000003E0 00000000 | ||
1481 | V000FFEF8 00100080 00100084 00000000 000FE000 | ||
1482 | V000FFF08 00010400 8001B2DC 8001B36A 000FFED8 | ||
1483 | |||
1484 | |||
1485 | Ah now look at whats in sp+56 (sp+0x38) this is 8001B36A our saved r14 if | ||
1486 | you look above at our stackframe & also agrees with GPR14. | ||
1487 | |||
1488 | now backchain:: | ||
1489 | |||
1490 | d 000FFF38.40 | ||
1491 | |||
1492 | we now are taking the contents of SP to get our first backchain:: | ||
1493 | |||
1494 | V000FFF38 000FFFA0 00000000 00014995 00147094 | ||
1495 | V000FFF48 00147090 001470A0 000003E0 00000000 | ||
1496 | V000FFF58 00100080 00100084 00000000 001BF1D0 | ||
1497 | V000FFF68 00010400 800149BA 80014CA6 000FFF38 | ||
1498 | |||
1499 | This displays a 2nd return address of 80014CA6 | ||
1500 | |||
1501 | now do:: | ||
1502 | |||
1503 | d 000FFFA0.40 | ||
1504 | |||
1505 | for our 3rd backchain:: | ||
1506 | |||
1507 | V000FFFA0 04B52002 0001107F 00000000 00000000 | ||
1508 | V000FFFB0 00000000 00000000 FF000000 0001107F | ||
1509 | V000FFFC0 00000000 00000000 00000000 00000000 | ||
1510 | V000FFFD0 00010400 80010802 8001085A 000FFFA0 | ||
1511 | |||
1512 | |||
1513 | our 3rd return address is 8001085A | ||
1514 | |||
1515 | as the 04B52002 looks suspiciously like rubbish it is fair to assume that the | ||
1516 | kernel entry routines for the sake of optimisation don't set up a backchain. | ||
1517 | |||
1518 | now look at System.map to see if the addresses make any sense:: | ||
1519 | |||
1520 | grep -i 0001b3 System.map | ||
1521 | |||
1522 | outputs among other things:: | ||
1523 | |||
1524 | 0001b304 T cpu_idle | ||
1525 | |||
1526 | so 8001B36A | ||
1527 | is cpu_idle+0x66 ( quiet the cpu is asleep, don't wake it ) | ||
1528 | |||
1529 | :: | ||
1530 | |||
1531 | grep -i 00014 System.map | ||
1532 | |||
1533 | produces among other things:: | ||
1534 | |||
1535 | 00014a78 T start_kernel | ||
1536 | |||
1537 | so 0014CA6 is start_kernel+some hex number I can't add in my head. | ||
1538 | |||
1539 | :: | ||
1540 | |||
1541 | grep -i 00108 System.map | ||
1542 | |||
1543 | this produces:: | ||
1544 | |||
1545 | 00010800 T _stext | ||
1546 | |||
1547 | so 8001085A is _stext+0x5a | ||
1548 | |||
1549 | Congrats you've done your first backchain. | ||
1550 | |||
1551 | |||
1552 | |||
1553 | s/390 & z/Architecture IO Overview | ||
1554 | ================================== | ||
1555 | |||
1556 | I am not going to give a course in 390 IO architecture as this would take me | ||
1557 | quite a while and I'm no expert. Instead I'll give a 390 IO architecture | ||
1558 | summary for Dummies. If you have the s/390 principles of operation available | ||
1559 | read this instead. If nothing else you may find a few useful keywords in here | ||
1560 | and be able to use them on a web search engine to find more useful information. | ||
1561 | |||
1562 | Unlike other bus architectures modern 390 systems do their IO using mostly | ||
1563 | fibre optics and devices such as tapes and disks can be shared between several | ||
1564 | mainframes. Also S390 can support up to 65536 devices while a high end PC based | ||
1565 | system might be choking with around 64. | ||
1566 | |||
1567 | Here is some of the common IO terminology: | ||
1568 | |||
1569 | Subchannel: | ||
1570 | This is the logical number most IO commands use to talk to an IO device. There | ||
1571 | can be up to 0x10000 (65536) of these in a configuration, typically there are a | ||
1572 | few hundred. Under VM for simplicity they are allocated contiguously, however | ||
1573 | on the native hardware they are not. They typically stay consistent between | ||
1574 | boots provided no new hardware is inserted or removed. | ||
1575 | |||
1576 | Under Linux for s390 we use these as IRQ's and also when issuing an IO command | ||
1577 | (CLEAR SUBCHANNEL, HALT SUBCHANNEL, MODIFY SUBCHANNEL, RESUME SUBCHANNEL, | ||
1578 | START SUBCHANNEL, STORE SUBCHANNEL and TEST SUBCHANNEL). We use this as the ID | ||
1579 | of the device we wish to talk to. The most important of these instructions are | ||
1580 | START SUBCHANNEL (to start IO), TEST SUBCHANNEL (to check whether the IO | ||
1581 | completed successfully) and HALT SUBCHANNEL (to kill IO). A subchannel can have | ||
1582 | up to 8 channel paths to a device, this offers redundancy if one is not | ||
1583 | available. | ||
1584 | |||
1585 | Device Number: | ||
1586 | This number remains static and is closely tied to the hardware. There are 65536 | ||
1587 | of these, made up of a CHPID (Channel Path ID, the most significant 8 bits) and | ||
1588 | another lsb 8 bits. These remain static even if more devices are inserted or | ||
1589 | removed from the hardware. There is a 1 to 1 mapping between subchannels and | ||
1590 | device numbers, provided devices aren't inserted or removed. | ||
1591 | |||
1592 | Channel Control Words: | ||
1593 | CCWs are linked lists of instructions initially pointed to by an operation | ||
1594 | request block (ORB), which is initially given to Start Subchannel (SSCH) | ||
1595 | command along with the subchannel number for the IO subsystem to process | ||
1596 | while the CPU continues executing normal code. | ||
1597 | CCWs come in two flavours, Format 0 (24 bit for backward compatibility) and | ||
1598 | Format 1 (31 bit). These are typically used to issue read and write (and many | ||
1599 | other) instructions. They consist of a length field and an absolute address | ||
1600 | field. | ||
1601 | |||
1602 | Each IO typically gets 1 or 2 interrupts, one for channel end (primary status) | ||
1603 | when the channel is idle, and the second for device end (secondary status). | ||
1604 | Sometimes you get both concurrently. You check how the IO went on by issuing a | ||
1605 | TEST SUBCHANNEL at each interrupt, from which you receive an Interruption | ||
1606 | response block (IRB). If you get channel and device end status in the IRB | ||
1607 | without channel checks etc. your IO probably went okay. If you didn't you | ||
1608 | probably need to examine the IRB, extended status word etc. | ||
1609 | If an error occurs, more sophisticated control units have a facility known as | ||
1610 | concurrent sense. This means that if an error occurs Extended sense information | ||
1611 | will be presented in the Extended status word in the IRB. If not you have to | ||
1612 | issue a subsequent SENSE CCW command after the test subchannel. | ||
1613 | |||
1614 | |||
1615 | TPI (Test pending interrupt) can also be used for polled IO, but in | ||
1616 | multitasking multiprocessor systems it isn't recommended except for | ||
1617 | checking special cases (i.e. non looping checks for pending IO etc.). | ||
1618 | |||
1619 | Store Subchannel and Modify Subchannel can be used to examine and modify | ||
1620 | operating characteristics of a subchannel (e.g. channel paths). | ||
1621 | |||
1622 | Other IO related Terms: | ||
1623 | |||
1624 | Sysplex: | ||
1625 | S390's Clustering Technology | ||
1626 | QDIO: | ||
1627 | S390's new high speed IO architecture to support devices such as gigabit | ||
1628 | ethernet, this architecture is also designed to be forward compatible with | ||
1629 | upcoming 64 bit machines. | ||
1630 | |||
1631 | |||
1632 | General Concepts | ||
1633 | ---------------- | ||
1634 | |||
1635 | Input Output Processors (IOP's) are responsible for communicating between | ||
1636 | the mainframe CPU's & the channel & relieve the mainframe CPU's from the | ||
1637 | burden of communicating with IO devices directly, this allows the CPU's to | ||
1638 | concentrate on data processing. | ||
1639 | |||
1640 | IOP's can use one or more links ( known as channel paths ) to talk to each | ||
1641 | IO device. It first checks for path availability & chooses an available one, | ||
1642 | then starts ( & sometimes terminates IO ). | ||
1643 | There are two types of channel path: ESCON & the Parallel IO interface. | ||
1644 | |||
1645 | IO devices are attached to control units, control units provide the | ||
1646 | logic to interface the channel paths & channel path IO protocols to | ||
1647 | the IO devices, they can be integrated with the devices or housed separately | ||
1648 | & often talk to several similar devices ( typical examples would be raid | ||
1649 | controllers or a control unit which connects to 1000 3270 terminals ):: | ||
1650 | |||
1651 | |||
1652 | +---------------------------------------------------------------+ | ||
1653 | | +-----+ +-----+ +-----+ +-----+ +----------+ +----------+ | | ||
1654 | | | CPU | | CPU | | CPU | | CPU | | Main | | Expanded | | | ||
1655 | | | | | | | | | | | Memory | | Storage | | | ||
1656 | | +-----+ +-----+ +-----+ +-----+ +----------+ +----------+ | | ||
1657 | |---------------------------------------------------------------+ | ||
1658 | | IOP | IOP | IOP | | ||
1659 | |--------------------------------------------------------------- | ||
1660 | | C | C | C | C | C | C | C | C | C | C | C | C | C | C | C | C | | ||
1661 | ---------------------------------------------------------------- | ||
1662 | || || | ||
1663 | || Bus & Tag Channel Path || ESCON | ||
1664 | || ====================== || Channel | ||
1665 | || || || || Path | ||
1666 | +----------+ +----------+ +----------+ | ||
1667 | | | | | | | | ||
1668 | | CU | | CU | | CU | | ||
1669 | | | | | | | | ||
1670 | +----------+ +----------+ +----------+ | ||
1671 | | | | | | | ||
1672 | +----------+ +----------+ +----------+ +----------+ +----------+ | ||
1673 | |I/O Device| |I/O Device| |I/O Device| |I/O Device| |I/O Device| | ||
1674 | +----------+ +----------+ +----------+ +----------+ +----------+ | ||
1675 | CPU = Central Processing Unit | ||
1676 | C = Channel | ||
1677 | IOP = IP Processor | ||
1678 | CU = Control Unit | ||
1679 | |||
1680 | The 390 IO systems come in 2 flavours the current 390 machines support both | ||
1681 | |||
1682 | The Older 360 & 370 Interface,sometimes called the Parallel I/O interface, | ||
1683 | sometimes called Bus-and Tag & sometimes Original Equipment Manufacturers | ||
1684 | Interface (OEMI). | ||
1685 | |||
1686 | This byte wide Parallel channel path/bus has parity & data on the "Bus" cable | ||
1687 | and control lines on the "Tag" cable. These can operate in byte multiplex mode | ||
1688 | for sharing between several slow devices or burst mode and monopolize the | ||
1689 | channel for the whole burst. Up to 256 devices can be addressed on one of these | ||
1690 | cables. These cables are about one inch in diameter. The maximum unextended | ||
1691 | length supported by these cables is 125 Meters but this can be extended up to | ||
1692 | 2km with a fibre optic channel extended such as a 3044. The maximum burst speed | ||
1693 | supported is 4.5 megabytes per second. However, some really old processors | ||
1694 | support only transfer rates of 3.0, 2.0 & 1.0 MB/sec. | ||
1695 | One of these paths can be daisy chained to up to 8 control units. | ||
1696 | |||
1697 | |||
1698 | ESCON if fibre optic it is also called FICON | ||
1699 | Was introduced by IBM in 1990. Has 2 fibre optic cables and uses either leds or | ||
1700 | lasers for communication at a signaling rate of up to 200 megabits/sec. As | ||
1701 | 10bits are transferred for every 8 bits info this drops to 160 megabits/sec | ||
1702 | and to 18.6 Megabytes/sec once control info and CRC are added. ESCON only | ||
1703 | operates in burst mode. | ||
1704 | |||
1705 | ESCONs typical max cable length is 3km for the led version and 20km for the | ||
1706 | laser version known as XDF (extended distance facility). This can be further | ||
1707 | extended by using an ESCON director which triples the above mentioned ranges. | ||
1708 | Unlike Bus & Tag as ESCON is serial it uses a packet switching architecture, | ||
1709 | the standard Bus & Tag control protocol is however present within the packets. | ||
1710 | Up to 256 devices can be attached to each control unit that uses one of these | ||
1711 | interfaces. | ||
1712 | |||
1713 | Common 390 Devices include: | ||
1714 | Network adapters typically OSA2,3172's,2116's & OSA-E gigabit ethernet adapters, | ||
1715 | Consoles 3270 & 3215 (a teletype emulated under linux for a line mode console). | ||
1716 | DASD's direct access storage devices ( otherwise known as hard disks ). | ||
1717 | Tape Drives. | ||
1718 | CTC ( Channel to Channel Adapters ), | ||
1719 | ESCON or Parallel Cables used as a very high speed serial link | ||
1720 | between 2 machines. | ||
1721 | |||
1722 | |||
1723 | Debugging IO on s/390 & z/Architecture under VM | ||
1724 | =============================================== | ||
1725 | |||
1726 | Now we are ready to go on with IO tracing commands under VM | ||
1727 | |||
1728 | A few self explanatory queries:: | ||
1729 | |||
1730 | Q OSA | ||
1731 | Q CTC | ||
1732 | Q DISK ( This command is CMS specific ) | ||
1733 | Q DASD | ||
1734 | |||
1735 | Q OSA on my machine returns:: | ||
1736 | |||
1737 | OSA 7C08 ON OSA 7C08 SUBCHANNEL = 0000 | ||
1738 | OSA 7C09 ON OSA 7C09 SUBCHANNEL = 0001 | ||
1739 | OSA 7C14 ON OSA 7C14 SUBCHANNEL = 0002 | ||
1740 | OSA 7C15 ON OSA 7C15 SUBCHANNEL = 0003 | ||
1741 | |||
1742 | If you have a guest with certain privileges you may be able to see devices | ||
1743 | which don't belong to you. To avoid this, add the option V. | ||
1744 | e.g.:: | ||
1745 | |||
1746 | Q V OSA | ||
1747 | |||
1748 | Now using the device numbers returned by this command we will | ||
1749 | Trace the io starting up on the first device 7c08 & 7c09 | ||
1750 | In our simplest case we can trace the | ||
1751 | start subchannels | ||
1752 | like TR SSCH 7C08-7C09 | ||
1753 | or the halt subchannels | ||
1754 | or TR HSCH 7C08-7C09 | ||
1755 | MSCH's ,STSCH's I think you can guess the rest | ||
1756 | |||
1757 | A good trick is tracing all the IO's and CCWS and spooling them into the reader | ||
1758 | of another VM guest so he can ftp the logfile back to his own machine. I'll do | ||
1759 | a small bit of this and give you a look at the output. | ||
1760 | |||
1761 | 1) Spool stdout to VM reader:: | ||
1762 | |||
1763 | SP PRT TO (another vm guest ) or * for the local vm guest | ||
1764 | |||
1765 | 2) Fill the reader with the trace:: | ||
1766 | |||
1767 | TR IO 7c08-7c09 INST INT CCW PRT RUN | ||
1768 | |||
1769 | 3) Start up linux:: | ||
1770 | |||
1771 | i 00c | ||
1772 | 4) Finish the trace:: | ||
1773 | |||
1774 | TR END | ||
1775 | |||
1776 | 5) close the reader:: | ||
1777 | |||
1778 | C PRT | ||
1779 | |||
1780 | 6) list reader contents:: | ||
1781 | |||
1782 | RDRLIST | ||
1783 | |||
1784 | 7) copy it to linux4's minidisk:: | ||
1785 | |||
1786 | RECEIVE / LOG TXT A1 ( replace | ||
1787 | |||
1788 | 8) | ||
1789 | filel & press F11 to look at it | ||
1790 | You should see something like:: | ||
1791 | |||
1792 | 00020942' SSCH B2334000 0048813C CC 0 SCH 0000 DEV 7C08 | ||
1793 | CPA 000FFDF0 PARM 00E2C9C4 KEY 0 FPI C0 LPM 80 | ||
1794 | CCW 000FFDF0 E4200100 00487FE8 0000 E4240100 ........ | ||
1795 | IDAL 43D8AFE8 | ||
1796 | IDAL 0FB76000 | ||
1797 | 00020B0A' I/O DEV 7C08 -> 000197BC' SCH 0000 PARM 00E2C9C4 | ||
1798 | 00021628' TSCH B2354000 >> 00488164 CC 0 SCH 0000 DEV 7C08 | ||
1799 | CCWA 000FFDF8 DEV STS 0C SCH STS 00 CNT 00EC | ||
1800 | KEY 0 FPI C0 CC 0 CTLS 4007 | ||
1801 | 00022238' STSCH B2344000 >> 00488108 CC 0 SCH 0000 DEV 7C08 | ||
1802 | |||
1803 | If you don't like messing up your readed ( because you possibly booted from it ) | ||
1804 | you can alternatively spool it to another readers guest. | ||
1805 | |||
1806 | |||
1807 | Other common VM device related commands | ||
1808 | --------------------------------------------- | ||
1809 | These commands are listed only because they have | ||
1810 | been of use to me in the past & may be of use to | ||
1811 | you too. For more complete info on each of the commands | ||
1812 | use type HELP <command> from CMS. | ||
1813 | |||
1814 | detaching devices:: | ||
1815 | |||
1816 | DET <devno range> | ||
1817 | ATT <devno range> <guest> | ||
1818 | |||
1819 | attach a device to guest * for your own guest | ||
1820 | |||
1821 | READY <devno> | ||
1822 | cause VM to issue a fake interrupt. | ||
1823 | |||
1824 | The VARY command is normally only available to VM administrators:: | ||
1825 | |||
1826 | VARY ON PATH <path> TO <devno range> | ||
1827 | VARY OFF PATH <PATH> FROM <devno range> | ||
1828 | |||
1829 | This is used to switch on or off channel paths to devices. | ||
1830 | |||
1831 | Q CHPID <channel path ID> | ||
1832 | This displays state of devices using this channel path | ||
1833 | |||
1834 | D SCHIB <subchannel> | ||
1835 | This displays the subchannel information SCHIB block for the device. | ||
1836 | this I believe is also only available to administrators. | ||
1837 | |||
1838 | DEFINE CTC <devno> | ||
1839 | defines a virtual CTC channel to channel connection | ||
1840 | 2 need to be defined on each guest for the CTC driver to use. | ||
1841 | |||
1842 | COUPLE devno userid remote devno | ||
1843 | Joins a local virtual device to a remote virtual device | ||
1844 | ( commonly used for the CTC driver ). | ||
1845 | |||
1846 | Building a VM ramdisk under CMS which linux can use:: | ||
1847 | |||
1848 | def vfb-<blocksize> <subchannel> <number blocks> | ||
1849 | |||
1850 | blocksize is commonly 4096 for linux. | ||
1851 | |||
1852 | Formatting it:: | ||
1853 | |||
1854 | format <subchannel> <driver letter e.g. x> (blksize <blocksize> | ||
1855 | |||
1856 | Sharing a disk between multiple guests:: | ||
1857 | |||
1858 | LINK userid devno1 devno2 mode password | ||
1859 | |||
1860 | |||
1861 | |||
1862 | GDB on S390 | ||
1863 | =========== | ||
1864 | N.B. if compiling for debugging gdb works better without optimisation | ||
1865 | ( see Compiling programs for debugging ) | ||
1866 | |||
1867 | invocation | ||
1868 | ---------- | ||
1869 | gdb <victim program> <optional corefile> | ||
1870 | |||
1871 | Online help | ||
1872 | ----------- | ||
1873 | help: gives help on commands | ||
1874 | |||
1875 | e.g.:: | ||
1876 | |||
1877 | help | ||
1878 | help display | ||
1879 | |||
1880 | Note gdb's online help is very good use it. | ||
1881 | |||
1882 | |||
1883 | Assembly | ||
1884 | -------- | ||
1885 | info registers: | ||
1886 | displays registers other than floating point. | ||
1887 | |||
1888 | info all-registers: | ||
1889 | displays floating points as well. | ||
1890 | |||
1891 | disassemble: | ||
1892 | disassembles | ||
1893 | |||
1894 | e.g.:: | ||
1895 | |||
1896 | disassemble without parameters will disassemble the current function | ||
1897 | disassemble $pc $pc+10 | ||
1898 | |||
1899 | Viewing & modifying variables | ||
1900 | ----------------------------- | ||
1901 | print or p: | ||
1902 | displays variable or register | ||
1903 | |||
1904 | e.g. p/x $sp will display the stack pointer | ||
1905 | |||
1906 | display: | ||
1907 | prints variable or register each time program stops | ||
1908 | |||
1909 | e.g.:: | ||
1910 | |||
1911 | display/x $pc will display the program counter | ||
1912 | display argc | ||
1913 | |||
1914 | undisplay: | ||
1915 | undo's display's | ||
1916 | |||
1917 | info breakpoints: | ||
1918 | shows all current breakpoints | ||
1919 | |||
1920 | info stack: | ||
1921 | shows stack back trace (if this doesn't work too well, I'll show | ||
1922 | you the stacktrace by hand below). | ||
1923 | |||
1924 | info locals: | ||
1925 | displays local variables. | ||
1926 | |||
1927 | info args: | ||
1928 | display current procedure arguments. | ||
1929 | |||
1930 | set args: | ||
1931 | will set argc & argv each time the victim program is invoked | ||
1932 | |||
1933 | e.g.:: | ||
1934 | |||
1935 | set <variable>=value | ||
1936 | set argc=100 | ||
1937 | set $pc=0 | ||
1938 | |||
1939 | |||
1940 | |||
1941 | Modifying execution | ||
1942 | ------------------- | ||
1943 | step: | ||
1944 | steps n lines of sourcecode | ||
1945 | |||
1946 | step | ||
1947 | steps 1 line. | ||
1948 | |||
1949 | step 100 | ||
1950 | steps 100 lines of code. | ||
1951 | |||
1952 | next: | ||
1953 | like step except this will not step into subroutines | ||
1954 | |||
1955 | stepi: | ||
1956 | steps a single machine code instruction. | ||
1957 | |||
1958 | e.g.:: | ||
1959 | |||
1960 | stepi 100 | ||
1961 | |||
1962 | nexti: | ||
1963 | steps a single machine code instruction but will not step into | ||
1964 | subroutines. | ||
1965 | |||
1966 | finish: | ||
1967 | will run until exit of the current routine | ||
1968 | |||
1969 | run: | ||
1970 | (re)starts a program | ||
1971 | |||
1972 | cont: | ||
1973 | continues a program | ||
1974 | |||
1975 | quit: | ||
1976 | exits gdb. | ||
1977 | |||
1978 | |||
1979 | breakpoints | ||
1980 | ------------ | ||
1981 | |||
1982 | break | ||
1983 | sets a breakpoint | ||
1984 | |||
1985 | e.g.:: | ||
1986 | |||
1987 | break main | ||
1988 | break *$pc | ||
1989 | break *0x400618 | ||
1990 | |||
1991 | Here's a really useful one for large programs | ||
1992 | |||
1993 | rbr | ||
1994 | Set a breakpoint for all functions matching REGEXP | ||
1995 | |||
1996 | e.g.:: | ||
1997 | |||
1998 | rbr 390 | ||
1999 | |||
2000 | will set a breakpoint with all functions with 390 in their name. | ||
2001 | |||
2002 | info breakpoints | ||
2003 | lists all breakpoints | ||
2004 | |||
2005 | delete: | ||
2006 | delete breakpoint by number or delete them all | ||
2007 | |||
2008 | e.g. | ||
2009 | |||
2010 | delete 1 | ||
2011 | will delete the first breakpoint | ||
2012 | |||
2013 | |||
2014 | delete | ||
2015 | will delete them all | ||
2016 | |||
2017 | watch: | ||
2018 | This will set a watchpoint ( usually hardware assisted ), | ||
2019 | |||
2020 | This will watch a variable till it changes | ||
2021 | |||
2022 | e.g. | ||
2023 | |||
2024 | watch cnt | ||
2025 | will watch the variable cnt till it changes. | ||
2026 | |||
2027 | As an aside unfortunately gdb's, architecture independent watchpoint code | ||
2028 | is inconsistent & not very good, watchpoints usually work but not always. | ||
2029 | |||
2030 | info watchpoints: | ||
2031 | Display currently active watchpoints | ||
2032 | |||
2033 | condition: ( another useful one ) | ||
2034 | Specify breakpoint number N to break only if COND is true. | ||
2035 | |||
2036 | Usage is `condition N COND`, where N is an integer and COND is an | ||
2037 | expression to be evaluated whenever breakpoint N is reached. | ||
2038 | |||
2039 | |||
2040 | |||
2041 | User defined functions/macros | ||
2042 | ----------------------------- | ||
2043 | define: ( Note this is very very useful,simple & powerful ) | ||
2044 | |||
2045 | usage define <name> <list of commands> end | ||
2046 | |||
2047 | examples which you should consider putting into .gdbinit in your home | ||
2048 | directory:: | ||
2049 | |||
2050 | define d | ||
2051 | stepi | ||
2052 | disassemble $pc $pc+10 | ||
2053 | end | ||
2054 | define e | ||
2055 | nexti | ||
2056 | disassemble $pc $pc+10 | ||
2057 | end | ||
2058 | |||
2059 | |||
2060 | Other hard to classify stuff | ||
2061 | ---------------------------- | ||
2062 | signal n: | ||
2063 | sends the victim program a signal. | ||
2064 | |||
2065 | e.g. `signal 3` will send a SIGQUIT. | ||
2066 | |||
2067 | info signals: | ||
2068 | what gdb does when the victim receives certain signals. | ||
2069 | |||
2070 | list: | ||
2071 | |||
2072 | e.g.: | ||
2073 | |||
2074 | list | ||
2075 | lists current function source | ||
2076 | list 1,10 | ||
2077 | list first 10 lines of current file. | ||
2078 | |||
2079 | list test.c:1,10 | ||
2080 | |||
2081 | |||
2082 | directory: | ||
2083 | Adds directories to be searched for source if gdb cannot find the source. | ||
2084 | (note it is a bit sensitive about slashes) | ||
2085 | |||
2086 | e.g. To add the root of the filesystem to the searchpath do:: | ||
2087 | |||
2088 | directory // | ||
2089 | |||
2090 | |||
2091 | call <function> | ||
2092 | This calls a function in the victim program, this is pretty powerful | ||
2093 | e.g. | ||
2094 | (gdb) call printf("hello world") | ||
2095 | outputs: | ||
2096 | $1 = 11 | ||
2097 | |||
2098 | You might now be thinking that the line above didn't work, something extra had | ||
2099 | to be done. | ||
2100 | (gdb) call fflush(stdout) | ||
2101 | hello world$2 = 0 | ||
2102 | As an aside the debugger also calls malloc & free under the hood | ||
2103 | to make space for the "hello world" string. | ||
2104 | |||
2105 | |||
2106 | |||
2107 | hints | ||
2108 | ----- | ||
2109 | 1) command completion works just like bash | ||
2110 | ( if you are a bad typist like me this really helps ) | ||
2111 | |||
2112 | e.g. hit br <TAB> & cursor up & down :-). | ||
2113 | |||
2114 | 2) if you have a debugging problem that takes a few steps to recreate | ||
2115 | put the steps into a file called .gdbinit in your current working directory | ||
2116 | if you have defined a few extra useful user defined commands put these in | ||
2117 | your home directory & they will be read each time gdb is launched. | ||
2118 | |||
2119 | A typical .gdbinit file might be.:: | ||
2120 | |||
2121 | break main | ||
2122 | run | ||
2123 | break runtime_exception | ||
2124 | cont | ||
2125 | |||
2126 | |||
2127 | stack chaining in gdb by hand | ||
2128 | ----------------------------- | ||
2129 | This is done using a the same trick described for VM:: | ||
2130 | |||
2131 | p/x (*($sp+56))&0x7fffffff | ||
2132 | |||
2133 | get the first backchain. | ||
2134 | |||
2135 | For z/Architecture | ||
2136 | Replace 56 with 112 & ignore the &0x7fffffff | ||
2137 | in the macros below & do nasty casts to longs like the following | ||
2138 | as gdb unfortunately deals with printed arguments as ints which | ||
2139 | messes up everything. | ||
2140 | |||
2141 | i.e. here is a 3rd backchain dereference:: | ||
2142 | |||
2143 | p/x *(long *)(***(long ***)$sp+112) | ||
2144 | |||
2145 | |||
2146 | this outputs:: | ||
2147 | |||
2148 | $5 = 0x528f18 | ||
2149 | |||
2150 | on my machine. | ||
2151 | |||
2152 | Now you can use:: | ||
2153 | |||
2154 | info symbol (*($sp+56))&0x7fffffff | ||
2155 | |||
2156 | you might see something like:: | ||
2157 | |||
2158 | rl_getc + 36 in section .text | ||
2159 | |||
2160 | telling you what is located at address 0x528f18 | ||
2161 | Now do:: | ||
2162 | |||
2163 | p/x (*(*$sp+56))&0x7fffffff | ||
2164 | |||
2165 | This outputs:: | ||
2166 | |||
2167 | $6 = 0x528ed0 | ||
2168 | |||
2169 | Now do:: | ||
2170 | |||
2171 | info symbol (*(*$sp+56))&0x7fffffff | ||
2172 | rl_read_key + 180 in section .text | ||
2173 | |||
2174 | now do:: | ||
2175 | |||
2176 | p/x (*(**$sp+56))&0x7fffffff | ||
2177 | |||
2178 | & so on. | ||
2179 | |||
2180 | Disassembling instructions without debug info | ||
2181 | --------------------------------------------- | ||
2182 | gdb typically complains if there is a lack of debugging | ||
2183 | symbols in the disassemble command with | ||
2184 | "No function contains specified address." To get around | ||
2185 | this do:: | ||
2186 | |||
2187 | x/<number lines to disassemble>xi <address> | ||
2188 | |||
2189 | e.g.:: | ||
2190 | |||
2191 | x/20xi 0x400730 | ||
2192 | |||
2193 | |||
2194 | |||
2195 | Note: | ||
2196 | Remember gdb has history just like bash you don't need to retype the | ||
2197 | whole line just use the up & down arrows. | ||
2198 | |||
2199 | |||
2200 | |||
2201 | For more info | ||
2202 | ------------- | ||
2203 | From your linuxbox do:: | ||
2204 | |||
2205 | man gdb | ||
2206 | |||
2207 | or:: | ||
2208 | |||
2209 | info gdb. | ||
2210 | |||
2211 | core dumps | ||
2212 | ---------- | ||
2213 | |||
2214 | What a core dump ? | ||
2215 | ^^^^^^^^^^^^^^^^^^ | ||
2216 | |||
2217 | A core dump is a file generated by the kernel (if allowed) which contains the | ||
2218 | registers and all active pages of the program which has crashed. | ||
2219 | |||
2220 | From this file gdb will allow you to look at the registers, stack trace and | ||
2221 | memory of the program as if it just crashed on your system. It is usually | ||
2222 | called core and created in the current working directory. | ||
2223 | |||
2224 | This is very useful in that a customer can mail a core dump to a technical | ||
2225 | support department and the technical support department can reconstruct what | ||
2226 | happened. Provided they have an identical copy of this program with debugging | ||
2227 | symbols compiled in and the source base of this build is available. | ||
2228 | |||
2229 | In short it is far more useful than something like a crash log could ever hope | ||
2230 | to be. | ||
2231 | |||
2232 | Why have I never seen one ? | ||
2233 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
2234 | |||
2235 | Probably because you haven't used the command:: | ||
2236 | |||
2237 | ulimit -c unlimited in bash | ||
2238 | |||
2239 | to allow core dumps, now do:: | ||
2240 | |||
2241 | ulimit -a | ||
2242 | |||
2243 | to verify that the limit was accepted. | ||
2244 | |||
2245 | A sample core dump | ||
2246 | To create this I'm going to do:: | ||
2247 | |||
2248 | ulimit -c unlimited | ||
2249 | gdb | ||
2250 | |||
2251 | to launch gdb (my victim app. ) now be bad & do the following from another | ||
2252 | telnet/xterm session to the same machine:: | ||
2253 | |||
2254 | ps -aux | grep gdb | ||
2255 | kill -SIGSEGV <gdb's pid> | ||
2256 | |||
2257 | or alternatively use `killall -SIGSEGV gdb` if you have the killall command. | ||
2258 | |||
2259 | Now look at the core dump:: | ||
2260 | |||
2261 | ./gdb core | ||
2262 | |||
2263 | Displays the following:: | ||
2264 | |||
2265 | GNU gdb 4.18 | ||
2266 | Copyright 1998 Free Software Foundation, Inc. | ||
2267 | GDB is free software, covered by the GNU General Public License, and you are | ||
2268 | welcome to change it and/or distribute copies of it under certain conditions. | ||
2269 | Type "show copying" to see the conditions. | ||
2270 | There is absolutely no warranty for GDB. Type "show warranty" for details. | ||
2271 | This GDB was configured as "s390-ibm-linux"... | ||
2272 | Core was generated by `./gdb'. | ||
2273 | Program terminated with signal 11, Segmentation fault. | ||
2274 | Reading symbols from /usr/lib/libncurses.so.4...done. | ||
2275 | Reading symbols from /lib/libm.so.6...done. | ||
2276 | Reading symbols from /lib/libc.so.6...done. | ||
2277 | Reading symbols from /lib/ld-linux.so.2...done. | ||
2278 | #0 0x40126d1a in read () from /lib/libc.so.6 | ||
2279 | Setting up the environment for debugging gdb. | ||
2280 | Breakpoint 1 at 0x4dc6f8: file utils.c, line 471. | ||
2281 | Breakpoint 2 at 0x4d87a4: file top.c, line 2609. | ||
2282 | (top-gdb) info stack | ||
2283 | #0 0x40126d1a in read () from /lib/libc.so.6 | ||
2284 | #1 0x528f26 in rl_getc (stream=0x7ffffde8) at input.c:402 | ||
2285 | #2 0x528ed0 in rl_read_key () at input.c:381 | ||
2286 | #3 0x5167e6 in readline_internal_char () at readline.c:454 | ||
2287 | #4 0x5168ee in readline_internal_charloop () at readline.c:507 | ||
2288 | #5 0x51692c in readline_internal () at readline.c:521 | ||
2289 | #6 0x5164fe in readline (prompt=0x7ffff810) | ||
2290 | at readline.c:349 | ||
2291 | #7 0x4d7a8a in command_line_input (prompt=0x564420 "(gdb) ", repeat=1, | ||
2292 | annotation_suffix=0x4d6b44 "prompt") at top.c:2091 | ||
2293 | #8 0x4d6cf0 in command_loop () at top.c:1345 | ||
2294 | #9 0x4e25bc in main (argc=1, argv=0x7ffffdf4) at main.c:635 | ||
2295 | |||
2296 | |||
2297 | LDD | ||
2298 | === | ||
2299 | This is a program which lists the shared libraries which a library needs, | ||
2300 | Note you also get the relocations of the shared library text segments which | ||
2301 | help when using objdump --source. | ||
2302 | |||
2303 | e.g.:: | ||
2304 | |||
2305 | ldd ./gdb | ||
2306 | |||
2307 | outputs:: | ||
2308 | |||
2309 | libncurses.so.4 => /usr/lib/libncurses.so.4 (0x40018000) | ||
2310 | libm.so.6 => /lib/libm.so.6 (0x4005e000) | ||
2311 | libc.so.6 => /lib/libc.so.6 (0x40084000) | ||
2312 | /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) | ||
2313 | |||
2314 | |||
2315 | Debugging shared libraries | ||
2316 | ========================== | ||
2317 | Most programs use shared libraries, however it can be very painful | ||
2318 | when you single step instruction into a function like printf for the | ||
2319 | first time & you end up in functions like _dl_runtime_resolve this is | ||
2320 | the ld.so doing lazy binding, lazy binding is a concept in ELF where | ||
2321 | shared library functions are not loaded into memory unless they are | ||
2322 | actually used, great for saving memory but a pain to debug. | ||
2323 | |||
2324 | To get around this either relink the program -static or exit gdb type | ||
2325 | export LD_BIND_NOW=true this will stop lazy binding & restart the gdb'ing | ||
2326 | the program in question. | ||
2327 | |||
2328 | |||
2329 | |||
2330 | Debugging modules | ||
2331 | ================= | ||
2332 | As modules are dynamically loaded into the kernel their address can be | ||
2333 | anywhere to get around this use the -m option with insmod to emit a load | ||
2334 | map which can be piped into a file if required. | ||
2335 | |||
2336 | The proc file system | ||
2337 | ==================== | ||
2338 | What is it ?. | ||
2339 | It is a filesystem created by the kernel with files which are created on demand | ||
2340 | by the kernel if read, or can be used to modify kernel parameters, | ||
2341 | it is a powerful concept. | ||
2342 | |||
2343 | e.g.:: | ||
2344 | |||
2345 | cat /proc/sys/net/ipv4/ip_forward | ||
2346 | |||
2347 | On my machine outputs:: | ||
2348 | |||
2349 | 0 | ||
2350 | |||
2351 | telling me ip_forwarding is not on to switch it on I can do:: | ||
2352 | |||
2353 | echo 1 > /proc/sys/net/ipv4/ip_forward | ||
2354 | |||
2355 | cat it again:: | ||
2356 | |||
2357 | cat /proc/sys/net/ipv4/ip_forward | ||
2358 | |||
2359 | On my machine now outputs:: | ||
2360 | |||
2361 | 1 | ||
2362 | |||
2363 | IP forwarding is on. | ||
2364 | |||
2365 | There is a lot of useful info in here best found by going in and having a look | ||
2366 | around, so I'll take you through some entries I consider important. | ||
2367 | |||
2368 | All the processes running on the machine have their own entry defined by | ||
2369 | /proc/<pid> | ||
2370 | |||
2371 | So lets have a look at the init process:: | ||
2372 | |||
2373 | cd /proc/1 | ||
2374 | cat cmdline | ||
2375 | |||
2376 | emits:: | ||
2377 | |||
2378 | init [2] | ||
2379 | |||
2380 | :: | ||
2381 | |||
2382 | cd /proc/1/fd | ||
2383 | |||
2384 | This contains numerical entries of all the open files, | ||
2385 | some of these you can cat e.g. stdout (2):: | ||
2386 | |||
2387 | cat /proc/29/maps | ||
2388 | |||
2389 | on my machine emits:: | ||
2390 | |||
2391 | 00400000-00478000 r-xp 00000000 5f:00 4103 /bin/bash | ||
2392 | 00478000-0047e000 rw-p 00077000 5f:00 4103 /bin/bash | ||
2393 | 0047e000-00492000 rwxp 00000000 00:00 0 | ||
2394 | 40000000-40015000 r-xp 00000000 5f:00 14382 /lib/ld-2.1.2.so | ||
2395 | 40015000-40016000 rw-p 00014000 5f:00 14382 /lib/ld-2.1.2.so | ||
2396 | 40016000-40017000 rwxp 00000000 00:00 0 | ||
2397 | 40017000-40018000 rw-p 00000000 00:00 0 | ||
2398 | 40018000-4001b000 r-xp 00000000 5f:00 14435 /lib/libtermcap.so.2.0.8 | ||
2399 | 4001b000-4001c000 rw-p 00002000 5f:00 14435 /lib/libtermcap.so.2.0.8 | ||
2400 | 4001c000-4010d000 r-xp 00000000 5f:00 14387 /lib/libc-2.1.2.so | ||
2401 | 4010d000-40111000 rw-p 000f0000 5f:00 14387 /lib/libc-2.1.2.so | ||
2402 | 40111000-40114000 rw-p 00000000 00:00 0 | ||
2403 | 40114000-4011e000 r-xp 00000000 5f:00 14408 /lib/libnss_files-2.1.2.so | ||
2404 | 4011e000-4011f000 rw-p 00009000 5f:00 14408 /lib/libnss_files-2.1.2.so | ||
2405 | 7fffd000-80000000 rwxp ffffe000 00:00 0 | ||
2406 | |||
2407 | |||
2408 | Showing us the shared libraries init uses where they are in memory | ||
2409 | & memory access permissions for each virtual memory area. | ||
2410 | |||
2411 | /proc/1/cwd is a softlink to the current working directory. | ||
2412 | |||
2413 | /proc/1/root is the root of the filesystem for this process. | ||
2414 | |||
2415 | /proc/1/mem is the current running processes memory which you | ||
2416 | can read & write to like a file. | ||
2417 | |||
2418 | strace uses this sometimes as it is a bit faster than the | ||
2419 | rather inefficient ptrace interface for peeking at DATA. | ||
2420 | |||
2421 | :: | ||
2422 | |||
2423 | cat status | ||
2424 | |||
2425 | Name: init | ||
2426 | State: S (sleeping) | ||
2427 | Pid: 1 | ||
2428 | PPid: 0 | ||
2429 | Uid: 0 0 0 0 | ||
2430 | Gid: 0 0 0 0 | ||
2431 | Groups: | ||
2432 | VmSize: 408 kB | ||
2433 | VmLck: 0 kB | ||
2434 | VmRSS: 208 kB | ||
2435 | VmData: 24 kB | ||
2436 | VmStk: 8 kB | ||
2437 | VmExe: 368 kB | ||
2438 | VmLib: 0 kB | ||
2439 | SigPnd: 0000000000000000 | ||
2440 | SigBlk: 0000000000000000 | ||
2441 | SigIgn: 7fffffffd7f0d8fc | ||
2442 | SigCgt: 00000000280b2603 | ||
2443 | CapInh: 00000000fffffeff | ||
2444 | CapPrm: 00000000ffffffff | ||
2445 | CapEff: 00000000fffffeff | ||
2446 | |||
2447 | User PSW: 070de000 80414146 | ||
2448 | task: 004b6000 tss: 004b62d8 ksp: 004b7ca8 pt_regs: 004b7f68 | ||
2449 | User GPRS: | ||
2450 | 00000400 00000000 0000000b 7ffffa90 | ||
2451 | 00000000 00000000 00000000 0045d9f4 | ||
2452 | 0045cafc 7ffffa90 7fffff18 0045cb08 | ||
2453 | 00010400 804039e8 80403af8 7ffff8b0 | ||
2454 | User ACRS: | ||
2455 | 00000000 00000000 00000000 00000000 | ||
2456 | 00000001 00000000 00000000 00000000 | ||
2457 | 00000000 00000000 00000000 00000000 | ||
2458 | 00000000 00000000 00000000 00000000 | ||
2459 | Kernel BackChain CallChain BackChain CallChain | ||
2460 | 004b7ca8 8002bd0c 004b7d18 8002b92c | ||
2461 | 004b7db8 8005cd50 004b7e38 8005d12a | ||
2462 | 004b7f08 80019114 | ||
2463 | |||
2464 | Showing among other things memory usage & status of some signals & | ||
2465 | the processes'es registers from the kernel task_structure | ||
2466 | as well as a backchain which may be useful if a process crashes | ||
2467 | in the kernel for some unknown reason. | ||
2468 | |||
2469 | Some driver debugging techniques | ||
2470 | ================================ | ||
2471 | debug feature | ||
2472 | ------------- | ||
2473 | Some of our drivers now support a "debug feature" in | ||
2474 | /proc/s390dbf see s390dbf.txt in the linux/Documentation directory | ||
2475 | for more info. | ||
2476 | |||
2477 | e.g. | ||
2478 | to switch on the lcs "debug feature":: | ||
2479 | |||
2480 | echo 5 > /proc/s390dbf/lcs/level | ||
2481 | |||
2482 | & then after the error occurred:: | ||
2483 | |||
2484 | cat /proc/s390dbf/lcs/sprintf >/logfile | ||
2485 | |||
2486 | the logfile now contains some information which may help | ||
2487 | tech support resolve a problem in the field. | ||
2488 | |||
2489 | |||
2490 | |||
2491 | high level debugging network drivers | ||
2492 | ------------------------------------ | ||
2493 | ifconfig is a quite useful command | ||
2494 | it gives the current state of network drivers. | ||
2495 | |||
2496 | If you suspect your network device driver is dead | ||
2497 | one way to check is type:: | ||
2498 | |||
2499 | ifconfig <network device> | ||
2500 | |||
2501 | e.g. tr0 | ||
2502 | |||
2503 | You should see something like:: | ||
2504 | |||
2505 | ifconfig tr0 | ||
2506 | tr0 Link encap:16/4 Mbps Token Ring (New) HWaddr 00:04:AC:20:8E:48 | ||
2507 | inet addr:9.164.185.132 Bcast:9.164.191.255 Mask:255.255.224.0 | ||
2508 | UP BROADCAST RUNNING MULTICAST MTU:2000 Metric:1 | ||
2509 | RX packets:246134 errors:0 dropped:0 overruns:0 frame:0 | ||
2510 | TX packets:5 errors:0 dropped:0 overruns:0 carrier:0 | ||
2511 | collisions:0 txqueuelen:100 | ||
2512 | |||
2513 | if the device doesn't say up | ||
2514 | try:: | ||
2515 | |||
2516 | /etc/rc.d/init.d/network start | ||
2517 | |||
2518 | ( this starts the network stack & hopefully calls ifconfig tr0 up ). | ||
2519 | ifconfig looks at the output of /proc/net/dev and presents it in a more | ||
2520 | presentable form. | ||
2521 | |||
2522 | Now ping the device from a machine in the same subnet. | ||
2523 | |||
2524 | if the RX packets count & TX packets counts don't increment you probably | ||
2525 | have problems. | ||
2526 | |||
2527 | next:: | ||
2528 | |||
2529 | cat /proc/net/arp | ||
2530 | |||
2531 | Do you see any hardware addresses in the cache if not you may have problems. | ||
2532 | Next try:: | ||
2533 | |||
2534 | ping -c 5 <broadcast_addr> | ||
2535 | |||
2536 | i.e. the Bcast field above in the output of | ||
2537 | ifconfig. Do you see any replies from machines other than the local machine | ||
2538 | if not you may have problems. also if the TX packets count in ifconfig | ||
2539 | hasn't incremented either you have serious problems in your driver | ||
2540 | (e.g. the txbusy field of the network device being stuck on ) | ||
2541 | or you may have multiple network devices connected. | ||
2542 | |||
2543 | |||
2544 | chandev | ||
2545 | ------- | ||
2546 | There is a new device layer for channel devices, some | ||
2547 | drivers e.g. lcs are registered with this layer. | ||
2548 | |||
2549 | If the device uses the channel device layer you'll be | ||
2550 | able to find what interrupts it uses & the current state | ||
2551 | of the device. | ||
2552 | |||
2553 | See the manpage chandev.8 &type cat /proc/chandev for more info. | ||
2554 | |||
2555 | |||
2556 | SysRq | ||
2557 | ===== | ||
2558 | This is now supported by linux for s/390 & z/Architecture. | ||
2559 | |||
2560 | To enable it do compile the kernel with:: | ||
2561 | |||
2562 | Kernel Hacking -> Magic SysRq Key Enabled | ||
2563 | |||
2564 | Then:: | ||
2565 | |||
2566 | echo "1" > /proc/sys/kernel/sysrq | ||
2567 | |||
2568 | also type:: | ||
2569 | |||
2570 | echo "8" >/proc/sys/kernel/printk | ||
2571 | |||
2572 | To make printk output go to console. | ||
2573 | |||
2574 | On 390 all commands are prefixed with:: | ||
2575 | |||
2576 | ^- | ||
2577 | |||
2578 | e.g.:: | ||
2579 | |||
2580 | ^-t will show tasks. | ||
2581 | ^-? or some unknown command will display help. | ||
2582 | |||
2583 | The sysrq key reading is very picky ( I have to type the keys in an | ||
2584 | xterm session & paste them into the x3270 console ) | ||
2585 | & it may be wise to predefine the keys as described in the VM hints above | ||
2586 | |||
2587 | This is particularly useful for syncing disks unmounting & rebooting | ||
2588 | if the machine gets partially hung. | ||
2589 | |||
2590 | Read Documentation/admin-guide/sysrq.rst for more info | ||
2591 | |||
2592 | References: | ||
2593 | =========== | ||
2594 | - Enterprise Systems Architecture Reference Summary | ||
2595 | - Enterprise Systems Architecture Principles of Operation | ||
2596 | - Hartmut Penners s390 stack frame sheet. | ||
2597 | - IBM Mainframe Channel Attachment a technology brief from a CISCO webpage | ||
2598 | - Various bits of man & info pages of Linux. | ||
2599 | - Linux & GDB source. | ||
2600 | - Various info & man pages. | ||
2601 | - CMS Help on tracing commands. | ||
2602 | - Linux for s/390 Elf Application Binary Interface | ||
2603 | - Linux for z/Series Elf Application Binary Interface ( Both Highly Recommended ) | ||
2604 | - z/Architecture Principles of Operation SA22-7832-00 | ||
2605 | - Enterprise Systems Architecture/390 Reference Summary SA22-7209-01 & the | ||
2606 | - Enterprise Systems Architecture/390 Principles of Operation SA22-7201-05 | ||
2607 | |||
2608 | Special Thanks | ||
2609 | ============== | ||
2610 | Special thanks to Neale Ferguson who maintains a much | ||
2611 | prettier HTML version of this page at | ||
2612 | http://linuxvm.org/penguinvm/ | ||
2613 | Bob Grainger Stefan Bader & others for reporting bugs | ||
diff --git a/Documentation/s390/index.rst b/Documentation/s390/index.rst index 4602312909d3..f7af2061e406 100644 --- a/Documentation/s390/index.rst +++ b/Documentation/s390/index.rst | |||
@@ -7,7 +7,6 @@ s390 Architecture | |||
7 | 7 | ||
8 | cds | 8 | cds |
9 | 3270 | 9 | 3270 |
10 | debugging390 | ||
11 | driver-model | 10 | driver-model |
12 | monreader | 11 | monreader |
13 | qeth | 12 | qeth |
@@ -15,7 +14,6 @@ s390 Architecture | |||
15 | vfio-ap | 14 | vfio-ap |
16 | vfio-ccw | 15 | vfio-ccw |
17 | zfcpdump | 16 | zfcpdump |
18 | dasd | ||
19 | common_io | 17 | common_io |
20 | 18 | ||
21 | text_files | 19 | text_files |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index a4ad2733eedf..8c5b05d91106 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -105,6 +105,7 @@ config S390 | |||
105 | select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE | 105 | select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE |
106 | select ARCH_KEEP_MEMBLOCK | 106 | select ARCH_KEEP_MEMBLOCK |
107 | select ARCH_SAVE_PAGE_KEYS if HIBERNATION | 107 | select ARCH_SAVE_PAGE_KEYS if HIBERNATION |
108 | select ARCH_STACKWALK | ||
108 | select ARCH_SUPPORTS_ATOMIC_RMW | 109 | select ARCH_SUPPORTS_ATOMIC_RMW |
109 | select ARCH_SUPPORTS_NUMA_BALANCING | 110 | select ARCH_SUPPORTS_NUMA_BALANCING |
110 | select ARCH_USE_BUILTIN_BSWAP | 111 | select ARCH_USE_BUILTIN_BSWAP |
@@ -236,6 +237,10 @@ config HAVE_MARCH_Z14_FEATURES | |||
236 | def_bool n | 237 | def_bool n |
237 | select HAVE_MARCH_Z13_FEATURES | 238 | select HAVE_MARCH_Z13_FEATURES |
238 | 239 | ||
240 | config HAVE_MARCH_Z15_FEATURES | ||
241 | def_bool n | ||
242 | select HAVE_MARCH_Z14_FEATURES | ||
243 | |||
239 | choice | 244 | choice |
240 | prompt "Processor type" | 245 | prompt "Processor type" |
241 | default MARCH_Z196 | 246 | default MARCH_Z196 |
@@ -307,6 +312,14 @@ config MARCH_Z14 | |||
307 | and 3906 series). The kernel will be slightly faster but will not | 312 | and 3906 series). The kernel will be slightly faster but will not |
308 | work on older machines. | 313 | work on older machines. |
309 | 314 | ||
315 | config MARCH_Z15 | ||
316 | bool "IBM z15" | ||
317 | select HAVE_MARCH_Z15_FEATURES | ||
318 | help | ||
319 | Select this to enable optimizations for IBM z15 (8562 | ||
320 | and 8561 series). The kernel will be slightly faster but will not | ||
321 | work on older machines. | ||
322 | |||
310 | endchoice | 323 | endchoice |
311 | 324 | ||
312 | config MARCH_Z900_TUNE | 325 | config MARCH_Z900_TUNE |
@@ -333,6 +346,9 @@ config MARCH_Z13_TUNE | |||
333 | config MARCH_Z14_TUNE | 346 | config MARCH_Z14_TUNE |
334 | def_bool TUNE_Z14 || MARCH_Z14 && TUNE_DEFAULT | 347 | def_bool TUNE_Z14 || MARCH_Z14 && TUNE_DEFAULT |
335 | 348 | ||
349 | config MARCH_Z15_TUNE | ||
350 | def_bool TUNE_Z15 || MARCH_Z15 && TUNE_DEFAULT | ||
351 | |||
336 | choice | 352 | choice |
337 | prompt "Tune code generation" | 353 | prompt "Tune code generation" |
338 | default TUNE_DEFAULT | 354 | default TUNE_DEFAULT |
@@ -377,6 +393,9 @@ config TUNE_Z13 | |||
377 | config TUNE_Z14 | 393 | config TUNE_Z14 |
378 | bool "IBM z14" | 394 | bool "IBM z14" |
379 | 395 | ||
396 | config TUNE_Z15 | ||
397 | bool "IBM z15" | ||
398 | |||
380 | endchoice | 399 | endchoice |
381 | 400 | ||
382 | config 64BIT | 401 | config 64BIT |
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index e0bab7ed4123..478b645b20dd 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
@@ -45,6 +45,7 @@ mflags-$(CONFIG_MARCH_Z196) := -march=z196 | |||
45 | mflags-$(CONFIG_MARCH_ZEC12) := -march=zEC12 | 45 | mflags-$(CONFIG_MARCH_ZEC12) := -march=zEC12 |
46 | mflags-$(CONFIG_MARCH_Z13) := -march=z13 | 46 | mflags-$(CONFIG_MARCH_Z13) := -march=z13 |
47 | mflags-$(CONFIG_MARCH_Z14) := -march=z14 | 47 | mflags-$(CONFIG_MARCH_Z14) := -march=z14 |
48 | mflags-$(CONFIG_MARCH_Z15) := -march=z15 | ||
48 | 49 | ||
49 | export CC_FLAGS_MARCH := $(mflags-y) | 50 | export CC_FLAGS_MARCH := $(mflags-y) |
50 | 51 | ||
@@ -59,6 +60,7 @@ cflags-$(CONFIG_MARCH_Z196_TUNE) += -mtune=z196 | |||
59 | cflags-$(CONFIG_MARCH_ZEC12_TUNE) += -mtune=zEC12 | 60 | cflags-$(CONFIG_MARCH_ZEC12_TUNE) += -mtune=zEC12 |
60 | cflags-$(CONFIG_MARCH_Z13_TUNE) += -mtune=z13 | 61 | cflags-$(CONFIG_MARCH_Z13_TUNE) += -mtune=z13 |
61 | cflags-$(CONFIG_MARCH_Z14_TUNE) += -mtune=z14 | 62 | cflags-$(CONFIG_MARCH_Z14_TUNE) += -mtune=z14 |
63 | cflags-$(CONFIG_MARCH_Z15_TUNE) += -mtune=z15 | ||
62 | 64 | ||
63 | cflags-y += -Wa,-I$(srctree)/arch/$(ARCH)/include | 65 | cflags-y += -Wa,-I$(srctree)/arch/$(ARCH)/include |
64 | 66 | ||
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile index 4cf0bddb7d92..e2c47d3a1c89 100644 --- a/arch/s390/boot/Makefile +++ b/arch/s390/boot/Makefile | |||
@@ -36,7 +36,7 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char | |||
36 | 36 | ||
37 | obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o | 37 | obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o |
38 | obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o | 38 | obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o |
39 | obj-y += version.o ctype.o text_dma.o | 39 | obj-y += version.o pgm_check_info.o ctype.o text_dma.o |
40 | obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) += uv.o | 40 | obj-$(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) += uv.o |
41 | obj-$(CONFIG_RELOCATABLE) += machine_kexec_reloc.o | 41 | obj-$(CONFIG_RELOCATABLE) += machine_kexec_reloc.o |
42 | obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o | 42 | obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o |
diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h index 1c3b2b257637..2ea603f70c3b 100644 --- a/arch/s390/boot/boot.h +++ b/arch/s390/boot/boot.h | |||
@@ -10,6 +10,7 @@ void parse_boot_command_line(void); | |||
10 | void setup_memory_end(void); | 10 | void setup_memory_end(void); |
11 | void verify_facilities(void); | 11 | void verify_facilities(void); |
12 | void print_missing_facilities(void); | 12 | void print_missing_facilities(void); |
13 | void print_pgm_check_info(void); | ||
13 | unsigned long get_random_base(unsigned long safe_addr); | 14 | unsigned long get_random_base(unsigned long safe_addr); |
14 | 15 | ||
15 | extern int kaslr_enabled; | 16 | extern int kaslr_enabled; |
diff --git a/arch/s390/boot/compressed/.gitignore b/arch/s390/boot/compressed/.gitignore index 45aeb4f08752..e72fcd7ecebb 100644 --- a/arch/s390/boot/compressed/.gitignore +++ b/arch/s390/boot/compressed/.gitignore | |||
@@ -1,5 +1,2 @@ | |||
1 | sizes.h | ||
2 | vmlinux | 1 | vmlinux |
3 | vmlinux.lds | 2 | vmlinux.lds |
4 | vmlinux.scr.lds | ||
5 | vmlinux.bin.full | ||
diff --git a/arch/s390/boot/compressed/vmlinux.lds.S b/arch/s390/boot/compressed/vmlinux.lds.S index 635217eb3d91..44561b2c3712 100644 --- a/arch/s390/boot/compressed/vmlinux.lds.S +++ b/arch/s390/boot/compressed/vmlinux.lds.S | |||
@@ -37,9 +37,9 @@ SECTIONS | |||
37 | * .dma section for code, data, ex_table that need to stay below 2 GB, | 37 | * .dma section for code, data, ex_table that need to stay below 2 GB, |
38 | * even when the kernel is relocate: above 2 GB. | 38 | * even when the kernel is relocate: above 2 GB. |
39 | */ | 39 | */ |
40 | . = ALIGN(PAGE_SIZE); | ||
40 | _sdma = .; | 41 | _sdma = .; |
41 | .dma.text : { | 42 | .dma.text : { |
42 | . = ALIGN(PAGE_SIZE); | ||
43 | _stext_dma = .; | 43 | _stext_dma = .; |
44 | *(.dma.text) | 44 | *(.dma.text) |
45 | . = ALIGN(PAGE_SIZE); | 45 | . = ALIGN(PAGE_SIZE); |
@@ -52,6 +52,7 @@ SECTIONS | |||
52 | _stop_dma_ex_table = .; | 52 | _stop_dma_ex_table = .; |
53 | } | 53 | } |
54 | .dma.data : { *(.dma.data) } | 54 | .dma.data : { *(.dma.data) } |
55 | . = ALIGN(PAGE_SIZE); | ||
55 | _edma = .; | 56 | _edma = .; |
56 | 57 | ||
57 | BOOT_DATA | 58 | BOOT_DATA |
diff --git a/arch/s390/boot/head.S b/arch/s390/boot/head.S index 2087bed6e60f..4b86a8d3c121 100644 --- a/arch/s390/boot/head.S +++ b/arch/s390/boot/head.S | |||
@@ -60,8 +60,10 @@ __HEAD | |||
60 | .long 0x02000690,0x60000050 | 60 | .long 0x02000690,0x60000050 |
61 | .long 0x020006e0,0x20000050 | 61 | .long 0x020006e0,0x20000050 |
62 | 62 | ||
63 | .org 0x1a0 | 63 | .org __LC_RST_NEW_PSW # 0x1a0 |
64 | .quad 0,iplstart | 64 | .quad 0,iplstart |
65 | .org __LC_PGM_NEW_PSW # 0x1d0 | ||
66 | .quad 0x0000000180000000,startup_pgm_check_handler | ||
65 | 67 | ||
66 | .org 0x200 | 68 | .org 0x200 |
67 | 69 | ||
@@ -352,6 +354,34 @@ ENTRY(startup_kdump) | |||
352 | #include "head_kdump.S" | 354 | #include "head_kdump.S" |
353 | 355 | ||
354 | # | 356 | # |
357 | # This program check is active immediately after kernel start | ||
358 | # and until early_pgm_check_handler is set in kernel/early.c | ||
359 | # It simply saves general/control registers and psw in | ||
360 | # the save area and does disabled wait with a faulty address. | ||
361 | # | ||
362 | ENTRY(startup_pgm_check_handler) | ||
363 | stmg %r0,%r15,__LC_SAVE_AREA_SYNC | ||
364 | la %r1,4095 | ||
365 | stctg %c0,%c15,__LC_CREGS_SAVE_AREA-4095(%r1) | ||
366 | mvc __LC_GPREGS_SAVE_AREA-4095(128,%r1),__LC_SAVE_AREA_SYNC | ||
367 | mvc __LC_PSW_SAVE_AREA-4095(16,%r1),__LC_PGM_OLD_PSW | ||
368 | mvc __LC_RETURN_PSW(16),__LC_PGM_OLD_PSW | ||
369 | ni __LC_RETURN_PSW,0xfc # remove IO and EX bits | ||
370 | ni __LC_RETURN_PSW+1,0xfb # remove MCHK bit | ||
371 | oi __LC_RETURN_PSW+1,0x2 # set wait state bit | ||
372 | larl %r2,.Lold_psw_disabled_wait | ||
373 | stg %r2,__LC_PGM_NEW_PSW+8 | ||
374 | l %r15,.Ldump_info_stack-.Lold_psw_disabled_wait(%r2) | ||
375 | brasl %r14,print_pgm_check_info | ||
376 | .Lold_psw_disabled_wait: | ||
377 | la %r1,4095 | ||
378 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) | ||
379 | lpswe __LC_RETURN_PSW # disabled wait | ||
380 | .Ldump_info_stack: | ||
381 | .long 0x5000 + PAGE_SIZE - STACK_FRAME_OVERHEAD | ||
382 | ENDPROC(startup_pgm_check_handler) | ||
383 | |||
384 | # | ||
355 | # params at 10400 (setup.h) | 385 | # params at 10400 (setup.h) |
356 | # Must be keept in sync with struct parmarea in setup.h | 386 | # Must be keept in sync with struct parmarea in setup.h |
357 | # | 387 | # |
diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c index b8aa6a9f937b..24ef67eb1cef 100644 --- a/arch/s390/boot/ipl_parm.c +++ b/arch/s390/boot/ipl_parm.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <asm/sections.h> | 7 | #include <asm/sections.h> |
8 | #include <asm/boot_data.h> | 8 | #include <asm/boot_data.h> |
9 | #include <asm/facility.h> | 9 | #include <asm/facility.h> |
10 | #include <asm/pgtable.h> | ||
10 | #include <asm/uv.h> | 11 | #include <asm/uv.h> |
11 | #include "boot.h" | 12 | #include "boot.h" |
12 | 13 | ||
@@ -14,6 +15,7 @@ char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; | |||
14 | struct ipl_parameter_block __bootdata_preserved(ipl_block); | 15 | struct ipl_parameter_block __bootdata_preserved(ipl_block); |
15 | int __bootdata_preserved(ipl_block_valid); | 16 | int __bootdata_preserved(ipl_block_valid); |
16 | 17 | ||
18 | unsigned long __bootdata(vmalloc_size) = VMALLOC_DEFAULT_SIZE; | ||
17 | unsigned long __bootdata(memory_end); | 19 | unsigned long __bootdata(memory_end); |
18 | int __bootdata(memory_end_set); | 20 | int __bootdata(memory_end_set); |
19 | int __bootdata(noexec_disabled); | 21 | int __bootdata(noexec_disabled); |
@@ -219,18 +221,21 @@ void parse_boot_command_line(void) | |||
219 | while (*args) { | 221 | while (*args) { |
220 | args = next_arg(args, ¶m, &val); | 222 | args = next_arg(args, ¶m, &val); |
221 | 223 | ||
222 | if (!strcmp(param, "mem")) { | 224 | if (!strcmp(param, "mem") && val) { |
223 | memory_end = memparse(val, NULL); | 225 | memory_end = round_down(memparse(val, NULL), PAGE_SIZE); |
224 | memory_end_set = 1; | 226 | memory_end_set = 1; |
225 | } | 227 | } |
226 | 228 | ||
229 | if (!strcmp(param, "vmalloc") && val) | ||
230 | vmalloc_size = round_up(memparse(val, NULL), PAGE_SIZE); | ||
231 | |||
227 | if (!strcmp(param, "noexec")) { | 232 | if (!strcmp(param, "noexec")) { |
228 | rc = kstrtobool(val, &enabled); | 233 | rc = kstrtobool(val, &enabled); |
229 | if (!rc && !enabled) | 234 | if (!rc && !enabled) |
230 | noexec_disabled = 1; | 235 | noexec_disabled = 1; |
231 | } | 236 | } |
232 | 237 | ||
233 | if (!strcmp(param, "facilities")) | 238 | if (!strcmp(param, "facilities") && val) |
234 | modify_fac_list(val); | 239 | modify_fac_list(val); |
235 | 240 | ||
236 | if (!strcmp(param, "nokaslr")) | 241 | if (!strcmp(param, "nokaslr")) |
diff --git a/arch/s390/boot/kaslr.c b/arch/s390/boot/kaslr.c index c34a6387ce38..5d12352545c5 100644 --- a/arch/s390/boot/kaslr.c +++ b/arch/s390/boot/kaslr.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright IBM Corp. 2019 | 3 | * Copyright IBM Corp. 2019 |
4 | */ | 4 | */ |
5 | #include <asm/mem_detect.h> | 5 | #include <asm/mem_detect.h> |
6 | #include <asm/pgtable.h> | ||
6 | #include <asm/cpacf.h> | 7 | #include <asm/cpacf.h> |
7 | #include <asm/timex.h> | 8 | #include <asm/timex.h> |
8 | #include <asm/sclp.h> | 9 | #include <asm/sclp.h> |
@@ -90,8 +91,10 @@ static unsigned long get_random(unsigned long limit) | |||
90 | 91 | ||
91 | unsigned long get_random_base(unsigned long safe_addr) | 92 | unsigned long get_random_base(unsigned long safe_addr) |
92 | { | 93 | { |
94 | unsigned long memory_limit = memory_end_set ? memory_end : 0; | ||
93 | unsigned long base, start, end, kernel_size; | 95 | unsigned long base, start, end, kernel_size; |
94 | unsigned long block_sum, offset; | 96 | unsigned long block_sum, offset; |
97 | unsigned long kasan_needs; | ||
95 | int i; | 98 | int i; |
96 | 99 | ||
97 | if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE) { | 100 | if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE) { |
@@ -100,14 +103,36 @@ unsigned long get_random_base(unsigned long safe_addr) | |||
100 | } | 103 | } |
101 | safe_addr = ALIGN(safe_addr, THREAD_SIZE); | 104 | safe_addr = ALIGN(safe_addr, THREAD_SIZE); |
102 | 105 | ||
106 | if ((IS_ENABLED(CONFIG_KASAN))) { | ||
107 | /* | ||
108 | * Estimate kasan memory requirements, which it will reserve | ||
109 | * at the very end of available physical memory. To estimate | ||
110 | * that, we take into account that kasan would require | ||
111 | * 1/8 of available physical memory (for shadow memory) + | ||
112 | * creating page tables for the whole memory + shadow memory | ||
113 | * region (1 + 1/8). To keep page tables estimates simple take | ||
114 | * the double of combined ptes size. | ||
115 | */ | ||
116 | memory_limit = get_mem_detect_end(); | ||
117 | if (memory_end_set && memory_limit > memory_end) | ||
118 | memory_limit = memory_end; | ||
119 | |||
120 | /* for shadow memory */ | ||
121 | kasan_needs = memory_limit / 8; | ||
122 | /* for paging structures */ | ||
123 | kasan_needs += (memory_limit + kasan_needs) / PAGE_SIZE / | ||
124 | _PAGE_ENTRIES * _PAGE_TABLE_SIZE * 2; | ||
125 | memory_limit -= kasan_needs; | ||
126 | } | ||
127 | |||
103 | kernel_size = vmlinux.image_size + vmlinux.bss_size; | 128 | kernel_size = vmlinux.image_size + vmlinux.bss_size; |
104 | block_sum = 0; | 129 | block_sum = 0; |
105 | for_each_mem_detect_block(i, &start, &end) { | 130 | for_each_mem_detect_block(i, &start, &end) { |
106 | if (memory_end_set) { | 131 | if (memory_limit) { |
107 | if (start >= memory_end) | 132 | if (start >= memory_limit) |
108 | break; | 133 | break; |
109 | if (end > memory_end) | 134 | if (end > memory_limit) |
110 | end = memory_end; | 135 | end = memory_limit; |
111 | } | 136 | } |
112 | if (end - start < kernel_size) | 137 | if (end - start < kernel_size) |
113 | continue; | 138 | continue; |
@@ -125,11 +150,11 @@ unsigned long get_random_base(unsigned long safe_addr) | |||
125 | base = safe_addr; | 150 | base = safe_addr; |
126 | block_sum = offset = 0; | 151 | block_sum = offset = 0; |
127 | for_each_mem_detect_block(i, &start, &end) { | 152 | for_each_mem_detect_block(i, &start, &end) { |
128 | if (memory_end_set) { | 153 | if (memory_limit) { |
129 | if (start >= memory_end) | 154 | if (start >= memory_limit) |
130 | break; | 155 | break; |
131 | if (end > memory_end) | 156 | if (end > memory_limit) |
132 | end = memory_end; | 157 | end = memory_limit; |
133 | } | 158 | } |
134 | if (end - start < kernel_size) | 159 | if (end - start < kernel_size) |
135 | continue; | 160 | continue; |
diff --git a/arch/s390/boot/mem_detect.c b/arch/s390/boot/mem_detect.c index 5d316fe40480..62e7c13ce85c 100644 --- a/arch/s390/boot/mem_detect.c +++ b/arch/s390/boot/mem_detect.c | |||
@@ -63,13 +63,6 @@ void add_mem_detect_block(u64 start, u64 end) | |||
63 | mem_detect.count++; | 63 | mem_detect.count++; |
64 | } | 64 | } |
65 | 65 | ||
66 | static unsigned long get_mem_detect_end(void) | ||
67 | { | ||
68 | if (mem_detect.count) | ||
69 | return __get_mem_detect_block_ptr(mem_detect.count - 1)->end; | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static int __diag260(unsigned long rx1, unsigned long rx2) | 66 | static int __diag260(unsigned long rx1, unsigned long rx2) |
74 | { | 67 | { |
75 | register unsigned long _rx1 asm("2") = rx1; | 68 | register unsigned long _rx1 asm("2") = rx1; |
diff --git a/arch/s390/boot/pgm_check_info.c b/arch/s390/boot/pgm_check_info.c new file mode 100644 index 000000000000..83b5b7915c32 --- /dev/null +++ b/arch/s390/boot/pgm_check_info.c | |||
@@ -0,0 +1,90 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/string.h> | ||
4 | #include <asm/lowcore.h> | ||
5 | #include <asm/sclp.h> | ||
6 | #include "boot.h" | ||
7 | |||
8 | const char hex_asc[] = "0123456789abcdef"; | ||
9 | |||
10 | #define add_val_as_hex(dst, val) \ | ||
11 | __add_val_as_hex(dst, (const unsigned char *)&val, sizeof(val)) | ||
12 | |||
13 | static char *__add_val_as_hex(char *dst, const unsigned char *src, size_t count) | ||
14 | { | ||
15 | while (count--) | ||
16 | dst = hex_byte_pack(dst, *src++); | ||
17 | return dst; | ||
18 | } | ||
19 | |||
20 | static char *add_str(char *dst, char *src) | ||
21 | { | ||
22 | strcpy(dst, src); | ||
23 | return dst + strlen(dst); | ||
24 | } | ||
25 | |||
26 | void print_pgm_check_info(void) | ||
27 | { | ||
28 | struct psw_bits *psw = &psw_bits(S390_lowcore.psw_save_area); | ||
29 | unsigned short ilc = S390_lowcore.pgm_ilc >> 1; | ||
30 | char buf[256]; | ||
31 | int row, col; | ||
32 | char *p; | ||
33 | |||
34 | add_str(buf, "Linux version "); | ||
35 | strlcat(buf, kernel_version, sizeof(buf)); | ||
36 | sclp_early_printk(buf); | ||
37 | |||
38 | p = add_str(buf, "Kernel fault: interruption code "); | ||
39 | p = add_val_as_hex(buf + strlen(buf), S390_lowcore.pgm_code); | ||
40 | p = add_str(p, " ilc:"); | ||
41 | *p++ = hex_asc_lo(ilc); | ||
42 | add_str(p, "\n"); | ||
43 | sclp_early_printk(buf); | ||
44 | |||
45 | p = add_str(buf, "PSW : "); | ||
46 | p = add_val_as_hex(p, S390_lowcore.psw_save_area.mask); | ||
47 | p = add_str(p, " "); | ||
48 | p = add_val_as_hex(p, S390_lowcore.psw_save_area.addr); | ||
49 | add_str(p, "\n"); | ||
50 | sclp_early_printk(buf); | ||
51 | |||
52 | p = add_str(buf, " R:"); | ||
53 | *p++ = hex_asc_lo(psw->per); | ||
54 | p = add_str(p, " T:"); | ||
55 | *p++ = hex_asc_lo(psw->dat); | ||
56 | p = add_str(p, " IO:"); | ||
57 | *p++ = hex_asc_lo(psw->io); | ||
58 | p = add_str(p, " EX:"); | ||
59 | *p++ = hex_asc_lo(psw->ext); | ||
60 | p = add_str(p, " Key:"); | ||
61 | *p++ = hex_asc_lo(psw->key); | ||
62 | p = add_str(p, " M:"); | ||
63 | *p++ = hex_asc_lo(psw->mcheck); | ||
64 | p = add_str(p, " W:"); | ||
65 | *p++ = hex_asc_lo(psw->wait); | ||
66 | p = add_str(p, " P:"); | ||
67 | *p++ = hex_asc_lo(psw->pstate); | ||
68 | p = add_str(p, " AS:"); | ||
69 | *p++ = hex_asc_lo(psw->as); | ||
70 | p = add_str(p, " CC:"); | ||
71 | *p++ = hex_asc_lo(psw->cc); | ||
72 | p = add_str(p, " PM:"); | ||
73 | *p++ = hex_asc_lo(psw->pm); | ||
74 | p = add_str(p, " RI:"); | ||
75 | *p++ = hex_asc_lo(psw->ri); | ||
76 | p = add_str(p, " EA:"); | ||
77 | *p++ = hex_asc_lo(psw->eaba); | ||
78 | add_str(p, "\n"); | ||
79 | sclp_early_printk(buf); | ||
80 | |||
81 | for (row = 0; row < 4; row++) { | ||
82 | p = add_str(buf, row == 0 ? "GPRS:" : " "); | ||
83 | for (col = 0; col < 4; col++) { | ||
84 | p = add_str(p, " "); | ||
85 | p = add_val_as_hex(p, S390_lowcore.gpregs_save_area[row * 4 + col]); | ||
86 | } | ||
87 | add_str(p, "\n"); | ||
88 | sclp_early_printk(buf); | ||
89 | } | ||
90 | } | ||
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index 7b0d05414618..596ca7cc4d7b 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c | |||
@@ -112,6 +112,11 @@ static void handle_relocs(unsigned long offset) | |||
112 | } | 112 | } |
113 | } | 113 | } |
114 | 114 | ||
115 | static void clear_bss_section(void) | ||
116 | { | ||
117 | memset((void *)vmlinux.default_lma + vmlinux.image_size, 0, vmlinux.bss_size); | ||
118 | } | ||
119 | |||
115 | void startup_kernel(void) | 120 | void startup_kernel(void) |
116 | { | 121 | { |
117 | unsigned long random_lma; | 122 | unsigned long random_lma; |
@@ -151,6 +156,7 @@ void startup_kernel(void) | |||
151 | } else if (__kaslr_offset) | 156 | } else if (__kaslr_offset) |
152 | memcpy((void *)vmlinux.default_lma, img, vmlinux.image_size); | 157 | memcpy((void *)vmlinux.default_lma, img, vmlinux.image_size); |
153 | 158 | ||
159 | clear_bss_section(); | ||
154 | copy_bootdata(); | 160 | copy_bootdata(); |
155 | if (IS_ENABLED(CONFIG_RELOCATABLE)) | 161 | if (IS_ENABLED(CONFIG_RELOCATABLE)) |
156 | handle_relocs(__kaslr_offset); | 162 | handle_relocs(__kaslr_offset); |
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig index 74e78ec5beb6..347f48702edb 100644 --- a/arch/s390/configs/debug_defconfig +++ b/arch/s390/configs/debug_defconfig | |||
@@ -717,6 +717,8 @@ CONFIG_CRYPTO_PAES_S390=m | |||
717 | CONFIG_CRYPTO_SHA1_S390=m | 717 | CONFIG_CRYPTO_SHA1_S390=m |
718 | CONFIG_CRYPTO_SHA256_S390=m | 718 | CONFIG_CRYPTO_SHA256_S390=m |
719 | CONFIG_CRYPTO_SHA512_S390=m | 719 | CONFIG_CRYPTO_SHA512_S390=m |
720 | CONFIG_CRYPTO_SHA3_256_S390=m | ||
721 | CONFIG_CRYPTO_SHA3_512_S390=m | ||
720 | CONFIG_CRYPTO_DES_S390=m | 722 | CONFIG_CRYPTO_DES_S390=m |
721 | CONFIG_CRYPTO_AES_S390=m | 723 | CONFIG_CRYPTO_AES_S390=m |
722 | CONFIG_CRYPTO_GHASH_S390=m | 724 | CONFIG_CRYPTO_GHASH_S390=m |
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig index 68d3ca83302b..8514b8b9500f 100644 --- a/arch/s390/configs/defconfig +++ b/arch/s390/configs/defconfig | |||
@@ -710,6 +710,8 @@ CONFIG_CRYPTO_PAES_S390=m | |||
710 | CONFIG_CRYPTO_SHA1_S390=m | 710 | CONFIG_CRYPTO_SHA1_S390=m |
711 | CONFIG_CRYPTO_SHA256_S390=m | 711 | CONFIG_CRYPTO_SHA256_S390=m |
712 | CONFIG_CRYPTO_SHA512_S390=m | 712 | CONFIG_CRYPTO_SHA512_S390=m |
713 | CONFIG_CRYPTO_SHA3_256_S390=m | ||
714 | CONFIG_CRYPTO_SHA3_512_S390=m | ||
713 | CONFIG_CRYPTO_DES_S390=m | 715 | CONFIG_CRYPTO_DES_S390=m |
714 | CONFIG_CRYPTO_AES_S390=m | 716 | CONFIG_CRYPTO_AES_S390=m |
715 | CONFIG_CRYPTO_GHASH_S390=m | 717 | CONFIG_CRYPTO_GHASH_S390=m |
diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile index a51010ea62fa..12889d4652cc 100644 --- a/arch/s390/crypto/Makefile +++ b/arch/s390/crypto/Makefile | |||
@@ -6,6 +6,8 @@ | |||
6 | obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o sha_common.o | 6 | obj-$(CONFIG_CRYPTO_SHA1_S390) += sha1_s390.o sha_common.o |
7 | obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o sha_common.o | 7 | obj-$(CONFIG_CRYPTO_SHA256_S390) += sha256_s390.o sha_common.o |
8 | obj-$(CONFIG_CRYPTO_SHA512_S390) += sha512_s390.o sha_common.o | 8 | obj-$(CONFIG_CRYPTO_SHA512_S390) += sha512_s390.o sha_common.o |
9 | obj-$(CONFIG_CRYPTO_SHA3_256_S390) += sha3_256_s390.o sha_common.o | ||
10 | obj-$(CONFIG_CRYPTO_SHA3_512_S390) += sha3_512_s390.o sha_common.o | ||
9 | obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o | 11 | obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o |
10 | obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o | 12 | obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o |
11 | obj-$(CONFIG_CRYPTO_PAES_S390) += paes_s390.o | 13 | obj-$(CONFIG_CRYPTO_PAES_S390) += paes_s390.o |
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index d00f84add5f4..6d2dbb5089d5 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c | |||
@@ -586,6 +586,9 @@ static int xts_aes_encrypt(struct blkcipher_desc *desc, | |||
586 | struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm); | 586 | struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm); |
587 | struct blkcipher_walk walk; | 587 | struct blkcipher_walk walk; |
588 | 588 | ||
589 | if (!nbytes) | ||
590 | return -EINVAL; | ||
591 | |||
589 | if (unlikely(!xts_ctx->fc)) | 592 | if (unlikely(!xts_ctx->fc)) |
590 | return xts_fallback_encrypt(desc, dst, src, nbytes); | 593 | return xts_fallback_encrypt(desc, dst, src, nbytes); |
591 | 594 | ||
@@ -600,6 +603,9 @@ static int xts_aes_decrypt(struct blkcipher_desc *desc, | |||
600 | struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm); | 603 | struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm); |
601 | struct blkcipher_walk walk; | 604 | struct blkcipher_walk walk; |
602 | 605 | ||
606 | if (!nbytes) | ||
607 | return -EINVAL; | ||
608 | |||
603 | if (unlikely(!xts_ctx->fc)) | 609 | if (unlikely(!xts_ctx->fc)) |
604 | return xts_fallback_decrypt(desc, dst, src, nbytes); | 610 | return xts_fallback_decrypt(desc, dst, src, nbytes); |
605 | 611 | ||
diff --git a/arch/s390/crypto/paes_s390.c b/arch/s390/crypto/paes_s390.c index e8d9fa54569c..6184dceed340 100644 --- a/arch/s390/crypto/paes_s390.c +++ b/arch/s390/crypto/paes_s390.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * s390 implementation of the AES Cipher Algorithm with protected keys. | 5 | * s390 implementation of the AES Cipher Algorithm with protected keys. |
6 | * | 6 | * |
7 | * s390 Version: | 7 | * s390 Version: |
8 | * Copyright IBM Corp. 2017 | 8 | * Copyright IBM Corp. 2017,2019 |
9 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> | 9 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> |
10 | * Harald Freudenberger <freude@de.ibm.com> | 10 | * Harald Freudenberger <freude@de.ibm.com> |
11 | */ | 11 | */ |
@@ -25,16 +25,59 @@ | |||
25 | #include <asm/cpacf.h> | 25 | #include <asm/cpacf.h> |
26 | #include <asm/pkey.h> | 26 | #include <asm/pkey.h> |
27 | 27 | ||
28 | /* | ||
29 | * Key blobs smaller/bigger than these defines are rejected | ||
30 | * by the common code even before the individual setkey function | ||
31 | * is called. As paes can handle different kinds of key blobs | ||
32 | * and padding is also possible, the limits need to be generous. | ||
33 | */ | ||
34 | #define PAES_MIN_KEYSIZE 64 | ||
35 | #define PAES_MAX_KEYSIZE 256 | ||
36 | |||
28 | static u8 *ctrblk; | 37 | static u8 *ctrblk; |
29 | static DEFINE_SPINLOCK(ctrblk_lock); | 38 | static DEFINE_SPINLOCK(ctrblk_lock); |
30 | 39 | ||
31 | static cpacf_mask_t km_functions, kmc_functions, kmctr_functions; | 40 | static cpacf_mask_t km_functions, kmc_functions, kmctr_functions; |
32 | 41 | ||
33 | struct key_blob { | 42 | struct key_blob { |
34 | __u8 key[MAXKEYBLOBSIZE]; | 43 | /* |
44 | * Small keys will be stored in the keybuf. Larger keys are | ||
45 | * stored in extra allocated memory. In both cases does | ||
46 | * key point to the memory where the key is stored. | ||
47 | * The code distinguishes by checking keylen against | ||
48 | * sizeof(keybuf). See the two following helper functions. | ||
49 | */ | ||
50 | u8 *key; | ||
51 | u8 keybuf[128]; | ||
35 | unsigned int keylen; | 52 | unsigned int keylen; |
36 | }; | 53 | }; |
37 | 54 | ||
55 | static inline int _copy_key_to_kb(struct key_blob *kb, | ||
56 | const u8 *key, | ||
57 | unsigned int keylen) | ||
58 | { | ||
59 | if (keylen <= sizeof(kb->keybuf)) | ||
60 | kb->key = kb->keybuf; | ||
61 | else { | ||
62 | kb->key = kmalloc(keylen, GFP_KERNEL); | ||
63 | if (!kb->key) | ||
64 | return -ENOMEM; | ||
65 | } | ||
66 | memcpy(kb->key, key, keylen); | ||
67 | kb->keylen = keylen; | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static inline void _free_kb_keybuf(struct key_blob *kb) | ||
73 | { | ||
74 | if (kb->key && kb->key != kb->keybuf | ||
75 | && kb->keylen > sizeof(kb->keybuf)) { | ||
76 | kfree(kb->key); | ||
77 | kb->key = NULL; | ||
78 | } | ||
79 | } | ||
80 | |||
38 | struct s390_paes_ctx { | 81 | struct s390_paes_ctx { |
39 | struct key_blob kb; | 82 | struct key_blob kb; |
40 | struct pkey_protkey pk; | 83 | struct pkey_protkey pk; |
@@ -80,13 +123,33 @@ static int __paes_set_key(struct s390_paes_ctx *ctx) | |||
80 | return ctx->fc ? 0 : -EINVAL; | 123 | return ctx->fc ? 0 : -EINVAL; |
81 | } | 124 | } |
82 | 125 | ||
126 | static int ecb_paes_init(struct crypto_tfm *tfm) | ||
127 | { | ||
128 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
129 | |||
130 | ctx->kb.key = NULL; | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static void ecb_paes_exit(struct crypto_tfm *tfm) | ||
136 | { | ||
137 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
138 | |||
139 | _free_kb_keybuf(&ctx->kb); | ||
140 | } | ||
141 | |||
83 | static int ecb_paes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | 142 | static int ecb_paes_set_key(struct crypto_tfm *tfm, const u8 *in_key, |
84 | unsigned int key_len) | 143 | unsigned int key_len) |
85 | { | 144 | { |
145 | int rc; | ||
86 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); | 146 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); |
87 | 147 | ||
88 | memcpy(ctx->kb.key, in_key, key_len); | 148 | _free_kb_keybuf(&ctx->kb); |
89 | ctx->kb.keylen = key_len; | 149 | rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); |
150 | if (rc) | ||
151 | return rc; | ||
152 | |||
90 | if (__paes_set_key(ctx)) { | 153 | if (__paes_set_key(ctx)) { |
91 | tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | 154 | tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; |
92 | return -EINVAL; | 155 | return -EINVAL; |
@@ -148,10 +211,12 @@ static struct crypto_alg ecb_paes_alg = { | |||
148 | .cra_type = &crypto_blkcipher_type, | 211 | .cra_type = &crypto_blkcipher_type, |
149 | .cra_module = THIS_MODULE, | 212 | .cra_module = THIS_MODULE, |
150 | .cra_list = LIST_HEAD_INIT(ecb_paes_alg.cra_list), | 213 | .cra_list = LIST_HEAD_INIT(ecb_paes_alg.cra_list), |
214 | .cra_init = ecb_paes_init, | ||
215 | .cra_exit = ecb_paes_exit, | ||
151 | .cra_u = { | 216 | .cra_u = { |
152 | .blkcipher = { | 217 | .blkcipher = { |
153 | .min_keysize = MINKEYBLOBSIZE, | 218 | .min_keysize = PAES_MIN_KEYSIZE, |
154 | .max_keysize = MAXKEYBLOBSIZE, | 219 | .max_keysize = PAES_MAX_KEYSIZE, |
155 | .setkey = ecb_paes_set_key, | 220 | .setkey = ecb_paes_set_key, |
156 | .encrypt = ecb_paes_encrypt, | 221 | .encrypt = ecb_paes_encrypt, |
157 | .decrypt = ecb_paes_decrypt, | 222 | .decrypt = ecb_paes_decrypt, |
@@ -159,6 +224,22 @@ static struct crypto_alg ecb_paes_alg = { | |||
159 | } | 224 | } |
160 | }; | 225 | }; |
161 | 226 | ||
227 | static int cbc_paes_init(struct crypto_tfm *tfm) | ||
228 | { | ||
229 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
230 | |||
231 | ctx->kb.key = NULL; | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static void cbc_paes_exit(struct crypto_tfm *tfm) | ||
237 | { | ||
238 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
239 | |||
240 | _free_kb_keybuf(&ctx->kb); | ||
241 | } | ||
242 | |||
162 | static int __cbc_paes_set_key(struct s390_paes_ctx *ctx) | 243 | static int __cbc_paes_set_key(struct s390_paes_ctx *ctx) |
163 | { | 244 | { |
164 | unsigned long fc; | 245 | unsigned long fc; |
@@ -180,10 +261,14 @@ static int __cbc_paes_set_key(struct s390_paes_ctx *ctx) | |||
180 | static int cbc_paes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | 261 | static int cbc_paes_set_key(struct crypto_tfm *tfm, const u8 *in_key, |
181 | unsigned int key_len) | 262 | unsigned int key_len) |
182 | { | 263 | { |
264 | int rc; | ||
183 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); | 265 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); |
184 | 266 | ||
185 | memcpy(ctx->kb.key, in_key, key_len); | 267 | _free_kb_keybuf(&ctx->kb); |
186 | ctx->kb.keylen = key_len; | 268 | rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); |
269 | if (rc) | ||
270 | return rc; | ||
271 | |||
187 | if (__cbc_paes_set_key(ctx)) { | 272 | if (__cbc_paes_set_key(ctx)) { |
188 | tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | 273 | tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; |
189 | return -EINVAL; | 274 | return -EINVAL; |
@@ -252,10 +337,12 @@ static struct crypto_alg cbc_paes_alg = { | |||
252 | .cra_type = &crypto_blkcipher_type, | 337 | .cra_type = &crypto_blkcipher_type, |
253 | .cra_module = THIS_MODULE, | 338 | .cra_module = THIS_MODULE, |
254 | .cra_list = LIST_HEAD_INIT(cbc_paes_alg.cra_list), | 339 | .cra_list = LIST_HEAD_INIT(cbc_paes_alg.cra_list), |
340 | .cra_init = cbc_paes_init, | ||
341 | .cra_exit = cbc_paes_exit, | ||
255 | .cra_u = { | 342 | .cra_u = { |
256 | .blkcipher = { | 343 | .blkcipher = { |
257 | .min_keysize = MINKEYBLOBSIZE, | 344 | .min_keysize = PAES_MIN_KEYSIZE, |
258 | .max_keysize = MAXKEYBLOBSIZE, | 345 | .max_keysize = PAES_MAX_KEYSIZE, |
259 | .ivsize = AES_BLOCK_SIZE, | 346 | .ivsize = AES_BLOCK_SIZE, |
260 | .setkey = cbc_paes_set_key, | 347 | .setkey = cbc_paes_set_key, |
261 | .encrypt = cbc_paes_encrypt, | 348 | .encrypt = cbc_paes_encrypt, |
@@ -264,6 +351,24 @@ static struct crypto_alg cbc_paes_alg = { | |||
264 | } | 351 | } |
265 | }; | 352 | }; |
266 | 353 | ||
354 | static int xts_paes_init(struct crypto_tfm *tfm) | ||
355 | { | ||
356 | struct s390_pxts_ctx *ctx = crypto_tfm_ctx(tfm); | ||
357 | |||
358 | ctx->kb[0].key = NULL; | ||
359 | ctx->kb[1].key = NULL; | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | static void xts_paes_exit(struct crypto_tfm *tfm) | ||
365 | { | ||
366 | struct s390_pxts_ctx *ctx = crypto_tfm_ctx(tfm); | ||
367 | |||
368 | _free_kb_keybuf(&ctx->kb[0]); | ||
369 | _free_kb_keybuf(&ctx->kb[1]); | ||
370 | } | ||
371 | |||
267 | static int __xts_paes_set_key(struct s390_pxts_ctx *ctx) | 372 | static int __xts_paes_set_key(struct s390_pxts_ctx *ctx) |
268 | { | 373 | { |
269 | unsigned long fc; | 374 | unsigned long fc; |
@@ -287,20 +392,27 @@ static int __xts_paes_set_key(struct s390_pxts_ctx *ctx) | |||
287 | } | 392 | } |
288 | 393 | ||
289 | static int xts_paes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | 394 | static int xts_paes_set_key(struct crypto_tfm *tfm, const u8 *in_key, |
290 | unsigned int key_len) | 395 | unsigned int xts_key_len) |
291 | { | 396 | { |
397 | int rc; | ||
292 | struct s390_pxts_ctx *ctx = crypto_tfm_ctx(tfm); | 398 | struct s390_pxts_ctx *ctx = crypto_tfm_ctx(tfm); |
293 | u8 ckey[2 * AES_MAX_KEY_SIZE]; | 399 | u8 ckey[2 * AES_MAX_KEY_SIZE]; |
294 | unsigned int ckey_len, keytok_len; | 400 | unsigned int ckey_len, key_len; |
295 | 401 | ||
296 | if (key_len % 2) | 402 | if (xts_key_len % 2) |
297 | return -EINVAL; | 403 | return -EINVAL; |
298 | 404 | ||
299 | keytok_len = key_len / 2; | 405 | key_len = xts_key_len / 2; |
300 | memcpy(ctx->kb[0].key, in_key, keytok_len); | 406 | |
301 | ctx->kb[0].keylen = keytok_len; | 407 | _free_kb_keybuf(&ctx->kb[0]); |
302 | memcpy(ctx->kb[1].key, in_key + keytok_len, keytok_len); | 408 | _free_kb_keybuf(&ctx->kb[1]); |
303 | ctx->kb[1].keylen = keytok_len; | 409 | rc = _copy_key_to_kb(&ctx->kb[0], in_key, key_len); |
410 | if (rc) | ||
411 | return rc; | ||
412 | rc = _copy_key_to_kb(&ctx->kb[1], in_key + key_len, key_len); | ||
413 | if (rc) | ||
414 | return rc; | ||
415 | |||
304 | if (__xts_paes_set_key(ctx)) { | 416 | if (__xts_paes_set_key(ctx)) { |
305 | tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | 417 | tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; |
306 | return -EINVAL; | 418 | return -EINVAL; |
@@ -394,10 +506,12 @@ static struct crypto_alg xts_paes_alg = { | |||
394 | .cra_type = &crypto_blkcipher_type, | 506 | .cra_type = &crypto_blkcipher_type, |
395 | .cra_module = THIS_MODULE, | 507 | .cra_module = THIS_MODULE, |
396 | .cra_list = LIST_HEAD_INIT(xts_paes_alg.cra_list), | 508 | .cra_list = LIST_HEAD_INIT(xts_paes_alg.cra_list), |
509 | .cra_init = xts_paes_init, | ||
510 | .cra_exit = xts_paes_exit, | ||
397 | .cra_u = { | 511 | .cra_u = { |
398 | .blkcipher = { | 512 | .blkcipher = { |
399 | .min_keysize = 2 * MINKEYBLOBSIZE, | 513 | .min_keysize = 2 * PAES_MIN_KEYSIZE, |
400 | .max_keysize = 2 * MAXKEYBLOBSIZE, | 514 | .max_keysize = 2 * PAES_MAX_KEYSIZE, |
401 | .ivsize = AES_BLOCK_SIZE, | 515 | .ivsize = AES_BLOCK_SIZE, |
402 | .setkey = xts_paes_set_key, | 516 | .setkey = xts_paes_set_key, |
403 | .encrypt = xts_paes_encrypt, | 517 | .encrypt = xts_paes_encrypt, |
@@ -406,6 +520,22 @@ static struct crypto_alg xts_paes_alg = { | |||
406 | } | 520 | } |
407 | }; | 521 | }; |
408 | 522 | ||
523 | static int ctr_paes_init(struct crypto_tfm *tfm) | ||
524 | { | ||
525 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
526 | |||
527 | ctx->kb.key = NULL; | ||
528 | |||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | static void ctr_paes_exit(struct crypto_tfm *tfm) | ||
533 | { | ||
534 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); | ||
535 | |||
536 | _free_kb_keybuf(&ctx->kb); | ||
537 | } | ||
538 | |||
409 | static int __ctr_paes_set_key(struct s390_paes_ctx *ctx) | 539 | static int __ctr_paes_set_key(struct s390_paes_ctx *ctx) |
410 | { | 540 | { |
411 | unsigned long fc; | 541 | unsigned long fc; |
@@ -428,10 +558,14 @@ static int __ctr_paes_set_key(struct s390_paes_ctx *ctx) | |||
428 | static int ctr_paes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | 558 | static int ctr_paes_set_key(struct crypto_tfm *tfm, const u8 *in_key, |
429 | unsigned int key_len) | 559 | unsigned int key_len) |
430 | { | 560 | { |
561 | int rc; | ||
431 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); | 562 | struct s390_paes_ctx *ctx = crypto_tfm_ctx(tfm); |
432 | 563 | ||
433 | memcpy(ctx->kb.key, in_key, key_len); | 564 | _free_kb_keybuf(&ctx->kb); |
434 | ctx->kb.keylen = key_len; | 565 | rc = _copy_key_to_kb(&ctx->kb, in_key, key_len); |
566 | if (rc) | ||
567 | return rc; | ||
568 | |||
435 | if (__ctr_paes_set_key(ctx)) { | 569 | if (__ctr_paes_set_key(ctx)) { |
436 | tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; | 570 | tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; |
437 | return -EINVAL; | 571 | return -EINVAL; |
@@ -541,10 +675,12 @@ static struct crypto_alg ctr_paes_alg = { | |||
541 | .cra_type = &crypto_blkcipher_type, | 675 | .cra_type = &crypto_blkcipher_type, |
542 | .cra_module = THIS_MODULE, | 676 | .cra_module = THIS_MODULE, |
543 | .cra_list = LIST_HEAD_INIT(ctr_paes_alg.cra_list), | 677 | .cra_list = LIST_HEAD_INIT(ctr_paes_alg.cra_list), |
678 | .cra_init = ctr_paes_init, | ||
679 | .cra_exit = ctr_paes_exit, | ||
544 | .cra_u = { | 680 | .cra_u = { |
545 | .blkcipher = { | 681 | .blkcipher = { |
546 | .min_keysize = MINKEYBLOBSIZE, | 682 | .min_keysize = PAES_MIN_KEYSIZE, |
547 | .max_keysize = MAXKEYBLOBSIZE, | 683 | .max_keysize = PAES_MAX_KEYSIZE, |
548 | .ivsize = AES_BLOCK_SIZE, | 684 | .ivsize = AES_BLOCK_SIZE, |
549 | .setkey = ctr_paes_set_key, | 685 | .setkey = ctr_paes_set_key, |
550 | .encrypt = ctr_paes_encrypt, | 686 | .encrypt = ctr_paes_encrypt, |
diff --git a/arch/s390/crypto/sha.h b/arch/s390/crypto/sha.h index d6f8258b44df..ada2f98c27b7 100644 --- a/arch/s390/crypto/sha.h +++ b/arch/s390/crypto/sha.h | |||
@@ -12,15 +12,17 @@ | |||
12 | 12 | ||
13 | #include <linux/crypto.h> | 13 | #include <linux/crypto.h> |
14 | #include <crypto/sha.h> | 14 | #include <crypto/sha.h> |
15 | #include <crypto/sha3.h> | ||
15 | 16 | ||
16 | /* must be big enough for the largest SHA variant */ | 17 | /* must be big enough for the largest SHA variant */ |
17 | #define SHA_MAX_STATE_SIZE (SHA512_DIGEST_SIZE / 4) | 18 | #define SHA3_STATE_SIZE 200 |
18 | #define SHA_MAX_BLOCK_SIZE SHA512_BLOCK_SIZE | 19 | #define CPACF_MAX_PARMBLOCK_SIZE SHA3_STATE_SIZE |
20 | #define SHA_MAX_BLOCK_SIZE SHA3_224_BLOCK_SIZE | ||
19 | 21 | ||
20 | struct s390_sha_ctx { | 22 | struct s390_sha_ctx { |
21 | u64 count; /* message length in bytes */ | 23 | u64 count; /* message length in bytes */ |
22 | u32 state[SHA_MAX_STATE_SIZE]; | 24 | u32 state[CPACF_MAX_PARMBLOCK_SIZE / sizeof(u32)]; |
23 | u8 buf[2 * SHA_MAX_BLOCK_SIZE]; | 25 | u8 buf[SHA_MAX_BLOCK_SIZE]; |
24 | int func; /* KIMD function to use */ | 26 | int func; /* KIMD function to use */ |
25 | }; | 27 | }; |
26 | 28 | ||
diff --git a/arch/s390/crypto/sha3_256_s390.c b/arch/s390/crypto/sha3_256_s390.c new file mode 100644 index 000000000000..460cbbbaa44a --- /dev/null +++ b/arch/s390/crypto/sha3_256_s390.c | |||
@@ -0,0 +1,147 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | /* | ||
3 | * Cryptographic API. | ||
4 | * | ||
5 | * s390 implementation of the SHA256 and SHA224 Secure Hash Algorithm. | ||
6 | * | ||
7 | * s390 Version: | ||
8 | * Copyright IBM Corp. 2019 | ||
9 | * Author(s): Joerg Schmidbauer (jschmidb@de.ibm.com) | ||
10 | */ | ||
11 | #include <crypto/internal/hash.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/cpufeature.h> | ||
15 | #include <crypto/sha.h> | ||
16 | #include <crypto/sha3.h> | ||
17 | #include <asm/cpacf.h> | ||
18 | |||
19 | #include "sha.h" | ||
20 | |||
21 | static int sha3_256_init(struct shash_desc *desc) | ||
22 | { | ||
23 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
24 | |||
25 | memset(sctx->state, 0, sizeof(sctx->state)); | ||
26 | sctx->count = 0; | ||
27 | sctx->func = CPACF_KIMD_SHA3_256; | ||
28 | |||
29 | return 0; | ||
30 | } | ||
31 | |||
32 | static int sha3_256_export(struct shash_desc *desc, void *out) | ||
33 | { | ||
34 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
35 | struct sha3_state *octx = out; | ||
36 | |||
37 | octx->rsiz = sctx->count; | ||
38 | memcpy(octx->st, sctx->state, sizeof(octx->st)); | ||
39 | memcpy(octx->buf, sctx->buf, sizeof(octx->buf)); | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | static int sha3_256_import(struct shash_desc *desc, const void *in) | ||
45 | { | ||
46 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
47 | const struct sha3_state *ictx = in; | ||
48 | |||
49 | sctx->count = ictx->rsiz; | ||
50 | memcpy(sctx->state, ictx->st, sizeof(ictx->st)); | ||
51 | memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); | ||
52 | sctx->func = CPACF_KIMD_SHA3_256; | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static int sha3_224_import(struct shash_desc *desc, const void *in) | ||
58 | { | ||
59 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
60 | const struct sha3_state *ictx = in; | ||
61 | |||
62 | sctx->count = ictx->rsiz; | ||
63 | memcpy(sctx->state, ictx->st, sizeof(ictx->st)); | ||
64 | memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); | ||
65 | sctx->func = CPACF_KIMD_SHA3_224; | ||
66 | |||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static struct shash_alg sha3_256_alg = { | ||
71 | .digestsize = SHA3_256_DIGEST_SIZE, /* = 32 */ | ||
72 | .init = sha3_256_init, | ||
73 | .update = s390_sha_update, | ||
74 | .final = s390_sha_final, | ||
75 | .export = sha3_256_export, | ||
76 | .import = sha3_256_import, | ||
77 | .descsize = sizeof(struct s390_sha_ctx), | ||
78 | .statesize = sizeof(struct sha3_state), | ||
79 | .base = { | ||
80 | .cra_name = "sha3-256", | ||
81 | .cra_driver_name = "sha3-256-s390", | ||
82 | .cra_priority = 300, | ||
83 | .cra_blocksize = SHA3_256_BLOCK_SIZE, | ||
84 | .cra_module = THIS_MODULE, | ||
85 | } | ||
86 | }; | ||
87 | |||
88 | static int sha3_224_init(struct shash_desc *desc) | ||
89 | { | ||
90 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
91 | |||
92 | memset(sctx->state, 0, sizeof(sctx->state)); | ||
93 | sctx->count = 0; | ||
94 | sctx->func = CPACF_KIMD_SHA3_224; | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static struct shash_alg sha3_224_alg = { | ||
100 | .digestsize = SHA3_224_DIGEST_SIZE, | ||
101 | .init = sha3_224_init, | ||
102 | .update = s390_sha_update, | ||
103 | .final = s390_sha_final, | ||
104 | .export = sha3_256_export, /* same as for 256 */ | ||
105 | .import = sha3_224_import, /* function code different! */ | ||
106 | .descsize = sizeof(struct s390_sha_ctx), | ||
107 | .statesize = sizeof(struct sha3_state), | ||
108 | .base = { | ||
109 | .cra_name = "sha3-224", | ||
110 | .cra_driver_name = "sha3-224-s390", | ||
111 | .cra_priority = 300, | ||
112 | .cra_blocksize = SHA3_224_BLOCK_SIZE, | ||
113 | .cra_module = THIS_MODULE, | ||
114 | } | ||
115 | }; | ||
116 | |||
117 | static int __init sha3_256_s390_init(void) | ||
118 | { | ||
119 | int ret; | ||
120 | |||
121 | if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_256)) | ||
122 | return -ENODEV; | ||
123 | |||
124 | ret = crypto_register_shash(&sha3_256_alg); | ||
125 | if (ret < 0) | ||
126 | goto out; | ||
127 | |||
128 | ret = crypto_register_shash(&sha3_224_alg); | ||
129 | if (ret < 0) | ||
130 | crypto_unregister_shash(&sha3_256_alg); | ||
131 | out: | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | static void __exit sha3_256_s390_fini(void) | ||
136 | { | ||
137 | crypto_unregister_shash(&sha3_224_alg); | ||
138 | crypto_unregister_shash(&sha3_256_alg); | ||
139 | } | ||
140 | |||
141 | module_cpu_feature_match(MSA, sha3_256_s390_init); | ||
142 | module_exit(sha3_256_s390_fini); | ||
143 | |||
144 | MODULE_ALIAS_CRYPTO("sha3-256"); | ||
145 | MODULE_ALIAS_CRYPTO("sha3-224"); | ||
146 | MODULE_LICENSE("GPL"); | ||
147 | MODULE_DESCRIPTION("SHA3-256 and SHA3-224 Secure Hash Algorithm"); | ||
diff --git a/arch/s390/crypto/sha3_512_s390.c b/arch/s390/crypto/sha3_512_s390.c new file mode 100644 index 000000000000..72cf460a53e5 --- /dev/null +++ b/arch/s390/crypto/sha3_512_s390.c | |||
@@ -0,0 +1,155 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | /* | ||
3 | * Cryptographic API. | ||
4 | * | ||
5 | * s390 implementation of the SHA512 and SHA384 Secure Hash Algorithm. | ||
6 | * | ||
7 | * Copyright IBM Corp. 2019 | ||
8 | * Author(s): Joerg Schmidbauer (jschmidb@de.ibm.com) | ||
9 | */ | ||
10 | #include <crypto/internal/hash.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/cpufeature.h> | ||
14 | #include <crypto/sha.h> | ||
15 | #include <crypto/sha3.h> | ||
16 | #include <asm/cpacf.h> | ||
17 | |||
18 | #include "sha.h" | ||
19 | |||
20 | static int sha3_512_init(struct shash_desc *desc) | ||
21 | { | ||
22 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
23 | |||
24 | memset(sctx->state, 0, sizeof(sctx->state)); | ||
25 | sctx->count = 0; | ||
26 | sctx->func = CPACF_KIMD_SHA3_512; | ||
27 | |||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | static int sha3_512_export(struct shash_desc *desc, void *out) | ||
32 | { | ||
33 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
34 | struct sha3_state *octx = out; | ||
35 | |||
36 | octx->rsiz = sctx->count; | ||
37 | octx->rsizw = sctx->count >> 32; | ||
38 | |||
39 | memcpy(octx->st, sctx->state, sizeof(octx->st)); | ||
40 | memcpy(octx->buf, sctx->buf, sizeof(octx->buf)); | ||
41 | |||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | static int sha3_512_import(struct shash_desc *desc, const void *in) | ||
46 | { | ||
47 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
48 | const struct sha3_state *ictx = in; | ||
49 | |||
50 | if (unlikely(ictx->rsizw)) | ||
51 | return -ERANGE; | ||
52 | sctx->count = ictx->rsiz; | ||
53 | |||
54 | memcpy(sctx->state, ictx->st, sizeof(ictx->st)); | ||
55 | memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); | ||
56 | sctx->func = CPACF_KIMD_SHA3_512; | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | static int sha3_384_import(struct shash_desc *desc, const void *in) | ||
62 | { | ||
63 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
64 | const struct sha3_state *ictx = in; | ||
65 | |||
66 | if (unlikely(ictx->rsizw)) | ||
67 | return -ERANGE; | ||
68 | sctx->count = ictx->rsiz; | ||
69 | |||
70 | memcpy(sctx->state, ictx->st, sizeof(ictx->st)); | ||
71 | memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); | ||
72 | sctx->func = CPACF_KIMD_SHA3_384; | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static struct shash_alg sha3_512_alg = { | ||
78 | .digestsize = SHA3_512_DIGEST_SIZE, | ||
79 | .init = sha3_512_init, | ||
80 | .update = s390_sha_update, | ||
81 | .final = s390_sha_final, | ||
82 | .export = sha3_512_export, | ||
83 | .import = sha3_512_import, | ||
84 | .descsize = sizeof(struct s390_sha_ctx), | ||
85 | .statesize = sizeof(struct sha3_state), | ||
86 | .base = { | ||
87 | .cra_name = "sha3-512", | ||
88 | .cra_driver_name = "sha3-512-s390", | ||
89 | .cra_priority = 300, | ||
90 | .cra_blocksize = SHA3_512_BLOCK_SIZE, | ||
91 | .cra_module = THIS_MODULE, | ||
92 | } | ||
93 | }; | ||
94 | |||
95 | MODULE_ALIAS_CRYPTO("sha3-512"); | ||
96 | |||
97 | static int sha3_384_init(struct shash_desc *desc) | ||
98 | { | ||
99 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
100 | |||
101 | memset(sctx->state, 0, sizeof(sctx->state)); | ||
102 | sctx->count = 0; | ||
103 | sctx->func = CPACF_KIMD_SHA3_384; | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static struct shash_alg sha3_384_alg = { | ||
109 | .digestsize = SHA3_384_DIGEST_SIZE, | ||
110 | .init = sha3_384_init, | ||
111 | .update = s390_sha_update, | ||
112 | .final = s390_sha_final, | ||
113 | .export = sha3_512_export, /* same as for 512 */ | ||
114 | .import = sha3_384_import, /* function code different! */ | ||
115 | .descsize = sizeof(struct s390_sha_ctx), | ||
116 | .statesize = sizeof(struct sha3_state), | ||
117 | .base = { | ||
118 | .cra_name = "sha3-384", | ||
119 | .cra_driver_name = "sha3-384-s390", | ||
120 | .cra_priority = 300, | ||
121 | .cra_blocksize = SHA3_384_BLOCK_SIZE, | ||
122 | .cra_ctxsize = sizeof(struct s390_sha_ctx), | ||
123 | .cra_module = THIS_MODULE, | ||
124 | } | ||
125 | }; | ||
126 | |||
127 | MODULE_ALIAS_CRYPTO("sha3-384"); | ||
128 | |||
129 | static int __init init(void) | ||
130 | { | ||
131 | int ret; | ||
132 | |||
133 | if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_512)) | ||
134 | return -ENODEV; | ||
135 | ret = crypto_register_shash(&sha3_512_alg); | ||
136 | if (ret < 0) | ||
137 | goto out; | ||
138 | ret = crypto_register_shash(&sha3_384_alg); | ||
139 | if (ret < 0) | ||
140 | crypto_unregister_shash(&sha3_512_alg); | ||
141 | out: | ||
142 | return ret; | ||
143 | } | ||
144 | |||
145 | static void __exit fini(void) | ||
146 | { | ||
147 | crypto_unregister_shash(&sha3_512_alg); | ||
148 | crypto_unregister_shash(&sha3_384_alg); | ||
149 | } | ||
150 | |||
151 | module_cpu_feature_match(MSA, init); | ||
152 | module_exit(fini); | ||
153 | |||
154 | MODULE_LICENSE("GPL"); | ||
155 | MODULE_DESCRIPTION("SHA3-512 and SHA3-384 Secure Hash Algorithm"); | ||
diff --git a/arch/s390/crypto/sha_common.c b/arch/s390/crypto/sha_common.c index cf0718d121bc..d39e0f079217 100644 --- a/arch/s390/crypto/sha_common.c +++ b/arch/s390/crypto/sha_common.c | |||
@@ -20,7 +20,7 @@ int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len) | |||
20 | unsigned int index, n; | 20 | unsigned int index, n; |
21 | 21 | ||
22 | /* how much is already in the buffer? */ | 22 | /* how much is already in the buffer? */ |
23 | index = ctx->count & (bsize - 1); | 23 | index = ctx->count % bsize; |
24 | ctx->count += len; | 24 | ctx->count += len; |
25 | 25 | ||
26 | if ((index + len) < bsize) | 26 | if ((index + len) < bsize) |
@@ -37,7 +37,7 @@ int s390_sha_update(struct shash_desc *desc, const u8 *data, unsigned int len) | |||
37 | 37 | ||
38 | /* process as many blocks as possible */ | 38 | /* process as many blocks as possible */ |
39 | if (len >= bsize) { | 39 | if (len >= bsize) { |
40 | n = len & ~(bsize - 1); | 40 | n = (len / bsize) * bsize; |
41 | cpacf_kimd(ctx->func, ctx->state, data, n); | 41 | cpacf_kimd(ctx->func, ctx->state, data, n); |
42 | data += n; | 42 | data += n; |
43 | len -= n; | 43 | len -= n; |
@@ -50,34 +50,63 @@ store: | |||
50 | } | 50 | } |
51 | EXPORT_SYMBOL_GPL(s390_sha_update); | 51 | EXPORT_SYMBOL_GPL(s390_sha_update); |
52 | 52 | ||
53 | static int s390_crypto_shash_parmsize(int func) | ||
54 | { | ||
55 | switch (func) { | ||
56 | case CPACF_KLMD_SHA_1: | ||
57 | return 20; | ||
58 | case CPACF_KLMD_SHA_256: | ||
59 | return 32; | ||
60 | case CPACF_KLMD_SHA_512: | ||
61 | return 64; | ||
62 | case CPACF_KLMD_SHA3_224: | ||
63 | case CPACF_KLMD_SHA3_256: | ||
64 | case CPACF_KLMD_SHA3_384: | ||
65 | case CPACF_KLMD_SHA3_512: | ||
66 | return 200; | ||
67 | default: | ||
68 | return -EINVAL; | ||
69 | } | ||
70 | } | ||
71 | |||
53 | int s390_sha_final(struct shash_desc *desc, u8 *out) | 72 | int s390_sha_final(struct shash_desc *desc, u8 *out) |
54 | { | 73 | { |
55 | struct s390_sha_ctx *ctx = shash_desc_ctx(desc); | 74 | struct s390_sha_ctx *ctx = shash_desc_ctx(desc); |
56 | unsigned int bsize = crypto_shash_blocksize(desc->tfm); | 75 | unsigned int bsize = crypto_shash_blocksize(desc->tfm); |
57 | u64 bits; | 76 | u64 bits; |
58 | unsigned int index, end, plen; | 77 | unsigned int n, mbl_offset; |
59 | |||
60 | /* SHA-512 uses 128 bit padding length */ | ||
61 | plen = (bsize > SHA256_BLOCK_SIZE) ? 16 : 8; | ||
62 | 78 | ||
63 | /* must perform manual padding */ | 79 | n = ctx->count % bsize; |
64 | index = ctx->count & (bsize - 1); | ||
65 | end = (index < bsize - plen) ? bsize : (2 * bsize); | ||
66 | |||
67 | /* start pad with 1 */ | ||
68 | ctx->buf[index] = 0x80; | ||
69 | index++; | ||
70 | |||
71 | /* pad with zeros */ | ||
72 | memset(ctx->buf + index, 0x00, end - index - 8); | ||
73 | |||
74 | /* | ||
75 | * Append message length. Well, SHA-512 wants a 128 bit length value, | ||
76 | * nevertheless we use u64, should be enough for now... | ||
77 | */ | ||
78 | bits = ctx->count * 8; | 80 | bits = ctx->count * 8; |
79 | memcpy(ctx->buf + end - 8, &bits, sizeof(bits)); | 81 | mbl_offset = s390_crypto_shash_parmsize(ctx->func) / sizeof(u32); |
80 | cpacf_kimd(ctx->func, ctx->state, ctx->buf, end); | 82 | if (mbl_offset < 0) |
83 | return -EINVAL; | ||
84 | |||
85 | /* set total msg bit length (mbl) in CPACF parmblock */ | ||
86 | switch (ctx->func) { | ||
87 | case CPACF_KLMD_SHA_1: | ||
88 | case CPACF_KLMD_SHA_256: | ||
89 | memcpy(ctx->state + mbl_offset, &bits, sizeof(bits)); | ||
90 | break; | ||
91 | case CPACF_KLMD_SHA_512: | ||
92 | /* | ||
93 | * the SHA512 parmblock has a 128-bit mbl field, clear | ||
94 | * high-order u64 field, copy bits to low-order u64 field | ||
95 | */ | ||
96 | memset(ctx->state + mbl_offset, 0x00, sizeof(bits)); | ||
97 | mbl_offset += sizeof(u64) / sizeof(u32); | ||
98 | memcpy(ctx->state + mbl_offset, &bits, sizeof(bits)); | ||
99 | break; | ||
100 | case CPACF_KLMD_SHA3_224: | ||
101 | case CPACF_KLMD_SHA3_256: | ||
102 | case CPACF_KLMD_SHA3_384: | ||
103 | case CPACF_KLMD_SHA3_512: | ||
104 | break; | ||
105 | default: | ||
106 | return -EINVAL; | ||
107 | } | ||
108 | |||
109 | cpacf_klmd(ctx->func, ctx->state, ctx->buf, n); | ||
81 | 110 | ||
82 | /* copy digest to out */ | 111 | /* copy digest to out */ |
83 | memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm)); | 112 | memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm)); |
diff --git a/arch/s390/include/asm/cpacf.h b/arch/s390/include/asm/cpacf.h index e3d53eb6bcf5..a092f63aac6a 100644 --- a/arch/s390/include/asm/cpacf.h +++ b/arch/s390/include/asm/cpacf.h | |||
@@ -93,6 +93,10 @@ | |||
93 | #define CPACF_KIMD_SHA_1 0x01 | 93 | #define CPACF_KIMD_SHA_1 0x01 |
94 | #define CPACF_KIMD_SHA_256 0x02 | 94 | #define CPACF_KIMD_SHA_256 0x02 |
95 | #define CPACF_KIMD_SHA_512 0x03 | 95 | #define CPACF_KIMD_SHA_512 0x03 |
96 | #define CPACF_KIMD_SHA3_224 0x20 | ||
97 | #define CPACF_KIMD_SHA3_256 0x21 | ||
98 | #define CPACF_KIMD_SHA3_384 0x22 | ||
99 | #define CPACF_KIMD_SHA3_512 0x23 | ||
96 | #define CPACF_KIMD_GHASH 0x41 | 100 | #define CPACF_KIMD_GHASH 0x41 |
97 | 101 | ||
98 | /* | 102 | /* |
@@ -103,6 +107,10 @@ | |||
103 | #define CPACF_KLMD_SHA_1 0x01 | 107 | #define CPACF_KLMD_SHA_1 0x01 |
104 | #define CPACF_KLMD_SHA_256 0x02 | 108 | #define CPACF_KLMD_SHA_256 0x02 |
105 | #define CPACF_KLMD_SHA_512 0x03 | 109 | #define CPACF_KLMD_SHA_512 0x03 |
110 | #define CPACF_KLMD_SHA3_224 0x20 | ||
111 | #define CPACF_KLMD_SHA3_256 0x21 | ||
112 | #define CPACF_KLMD_SHA3_384 0x22 | ||
113 | #define CPACF_KLMD_SHA3_512 0x23 | ||
106 | 114 | ||
107 | /* | 115 | /* |
108 | * function codes for the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) | 116 | * function codes for the KMAC (COMPUTE MESSAGE AUTHENTICATION CODE) |
diff --git a/arch/s390/include/asm/gmap.h b/arch/s390/include/asm/gmap.h index fcbd638fb9f4..37f96b6f0e61 100644 --- a/arch/s390/include/asm/gmap.h +++ b/arch/s390/include/asm/gmap.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #ifndef _ASM_S390_GMAP_H | 9 | #ifndef _ASM_S390_GMAP_H |
10 | #define _ASM_S390_GMAP_H | 10 | #define _ASM_S390_GMAP_H |
11 | 11 | ||
12 | #include <linux/refcount.h> | ||
13 | |||
12 | /* Generic bits for GMAP notification on DAT table entry changes. */ | 14 | /* Generic bits for GMAP notification on DAT table entry changes. */ |
13 | #define GMAP_NOTIFY_SHADOW 0x2 | 15 | #define GMAP_NOTIFY_SHADOW 0x2 |
14 | #define GMAP_NOTIFY_MPROT 0x1 | 16 | #define GMAP_NOTIFY_MPROT 0x1 |
@@ -46,7 +48,7 @@ struct gmap { | |||
46 | struct radix_tree_root guest_to_host; | 48 | struct radix_tree_root guest_to_host; |
47 | struct radix_tree_root host_to_guest; | 49 | struct radix_tree_root host_to_guest; |
48 | spinlock_t guest_table_lock; | 50 | spinlock_t guest_table_lock; |
49 | atomic_t ref_count; | 51 | refcount_t ref_count; |
50 | unsigned long *table; | 52 | unsigned long *table; |
51 | unsigned long asce; | 53 | unsigned long asce; |
52 | unsigned long asce_end; | 54 | unsigned long asce_end; |
diff --git a/arch/s390/include/asm/mem_detect.h b/arch/s390/include/asm/mem_detect.h index 6114b92ab667..a7c922a69050 100644 --- a/arch/s390/include/asm/mem_detect.h +++ b/arch/s390/include/asm/mem_detect.h | |||
@@ -79,4 +79,16 @@ static inline void get_mem_detect_reserved(unsigned long *start, | |||
79 | *size = 0; | 79 | *size = 0; |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline unsigned long get_mem_detect_end(void) | ||
83 | { | ||
84 | unsigned long start; | ||
85 | unsigned long end; | ||
86 | |||
87 | if (mem_detect.count) { | ||
88 | __get_mem_detect_block(mem_detect.count - 1, &start, &end); | ||
89 | return end; | ||
90 | } | ||
91 | return 0; | ||
92 | } | ||
93 | |||
82 | #endif | 94 | #endif |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 9b274fcaacb6..0c4600725fc2 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -86,6 +86,7 @@ extern unsigned long zero_page_mask; | |||
86 | */ | 86 | */ |
87 | extern unsigned long VMALLOC_START; | 87 | extern unsigned long VMALLOC_START; |
88 | extern unsigned long VMALLOC_END; | 88 | extern unsigned long VMALLOC_END; |
89 | #define VMALLOC_DEFAULT_SIZE ((128UL << 30) - MODULES_LEN) | ||
89 | extern struct page *vmemmap; | 90 | extern struct page *vmemmap; |
90 | 91 | ||
91 | #define VMEM_MAX_PHYS ((unsigned long) vmemmap) | 92 | #define VMEM_MAX_PHYS ((unsigned long) vmemmap) |
diff --git a/arch/s390/include/asm/pkey.h b/arch/s390/include/asm/pkey.h index 9b6e79077866..dd3d20c332ac 100644 --- a/arch/s390/include/asm/pkey.h +++ b/arch/s390/include/asm/pkey.h | |||
@@ -2,7 +2,7 @@ | |||
2 | /* | 2 | /* |
3 | * Kernelspace interface to the pkey device driver | 3 | * Kernelspace interface to the pkey device driver |
4 | * | 4 | * |
5 | * Copyright IBM Corp. 2016 | 5 | * Copyright IBM Corp. 2016,2019 |
6 | * | 6 | * |
7 | * Author: Harald Freudenberger <freude@de.ibm.com> | 7 | * Author: Harald Freudenberger <freude@de.ibm.com> |
8 | * | 8 | * |
@@ -16,123 +16,13 @@ | |||
16 | #include <uapi/asm/pkey.h> | 16 | #include <uapi/asm/pkey.h> |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * Generate (AES) random secure key. | ||
20 | * @param cardnr may be -1 (use default card) | ||
21 | * @param domain may be -1 (use default domain) | ||
22 | * @param keytype one of the PKEY_KEYTYPE values | ||
23 | * @param seckey pointer to buffer receiving the secure key | ||
24 | * @return 0 on success, negative errno value on failure | ||
25 | */ | ||
26 | int pkey_genseckey(__u16 cardnr, __u16 domain, | ||
27 | __u32 keytype, struct pkey_seckey *seckey); | ||
28 | |||
29 | /* | ||
30 | * Generate (AES) secure key with given key value. | ||
31 | * @param cardnr may be -1 (use default card) | ||
32 | * @param domain may be -1 (use default domain) | ||
33 | * @param keytype one of the PKEY_KEYTYPE values | ||
34 | * @param clrkey pointer to buffer with clear key data | ||
35 | * @param seckey pointer to buffer receiving the secure key | ||
36 | * @return 0 on success, negative errno value on failure | ||
37 | */ | ||
38 | int pkey_clr2seckey(__u16 cardnr, __u16 domain, __u32 keytype, | ||
39 | const struct pkey_clrkey *clrkey, | ||
40 | struct pkey_seckey *seckey); | ||
41 | |||
42 | /* | ||
43 | * Derive (AES) proteced key from the (AES) secure key blob. | ||
44 | * @param cardnr may be -1 (use default card) | ||
45 | * @param domain may be -1 (use default domain) | ||
46 | * @param seckey pointer to buffer with the input secure key | ||
47 | * @param protkey pointer to buffer receiving the protected key and | ||
48 | * additional info (type, length) | ||
49 | * @return 0 on success, negative errno value on failure | ||
50 | */ | ||
51 | int pkey_sec2protkey(__u16 cardnr, __u16 domain, | ||
52 | const struct pkey_seckey *seckey, | ||
53 | struct pkey_protkey *protkey); | ||
54 | |||
55 | /* | ||
56 | * Derive (AES) protected key from a given clear key value. | ||
57 | * @param keytype one of the PKEY_KEYTYPE values | ||
58 | * @param clrkey pointer to buffer with clear key data | ||
59 | * @param protkey pointer to buffer receiving the protected key and | ||
60 | * additional info (type, length) | ||
61 | * @return 0 on success, negative errno value on failure | ||
62 | */ | ||
63 | int pkey_clr2protkey(__u32 keytype, | ||
64 | const struct pkey_clrkey *clrkey, | ||
65 | struct pkey_protkey *protkey); | ||
66 | |||
67 | /* | ||
68 | * Search for a matching crypto card based on the Master Key | ||
69 | * Verification Pattern provided inside a secure key. | ||
70 | * @param seckey pointer to buffer with the input secure key | ||
71 | * @param cardnr pointer to cardnr, receives the card number on success | ||
72 | * @param domain pointer to domain, receives the domain number on success | ||
73 | * @param verify if set, always verify by fetching verification pattern | ||
74 | * from card | ||
75 | * @return 0 on success, negative errno value on failure. If no card could be | ||
76 | * found, -ENODEV is returned. | ||
77 | */ | ||
78 | int pkey_findcard(const struct pkey_seckey *seckey, | ||
79 | __u16 *cardnr, __u16 *domain, int verify); | ||
80 | |||
81 | /* | ||
82 | * Find card and transform secure key to protected key. | ||
83 | * @param seckey pointer to buffer with the input secure key | ||
84 | * @param protkey pointer to buffer receiving the protected key and | ||
85 | * additional info (type, length) | ||
86 | * @return 0 on success, negative errno value on failure | ||
87 | */ | ||
88 | int pkey_skey2pkey(const struct pkey_seckey *seckey, | ||
89 | struct pkey_protkey *protkey); | ||
90 | |||
91 | /* | ||
92 | * Verify the given secure key for being able to be useable with | ||
93 | * the pkey module. Check for correct key type and check for having at | ||
94 | * least one crypto card being able to handle this key (master key | ||
95 | * or old master key verification pattern matches). | ||
96 | * Return some info about the key: keysize in bits, keytype (currently | ||
97 | * only AES), flag if key is wrapped with an old MKVP. | ||
98 | * @param seckey pointer to buffer with the input secure key | ||
99 | * @param pcardnr pointer to cardnr, receives the card number on success | ||
100 | * @param pdomain pointer to domain, receives the domain number on success | ||
101 | * @param pkeysize pointer to keysize, receives the bitsize of the key | ||
102 | * @param pattributes pointer to attributes, receives additional info | ||
103 | * PKEY_VERIFY_ATTR_AES if the key is an AES key | ||
104 | * PKEY_VERIFY_ATTR_OLD_MKVP if key has old mkvp stored in | ||
105 | * @return 0 on success, negative errno value on failure. If no card could | ||
106 | * be found which is able to handle this key, -ENODEV is returned. | ||
107 | */ | ||
108 | int pkey_verifykey(const struct pkey_seckey *seckey, | ||
109 | u16 *pcardnr, u16 *pdomain, | ||
110 | u16 *pkeysize, u32 *pattributes); | ||
111 | |||
112 | /* | ||
113 | * In-kernel API: Generate (AES) random protected key. | ||
114 | * @param keytype one of the PKEY_KEYTYPE values | ||
115 | * @param protkey pointer to buffer receiving the protected key | ||
116 | * @return 0 on success, negative errno value on failure | ||
117 | */ | ||
118 | int pkey_genprotkey(__u32 keytype, struct pkey_protkey *protkey); | ||
119 | |||
120 | /* | ||
121 | * In-kernel API: Verify an (AES) protected key. | ||
122 | * @param protkey pointer to buffer containing the protected key to verify | ||
123 | * @return 0 on success, negative errno value on failure. In case the protected | ||
124 | * key is not valid -EKEYREJECTED is returned | ||
125 | */ | ||
126 | int pkey_verifyprotkey(const struct pkey_protkey *protkey); | ||
127 | |||
128 | /* | ||
129 | * In-kernel API: Transform an key blob (of any type) into a protected key. | 19 | * In-kernel API: Transform an key blob (of any type) into a protected key. |
130 | * @param key pointer to a buffer containing the key blob | 20 | * @param key pointer to a buffer containing the key blob |
131 | * @param keylen size of the key blob in bytes | 21 | * @param keylen size of the key blob in bytes |
132 | * @param protkey pointer to buffer receiving the protected key | 22 | * @param protkey pointer to buffer receiving the protected key |
133 | * @return 0 on success, negative errno value on failure | 23 | * @return 0 on success, negative errno value on failure |
134 | */ | 24 | */ |
135 | int pkey_keyblob2pkey(const __u8 *key, __u32 keylen, | 25 | int pkey_keyblob2pkey(const u8 *key, u32 keylen, |
136 | struct pkey_protkey *protkey); | 26 | struct pkey_protkey *protkey); |
137 | 27 | ||
138 | #endif /* _KAPI_PKEY_H */ | 28 | #endif /* _KAPI_PKEY_H */ |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index d56c519bc696..51a0e4a2dc96 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
@@ -324,11 +324,9 @@ static inline void __noreturn disabled_wait(void) | |||
324 | * Basic Machine Check/Program Check Handler. | 324 | * Basic Machine Check/Program Check Handler. |
325 | */ | 325 | */ |
326 | 326 | ||
327 | extern void s390_base_mcck_handler(void); | ||
328 | extern void s390_base_pgm_handler(void); | 327 | extern void s390_base_pgm_handler(void); |
329 | extern void s390_base_ext_handler(void); | 328 | extern void s390_base_ext_handler(void); |
330 | 329 | ||
331 | extern void (*s390_base_mcck_handler_fn)(void); | ||
332 | extern void (*s390_base_pgm_handler_fn)(void); | 330 | extern void (*s390_base_pgm_handler_fn)(void); |
333 | extern void (*s390_base_ext_handler_fn)(void); | 331 | extern void (*s390_base_ext_handler_fn)(void); |
334 | 332 | ||
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 70bd65724ec4..6dc6c4fbc8e2 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h | |||
@@ -83,6 +83,7 @@ struct parmarea { | |||
83 | extern int noexec_disabled; | 83 | extern int noexec_disabled; |
84 | extern int memory_end_set; | 84 | extern int memory_end_set; |
85 | extern unsigned long memory_end; | 85 | extern unsigned long memory_end; |
86 | extern unsigned long vmalloc_size; | ||
86 | extern unsigned long max_physmem_end; | 87 | extern unsigned long max_physmem_end; |
87 | extern unsigned long __swsusp_reset_dma; | 88 | extern unsigned long __swsusp_reset_dma; |
88 | 89 | ||
diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h index 70d87db54e62..4c0690fc5167 100644 --- a/arch/s390/include/asm/string.h +++ b/arch/s390/include/asm/string.h | |||
@@ -71,11 +71,16 @@ extern void *__memmove(void *dest, const void *src, size_t n); | |||
71 | #define memcpy(dst, src, len) __memcpy(dst, src, len) | 71 | #define memcpy(dst, src, len) __memcpy(dst, src, len) |
72 | #define memmove(dst, src, len) __memmove(dst, src, len) | 72 | #define memmove(dst, src, len) __memmove(dst, src, len) |
73 | #define memset(s, c, n) __memset(s, c, n) | 73 | #define memset(s, c, n) __memset(s, c, n) |
74 | #define strlen(s) __strlen(s) | ||
75 | |||
76 | #define __no_sanitize_prefix_strfunc(x) __##x | ||
74 | 77 | ||
75 | #ifndef __NO_FORTIFY | 78 | #ifndef __NO_FORTIFY |
76 | #define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */ | 79 | #define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */ |
77 | #endif | 80 | #endif |
78 | 81 | ||
82 | #else | ||
83 | #define __no_sanitize_prefix_strfunc(x) x | ||
79 | #endif /* defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) */ | 84 | #endif /* defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) */ |
80 | 85 | ||
81 | void *__memset16(uint16_t *s, uint16_t v, size_t count); | 86 | void *__memset16(uint16_t *s, uint16_t v, size_t count); |
@@ -163,8 +168,8 @@ static inline char *strcpy(char *dst, const char *src) | |||
163 | } | 168 | } |
164 | #endif | 169 | #endif |
165 | 170 | ||
166 | #ifdef __HAVE_ARCH_STRLEN | 171 | #if defined(__HAVE_ARCH_STRLEN) || (defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)) |
167 | static inline size_t strlen(const char *s) | 172 | static inline size_t __no_sanitize_prefix_strfunc(strlen)(const char *s) |
168 | { | 173 | { |
169 | register unsigned long r0 asm("0") = 0; | 174 | register unsigned long r0 asm("0") = 0; |
170 | const char *tmp = s; | 175 | const char *tmp = s; |
diff --git a/arch/s390/include/uapi/asm/pkey.h b/arch/s390/include/uapi/asm/pkey.h index c0e86ce4a00b..e22f0720bbb8 100644 --- a/arch/s390/include/uapi/asm/pkey.h +++ b/arch/s390/include/uapi/asm/pkey.h | |||
@@ -2,7 +2,7 @@ | |||
2 | /* | 2 | /* |
3 | * Userspace interface to the pkey device driver | 3 | * Userspace interface to the pkey device driver |
4 | * | 4 | * |
5 | * Copyright IBM Corp. 2017 | 5 | * Copyright IBM Corp. 2017, 2019 |
6 | * | 6 | * |
7 | * Author: Harald Freudenberger <freude@de.ibm.com> | 7 | * Author: Harald Freudenberger <freude@de.ibm.com> |
8 | * | 8 | * |
@@ -20,38 +20,74 @@ | |||
20 | 20 | ||
21 | #define PKEY_IOCTL_MAGIC 'p' | 21 | #define PKEY_IOCTL_MAGIC 'p' |
22 | 22 | ||
23 | #define SECKEYBLOBSIZE 64 /* secure key blob size is always 64 bytes */ | 23 | #define SECKEYBLOBSIZE 64 /* secure key blob size is always 64 bytes */ |
24 | #define PROTKEYBLOBSIZE 80 /* protected key blob size is always 80 bytes */ | 24 | #define PROTKEYBLOBSIZE 80 /* protected key blob size is always 80 bytes */ |
25 | #define MAXPROTKEYSIZE 64 /* a protected key blob may be up to 64 bytes */ | 25 | #define MAXPROTKEYSIZE 64 /* a protected key blob may be up to 64 bytes */ |
26 | #define MAXCLRKEYSIZE 32 /* a clear key value may be up to 32 bytes */ | 26 | #define MAXCLRKEYSIZE 32 /* a clear key value may be up to 32 bytes */ |
27 | #define MAXAESCIPHERKEYSIZE 136 /* our aes cipher keys have always 136 bytes */ | ||
27 | 28 | ||
28 | #define MINKEYBLOBSIZE SECKEYBLOBSIZE /* Minimum size of a key blob */ | 29 | /* Minimum and maximum size of a key blob */ |
29 | #define MAXKEYBLOBSIZE PROTKEYBLOBSIZE /* Maximum size of a key blob */ | 30 | #define MINKEYBLOBSIZE SECKEYBLOBSIZE |
31 | #define MAXKEYBLOBSIZE MAXAESCIPHERKEYSIZE | ||
30 | 32 | ||
31 | /* defines for the type field within the pkey_protkey struct */ | 33 | /* defines for the type field within the pkey_protkey struct */ |
32 | #define PKEY_KEYTYPE_AES_128 1 | 34 | #define PKEY_KEYTYPE_AES_128 1 |
33 | #define PKEY_KEYTYPE_AES_192 2 | 35 | #define PKEY_KEYTYPE_AES_192 2 |
34 | #define PKEY_KEYTYPE_AES_256 3 | 36 | #define PKEY_KEYTYPE_AES_256 3 |
35 | 37 | ||
36 | /* Struct to hold a secure key blob */ | 38 | /* the newer ioctls use a pkey_key_type enum for type information */ |
39 | enum pkey_key_type { | ||
40 | PKEY_TYPE_CCA_DATA = (__u32) 1, | ||
41 | PKEY_TYPE_CCA_CIPHER = (__u32) 2, | ||
42 | }; | ||
43 | |||
44 | /* the newer ioctls use a pkey_key_size enum for key size information */ | ||
45 | enum pkey_key_size { | ||
46 | PKEY_SIZE_AES_128 = (__u32) 128, | ||
47 | PKEY_SIZE_AES_192 = (__u32) 192, | ||
48 | PKEY_SIZE_AES_256 = (__u32) 256, | ||
49 | PKEY_SIZE_UNKNOWN = (__u32) 0xFFFFFFFF, | ||
50 | }; | ||
51 | |||
52 | /* some of the newer ioctls use these flags */ | ||
53 | #define PKEY_FLAGS_MATCH_CUR_MKVP 0x00000002 | ||
54 | #define PKEY_FLAGS_MATCH_ALT_MKVP 0x00000004 | ||
55 | |||
56 | /* keygenflags defines for CCA AES cipher keys */ | ||
57 | #define PKEY_KEYGEN_XPRT_SYM 0x00008000 | ||
58 | #define PKEY_KEYGEN_XPRT_UASY 0x00004000 | ||
59 | #define PKEY_KEYGEN_XPRT_AASY 0x00002000 | ||
60 | #define PKEY_KEYGEN_XPRT_RAW 0x00001000 | ||
61 | #define PKEY_KEYGEN_XPRT_CPAC 0x00000800 | ||
62 | #define PKEY_KEYGEN_XPRT_DES 0x00000080 | ||
63 | #define PKEY_KEYGEN_XPRT_AES 0x00000040 | ||
64 | #define PKEY_KEYGEN_XPRT_RSA 0x00000008 | ||
65 | |||
66 | /* Struct to hold apqn target info (card/domain pair) */ | ||
67 | struct pkey_apqn { | ||
68 | __u16 card; | ||
69 | __u16 domain; | ||
70 | }; | ||
71 | |||
72 | /* Struct to hold a CCA AES secure key blob */ | ||
37 | struct pkey_seckey { | 73 | struct pkey_seckey { |
38 | __u8 seckey[SECKEYBLOBSIZE]; /* the secure key blob */ | 74 | __u8 seckey[SECKEYBLOBSIZE]; /* the secure key blob */ |
39 | }; | 75 | }; |
40 | 76 | ||
41 | /* Struct to hold protected key and length info */ | 77 | /* Struct to hold protected key and length info */ |
42 | struct pkey_protkey { | 78 | struct pkey_protkey { |
43 | __u32 type; /* key type, one of the PKEY_KEYTYPE values */ | 79 | __u32 type; /* key type, one of the PKEY_KEYTYPE_AES values */ |
44 | __u32 len; /* bytes actually stored in protkey[] */ | 80 | __u32 len; /* bytes actually stored in protkey[] */ |
45 | __u8 protkey[MAXPROTKEYSIZE]; /* the protected key blob */ | 81 | __u8 protkey[MAXPROTKEYSIZE]; /* the protected key blob */ |
46 | }; | 82 | }; |
47 | 83 | ||
48 | /* Struct to hold a clear key value */ | 84 | /* Struct to hold an AES clear key value */ |
49 | struct pkey_clrkey { | 85 | struct pkey_clrkey { |
50 | __u8 clrkey[MAXCLRKEYSIZE]; /* 16, 24, or 32 byte clear key value */ | 86 | __u8 clrkey[MAXCLRKEYSIZE]; /* 16, 24, or 32 byte clear key value */ |
51 | }; | 87 | }; |
52 | 88 | ||
53 | /* | 89 | /* |
54 | * Generate secure key | 90 | * Generate CCA AES secure key. |
55 | */ | 91 | */ |
56 | struct pkey_genseck { | 92 | struct pkey_genseck { |
57 | __u16 cardnr; /* in: card to use or FFFF for any */ | 93 | __u16 cardnr; /* in: card to use or FFFF for any */ |
@@ -62,7 +98,7 @@ struct pkey_genseck { | |||
62 | #define PKEY_GENSECK _IOWR(PKEY_IOCTL_MAGIC, 0x01, struct pkey_genseck) | 98 | #define PKEY_GENSECK _IOWR(PKEY_IOCTL_MAGIC, 0x01, struct pkey_genseck) |
63 | 99 | ||
64 | /* | 100 | /* |
65 | * Construct secure key from clear key value | 101 | * Construct CCA AES secure key from clear key value |
66 | */ | 102 | */ |
67 | struct pkey_clr2seck { | 103 | struct pkey_clr2seck { |
68 | __u16 cardnr; /* in: card to use or FFFF for any */ | 104 | __u16 cardnr; /* in: card to use or FFFF for any */ |
@@ -74,7 +110,7 @@ struct pkey_clr2seck { | |||
74 | #define PKEY_CLR2SECK _IOWR(PKEY_IOCTL_MAGIC, 0x02, struct pkey_clr2seck) | 110 | #define PKEY_CLR2SECK _IOWR(PKEY_IOCTL_MAGIC, 0x02, struct pkey_clr2seck) |
75 | 111 | ||
76 | /* | 112 | /* |
77 | * Fabricate protected key from a secure key | 113 | * Fabricate AES protected key from a CCA AES secure key |
78 | */ | 114 | */ |
79 | struct pkey_sec2protk { | 115 | struct pkey_sec2protk { |
80 | __u16 cardnr; /* in: card to use or FFFF for any */ | 116 | __u16 cardnr; /* in: card to use or FFFF for any */ |
@@ -85,7 +121,7 @@ struct pkey_sec2protk { | |||
85 | #define PKEY_SEC2PROTK _IOWR(PKEY_IOCTL_MAGIC, 0x03, struct pkey_sec2protk) | 121 | #define PKEY_SEC2PROTK _IOWR(PKEY_IOCTL_MAGIC, 0x03, struct pkey_sec2protk) |
86 | 122 | ||
87 | /* | 123 | /* |
88 | * Fabricate protected key from an clear key value | 124 | * Fabricate AES protected key from clear key value |
89 | */ | 125 | */ |
90 | struct pkey_clr2protk { | 126 | struct pkey_clr2protk { |
91 | __u32 keytype; /* in: key type to generate */ | 127 | __u32 keytype; /* in: key type to generate */ |
@@ -96,7 +132,7 @@ struct pkey_clr2protk { | |||
96 | 132 | ||
97 | /* | 133 | /* |
98 | * Search for matching crypto card based on the Master Key | 134 | * Search for matching crypto card based on the Master Key |
99 | * Verification Pattern provided inside a secure key. | 135 | * Verification Pattern provided inside a CCA AES secure key. |
100 | */ | 136 | */ |
101 | struct pkey_findcard { | 137 | struct pkey_findcard { |
102 | struct pkey_seckey seckey; /* in: the secure key blob */ | 138 | struct pkey_seckey seckey; /* in: the secure key blob */ |
@@ -115,7 +151,7 @@ struct pkey_skey2pkey { | |||
115 | #define PKEY_SKEY2PKEY _IOWR(PKEY_IOCTL_MAGIC, 0x06, struct pkey_skey2pkey) | 151 | #define PKEY_SKEY2PKEY _IOWR(PKEY_IOCTL_MAGIC, 0x06, struct pkey_skey2pkey) |
116 | 152 | ||
117 | /* | 153 | /* |
118 | * Verify the given secure key for being able to be useable with | 154 | * Verify the given CCA AES secure key for being able to be useable with |
119 | * the pkey module. Check for correct key type and check for having at | 155 | * the pkey module. Check for correct key type and check for having at |
120 | * least one crypto card being able to handle this key (master key | 156 | * least one crypto card being able to handle this key (master key |
121 | * or old master key verification pattern matches). | 157 | * or old master key verification pattern matches). |
@@ -134,7 +170,7 @@ struct pkey_verifykey { | |||
134 | #define PKEY_VERIFY_ATTR_OLD_MKVP 0x00000100 /* key has old MKVP value */ | 170 | #define PKEY_VERIFY_ATTR_OLD_MKVP 0x00000100 /* key has old MKVP value */ |
135 | 171 | ||
136 | /* | 172 | /* |
137 | * Generate (AES) random protected key. | 173 | * Generate AES random protected key. |
138 | */ | 174 | */ |
139 | struct pkey_genprotk { | 175 | struct pkey_genprotk { |
140 | __u32 keytype; /* in: key type to generate */ | 176 | __u32 keytype; /* in: key type to generate */ |
@@ -144,7 +180,7 @@ struct pkey_genprotk { | |||
144 | #define PKEY_GENPROTK _IOWR(PKEY_IOCTL_MAGIC, 0x08, struct pkey_genprotk) | 180 | #define PKEY_GENPROTK _IOWR(PKEY_IOCTL_MAGIC, 0x08, struct pkey_genprotk) |
145 | 181 | ||
146 | /* | 182 | /* |
147 | * Verify an (AES) protected key. | 183 | * Verify an AES protected key. |
148 | */ | 184 | */ |
149 | struct pkey_verifyprotk { | 185 | struct pkey_verifyprotk { |
150 | struct pkey_protkey protkey; /* in: the protected key to verify */ | 186 | struct pkey_protkey protkey; /* in: the protected key to verify */ |
@@ -160,7 +196,184 @@ struct pkey_kblob2pkey { | |||
160 | __u32 keylen; /* in: the key blob length */ | 196 | __u32 keylen; /* in: the key blob length */ |
161 | struct pkey_protkey protkey; /* out: the protected key */ | 197 | struct pkey_protkey protkey; /* out: the protected key */ |
162 | }; | 198 | }; |
163 | |||
164 | #define PKEY_KBLOB2PROTK _IOWR(PKEY_IOCTL_MAGIC, 0x0A, struct pkey_kblob2pkey) | 199 | #define PKEY_KBLOB2PROTK _IOWR(PKEY_IOCTL_MAGIC, 0x0A, struct pkey_kblob2pkey) |
165 | 200 | ||
201 | /* | ||
202 | * Generate secure key, version 2. | ||
203 | * Generate either a CCA AES secure key or a CCA AES cipher key. | ||
204 | * There needs to be a list of apqns given with at least one entry in there. | ||
205 | * All apqns in the list need to be exact apqns, 0xFFFF as ANY card or domain | ||
206 | * is not supported. The implementation walks through the list of apqns and | ||
207 | * tries to send the request to each apqn without any further checking (like | ||
208 | * card type or online state). If the apqn fails, simple the next one in the | ||
209 | * list is tried until success (return 0) or the end of the list is reached | ||
210 | * (return -1 with errno ENODEV). You may use the PKEY_APQNS4KT ioctl to | ||
211 | * generate a list of apqns based on the key type to generate. | ||
212 | * The keygenflags argument is passed to the low level generation functions | ||
213 | * individual for the key type and has a key type specific meaning. Currently | ||
214 | * only CCA AES cipher keys react to this parameter: Use one or more of the | ||
215 | * PKEY_KEYGEN_* flags to widen the export possibilities. By default a cipher | ||
216 | * key is only exportable for CPACF (PKEY_KEYGEN_XPRT_CPAC). | ||
217 | */ | ||
218 | struct pkey_genseck2 { | ||
219 | struct pkey_apqn __user *apqns; /* in: ptr to list of apqn targets*/ | ||
220 | __u32 apqn_entries; /* in: # of apqn target list entries */ | ||
221 | enum pkey_key_type type; /* in: key type to generate */ | ||
222 | enum pkey_key_size size; /* in: key size to generate */ | ||
223 | __u32 keygenflags; /* in: key generation flags */ | ||
224 | __u8 __user *key; /* in: pointer to key blob buffer */ | ||
225 | __u32 keylen; /* in: available key blob buffer size */ | ||
226 | /* out: actual key blob size */ | ||
227 | }; | ||
228 | #define PKEY_GENSECK2 _IOWR(PKEY_IOCTL_MAGIC, 0x11, struct pkey_genseck2) | ||
229 | |||
230 | /* | ||
231 | * Generate secure key from clear key value, version 2. | ||
232 | * Construct a CCA AES secure key or CCA AES cipher key from a given clear key | ||
233 | * value. | ||
234 | * There needs to be a list of apqns given with at least one entry in there. | ||
235 | * All apqns in the list need to be exact apqns, 0xFFFF as ANY card or domain | ||
236 | * is not supported. The implementation walks through the list of apqns and | ||
237 | * tries to send the request to each apqn without any further checking (like | ||
238 | * card type or online state). If the apqn fails, simple the next one in the | ||
239 | * list is tried until success (return 0) or the end of the list is reached | ||
240 | * (return -1 with errno ENODEV). You may use the PKEY_APQNS4KT ioctl to | ||
241 | * generate a list of apqns based on the key type to generate. | ||
242 | * The keygenflags argument is passed to the low level generation functions | ||
243 | * individual for the key type and has a key type specific meaning. Currently | ||
244 | * only CCA AES cipher keys react to this parameter: Use one or more of the | ||
245 | * PKEY_KEYGEN_* flags to widen the export possibilities. By default a cipher | ||
246 | * key is only exportable for CPACF (PKEY_KEYGEN_XPRT_CPAC). | ||
247 | */ | ||
248 | struct pkey_clr2seck2 { | ||
249 | struct pkey_apqn __user *apqns; /* in: ptr to list of apqn targets */ | ||
250 | __u32 apqn_entries; /* in: # of apqn target list entries */ | ||
251 | enum pkey_key_type type; /* in: key type to generate */ | ||
252 | enum pkey_key_size size; /* in: key size to generate */ | ||
253 | __u32 keygenflags; /* in: key generation flags */ | ||
254 | struct pkey_clrkey clrkey; /* in: the clear key value */ | ||
255 | __u8 __user *key; /* in: pointer to key blob buffer */ | ||
256 | __u32 keylen; /* in: available key blob buffer size */ | ||
257 | /* out: actual key blob size */ | ||
258 | }; | ||
259 | #define PKEY_CLR2SECK2 _IOWR(PKEY_IOCTL_MAGIC, 0x12, struct pkey_clr2seck2) | ||
260 | |||
261 | /* | ||
262 | * Verify the given secure key, version 2. | ||
263 | * Check for correct key type. If cardnr and domain are given (are not | ||
264 | * 0xFFFF) also check if this apqn is able to handle this type of key. | ||
265 | * If cardnr and/or domain is 0xFFFF, on return these values are filled | ||
266 | * with one apqn able to handle this key. | ||
267 | * The function also checks for the master key verification patterns | ||
268 | * of the key matching to the current or alternate mkvp of the apqn. | ||
269 | * Currently CCA AES secure keys and CCA AES cipher keys are supported. | ||
270 | * The flags field is updated with some additional info about the apqn mkvp | ||
271 | * match: If the current mkvp matches to the key's mkvp then the | ||
272 | * PKEY_FLAGS_MATCH_CUR_MKVP bit is set, if the alternate mkvp matches to | ||
273 | * the key's mkvp the PKEY_FLAGS_MATCH_ALT_MKVP is set. For CCA keys the | ||
274 | * alternate mkvp is the old master key verification pattern. | ||
275 | * CCA AES secure keys are also checked to have the CPACF export allowed | ||
276 | * bit enabled (XPRTCPAC) in the kmf1 field. | ||
277 | * The ioctl returns 0 as long as the given or found apqn matches to | ||
278 | * matches with the current or alternate mkvp to the key's mkvp. If the given | ||
279 | * apqn does not match or there is no such apqn found, -1 with errno | ||
280 | * ENODEV is returned. | ||
281 | */ | ||
282 | struct pkey_verifykey2 { | ||
283 | __u8 __user *key; /* in: pointer to key blob */ | ||
284 | __u32 keylen; /* in: key blob size */ | ||
285 | __u16 cardnr; /* in/out: card number */ | ||
286 | __u16 domain; /* in/out: domain number */ | ||
287 | enum pkey_key_type type; /* out: the key type */ | ||
288 | enum pkey_key_size size; /* out: the key size */ | ||
289 | __u32 flags; /* out: additional key info flags */ | ||
290 | }; | ||
291 | #define PKEY_VERIFYKEY2 _IOWR(PKEY_IOCTL_MAGIC, 0x17, struct pkey_verifykey2) | ||
292 | |||
293 | /* | ||
294 | * Transform a key blob (of any type) into a protected key, version 2. | ||
295 | * There needs to be a list of apqns given with at least one entry in there. | ||
296 | * All apqns in the list need to be exact apqns, 0xFFFF as ANY card or domain | ||
297 | * is not supported. The implementation walks through the list of apqns and | ||
298 | * tries to send the request to each apqn without any further checking (like | ||
299 | * card type or online state). If the apqn fails, simple the next one in the | ||
300 | * list is tried until success (return 0) or the end of the list is reached | ||
301 | * (return -1 with errno ENODEV). You may use the PKEY_APQNS4K ioctl to | ||
302 | * generate a list of apqns based on the key. | ||
303 | */ | ||
304 | struct pkey_kblob2pkey2 { | ||
305 | __u8 __user *key; /* in: pointer to key blob */ | ||
306 | __u32 keylen; /* in: key blob size */ | ||
307 | struct pkey_apqn __user *apqns; /* in: ptr to list of apqn targets */ | ||
308 | __u32 apqn_entries; /* in: # of apqn target list entries */ | ||
309 | struct pkey_protkey protkey; /* out: the protected key */ | ||
310 | }; | ||
311 | #define PKEY_KBLOB2PROTK2 _IOWR(PKEY_IOCTL_MAGIC, 0x1A, struct pkey_kblob2pkey2) | ||
312 | |||
313 | /* | ||
314 | * Build a list of APQNs based on a key blob given. | ||
315 | * Is able to find out which type of secure key is given (CCA AES secure | ||
316 | * key or CCA AES cipher key) and tries to find all matching crypto cards | ||
317 | * based on the MKVP and maybe other criterias (like CCA AES cipher keys | ||
318 | * need a CEX5C or higher). The list of APQNs is further filtered by the key's | ||
319 | * mkvp which needs to match to either the current mkvp or the alternate mkvp | ||
320 | * (which is the old mkvp on CCA adapters) of the apqns. The flags argument may | ||
321 | * be used to limit the matching apqns. If the PKEY_FLAGS_MATCH_CUR_MKVP is | ||
322 | * given, only the current mkvp of each apqn is compared. Likewise with the | ||
323 | * PKEY_FLAGS_MATCH_ALT_MKVP. If both are given, it is assumed to | ||
324 | * return apqns where either the current or the alternate mkvp | ||
325 | * matches. At least one of the matching flags needs to be given. | ||
326 | * The list of matching apqns is stored into the space given by the apqns | ||
327 | * argument and the number of stored entries goes into apqn_entries. If the list | ||
328 | * is empty (apqn_entries is 0) the apqn_entries field is updated to the number | ||
329 | * of apqn targets found and the ioctl returns with 0. If apqn_entries is > 0 | ||
330 | * but the number of apqn targets does not fit into the list, the apqn_targets | ||
331 | * field is updatedd with the number of reqired entries but there are no apqn | ||
332 | * values stored in the list and the ioctl returns with ENOSPC. If no matching | ||
333 | * APQN is found, the ioctl returns with 0 but the apqn_entries value is 0. | ||
334 | */ | ||
335 | struct pkey_apqns4key { | ||
336 | __u8 __user *key; /* in: pointer to key blob */ | ||
337 | __u32 keylen; /* in: key blob size */ | ||
338 | __u32 flags; /* in: match controlling flags */ | ||
339 | struct pkey_apqn __user *apqns; /* in/out: ptr to list of apqn targets*/ | ||
340 | __u32 apqn_entries; /* in: max # of apqn entries in the list */ | ||
341 | /* out: # apqns stored into the list */ | ||
342 | }; | ||
343 | #define PKEY_APQNS4K _IOWR(PKEY_IOCTL_MAGIC, 0x1B, struct pkey_apqns4key) | ||
344 | |||
345 | /* | ||
346 | * Build a list of APQNs based on a key type given. | ||
347 | * Build a list of APQNs based on a given key type and maybe further | ||
348 | * restrict the list by given master key verification patterns. | ||
349 | * For different key types there may be different ways to match the | ||
350 | * master key verification patterns. For CCA keys (CCA data key and CCA | ||
351 | * cipher key) the first 8 bytes of cur_mkvp refer to the current mkvp value | ||
352 | * of the apqn and the first 8 bytes of the alt_mkvp refer to the old mkvp. | ||
353 | * The flags argument controls if the apqns current and/or alternate mkvp | ||
354 | * should match. If the PKEY_FLAGS_MATCH_CUR_MKVP is given, only the current | ||
355 | * mkvp of each apqn is compared. Likewise with the PKEY_FLAGS_MATCH_ALT_MKVP. | ||
356 | * If both are given, it is assumed to return apqns where either the | ||
357 | * current or the alternate mkvp matches. If no match flag is given | ||
358 | * (flags is 0) the mkvp values are ignored for the match process. | ||
359 | * The list of matching apqns is stored into the space given by the apqns | ||
360 | * argument and the number of stored entries goes into apqn_entries. If the list | ||
361 | * is empty (apqn_entries is 0) the apqn_entries field is updated to the number | ||
362 | * of apqn targets found and the ioctl returns with 0. If apqn_entries is > 0 | ||
363 | * but the number of apqn targets does not fit into the list, the apqn_targets | ||
364 | * field is updatedd with the number of reqired entries but there are no apqn | ||
365 | * values stored in the list and the ioctl returns with ENOSPC. If no matching | ||
366 | * APQN is found, the ioctl returns with 0 but the apqn_entries value is 0. | ||
367 | */ | ||
368 | struct pkey_apqns4keytype { | ||
369 | enum pkey_key_type type; /* in: key type */ | ||
370 | __u8 cur_mkvp[32]; /* in: current mkvp */ | ||
371 | __u8 alt_mkvp[32]; /* in: alternate mkvp */ | ||
372 | __u32 flags; /* in: match controlling flags */ | ||
373 | struct pkey_apqn __user *apqns; /* in/out: ptr to list of apqn targets*/ | ||
374 | __u32 apqn_entries; /* in: max # of apqn entries in the list */ | ||
375 | /* out: # apqns stored into the list */ | ||
376 | }; | ||
377 | #define PKEY_APQNS4KT _IOWR(PKEY_IOCTL_MAGIC, 0x1C, struct pkey_apqns4keytype) | ||
378 | |||
166 | #endif /* _UAPI_PKEY_H */ | 379 | #endif /* _UAPI_PKEY_H */ |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 0f255b54b051..7edbbcd8228a 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -10,20 +10,12 @@ CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) | |||
10 | 10 | ||
11 | # Do not trace early setup code | 11 | # Do not trace early setup code |
12 | CFLAGS_REMOVE_early.o = $(CC_FLAGS_FTRACE) | 12 | CFLAGS_REMOVE_early.o = $(CC_FLAGS_FTRACE) |
13 | CFLAGS_REMOVE_early_nobss.o = $(CC_FLAGS_FTRACE) | ||
14 | 13 | ||
15 | endif | 14 | endif |
16 | 15 | ||
17 | GCOV_PROFILE_early.o := n | 16 | GCOV_PROFILE_early.o := n |
18 | GCOV_PROFILE_early_nobss.o := n | ||
19 | |||
20 | KCOV_INSTRUMENT_early.o := n | 17 | KCOV_INSTRUMENT_early.o := n |
21 | KCOV_INSTRUMENT_early_nobss.o := n | ||
22 | |||
23 | UBSAN_SANITIZE_early.o := n | 18 | UBSAN_SANITIZE_early.o := n |
24 | UBSAN_SANITIZE_early_nobss.o := n | ||
25 | |||
26 | KASAN_SANITIZE_early_nobss.o := n | ||
27 | KASAN_SANITIZE_ipl.o := n | 19 | KASAN_SANITIZE_ipl.o := n |
28 | KASAN_SANITIZE_machine_kexec.o := n | 20 | KASAN_SANITIZE_machine_kexec.o := n |
29 | 21 | ||
@@ -48,7 +40,7 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' | |||
48 | 40 | ||
49 | obj-y := traps.o time.o process.o base.o early.o setup.o idle.o vtime.o | 41 | obj-y := traps.o time.o process.o base.o early.o setup.o idle.o vtime.o |
50 | obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o | 42 | obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o |
51 | obj-y += debug.o irq.o ipl.o dis.o diag.o vdso.o early_nobss.o | 43 | obj-y += debug.o irq.o ipl.o dis.o diag.o vdso.o |
52 | obj-y += sysinfo.o lgr.o os_info.o machine_kexec.o pgm_check.o | 44 | obj-y += sysinfo.o lgr.o os_info.o machine_kexec.o pgm_check.o |
53 | obj-y += runtime_instr.o cache.o fpu.o dumpstack.o guarded_storage.o sthyi.o | 45 | obj-y += runtime_instr.o cache.o fpu.o dumpstack.o guarded_storage.o sthyi.o |
54 | obj-y += entry.o reipl.o relocate_kernel.o kdebugfs.o alternative.o | 46 | obj-y += entry.o reipl.o relocate_kernel.o kdebugfs.o alternative.o |
@@ -90,6 +82,3 @@ obj-$(CONFIG_TRACEPOINTS) += trace.o | |||
90 | # vdso | 82 | # vdso |
91 | obj-y += vdso64/ | 83 | obj-y += vdso64/ |
92 | obj-$(CONFIG_COMPAT_VDSO) += vdso32/ | 84 | obj-$(CONFIG_COMPAT_VDSO) += vdso32/ |
93 | |||
94 | chkbss := head64.o early_nobss.o | ||
95 | include $(srctree)/arch/s390/scripts/Makefile.chkbss | ||
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S index 2f39ea57f358..b79e0fd571f8 100644 --- a/arch/s390/kernel/base.S +++ b/arch/s390/kernel/base.S | |||
@@ -16,27 +16,6 @@ | |||
16 | GEN_BR_THUNK %r9 | 16 | GEN_BR_THUNK %r9 |
17 | GEN_BR_THUNK %r14 | 17 | GEN_BR_THUNK %r14 |
18 | 18 | ||
19 | ENTRY(s390_base_mcck_handler) | ||
20 | basr %r13,0 | ||
21 | 0: lg %r15,__LC_NODAT_STACK # load panic stack | ||
22 | aghi %r15,-STACK_FRAME_OVERHEAD | ||
23 | larl %r1,s390_base_mcck_handler_fn | ||
24 | lg %r9,0(%r1) | ||
25 | ltgr %r9,%r9 | ||
26 | jz 1f | ||
27 | BASR_EX %r14,%r9 | ||
28 | 1: la %r1,4095 | ||
29 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) | ||
30 | lpswe __LC_MCK_OLD_PSW | ||
31 | ENDPROC(s390_base_mcck_handler) | ||
32 | |||
33 | .section .bss | ||
34 | .align 8 | ||
35 | .globl s390_base_mcck_handler_fn | ||
36 | s390_base_mcck_handler_fn: | ||
37 | .quad 0 | ||
38 | .previous | ||
39 | |||
40 | ENTRY(s390_base_ext_handler) | 19 | ENTRY(s390_base_ext_handler) |
41 | stmg %r0,%r15,__LC_SAVE_AREA_ASYNC | 20 | stmg %r0,%r15,__LC_SAVE_AREA_ASYNC |
42 | basr %r13,0 | 21 | basr %r13,0 |
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 6312fed48530..b432d63d0b37 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -32,6 +32,21 @@ | |||
32 | #include <asm/boot_data.h> | 32 | #include <asm/boot_data.h> |
33 | #include "entry.h" | 33 | #include "entry.h" |
34 | 34 | ||
35 | static void __init reset_tod_clock(void) | ||
36 | { | ||
37 | u64 time; | ||
38 | |||
39 | if (store_tod_clock(&time) == 0) | ||
40 | return; | ||
41 | /* TOD clock not running. Set the clock to Unix Epoch. */ | ||
42 | if (set_tod_clock(TOD_UNIX_EPOCH) != 0 || store_tod_clock(&time) != 0) | ||
43 | disabled_wait(); | ||
44 | |||
45 | memset(tod_clock_base, 0, 16); | ||
46 | *(__u64 *) &tod_clock_base[1] = TOD_UNIX_EPOCH; | ||
47 | S390_lowcore.last_update_clock = TOD_UNIX_EPOCH; | ||
48 | } | ||
49 | |||
35 | /* | 50 | /* |
36 | * Initialize storage key for kernel pages | 51 | * Initialize storage key for kernel pages |
37 | */ | 52 | */ |
@@ -301,6 +316,7 @@ static void __init check_image_bootable(void) | |||
301 | 316 | ||
302 | void __init startup_init(void) | 317 | void __init startup_init(void) |
303 | { | 318 | { |
319 | reset_tod_clock(); | ||
304 | check_image_bootable(); | 320 | check_image_bootable(); |
305 | time_early_init(); | 321 | time_early_init(); |
306 | init_kernel_storage_key(); | 322 | init_kernel_storage_key(); |
diff --git a/arch/s390/kernel/early_nobss.c b/arch/s390/kernel/early_nobss.c deleted file mode 100644 index 52a3ef959341..000000000000 --- a/arch/s390/kernel/early_nobss.c +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright IBM Corp. 2007, 2018 | ||
4 | */ | ||
5 | |||
6 | /* | ||
7 | * Early setup functions which may not rely on an initialized bss | ||
8 | * section. The last thing that is supposed to happen here is | ||
9 | * initialization of the bss section. | ||
10 | */ | ||
11 | |||
12 | #include <linux/processor.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <asm/sections.h> | ||
15 | #include <asm/lowcore.h> | ||
16 | #include <asm/timex.h> | ||
17 | #include <asm/kasan.h> | ||
18 | #include "entry.h" | ||
19 | |||
20 | static void __init reset_tod_clock(void) | ||
21 | { | ||
22 | u64 time; | ||
23 | |||
24 | if (store_tod_clock(&time) == 0) | ||
25 | return; | ||
26 | /* TOD clock not running. Set the clock to Unix Epoch. */ | ||
27 | if (set_tod_clock(TOD_UNIX_EPOCH) != 0 || store_tod_clock(&time) != 0) | ||
28 | disabled_wait(); | ||
29 | |||
30 | memset(tod_clock_base, 0, 16); | ||
31 | *(__u64 *) &tod_clock_base[1] = TOD_UNIX_EPOCH; | ||
32 | S390_lowcore.last_update_clock = TOD_UNIX_EPOCH; | ||
33 | } | ||
34 | |||
35 | static void __init clear_bss_section(void) | ||
36 | { | ||
37 | memset(__bss_start, 0, __bss_stop - __bss_start); | ||
38 | } | ||
39 | |||
40 | void __init startup_init_nobss(void) | ||
41 | { | ||
42 | reset_tod_clock(); | ||
43 | clear_bss_section(); | ||
44 | kasan_early_init(); | ||
45 | } | ||
diff --git a/arch/s390/kernel/early_printk.c b/arch/s390/kernel/early_printk.c index 40c1dfec944e..6f24d83bc5dc 100644 --- a/arch/s390/kernel/early_printk.c +++ b/arch/s390/kernel/early_printk.c | |||
@@ -25,7 +25,7 @@ static int __init setup_early_printk(char *buf) | |||
25 | if (early_console) | 25 | if (early_console) |
26 | return 0; | 26 | return 0; |
27 | /* Accept only "earlyprintk" and "earlyprintk=sclp" */ | 27 | /* Accept only "earlyprintk" and "earlyprintk=sclp" */ |
28 | if (buf && strncmp(buf, "sclp", 4)) | 28 | if (buf && !str_has_prefix(buf, "sclp")) |
29 | return 0; | 29 | return 0; |
30 | if (!sclp.has_linemode && !sclp.has_vt220) | 30 | if (!sclp.has_linemode && !sclp.has_vt220) |
31 | return 0; | 31 | return 0; |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index f384a18e6c26..0d9ee198f4eb 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -34,11 +34,9 @@ ENTRY(startup_continue) | |||
34 | larl %r14,init_task | 34 | larl %r14,init_task |
35 | stg %r14,__LC_CURRENT | 35 | stg %r14,__LC_CURRENT |
36 | larl %r15,init_thread_union+THREAD_SIZE-STACK_FRAME_OVERHEAD | 36 | larl %r15,init_thread_union+THREAD_SIZE-STACK_FRAME_OVERHEAD |
37 | # | 37 | #ifdef CONFIG_KASAN |
38 | # Early setup functions that may not rely on an initialized bss section, | 38 | brasl %r14,kasan_early_init |
39 | # like moving the initrd. Returns with an initialized bss section. | 39 | #endif |
40 | # | ||
41 | brasl %r14,startup_init_nobss | ||
42 | # | 40 | # |
43 | # Early machine initialization and detection functions. | 41 | # Early machine initialization and detection functions. |
44 | # | 42 | # |
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 31889db609e9..ba8f19bb438b 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c | |||
@@ -472,11 +472,11 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
472 | apply_alternatives(aseg, aseg + s->sh_size); | 472 | apply_alternatives(aseg, aseg + s->sh_size); |
473 | 473 | ||
474 | if (IS_ENABLED(CONFIG_EXPOLINE) && | 474 | if (IS_ENABLED(CONFIG_EXPOLINE) && |
475 | (!strncmp(".s390_indirect", secname, 14))) | 475 | (str_has_prefix(secname, ".s390_indirect"))) |
476 | nospec_revert(aseg, aseg + s->sh_size); | 476 | nospec_revert(aseg, aseg + s->sh_size); |
477 | 477 | ||
478 | if (IS_ENABLED(CONFIG_EXPOLINE) && | 478 | if (IS_ENABLED(CONFIG_EXPOLINE) && |
479 | (!strncmp(".s390_return", secname, 12))) | 479 | (str_has_prefix(secname, ".s390_return"))) |
480 | nospec_revert(aseg, aseg + s->sh_size); | 480 | nospec_revert(aseg, aseg + s->sh_size); |
481 | } | 481 | } |
482 | 482 | ||
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index 1266194afb02..292a452cd1f3 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c | |||
@@ -514,7 +514,6 @@ static void extend_sampling_buffer(struct sf_buffer *sfb, | |||
514 | sfb_pending_allocs(sfb, hwc)); | 514 | sfb_pending_allocs(sfb, hwc)); |
515 | } | 515 | } |
516 | 516 | ||
517 | |||
518 | /* Number of perf events counting hardware events */ | 517 | /* Number of perf events counting hardware events */ |
519 | static atomic_t num_events; | 518 | static atomic_t num_events; |
520 | /* Used to avoid races in calling reserve/release_cpumf_hardware */ | 519 | /* Used to avoid races in calling reserve/release_cpumf_hardware */ |
@@ -923,9 +922,10 @@ static void cpumsf_pmu_enable(struct pmu *pmu) | |||
923 | lpp(&S390_lowcore.lpp); | 922 | lpp(&S390_lowcore.lpp); |
924 | 923 | ||
925 | debug_sprintf_event(sfdbg, 6, "pmu_enable: es=%i cs=%i ed=%i cd=%i " | 924 | debug_sprintf_event(sfdbg, 6, "pmu_enable: es=%i cs=%i ed=%i cd=%i " |
926 | "tear=%p dear=%p\n", cpuhw->lsctl.es, cpuhw->lsctl.cs, | 925 | "tear=%p dear=%p\n", cpuhw->lsctl.es, |
927 | cpuhw->lsctl.ed, cpuhw->lsctl.cd, | 926 | cpuhw->lsctl.cs, cpuhw->lsctl.ed, cpuhw->lsctl.cd, |
928 | (void *) cpuhw->lsctl.tear, (void *) cpuhw->lsctl.dear); | 927 | (void *) cpuhw->lsctl.tear, |
928 | (void *) cpuhw->lsctl.dear); | ||
929 | } | 929 | } |
930 | 930 | ||
931 | static void cpumsf_pmu_disable(struct pmu *pmu) | 931 | static void cpumsf_pmu_disable(struct pmu *pmu) |
@@ -1083,7 +1083,8 @@ static void debug_sample_entry(struct hws_basic_entry *sample, | |||
1083 | struct hws_trailer_entry *te) | 1083 | struct hws_trailer_entry *te) |
1084 | { | 1084 | { |
1085 | debug_sprintf_event(sfdbg, 4, "hw_collect_samples: Found unknown " | 1085 | debug_sprintf_event(sfdbg, 4, "hw_collect_samples: Found unknown " |
1086 | "sampling data entry: te->f=%i basic.def=%04x (%p)\n", | 1086 | "sampling data entry: te->f=%i basic.def=%04x " |
1087 | "(%p)\n", | ||
1087 | te->f, sample->def, sample); | 1088 | te->f, sample->def, sample); |
1088 | } | 1089 | } |
1089 | 1090 | ||
@@ -1216,7 +1217,7 @@ static void hw_perf_event_update(struct perf_event *event, int flush_all) | |||
1216 | 1217 | ||
1217 | /* Timestamps are valid for full sample-data-blocks only */ | 1218 | /* Timestamps are valid for full sample-data-blocks only */ |
1218 | debug_sprintf_event(sfdbg, 6, "hw_perf_event_update: sdbt=%p " | 1219 | debug_sprintf_event(sfdbg, 6, "hw_perf_event_update: sdbt=%p " |
1219 | "overflow=%llu timestamp=0x%llx\n", | 1220 | "overflow=%llu timestamp=%#llx\n", |
1220 | sdbt, te->overflow, | 1221 | sdbt, te->overflow, |
1221 | (te->f) ? trailer_timestamp(te) : 0ULL); | 1222 | (te->f) ? trailer_timestamp(te) : 0ULL); |
1222 | 1223 | ||
@@ -1879,10 +1880,12 @@ static struct attribute_group cpumsf_pmu_events_group = { | |||
1879 | .name = "events", | 1880 | .name = "events", |
1880 | .attrs = cpumsf_pmu_events_attr, | 1881 | .attrs = cpumsf_pmu_events_attr, |
1881 | }; | 1882 | }; |
1883 | |||
1882 | static struct attribute_group cpumsf_pmu_format_group = { | 1884 | static struct attribute_group cpumsf_pmu_format_group = { |
1883 | .name = "format", | 1885 | .name = "format", |
1884 | .attrs = cpumsf_pmu_format_attr, | 1886 | .attrs = cpumsf_pmu_format_attr, |
1885 | }; | 1887 | }; |
1888 | |||
1886 | static const struct attribute_group *cpumsf_pmu_attr_groups[] = { | 1889 | static const struct attribute_group *cpumsf_pmu_attr_groups[] = { |
1887 | &cpumsf_pmu_events_group, | 1890 | &cpumsf_pmu_events_group, |
1888 | &cpumsf_pmu_format_group, | 1891 | &cpumsf_pmu_format_group, |
@@ -1938,7 +1941,8 @@ static void cpumf_measurement_alert(struct ext_code ext_code, | |||
1938 | 1941 | ||
1939 | /* Report measurement alerts only for non-PRA codes */ | 1942 | /* Report measurement alerts only for non-PRA codes */ |
1940 | if (alert != CPU_MF_INT_SF_PRA) | 1943 | if (alert != CPU_MF_INT_SF_PRA) |
1941 | debug_sprintf_event(sfdbg, 6, "measurement alert: 0x%x\n", alert); | 1944 | debug_sprintf_event(sfdbg, 6, "measurement alert: %#x\n", |
1945 | alert); | ||
1942 | 1946 | ||
1943 | /* Sampling authorization change request */ | 1947 | /* Sampling authorization change request */ |
1944 | if (alert & CPU_MF_INT_SF_SACA) | 1948 | if (alert & CPU_MF_INT_SF_SACA) |
@@ -1959,6 +1963,7 @@ static void cpumf_measurement_alert(struct ext_code ext_code, | |||
1959 | sf_disable(); | 1963 | sf_disable(); |
1960 | } | 1964 | } |
1961 | } | 1965 | } |
1966 | |||
1962 | static int cpusf_pmu_setup(unsigned int cpu, int flags) | 1967 | static int cpusf_pmu_setup(unsigned int cpu, int flags) |
1963 | { | 1968 | { |
1964 | /* Ignore the notification if no events are scheduled on the PMU. | 1969 | /* Ignore the notification if no events are scheduled on the PMU. |
@@ -2096,5 +2101,6 @@ static int __init init_cpum_sampling_pmu(void) | |||
2096 | out: | 2101 | out: |
2097 | return err; | 2102 | return err; |
2098 | } | 2103 | } |
2104 | |||
2099 | arch_initcall(init_cpum_sampling_pmu); | 2105 | arch_initcall(init_cpum_sampling_pmu); |
2100 | core_param(cpum_sfb_size, CPUM_SF_MAX_SDB, sfb_size, 0640); | 2106 | core_param(cpum_sfb_size, CPUM_SF_MAX_SDB, sfb_size, 0640); |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 63873aa6693f..b0afec673f77 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -184,20 +184,30 @@ unsigned long get_wchan(struct task_struct *p) | |||
184 | 184 | ||
185 | if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p)) | 185 | if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p)) |
186 | return 0; | 186 | return 0; |
187 | |||
188 | if (!try_get_task_stack(p)) | ||
189 | return 0; | ||
190 | |||
187 | low = task_stack_page(p); | 191 | low = task_stack_page(p); |
188 | high = (struct stack_frame *) task_pt_regs(p); | 192 | high = (struct stack_frame *) task_pt_regs(p); |
189 | sf = (struct stack_frame *) p->thread.ksp; | 193 | sf = (struct stack_frame *) p->thread.ksp; |
190 | if (sf <= low || sf > high) | 194 | if (sf <= low || sf > high) { |
191 | return 0; | 195 | return_address = 0; |
196 | goto out; | ||
197 | } | ||
192 | for (count = 0; count < 16; count++) { | 198 | for (count = 0; count < 16; count++) { |
193 | sf = (struct stack_frame *) sf->back_chain; | 199 | sf = (struct stack_frame *)READ_ONCE_NOCHECK(sf->back_chain); |
194 | if (sf <= low || sf > high) | 200 | if (sf <= low || sf > high) { |
195 | return 0; | 201 | return_address = 0; |
196 | return_address = sf->gprs[8]; | 202 | goto out; |
203 | } | ||
204 | return_address = READ_ONCE_NOCHECK(sf->gprs[8]); | ||
197 | if (!in_sched_functions(return_address)) | 205 | if (!in_sched_functions(return_address)) |
198 | return return_address; | 206 | goto out; |
199 | } | 207 | } |
200 | return 0; | 208 | out: |
209 | put_task_stack(p); | ||
210 | return return_address; | ||
201 | } | 211 | } |
202 | 212 | ||
203 | unsigned long arch_align_stack(unsigned long sp) | 213 | unsigned long arch_align_stack(unsigned long sp) |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 253177900950..3ff291bc63b7 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -99,6 +99,7 @@ int __bootdata_preserved(prot_virt_guest); | |||
99 | int __bootdata(noexec_disabled); | 99 | int __bootdata(noexec_disabled); |
100 | int __bootdata(memory_end_set); | 100 | int __bootdata(memory_end_set); |
101 | unsigned long __bootdata(memory_end); | 101 | unsigned long __bootdata(memory_end); |
102 | unsigned long __bootdata(vmalloc_size); | ||
102 | unsigned long __bootdata(max_physmem_end); | 103 | unsigned long __bootdata(max_physmem_end); |
103 | struct mem_detect_info __bootdata(mem_detect); | 104 | struct mem_detect_info __bootdata(mem_detect); |
104 | 105 | ||
@@ -168,15 +169,15 @@ static void __init set_preferred_console(void) | |||
168 | static int __init conmode_setup(char *str) | 169 | static int __init conmode_setup(char *str) |
169 | { | 170 | { |
170 | #if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) | 171 | #if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) |
171 | if (strncmp(str, "hwc", 4) == 0 || strncmp(str, "sclp", 5) == 0) | 172 | if (!strcmp(str, "hwc") || !strcmp(str, "sclp")) |
172 | SET_CONSOLE_SCLP; | 173 | SET_CONSOLE_SCLP; |
173 | #endif | 174 | #endif |
174 | #if defined(CONFIG_TN3215_CONSOLE) | 175 | #if defined(CONFIG_TN3215_CONSOLE) |
175 | if (strncmp(str, "3215", 5) == 0) | 176 | if (!strcmp(str, "3215")) |
176 | SET_CONSOLE_3215; | 177 | SET_CONSOLE_3215; |
177 | #endif | 178 | #endif |
178 | #if defined(CONFIG_TN3270_CONSOLE) | 179 | #if defined(CONFIG_TN3270_CONSOLE) |
179 | if (strncmp(str, "3270", 5) == 0) | 180 | if (!strcmp(str, "3270")) |
180 | SET_CONSOLE_3270; | 181 | SET_CONSOLE_3270; |
181 | #endif | 182 | #endif |
182 | set_preferred_console(); | 183 | set_preferred_console(); |
@@ -211,7 +212,7 @@ static void __init conmode_default(void) | |||
211 | #endif | 212 | #endif |
212 | return; | 213 | return; |
213 | } | 214 | } |
214 | if (strncmp(ptr + 8, "3270", 4) == 0) { | 215 | if (str_has_prefix(ptr + 8, "3270")) { |
215 | #if defined(CONFIG_TN3270_CONSOLE) | 216 | #if defined(CONFIG_TN3270_CONSOLE) |
216 | SET_CONSOLE_3270; | 217 | SET_CONSOLE_3270; |
217 | #elif defined(CONFIG_TN3215_CONSOLE) | 218 | #elif defined(CONFIG_TN3215_CONSOLE) |
@@ -219,7 +220,7 @@ static void __init conmode_default(void) | |||
219 | #elif defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) | 220 | #elif defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) |
220 | SET_CONSOLE_SCLP; | 221 | SET_CONSOLE_SCLP; |
221 | #endif | 222 | #endif |
222 | } else if (strncmp(ptr + 8, "3215", 4) == 0) { | 223 | } else if (str_has_prefix(ptr + 8, "3215")) { |
223 | #if defined(CONFIG_TN3215_CONSOLE) | 224 | #if defined(CONFIG_TN3215_CONSOLE) |
224 | SET_CONSOLE_3215; | 225 | SET_CONSOLE_3215; |
225 | #elif defined(CONFIG_TN3270_CONSOLE) | 226 | #elif defined(CONFIG_TN3270_CONSOLE) |
@@ -302,15 +303,6 @@ void machine_power_off(void) | |||
302 | void (*pm_power_off)(void) = machine_power_off; | 303 | void (*pm_power_off)(void) = machine_power_off; |
303 | EXPORT_SYMBOL_GPL(pm_power_off); | 304 | EXPORT_SYMBOL_GPL(pm_power_off); |
304 | 305 | ||
305 | static int __init parse_vmalloc(char *arg) | ||
306 | { | ||
307 | if (!arg) | ||
308 | return -EINVAL; | ||
309 | VMALLOC_END = (memparse(arg, &arg) + PAGE_SIZE - 1) & PAGE_MASK; | ||
310 | return 0; | ||
311 | } | ||
312 | early_param("vmalloc", parse_vmalloc); | ||
313 | |||
314 | void *restart_stack __section(.data); | 306 | void *restart_stack __section(.data); |
315 | 307 | ||
316 | unsigned long stack_alloc(void) | 308 | unsigned long stack_alloc(void) |
@@ -563,10 +555,9 @@ static void __init setup_resources(void) | |||
563 | 555 | ||
564 | static void __init setup_memory_end(void) | 556 | static void __init setup_memory_end(void) |
565 | { | 557 | { |
566 | unsigned long vmax, vmalloc_size, tmp; | 558 | unsigned long vmax, tmp; |
567 | 559 | ||
568 | /* Choose kernel address space layout: 3 or 4 levels. */ | 560 | /* Choose kernel address space layout: 3 or 4 levels. */ |
569 | vmalloc_size = VMALLOC_END ?: (128UL << 30) - MODULES_LEN; | ||
570 | if (IS_ENABLED(CONFIG_KASAN)) { | 561 | if (IS_ENABLED(CONFIG_KASAN)) { |
571 | vmax = IS_ENABLED(CONFIG_KASAN_S390_4_LEVEL_PAGING) | 562 | vmax = IS_ENABLED(CONFIG_KASAN_S390_4_LEVEL_PAGING) |
572 | ? _REGION1_SIZE | 563 | ? _REGION1_SIZE |
@@ -990,6 +981,10 @@ static int __init setup_hwcaps(void) | |||
990 | case 0x3907: | 981 | case 0x3907: |
991 | strcpy(elf_platform, "z14"); | 982 | strcpy(elf_platform, "z14"); |
992 | break; | 983 | break; |
984 | case 0x8561: | ||
985 | case 0x8562: | ||
986 | strcpy(elf_platform, "z15"); | ||
987 | break; | ||
993 | } | 988 | } |
994 | 989 | ||
995 | /* | 990 | /* |
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c index f6a620f854e1..f8fc4f8aef9b 100644 --- a/arch/s390/kernel/stacktrace.c +++ b/arch/s390/kernel/stacktrace.c | |||
@@ -6,57 +6,19 @@ | |||
6 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | 6 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/sched.h> | ||
10 | #include <linux/sched/debug.h> | ||
11 | #include <linux/stacktrace.h> | 9 | #include <linux/stacktrace.h> |
12 | #include <linux/kallsyms.h> | ||
13 | #include <linux/export.h> | ||
14 | #include <asm/stacktrace.h> | 10 | #include <asm/stacktrace.h> |
15 | #include <asm/unwind.h> | 11 | #include <asm/unwind.h> |
16 | 12 | ||
17 | void save_stack_trace(struct stack_trace *trace) | 13 | void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, |
14 | struct task_struct *task, struct pt_regs *regs) | ||
18 | { | 15 | { |
19 | struct unwind_state state; | 16 | struct unwind_state state; |
17 | unsigned long addr; | ||
20 | 18 | ||
21 | unwind_for_each_frame(&state, current, NULL, 0) { | 19 | unwind_for_each_frame(&state, task, regs, 0) { |
22 | if (trace->nr_entries >= trace->max_entries) | 20 | addr = unwind_get_return_address(&state); |
21 | if (!addr || !consume_entry(cookie, addr, false)) | ||
23 | break; | 22 | break; |
24 | if (trace->skip > 0) | ||
25 | trace->skip--; | ||
26 | else | ||
27 | trace->entries[trace->nr_entries++] = state.ip; | ||
28 | } | 23 | } |
29 | } | 24 | } |
30 | EXPORT_SYMBOL_GPL(save_stack_trace); | ||
31 | |||
32 | void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) | ||
33 | { | ||
34 | struct unwind_state state; | ||
35 | |||
36 | unwind_for_each_frame(&state, tsk, NULL, 0) { | ||
37 | if (trace->nr_entries >= trace->max_entries) | ||
38 | break; | ||
39 | if (in_sched_functions(state.ip)) | ||
40 | continue; | ||
41 | if (trace->skip > 0) | ||
42 | trace->skip--; | ||
43 | else | ||
44 | trace->entries[trace->nr_entries++] = state.ip; | ||
45 | } | ||
46 | } | ||
47 | EXPORT_SYMBOL_GPL(save_stack_trace_tsk); | ||
48 | |||
49 | void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) | ||
50 | { | ||
51 | struct unwind_state state; | ||
52 | |||
53 | unwind_for_each_frame(&state, current, regs, 0) { | ||
54 | if (trace->nr_entries >= trace->max_entries) | ||
55 | break; | ||
56 | if (trace->skip > 0) | ||
57 | trace->skip--; | ||
58 | else | ||
59 | trace->entries[trace->nr_entries++] = state.ip; | ||
60 | } | ||
61 | } | ||
62 | EXPORT_SYMBOL_GPL(save_stack_trace_regs); | ||
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index c6bc190f3c28..ed1fc08ccea2 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
@@ -97,21 +97,13 @@ static const struct vm_special_mapping vdso_mapping = { | |||
97 | .mremap = vdso_mremap, | 97 | .mremap = vdso_mremap, |
98 | }; | 98 | }; |
99 | 99 | ||
100 | static int __init vdso_setup(char *s) | 100 | static int __init vdso_setup(char *str) |
101 | { | 101 | { |
102 | unsigned long val; | 102 | bool enabled; |
103 | int rc; | ||
104 | 103 | ||
105 | rc = 0; | 104 | if (!kstrtobool(str, &enabled)) |
106 | if (strncmp(s, "on", 3) == 0) | 105 | vdso_enabled = enabled; |
107 | vdso_enabled = 1; | 106 | return 1; |
108 | else if (strncmp(s, "off", 4) == 0) | ||
109 | vdso_enabled = 0; | ||
110 | else { | ||
111 | rc = kstrtoul(s, 0, &val); | ||
112 | vdso_enabled = rc ? 0 : !!val; | ||
113 | } | ||
114 | return !rc; | ||
115 | } | 107 | } |
116 | __setup("vdso=", vdso_setup); | 108 | __setup("vdso=", vdso_setup); |
117 | 109 | ||
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index a1ec63abfb95..d7c218e8b559 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile | |||
@@ -11,6 +11,3 @@ lib-$(CONFIG_UPROBES) += probes.o | |||
11 | # Instrumenting memory accesses to __user data (in different address space) | 11 | # Instrumenting memory accesses to __user data (in different address space) |
12 | # produce false positives | 12 | # produce false positives |
13 | KASAN_SANITIZE_uaccess.o := n | 13 | KASAN_SANITIZE_uaccess.o := n |
14 | |||
15 | chkbss := mem.o | ||
16 | include $(srctree)/arch/s390/scripts/Makefile.chkbss | ||
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 0b5622714c12..fd0dae9d10f4 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/memblock.h> | 19 | #include <linux/memblock.h> |
20 | #include <linux/ctype.h> | 20 | #include <linux/ctype.h> |
21 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
22 | #include <linux/refcount.h> | ||
22 | #include <asm/diag.h> | 23 | #include <asm/diag.h> |
23 | #include <asm/page.h> | 24 | #include <asm/page.h> |
24 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
@@ -64,7 +65,7 @@ struct dcss_segment { | |||
64 | char res_name[16]; | 65 | char res_name[16]; |
65 | unsigned long start_addr; | 66 | unsigned long start_addr; |
66 | unsigned long end; | 67 | unsigned long end; |
67 | atomic_t ref_count; | 68 | refcount_t ref_count; |
68 | int do_nonshared; | 69 | int do_nonshared; |
69 | unsigned int vm_segtype; | 70 | unsigned int vm_segtype; |
70 | struct qrange range[6]; | 71 | struct qrange range[6]; |
@@ -362,7 +363,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long | |||
362 | seg->start_addr = start_addr; | 363 | seg->start_addr = start_addr; |
363 | seg->end = end_addr; | 364 | seg->end = end_addr; |
364 | seg->do_nonshared = do_nonshared; | 365 | seg->do_nonshared = do_nonshared; |
365 | atomic_set(&seg->ref_count, 1); | 366 | refcount_set(&seg->ref_count, 1); |
366 | list_add(&seg->list, &dcss_list); | 367 | list_add(&seg->list, &dcss_list); |
367 | *addr = seg->start_addr; | 368 | *addr = seg->start_addr; |
368 | *end = seg->end; | 369 | *end = seg->end; |
@@ -422,7 +423,7 @@ segment_load (char *name, int do_nonshared, unsigned long *addr, | |||
422 | rc = __segment_load (name, do_nonshared, addr, end); | 423 | rc = __segment_load (name, do_nonshared, addr, end); |
423 | else { | 424 | else { |
424 | if (do_nonshared == seg->do_nonshared) { | 425 | if (do_nonshared == seg->do_nonshared) { |
425 | atomic_inc(&seg->ref_count); | 426 | refcount_inc(&seg->ref_count); |
426 | *addr = seg->start_addr; | 427 | *addr = seg->start_addr; |
427 | *end = seg->end; | 428 | *end = seg->end; |
428 | rc = seg->vm_segtype; | 429 | rc = seg->vm_segtype; |
@@ -468,7 +469,7 @@ segment_modify_shared (char *name, int do_nonshared) | |||
468 | rc = 0; | 469 | rc = 0; |
469 | goto out_unlock; | 470 | goto out_unlock; |
470 | } | 471 | } |
471 | if (atomic_read (&seg->ref_count) != 1) { | 472 | if (refcount_read(&seg->ref_count) != 1) { |
472 | pr_warn("DCSS %s is in use and cannot be reloaded\n", name); | 473 | pr_warn("DCSS %s is in use and cannot be reloaded\n", name); |
473 | rc = -EAGAIN; | 474 | rc = -EAGAIN; |
474 | goto out_unlock; | 475 | goto out_unlock; |
@@ -544,7 +545,7 @@ segment_unload(char *name) | |||
544 | pr_err("Unloading unknown DCSS %s failed\n", name); | 545 | pr_err("Unloading unknown DCSS %s failed\n", name); |
545 | goto out_unlock; | 546 | goto out_unlock; |
546 | } | 547 | } |
547 | if (atomic_dec_return(&seg->ref_count) != 0) | 548 | if (!refcount_dec_and_test(&seg->ref_count)) |
548 | goto out_unlock; | 549 | goto out_unlock; |
549 | release_resource(seg->res); | 550 | release_resource(seg->res); |
550 | kfree(seg->res); | 551 | kfree(seg->res); |
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index 39c3a6e3d262..cd8e03f04d6d 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c | |||
@@ -67,7 +67,7 @@ static struct gmap *gmap_alloc(unsigned long limit) | |||
67 | INIT_RADIX_TREE(&gmap->host_to_rmap, GFP_ATOMIC); | 67 | INIT_RADIX_TREE(&gmap->host_to_rmap, GFP_ATOMIC); |
68 | spin_lock_init(&gmap->guest_table_lock); | 68 | spin_lock_init(&gmap->guest_table_lock); |
69 | spin_lock_init(&gmap->shadow_lock); | 69 | spin_lock_init(&gmap->shadow_lock); |
70 | atomic_set(&gmap->ref_count, 1); | 70 | refcount_set(&gmap->ref_count, 1); |
71 | page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); | 71 | page = alloc_pages(GFP_KERNEL, CRST_ALLOC_ORDER); |
72 | if (!page) | 72 | if (!page) |
73 | goto out_free; | 73 | goto out_free; |
@@ -214,7 +214,7 @@ static void gmap_free(struct gmap *gmap) | |||
214 | */ | 214 | */ |
215 | struct gmap *gmap_get(struct gmap *gmap) | 215 | struct gmap *gmap_get(struct gmap *gmap) |
216 | { | 216 | { |
217 | atomic_inc(&gmap->ref_count); | 217 | refcount_inc(&gmap->ref_count); |
218 | return gmap; | 218 | return gmap; |
219 | } | 219 | } |
220 | EXPORT_SYMBOL_GPL(gmap_get); | 220 | EXPORT_SYMBOL_GPL(gmap_get); |
@@ -227,7 +227,7 @@ EXPORT_SYMBOL_GPL(gmap_get); | |||
227 | */ | 227 | */ |
228 | void gmap_put(struct gmap *gmap) | 228 | void gmap_put(struct gmap *gmap) |
229 | { | 229 | { |
230 | if (atomic_dec_return(&gmap->ref_count) == 0) | 230 | if (refcount_dec_and_test(&gmap->ref_count)) |
231 | gmap_free(gmap); | 231 | gmap_free(gmap); |
232 | } | 232 | } |
233 | EXPORT_SYMBOL_GPL(gmap_put); | 233 | EXPORT_SYMBOL_GPL(gmap_put); |
@@ -1594,7 +1594,7 @@ static struct gmap *gmap_find_shadow(struct gmap *parent, unsigned long asce, | |||
1594 | continue; | 1594 | continue; |
1595 | if (!sg->initialized) | 1595 | if (!sg->initialized) |
1596 | return ERR_PTR(-EAGAIN); | 1596 | return ERR_PTR(-EAGAIN); |
1597 | atomic_inc(&sg->ref_count); | 1597 | refcount_inc(&sg->ref_count); |
1598 | return sg; | 1598 | return sg; |
1599 | } | 1599 | } |
1600 | return NULL; | 1600 | return NULL; |
@@ -1682,7 +1682,7 @@ struct gmap *gmap_shadow(struct gmap *parent, unsigned long asce, | |||
1682 | } | 1682 | } |
1683 | } | 1683 | } |
1684 | } | 1684 | } |
1685 | atomic_set(&new->ref_count, 2); | 1685 | refcount_set(&new->ref_count, 2); |
1686 | list_add(&new->list, &parent->children); | 1686 | list_add(&new->list, &parent->children); |
1687 | if (asce & _ASCE_REAL_SPACE) { | 1687 | if (asce & _ASCE_REAL_SPACE) { |
1688 | /* nothing to protect, return right away */ | 1688 | /* nothing to protect, return right away */ |
diff --git a/arch/s390/mm/kasan_init.c b/arch/s390/mm/kasan_init.c index 0c1f257be422..460f25572940 100644 --- a/arch/s390/mm/kasan_init.c +++ b/arch/s390/mm/kasan_init.c | |||
@@ -236,18 +236,6 @@ static void __init kasan_early_detect_facilities(void) | |||
236 | } | 236 | } |
237 | } | 237 | } |
238 | 238 | ||
239 | static unsigned long __init get_mem_detect_end(void) | ||
240 | { | ||
241 | unsigned long start; | ||
242 | unsigned long end; | ||
243 | |||
244 | if (mem_detect.count) { | ||
245 | __get_mem_detect_block(mem_detect.count - 1, &start, &end); | ||
246 | return end; | ||
247 | } | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | void __init kasan_early_init(void) | 239 | void __init kasan_early_init(void) |
252 | { | 240 | { |
253 | unsigned long untracked_mem_end; | 241 | unsigned long untracked_mem_end; |
@@ -273,6 +261,8 @@ void __init kasan_early_init(void) | |||
273 | /* respect mem= cmdline parameter */ | 261 | /* respect mem= cmdline parameter */ |
274 | if (memory_end_set && memsize > memory_end) | 262 | if (memory_end_set && memsize > memory_end) |
275 | memsize = memory_end; | 263 | memsize = memory_end; |
264 | if (IS_ENABLED(CONFIG_CRASH_DUMP) && OLDMEM_BASE) | ||
265 | memsize = min(memsize, OLDMEM_SIZE); | ||
276 | memsize = min(memsize, KASAN_SHADOW_START); | 266 | memsize = min(memsize, KASAN_SHADOW_START); |
277 | 267 | ||
278 | if (IS_ENABLED(CONFIG_KASAN_S390_4_LEVEL_PAGING)) { | 268 | if (IS_ENABLED(CONFIG_KASAN_S390_4_LEVEL_PAGING)) { |
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c index dc3cede7f2ec..fc141893d028 100644 --- a/arch/s390/mm/page-states.c +++ b/arch/s390/mm/page-states.c | |||
@@ -21,17 +21,11 @@ static int cmma_flag = 1; | |||
21 | 21 | ||
22 | static int __init cmma(char *str) | 22 | static int __init cmma(char *str) |
23 | { | 23 | { |
24 | char *parm; | 24 | bool enabled; |
25 | 25 | ||
26 | parm = strstrip(str); | 26 | if (!kstrtobool(str, &enabled)) |
27 | if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) { | 27 | cmma_flag = enabled; |
28 | cmma_flag = 1; | 28 | return 1; |
29 | return 1; | ||
30 | } | ||
31 | cmma_flag = 0; | ||
32 | if (strcmp(parm, "no") == 0 || strcmp(parm, "off") == 0) | ||
33 | return 1; | ||
34 | return 0; | ||
35 | } | 29 | } |
36 | __setup("cmma=", cmma); | 30 | __setup("cmma=", cmma); |
37 | 31 | ||
diff --git a/arch/s390/numa/mode_emu.c b/arch/s390/numa/mode_emu.c index 71a12a4f4906..72d742bb2d17 100644 --- a/arch/s390/numa/mode_emu.c +++ b/arch/s390/numa/mode_emu.c | |||
@@ -558,9 +558,7 @@ static int __init early_parse_emu_nodes(char *p) | |||
558 | { | 558 | { |
559 | int count; | 559 | int count; |
560 | 560 | ||
561 | if (kstrtoint(p, 0, &count) != 0 || count <= 0) | 561 | if (!p || kstrtoint(p, 0, &count) != 0 || count <= 0) |
562 | return 0; | ||
563 | if (count <= 0) | ||
564 | return 0; | 562 | return 0; |
565 | emu_nodes = min(count, MAX_NUMNODES); | 563 | emu_nodes = min(count, MAX_NUMNODES); |
566 | return 0; | 564 | return 0; |
@@ -572,7 +570,8 @@ early_param("emu_nodes", early_parse_emu_nodes); | |||
572 | */ | 570 | */ |
573 | static int __init early_parse_emu_size(char *p) | 571 | static int __init early_parse_emu_size(char *p) |
574 | { | 572 | { |
575 | emu_size = memparse(p, NULL); | 573 | if (p) |
574 | emu_size = memparse(p, NULL); | ||
576 | return 0; | 575 | return 0; |
577 | } | 576 | } |
578 | early_param("emu_size", early_parse_emu_size); | 577 | early_param("emu_size", early_parse_emu_size); |
diff --git a/arch/s390/numa/numa.c b/arch/s390/numa/numa.c index 8eb9e9743f5d..d2910fa834c8 100644 --- a/arch/s390/numa/numa.c +++ b/arch/s390/numa/numa.c | |||
@@ -158,6 +158,8 @@ early_param("numa_debug", parse_debug); | |||
158 | 158 | ||
159 | static int __init parse_numa(char *parm) | 159 | static int __init parse_numa(char *parm) |
160 | { | 160 | { |
161 | if (!parm) | ||
162 | return 1; | ||
161 | if (strcmp(parm, numa_mode_plain.name) == 0) | 163 | if (strcmp(parm, numa_mode_plain.name) == 0) |
162 | mode = &numa_mode_plain; | 164 | mode = &numa_mode_plain; |
163 | #ifdef CONFIG_NUMA_EMU | 165 | #ifdef CONFIG_NUMA_EMU |
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index b0e3b9a0e488..c7fea9bea8cb 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -431,13 +431,13 @@ static void zpci_map_resources(struct pci_dev *pdev) | |||
431 | } | 431 | } |
432 | 432 | ||
433 | #ifdef CONFIG_PCI_IOV | 433 | #ifdef CONFIG_PCI_IOV |
434 | i = PCI_IOV_RESOURCES; | 434 | for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { |
435 | int bar = i + PCI_IOV_RESOURCES; | ||
435 | 436 | ||
436 | for (; i < PCI_SRIOV_NUM_BARS + PCI_IOV_RESOURCES; i++) { | 437 | len = pci_resource_len(pdev, bar); |
437 | len = pci_resource_len(pdev, i); | ||
438 | if (!len) | 438 | if (!len) |
439 | continue; | 439 | continue; |
440 | pdev->resource[i].parent = &iov_res; | 440 | pdev->resource[bar].parent = &iov_res; |
441 | } | 441 | } |
442 | #endif | 442 | #endif |
443 | } | 443 | } |
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index 9e52d1527f71..fb2c7db0164e 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c | |||
@@ -674,9 +674,9 @@ EXPORT_SYMBOL_GPL(s390_pci_dma_ops); | |||
674 | 674 | ||
675 | static int __init s390_iommu_setup(char *str) | 675 | static int __init s390_iommu_setup(char *str) |
676 | { | 676 | { |
677 | if (!strncmp(str, "strict", 6)) | 677 | if (!strcmp(str, "strict")) |
678 | s390_iommu_strict = 1; | 678 | s390_iommu_strict = 1; |
679 | return 0; | 679 | return 1; |
680 | } | 680 | } |
681 | 681 | ||
682 | __setup("s390_iommu=", s390_iommu_setup); | 682 | __setup("s390_iommu=", s390_iommu_setup); |
diff --git a/arch/s390/pci/pci_irq.c b/arch/s390/pci/pci_irq.c index d80616ae8dd8..fbe97ab2e228 100644 --- a/arch/s390/pci/pci_irq.c +++ b/arch/s390/pci/pci_irq.c | |||
@@ -284,7 +284,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
284 | return rc; | 284 | return rc; |
285 | irq_set_chip_and_handler(irq, &zpci_irq_chip, | 285 | irq_set_chip_and_handler(irq, &zpci_irq_chip, |
286 | handle_percpu_irq); | 286 | handle_percpu_irq); |
287 | msg.data = hwirq; | 287 | msg.data = hwirq - bit; |
288 | if (irq_delivery == DIRECTED) { | 288 | if (irq_delivery == DIRECTED) { |
289 | msg.address_lo = zdev->msi_addr & 0xff0000ff; | 289 | msg.address_lo = zdev->msi_addr & 0xff0000ff; |
290 | msg.address_lo |= msi->affinity ? | 290 | msg.address_lo |= msi->affinity ? |
diff --git a/arch/s390/tools/gen_facilities.c b/arch/s390/tools/gen_facilities.c index cead9e0dcffb..61ce5b59b828 100644 --- a/arch/s390/tools/gen_facilities.c +++ b/arch/s390/tools/gen_facilities.c | |||
@@ -58,6 +58,9 @@ static struct facility_def facility_defs[] = { | |||
58 | #ifdef CONFIG_HAVE_MARCH_Z14_FEATURES | 58 | #ifdef CONFIG_HAVE_MARCH_Z14_FEATURES |
59 | 58, /* miscellaneous-instruction-extension 2 */ | 59 | 58, /* miscellaneous-instruction-extension 2 */ |
60 | #endif | 60 | #endif |
61 | #ifdef CONFIG_HAVE_MARCH_Z15_FEATURES | ||
62 | 61, /* miscellaneous-instruction-extension 3 */ | ||
63 | #endif | ||
61 | -1 /* END */ | 64 | -1 /* END */ |
62 | } | 65 | } |
63 | }, | 66 | }, |
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 603413f28fa3..d7c85c79094b 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig | |||
@@ -145,6 +145,26 @@ config CRYPTO_SHA512_S390 | |||
145 | 145 | ||
146 | It is available as of z10. | 146 | It is available as of z10. |
147 | 147 | ||
148 | config CRYPTO_SHA3_256_S390 | ||
149 | tristate "SHA3_224 and SHA3_256 digest algorithm" | ||
150 | depends on S390 | ||
151 | select CRYPTO_HASH | ||
152 | help | ||
153 | This is the s390 hardware accelerated implementation of the | ||
154 | SHA3_256 secure hash standard. | ||
155 | |||
156 | It is available as of z14. | ||
157 | |||
158 | config CRYPTO_SHA3_512_S390 | ||
159 | tristate "SHA3_384 and SHA3_512 digest algorithm" | ||
160 | depends on S390 | ||
161 | select CRYPTO_HASH | ||
162 | help | ||
163 | This is the s390 hardware accelerated implementation of the | ||
164 | SHA3_512 secure hash standard. | ||
165 | |||
166 | It is available as of z14. | ||
167 | |||
148 | config CRYPTO_DES_S390 | 168 | config CRYPTO_DES_S390 |
149 | tristate "DES and Triple DES cipher algorithms" | 169 | tristate "DES and Triple DES cipher algorithms" |
150 | depends on S390 | 170 | depends on S390 |
diff --git a/drivers/s390/Makefile b/drivers/s390/Makefile index a863b0462b43..cde73b6a9afb 100644 --- a/drivers/s390/Makefile +++ b/drivers/s390/Makefile | |||
@@ -4,6 +4,3 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += cio/ block/ char/ crypto/ net/ scsi/ virtio/ | 6 | obj-y += cio/ block/ char/ crypto/ net/ scsi/ virtio/ |
7 | |||
8 | drivers-y += drivers/s390/built-in.a | ||
9 | |||
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index b8a8816d94e7..845e12ac5954 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile | |||
@@ -49,6 +49,3 @@ obj-$(CONFIG_CRASH_DUMP) += sclp_sdias.o zcore.o | |||
49 | 49 | ||
50 | hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o | 50 | hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o |
51 | obj-$(CONFIG_HMC_DRV) += hmcdrv.o | 51 | obj-$(CONFIG_HMC_DRV) += hmcdrv.o |
52 | |||
53 | chkbss := sclp_early_core.o | ||
54 | include $(srctree)/arch/s390/scripts/Makefile.chkbss | ||
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index e71992a3c55f..cc5e84b80c69 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c | |||
@@ -40,7 +40,7 @@ static void __init sclp_early_facilities_detect(struct read_info_sccb *sccb) | |||
40 | sclp.has_gisaf = !!(sccb->fac118 & 0x08); | 40 | sclp.has_gisaf = !!(sccb->fac118 & 0x08); |
41 | sclp.has_hvs = !!(sccb->fac119 & 0x80); | 41 | sclp.has_hvs = !!(sccb->fac119 & 0x80); |
42 | sclp.has_kss = !!(sccb->fac98 & 0x01); | 42 | sclp.has_kss = !!(sccb->fac98 & 0x01); |
43 | sclp.has_sipl = !!(sccb->cbl & 0x02); | 43 | sclp.has_sipl = !!(sccb->cbl & 0x4000); |
44 | if (sccb->fac85 & 0x02) | 44 | if (sccb->fac85 & 0x02) |
45 | S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; | 45 | S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; |
46 | if (sccb->fac91 & 0x40) | 46 | if (sccb->fac91 & 0x40) |
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 0fa1b6b1491a..9e066281e2d0 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c | |||
@@ -43,6 +43,8 @@ static struct cma *vmcp_cma; | |||
43 | 43 | ||
44 | static int __init early_parse_vmcp_cma(char *p) | 44 | static int __init early_parse_vmcp_cma(char *p) |
45 | { | 45 | { |
46 | if (!p) | ||
47 | return 1; | ||
46 | vmcp_cma_size = ALIGN(memparse(p, NULL), PAGE_SIZE); | 48 | vmcp_cma_size = ALIGN(memparse(p, NULL), PAGE_SIZE); |
47 | return 0; | 49 | return 0; |
48 | } | 50 | } |
diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 9208c0e56c33..e401a3d0aa57 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c | |||
@@ -27,6 +27,9 @@ struct workqueue_struct *vfio_ccw_work_q; | |||
27 | static struct kmem_cache *vfio_ccw_io_region; | 27 | static struct kmem_cache *vfio_ccw_io_region; |
28 | static struct kmem_cache *vfio_ccw_cmd_region; | 28 | static struct kmem_cache *vfio_ccw_cmd_region; |
29 | 29 | ||
30 | debug_info_t *vfio_ccw_debug_msg_id; | ||
31 | debug_info_t *vfio_ccw_debug_trace_id; | ||
32 | |||
30 | /* | 33 | /* |
31 | * Helpers | 34 | * Helpers |
32 | */ | 35 | */ |
@@ -164,6 +167,9 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) | |||
164 | if (ret) | 167 | if (ret) |
165 | goto out_disable; | 168 | goto out_disable; |
166 | 169 | ||
170 | VFIO_CCW_MSG_EVENT(4, "bound to subchannel %x.%x.%04x\n", | ||
171 | sch->schid.cssid, sch->schid.ssid, | ||
172 | sch->schid.sch_no); | ||
167 | return 0; | 173 | return 0; |
168 | 174 | ||
169 | out_disable: | 175 | out_disable: |
@@ -194,6 +200,9 @@ static int vfio_ccw_sch_remove(struct subchannel *sch) | |||
194 | kfree(private->cp.guest_cp); | 200 | kfree(private->cp.guest_cp); |
195 | kfree(private); | 201 | kfree(private); |
196 | 202 | ||
203 | VFIO_CCW_MSG_EVENT(4, "unbound from subchannel %x.%x.%04x\n", | ||
204 | sch->schid.cssid, sch->schid.ssid, | ||
205 | sch->schid.sch_no); | ||
197 | return 0; | 206 | return 0; |
198 | } | 207 | } |
199 | 208 | ||
@@ -263,27 +272,64 @@ static struct css_driver vfio_ccw_sch_driver = { | |||
263 | .sch_event = vfio_ccw_sch_event, | 272 | .sch_event = vfio_ccw_sch_event, |
264 | }; | 273 | }; |
265 | 274 | ||
275 | static int __init vfio_ccw_debug_init(void) | ||
276 | { | ||
277 | vfio_ccw_debug_msg_id = debug_register("vfio_ccw_msg", 16, 1, | ||
278 | 11 * sizeof(long)); | ||
279 | if (!vfio_ccw_debug_msg_id) | ||
280 | goto out_unregister; | ||
281 | debug_register_view(vfio_ccw_debug_msg_id, &debug_sprintf_view); | ||
282 | debug_set_level(vfio_ccw_debug_msg_id, 2); | ||
283 | vfio_ccw_debug_trace_id = debug_register("vfio_ccw_trace", 16, 1, 16); | ||
284 | if (!vfio_ccw_debug_trace_id) | ||
285 | goto out_unregister; | ||
286 | debug_register_view(vfio_ccw_debug_trace_id, &debug_hex_ascii_view); | ||
287 | debug_set_level(vfio_ccw_debug_trace_id, 2); | ||
288 | return 0; | ||
289 | |||
290 | out_unregister: | ||
291 | debug_unregister(vfio_ccw_debug_msg_id); | ||
292 | debug_unregister(vfio_ccw_debug_trace_id); | ||
293 | return -1; | ||
294 | } | ||
295 | |||
296 | static void vfio_ccw_debug_exit(void) | ||
297 | { | ||
298 | debug_unregister(vfio_ccw_debug_msg_id); | ||
299 | debug_unregister(vfio_ccw_debug_trace_id); | ||
300 | } | ||
301 | |||
266 | static int __init vfio_ccw_sch_init(void) | 302 | static int __init vfio_ccw_sch_init(void) |
267 | { | 303 | { |
268 | int ret = -ENOMEM; | 304 | int ret; |
305 | |||
306 | ret = vfio_ccw_debug_init(); | ||
307 | if (ret) | ||
308 | return ret; | ||
269 | 309 | ||
270 | vfio_ccw_work_q = create_singlethread_workqueue("vfio-ccw"); | 310 | vfio_ccw_work_q = create_singlethread_workqueue("vfio-ccw"); |
271 | if (!vfio_ccw_work_q) | 311 | if (!vfio_ccw_work_q) { |
272 | return -ENOMEM; | 312 | ret = -ENOMEM; |
313 | goto out_err; | ||
314 | } | ||
273 | 315 | ||
274 | vfio_ccw_io_region = kmem_cache_create_usercopy("vfio_ccw_io_region", | 316 | vfio_ccw_io_region = kmem_cache_create_usercopy("vfio_ccw_io_region", |
275 | sizeof(struct ccw_io_region), 0, | 317 | sizeof(struct ccw_io_region), 0, |
276 | SLAB_ACCOUNT, 0, | 318 | SLAB_ACCOUNT, 0, |
277 | sizeof(struct ccw_io_region), NULL); | 319 | sizeof(struct ccw_io_region), NULL); |
278 | if (!vfio_ccw_io_region) | 320 | if (!vfio_ccw_io_region) { |
321 | ret = -ENOMEM; | ||
279 | goto out_err; | 322 | goto out_err; |
323 | } | ||
280 | 324 | ||
281 | vfio_ccw_cmd_region = kmem_cache_create_usercopy("vfio_ccw_cmd_region", | 325 | vfio_ccw_cmd_region = kmem_cache_create_usercopy("vfio_ccw_cmd_region", |
282 | sizeof(struct ccw_cmd_region), 0, | 326 | sizeof(struct ccw_cmd_region), 0, |
283 | SLAB_ACCOUNT, 0, | 327 | SLAB_ACCOUNT, 0, |
284 | sizeof(struct ccw_cmd_region), NULL); | 328 | sizeof(struct ccw_cmd_region), NULL); |
285 | if (!vfio_ccw_cmd_region) | 329 | if (!vfio_ccw_cmd_region) { |
330 | ret = -ENOMEM; | ||
286 | goto out_err; | 331 | goto out_err; |
332 | } | ||
287 | 333 | ||
288 | isc_register(VFIO_CCW_ISC); | 334 | isc_register(VFIO_CCW_ISC); |
289 | ret = css_driver_register(&vfio_ccw_sch_driver); | 335 | ret = css_driver_register(&vfio_ccw_sch_driver); |
@@ -298,6 +344,7 @@ out_err: | |||
298 | kmem_cache_destroy(vfio_ccw_cmd_region); | 344 | kmem_cache_destroy(vfio_ccw_cmd_region); |
299 | kmem_cache_destroy(vfio_ccw_io_region); | 345 | kmem_cache_destroy(vfio_ccw_io_region); |
300 | destroy_workqueue(vfio_ccw_work_q); | 346 | destroy_workqueue(vfio_ccw_work_q); |
347 | vfio_ccw_debug_exit(); | ||
301 | return ret; | 348 | return ret; |
302 | } | 349 | } |
303 | 350 | ||
@@ -308,6 +355,7 @@ static void __exit vfio_ccw_sch_exit(void) | |||
308 | kmem_cache_destroy(vfio_ccw_io_region); | 355 | kmem_cache_destroy(vfio_ccw_io_region); |
309 | kmem_cache_destroy(vfio_ccw_cmd_region); | 356 | kmem_cache_destroy(vfio_ccw_cmd_region); |
310 | destroy_workqueue(vfio_ccw_work_q); | 357 | destroy_workqueue(vfio_ccw_work_q); |
358 | vfio_ccw_debug_exit(); | ||
311 | } | 359 | } |
312 | module_init(vfio_ccw_sch_init); | 360 | module_init(vfio_ccw_sch_init); |
313 | module_exit(vfio_ccw_sch_exit); | 361 | module_exit(vfio_ccw_sch_exit); |
diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c index 49d9d3da0282..4a1e727c62d9 100644 --- a/drivers/s390/cio/vfio_ccw_fsm.c +++ b/drivers/s390/cio/vfio_ccw_fsm.c | |||
@@ -37,9 +37,14 @@ static int fsm_io_helper(struct vfio_ccw_private *private) | |||
37 | goto out; | 37 | goto out; |
38 | } | 38 | } |
39 | 39 | ||
40 | VFIO_CCW_TRACE_EVENT(5, "stIO"); | ||
41 | VFIO_CCW_TRACE_EVENT(5, dev_name(&sch->dev)); | ||
42 | |||
40 | /* Issue "Start Subchannel" */ | 43 | /* Issue "Start Subchannel" */ |
41 | ccode = ssch(sch->schid, orb); | 44 | ccode = ssch(sch->schid, orb); |
42 | 45 | ||
46 | VFIO_CCW_HEX_EVENT(5, &ccode, sizeof(ccode)); | ||
47 | |||
43 | switch (ccode) { | 48 | switch (ccode) { |
44 | case 0: | 49 | case 0: |
45 | /* | 50 | /* |
@@ -86,9 +91,14 @@ static int fsm_do_halt(struct vfio_ccw_private *private) | |||
86 | 91 | ||
87 | spin_lock_irqsave(sch->lock, flags); | 92 | spin_lock_irqsave(sch->lock, flags); |
88 | 93 | ||
94 | VFIO_CCW_TRACE_EVENT(2, "haltIO"); | ||
95 | VFIO_CCW_TRACE_EVENT(2, dev_name(&sch->dev)); | ||
96 | |||
89 | /* Issue "Halt Subchannel" */ | 97 | /* Issue "Halt Subchannel" */ |
90 | ccode = hsch(sch->schid); | 98 | ccode = hsch(sch->schid); |
91 | 99 | ||
100 | VFIO_CCW_HEX_EVENT(2, &ccode, sizeof(ccode)); | ||
101 | |||
92 | switch (ccode) { | 102 | switch (ccode) { |
93 | case 0: | 103 | case 0: |
94 | /* | 104 | /* |
@@ -122,9 +132,14 @@ static int fsm_do_clear(struct vfio_ccw_private *private) | |||
122 | 132 | ||
123 | spin_lock_irqsave(sch->lock, flags); | 133 | spin_lock_irqsave(sch->lock, flags); |
124 | 134 | ||
135 | VFIO_CCW_TRACE_EVENT(2, "clearIO"); | ||
136 | VFIO_CCW_TRACE_EVENT(2, dev_name(&sch->dev)); | ||
137 | |||
125 | /* Issue "Clear Subchannel" */ | 138 | /* Issue "Clear Subchannel" */ |
126 | ccode = csch(sch->schid); | 139 | ccode = csch(sch->schid); |
127 | 140 | ||
141 | VFIO_CCW_HEX_EVENT(2, &ccode, sizeof(ccode)); | ||
142 | |||
128 | switch (ccode) { | 143 | switch (ccode) { |
129 | case 0: | 144 | case 0: |
130 | /* | 145 | /* |
@@ -149,6 +164,9 @@ static void fsm_notoper(struct vfio_ccw_private *private, | |||
149 | { | 164 | { |
150 | struct subchannel *sch = private->sch; | 165 | struct subchannel *sch = private->sch; |
151 | 166 | ||
167 | VFIO_CCW_TRACE_EVENT(2, "notoper"); | ||
168 | VFIO_CCW_TRACE_EVENT(2, dev_name(&sch->dev)); | ||
169 | |||
152 | /* | 170 | /* |
153 | * TODO: | 171 | * TODO: |
154 | * Probably we should send the machine check to the guest. | 172 | * Probably we should send the machine check to the guest. |
@@ -229,6 +247,7 @@ static void fsm_io_request(struct vfio_ccw_private *private, | |||
229 | struct ccw_io_region *io_region = private->io_region; | 247 | struct ccw_io_region *io_region = private->io_region; |
230 | struct mdev_device *mdev = private->mdev; | 248 | struct mdev_device *mdev = private->mdev; |
231 | char *errstr = "request"; | 249 | char *errstr = "request"; |
250 | struct subchannel_id schid = get_schid(private); | ||
232 | 251 | ||
233 | private->state = VFIO_CCW_STATE_CP_PROCESSING; | 252 | private->state = VFIO_CCW_STATE_CP_PROCESSING; |
234 | memcpy(scsw, io_region->scsw_area, sizeof(*scsw)); | 253 | memcpy(scsw, io_region->scsw_area, sizeof(*scsw)); |
@@ -239,18 +258,32 @@ static void fsm_io_request(struct vfio_ccw_private *private, | |||
239 | /* Don't try to build a cp if transport mode is specified. */ | 258 | /* Don't try to build a cp if transport mode is specified. */ |
240 | if (orb->tm.b) { | 259 | if (orb->tm.b) { |
241 | io_region->ret_code = -EOPNOTSUPP; | 260 | io_region->ret_code = -EOPNOTSUPP; |
261 | VFIO_CCW_MSG_EVENT(2, | ||
262 | "%pUl (%x.%x.%04x): transport mode\n", | ||
263 | mdev_uuid(mdev), schid.cssid, | ||
264 | schid.ssid, schid.sch_no); | ||
242 | errstr = "transport mode"; | 265 | errstr = "transport mode"; |
243 | goto err_out; | 266 | goto err_out; |
244 | } | 267 | } |
245 | io_region->ret_code = cp_init(&private->cp, mdev_dev(mdev), | 268 | io_region->ret_code = cp_init(&private->cp, mdev_dev(mdev), |
246 | orb); | 269 | orb); |
247 | if (io_region->ret_code) { | 270 | if (io_region->ret_code) { |
271 | VFIO_CCW_MSG_EVENT(2, | ||
272 | "%pUl (%x.%x.%04x): cp_init=%d\n", | ||
273 | mdev_uuid(mdev), schid.cssid, | ||
274 | schid.ssid, schid.sch_no, | ||
275 | io_region->ret_code); | ||
248 | errstr = "cp init"; | 276 | errstr = "cp init"; |
249 | goto err_out; | 277 | goto err_out; |
250 | } | 278 | } |
251 | 279 | ||
252 | io_region->ret_code = cp_prefetch(&private->cp); | 280 | io_region->ret_code = cp_prefetch(&private->cp); |
253 | if (io_region->ret_code) { | 281 | if (io_region->ret_code) { |
282 | VFIO_CCW_MSG_EVENT(2, | ||
283 | "%pUl (%x.%x.%04x): cp_prefetch=%d\n", | ||
284 | mdev_uuid(mdev), schid.cssid, | ||
285 | schid.ssid, schid.sch_no, | ||
286 | io_region->ret_code); | ||
254 | errstr = "cp prefetch"; | 287 | errstr = "cp prefetch"; |
255 | cp_free(&private->cp); | 288 | cp_free(&private->cp); |
256 | goto err_out; | 289 | goto err_out; |
@@ -259,23 +292,36 @@ static void fsm_io_request(struct vfio_ccw_private *private, | |||
259 | /* Start channel program and wait for I/O interrupt. */ | 292 | /* Start channel program and wait for I/O interrupt. */ |
260 | io_region->ret_code = fsm_io_helper(private); | 293 | io_region->ret_code = fsm_io_helper(private); |
261 | if (io_region->ret_code) { | 294 | if (io_region->ret_code) { |
295 | VFIO_CCW_MSG_EVENT(2, | ||
296 | "%pUl (%x.%x.%04x): fsm_io_helper=%d\n", | ||
297 | mdev_uuid(mdev), schid.cssid, | ||
298 | schid.ssid, schid.sch_no, | ||
299 | io_region->ret_code); | ||
262 | errstr = "cp fsm_io_helper"; | 300 | errstr = "cp fsm_io_helper"; |
263 | cp_free(&private->cp); | 301 | cp_free(&private->cp); |
264 | goto err_out; | 302 | goto err_out; |
265 | } | 303 | } |
266 | return; | 304 | return; |
267 | } else if (scsw->cmd.fctl & SCSW_FCTL_HALT_FUNC) { | 305 | } else if (scsw->cmd.fctl & SCSW_FCTL_HALT_FUNC) { |
306 | VFIO_CCW_MSG_EVENT(2, | ||
307 | "%pUl (%x.%x.%04x): halt on io_region\n", | ||
308 | mdev_uuid(mdev), schid.cssid, | ||
309 | schid.ssid, schid.sch_no); | ||
268 | /* halt is handled via the async cmd region */ | 310 | /* halt is handled via the async cmd region */ |
269 | io_region->ret_code = -EOPNOTSUPP; | 311 | io_region->ret_code = -EOPNOTSUPP; |
270 | goto err_out; | 312 | goto err_out; |
271 | } else if (scsw->cmd.fctl & SCSW_FCTL_CLEAR_FUNC) { | 313 | } else if (scsw->cmd.fctl & SCSW_FCTL_CLEAR_FUNC) { |
314 | VFIO_CCW_MSG_EVENT(2, | ||
315 | "%pUl (%x.%x.%04x): clear on io_region\n", | ||
316 | mdev_uuid(mdev), schid.cssid, | ||
317 | schid.ssid, schid.sch_no); | ||
272 | /* clear is handled via the async cmd region */ | 318 | /* clear is handled via the async cmd region */ |
273 | io_region->ret_code = -EOPNOTSUPP; | 319 | io_region->ret_code = -EOPNOTSUPP; |
274 | goto err_out; | 320 | goto err_out; |
275 | } | 321 | } |
276 | 322 | ||
277 | err_out: | 323 | err_out: |
278 | trace_vfio_ccw_io_fctl(scsw->cmd.fctl, get_schid(private), | 324 | trace_vfio_ccw_io_fctl(scsw->cmd.fctl, schid, |
279 | io_region->ret_code, errstr); | 325 | io_region->ret_code, errstr); |
280 | } | 326 | } |
281 | 327 | ||
@@ -308,6 +354,9 @@ static void fsm_irq(struct vfio_ccw_private *private, | |||
308 | { | 354 | { |
309 | struct irb *irb = this_cpu_ptr(&cio_irb); | 355 | struct irb *irb = this_cpu_ptr(&cio_irb); |
310 | 356 | ||
357 | VFIO_CCW_TRACE_EVENT(6, "IRQ"); | ||
358 | VFIO_CCW_TRACE_EVENT(6, dev_name(&private->sch->dev)); | ||
359 | |||
311 | memcpy(&private->irb, irb, sizeof(*irb)); | 360 | memcpy(&private->irb, irb, sizeof(*irb)); |
312 | 361 | ||
313 | queue_work(vfio_ccw_work_q, &private->io_work); | 362 | queue_work(vfio_ccw_work_q, &private->io_work); |
diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index 5eb61116ca6f..f0d71ab77c50 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c | |||
@@ -124,6 +124,11 @@ static int vfio_ccw_mdev_create(struct kobject *kobj, struct mdev_device *mdev) | |||
124 | private->mdev = mdev; | 124 | private->mdev = mdev; |
125 | private->state = VFIO_CCW_STATE_IDLE; | 125 | private->state = VFIO_CCW_STATE_IDLE; |
126 | 126 | ||
127 | VFIO_CCW_MSG_EVENT(2, "mdev %pUl, sch %x.%x.%04x: create\n", | ||
128 | mdev_uuid(mdev), private->sch->schid.cssid, | ||
129 | private->sch->schid.ssid, | ||
130 | private->sch->schid.sch_no); | ||
131 | |||
127 | return 0; | 132 | return 0; |
128 | } | 133 | } |
129 | 134 | ||
@@ -132,6 +137,11 @@ static int vfio_ccw_mdev_remove(struct mdev_device *mdev) | |||
132 | struct vfio_ccw_private *private = | 137 | struct vfio_ccw_private *private = |
133 | dev_get_drvdata(mdev_parent_dev(mdev)); | 138 | dev_get_drvdata(mdev_parent_dev(mdev)); |
134 | 139 | ||
140 | VFIO_CCW_MSG_EVENT(2, "mdev %pUl, sch %x.%x.%04x: remove\n", | ||
141 | mdev_uuid(mdev), private->sch->schid.cssid, | ||
142 | private->sch->schid.ssid, | ||
143 | private->sch->schid.sch_no); | ||
144 | |||
135 | if ((private->state != VFIO_CCW_STATE_NOT_OPER) && | 145 | if ((private->state != VFIO_CCW_STATE_NOT_OPER) && |
136 | (private->state != VFIO_CCW_STATE_STANDBY)) { | 146 | (private->state != VFIO_CCW_STATE_STANDBY)) { |
137 | if (!vfio_ccw_sch_quiesce(private->sch)) | 147 | if (!vfio_ccw_sch_quiesce(private->sch)) |
diff --git a/drivers/s390/cio/vfio_ccw_private.h b/drivers/s390/cio/vfio_ccw_private.h index f1092c3dc1b1..bbe9babf767b 100644 --- a/drivers/s390/cio/vfio_ccw_private.h +++ b/drivers/s390/cio/vfio_ccw_private.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/eventfd.h> | 17 | #include <linux/eventfd.h> |
18 | #include <linux/workqueue.h> | 18 | #include <linux/workqueue.h> |
19 | #include <linux/vfio_ccw.h> | 19 | #include <linux/vfio_ccw.h> |
20 | #include <asm/debug.h> | ||
20 | 21 | ||
21 | #include "css.h" | 22 | #include "css.h" |
22 | #include "vfio_ccw_cp.h" | 23 | #include "vfio_ccw_cp.h" |
@@ -139,4 +140,20 @@ static inline void vfio_ccw_fsm_event(struct vfio_ccw_private *private, | |||
139 | 140 | ||
140 | extern struct workqueue_struct *vfio_ccw_work_q; | 141 | extern struct workqueue_struct *vfio_ccw_work_q; |
141 | 142 | ||
143 | |||
144 | /* s390 debug feature, similar to base cio */ | ||
145 | extern debug_info_t *vfio_ccw_debug_msg_id; | ||
146 | extern debug_info_t *vfio_ccw_debug_trace_id; | ||
147 | |||
148 | #define VFIO_CCW_TRACE_EVENT(imp, txt) \ | ||
149 | debug_text_event(vfio_ccw_debug_trace_id, imp, txt) | ||
150 | |||
151 | #define VFIO_CCW_MSG_EVENT(imp, args...) \ | ||
152 | debug_sprintf_event(vfio_ccw_debug_msg_id, imp, ##args) | ||
153 | |||
154 | static inline void VFIO_CCW_HEX_EVENT(int level, void *data, int length) | ||
155 | { | ||
156 | debug_event(vfio_ccw_debug_trace_id, level, data, length); | ||
157 | } | ||
158 | |||
142 | #endif | 159 | #endif |
diff --git a/drivers/s390/crypto/Makefile b/drivers/s390/crypto/Makefile index 6ccd93d0b1cb..52aa95c8af4b 100644 --- a/drivers/s390/crypto/Makefile +++ b/drivers/s390/crypto/Makefile | |||
@@ -7,7 +7,7 @@ ap-objs := ap_bus.o ap_card.o ap_queue.o | |||
7 | obj-$(subst m,y,$(CONFIG_ZCRYPT)) += ap.o | 7 | obj-$(subst m,y,$(CONFIG_ZCRYPT)) += ap.o |
8 | # zcrypt_api.o and zcrypt_msgtype*.o depend on ap.o | 8 | # zcrypt_api.o and zcrypt_msgtype*.o depend on ap.o |
9 | zcrypt-objs := zcrypt_api.o zcrypt_card.o zcrypt_queue.o | 9 | zcrypt-objs := zcrypt_api.o zcrypt_card.o zcrypt_queue.o |
10 | zcrypt-objs += zcrypt_msgtype6.o zcrypt_msgtype50.o | 10 | zcrypt-objs += zcrypt_msgtype6.o zcrypt_msgtype50.o zcrypt_ccamisc.o |
11 | obj-$(CONFIG_ZCRYPT) += zcrypt.o | 11 | obj-$(CONFIG_ZCRYPT) += zcrypt.o |
12 | # adapter drivers depend on ap.o and zcrypt.o | 12 | # adapter drivers depend on ap.o and zcrypt.o |
13 | obj-$(CONFIG_ZCRYPT) += zcrypt_cex2c.o zcrypt_cex2a.o zcrypt_cex4.o | 13 | obj-$(CONFIG_ZCRYPT) += zcrypt_cex2c.o zcrypt_cex2a.o zcrypt_cex4.o |
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c index 7f418d2d8cdf..f76a1d0f54c4 100644 --- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c | |||
@@ -2,7 +2,7 @@ | |||
2 | /* | 2 | /* |
3 | * pkey device driver | 3 | * pkey device driver |
4 | * | 4 | * |
5 | * Copyright IBM Corp. 2017 | 5 | * Copyright IBM Corp. 2017,2019 |
6 | * Author(s): Harald Freudenberger | 6 | * Author(s): Harald Freudenberger |
7 | */ | 7 | */ |
8 | 8 | ||
@@ -24,16 +24,14 @@ | |||
24 | #include <crypto/aes.h> | 24 | #include <crypto/aes.h> |
25 | 25 | ||
26 | #include "zcrypt_api.h" | 26 | #include "zcrypt_api.h" |
27 | #include "zcrypt_ccamisc.h" | ||
27 | 28 | ||
28 | MODULE_LICENSE("GPL"); | 29 | MODULE_LICENSE("GPL"); |
29 | MODULE_AUTHOR("IBM Corporation"); | 30 | MODULE_AUTHOR("IBM Corporation"); |
30 | MODULE_DESCRIPTION("s390 protected key interface"); | 31 | MODULE_DESCRIPTION("s390 protected key interface"); |
31 | 32 | ||
32 | /* Size of parameter block used for all cca requests/replies */ | 33 | #define KEYBLOBBUFSIZE 8192 /* key buffer size used for internal processing */ |
33 | #define PARMBSIZE 512 | 34 | #define MAXAPQNSINLIST 64 /* max 64 apqns within a apqn list */ |
34 | |||
35 | /* Size of vardata block used for some of the cca requests/replies */ | ||
36 | #define VARDATASIZE 4096 | ||
37 | 35 | ||
38 | /* mask of available pckmo subfunctions, fetched once at module init */ | 36 | /* mask of available pckmo subfunctions, fetched once at module init */ |
39 | static cpacf_mask_t pckmo_functions; | 37 | static cpacf_mask_t pckmo_functions; |
@@ -62,40 +60,6 @@ static void __exit pkey_debug_exit(void) | |||
62 | debug_unregister(debug_info); | 60 | debug_unregister(debug_info); |
63 | } | 61 | } |
64 | 62 | ||
65 | /* Key token types */ | ||
66 | #define TOKTYPE_NON_CCA 0x00 /* Non-CCA key token */ | ||
67 | #define TOKTYPE_CCA_INTERNAL 0x01 /* CCA internal key token */ | ||
68 | |||
69 | /* For TOKTYPE_NON_CCA: */ | ||
70 | #define TOKVER_PROTECTED_KEY 0x01 /* Protected key token */ | ||
71 | |||
72 | /* For TOKTYPE_CCA_INTERNAL: */ | ||
73 | #define TOKVER_CCA_AES 0x04 /* CCA AES key token */ | ||
74 | |||
75 | /* header part of a key token */ | ||
76 | struct keytoken_header { | ||
77 | u8 type; /* one of the TOKTYPE values */ | ||
78 | u8 res0[3]; | ||
79 | u8 version; /* one of the TOKVER values */ | ||
80 | u8 res1[3]; | ||
81 | } __packed; | ||
82 | |||
83 | /* inside view of a secure key token (only type 0x01 version 0x04) */ | ||
84 | struct secaeskeytoken { | ||
85 | u8 type; /* 0x01 for internal key token */ | ||
86 | u8 res0[3]; | ||
87 | u8 version; /* should be 0x04 */ | ||
88 | u8 res1[1]; | ||
89 | u8 flag; /* key flags */ | ||
90 | u8 res2[1]; | ||
91 | u64 mkvp; /* master key verification pattern */ | ||
92 | u8 key[32]; /* key value (encrypted) */ | ||
93 | u8 cv[8]; /* control vector */ | ||
94 | u16 bitsize; /* key bit size */ | ||
95 | u16 keysize; /* key byte size */ | ||
96 | u8 tvv[4]; /* token validation value */ | ||
97 | } __packed; | ||
98 | |||
99 | /* inside view of a protected key token (only type 0x00 version 0x01) */ | 63 | /* inside view of a protected key token (only type 0x00 version 0x01) */ |
100 | struct protaeskeytoken { | 64 | struct protaeskeytoken { |
101 | u8 type; /* 0x00 for PAES specific key tokens */ | 65 | u8 type; /* 0x00 for PAES specific key tokens */ |
@@ -108,557 +72,11 @@ struct protaeskeytoken { | |||
108 | } __packed; | 72 | } __packed; |
109 | 73 | ||
110 | /* | 74 | /* |
111 | * Simple check if the token is a valid CCA secure AES key | ||
112 | * token. If keybitsize is given, the bitsize of the key is | ||
113 | * also checked. Returns 0 on success or errno value on failure. | ||
114 | */ | ||
115 | static int check_secaeskeytoken(const u8 *token, int keybitsize) | ||
116 | { | ||
117 | struct secaeskeytoken *t = (struct secaeskeytoken *) token; | ||
118 | |||
119 | if (t->type != TOKTYPE_CCA_INTERNAL) { | ||
120 | DEBUG_ERR( | ||
121 | "%s secure token check failed, type mismatch 0x%02x != 0x%02x\n", | ||
122 | __func__, (int) t->type, TOKTYPE_CCA_INTERNAL); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | if (t->version != TOKVER_CCA_AES) { | ||
126 | DEBUG_ERR( | ||
127 | "%s secure token check failed, version mismatch 0x%02x != 0x%02x\n", | ||
128 | __func__, (int) t->version, TOKVER_CCA_AES); | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | if (keybitsize > 0 && t->bitsize != keybitsize) { | ||
132 | DEBUG_ERR( | ||
133 | "%s secure token check failed, bitsize mismatch %d != %d\n", | ||
134 | __func__, (int) t->bitsize, keybitsize); | ||
135 | return -EINVAL; | ||
136 | } | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * Allocate consecutive memory for request CPRB, request param | ||
143 | * block, reply CPRB and reply param block and fill in values | ||
144 | * for the common fields. Returns 0 on success or errno value | ||
145 | * on failure. | ||
146 | */ | ||
147 | static int alloc_and_prep_cprbmem(size_t paramblen, | ||
148 | u8 **pcprbmem, | ||
149 | struct CPRBX **preqCPRB, | ||
150 | struct CPRBX **prepCPRB) | ||
151 | { | ||
152 | u8 *cprbmem; | ||
153 | size_t cprbplusparamblen = sizeof(struct CPRBX) + paramblen; | ||
154 | struct CPRBX *preqcblk, *prepcblk; | ||
155 | |||
156 | /* | ||
157 | * allocate consecutive memory for request CPRB, request param | ||
158 | * block, reply CPRB and reply param block | ||
159 | */ | ||
160 | cprbmem = kcalloc(2, cprbplusparamblen, GFP_KERNEL); | ||
161 | if (!cprbmem) | ||
162 | return -ENOMEM; | ||
163 | |||
164 | preqcblk = (struct CPRBX *) cprbmem; | ||
165 | prepcblk = (struct CPRBX *) (cprbmem + cprbplusparamblen); | ||
166 | |||
167 | /* fill request cprb struct */ | ||
168 | preqcblk->cprb_len = sizeof(struct CPRBX); | ||
169 | preqcblk->cprb_ver_id = 0x02; | ||
170 | memcpy(preqcblk->func_id, "T2", 2); | ||
171 | preqcblk->rpl_msgbl = cprbplusparamblen; | ||
172 | if (paramblen) { | ||
173 | preqcblk->req_parmb = | ||
174 | ((u8 *) preqcblk) + sizeof(struct CPRBX); | ||
175 | preqcblk->rpl_parmb = | ||
176 | ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
177 | } | ||
178 | |||
179 | *pcprbmem = cprbmem; | ||
180 | *preqCPRB = preqcblk; | ||
181 | *prepCPRB = prepcblk; | ||
182 | |||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * Free the cprb memory allocated with the function above. | ||
188 | * If the scrub value is not zero, the memory is filled | ||
189 | * with zeros before freeing (useful if there was some | ||
190 | * clear key material in there). | ||
191 | */ | ||
192 | static void free_cprbmem(void *mem, size_t paramblen, int scrub) | ||
193 | { | ||
194 | if (scrub) | ||
195 | memzero_explicit(mem, 2 * (sizeof(struct CPRBX) + paramblen)); | ||
196 | kfree(mem); | ||
197 | } | ||
198 | |||
199 | /* | ||
200 | * Helper function to prepare the xcrb struct | ||
201 | */ | ||
202 | static inline void prep_xcrb(struct ica_xcRB *pxcrb, | ||
203 | u16 cardnr, | ||
204 | struct CPRBX *preqcblk, | ||
205 | struct CPRBX *prepcblk) | ||
206 | { | ||
207 | memset(pxcrb, 0, sizeof(*pxcrb)); | ||
208 | pxcrb->agent_ID = 0x4341; /* 'CA' */ | ||
209 | pxcrb->user_defined = (cardnr == 0xFFFF ? AUTOSELECT : cardnr); | ||
210 | pxcrb->request_control_blk_length = | ||
211 | preqcblk->cprb_len + preqcblk->req_parml; | ||
212 | pxcrb->request_control_blk_addr = (void __user *) preqcblk; | ||
213 | pxcrb->reply_control_blk_length = preqcblk->rpl_msgbl; | ||
214 | pxcrb->reply_control_blk_addr = (void __user *) prepcblk; | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * Helper function which calls zcrypt_send_cprb with | ||
219 | * memory management segment adjusted to kernel space | ||
220 | * so that the copy_from_user called within this | ||
221 | * function do in fact copy from kernel space. | ||
222 | */ | ||
223 | static inline int _zcrypt_send_cprb(struct ica_xcRB *xcrb) | ||
224 | { | ||
225 | int rc; | ||
226 | mm_segment_t old_fs = get_fs(); | ||
227 | |||
228 | set_fs(KERNEL_DS); | ||
229 | rc = zcrypt_send_cprb(xcrb); | ||
230 | set_fs(old_fs); | ||
231 | |||
232 | return rc; | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | * Generate (random) AES secure key. | ||
237 | */ | ||
238 | int pkey_genseckey(u16 cardnr, u16 domain, | ||
239 | u32 keytype, struct pkey_seckey *seckey) | ||
240 | { | ||
241 | int i, rc, keysize; | ||
242 | int seckeysize; | ||
243 | u8 *mem; | ||
244 | struct CPRBX *preqcblk, *prepcblk; | ||
245 | struct ica_xcRB xcrb; | ||
246 | struct kgreqparm { | ||
247 | u8 subfunc_code[2]; | ||
248 | u16 rule_array_len; | ||
249 | struct lv1 { | ||
250 | u16 len; | ||
251 | char key_form[8]; | ||
252 | char key_length[8]; | ||
253 | char key_type1[8]; | ||
254 | char key_type2[8]; | ||
255 | } lv1; | ||
256 | struct lv2 { | ||
257 | u16 len; | ||
258 | struct keyid { | ||
259 | u16 len; | ||
260 | u16 attr; | ||
261 | u8 data[SECKEYBLOBSIZE]; | ||
262 | } keyid[6]; | ||
263 | } lv2; | ||
264 | } *preqparm; | ||
265 | struct kgrepparm { | ||
266 | u8 subfunc_code[2]; | ||
267 | u16 rule_array_len; | ||
268 | struct lv3 { | ||
269 | u16 len; | ||
270 | u16 keyblocklen; | ||
271 | struct { | ||
272 | u16 toklen; | ||
273 | u16 tokattr; | ||
274 | u8 tok[0]; | ||
275 | /* ... some more data ... */ | ||
276 | } keyblock; | ||
277 | } lv3; | ||
278 | } *prepparm; | ||
279 | |||
280 | /* get already prepared memory for 2 cprbs with param block each */ | ||
281 | rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); | ||
282 | if (rc) | ||
283 | return rc; | ||
284 | |||
285 | /* fill request cprb struct */ | ||
286 | preqcblk->domain = domain; | ||
287 | |||
288 | /* fill request cprb param block with KG request */ | ||
289 | preqparm = (struct kgreqparm *) preqcblk->req_parmb; | ||
290 | memcpy(preqparm->subfunc_code, "KG", 2); | ||
291 | preqparm->rule_array_len = sizeof(preqparm->rule_array_len); | ||
292 | preqparm->lv1.len = sizeof(struct lv1); | ||
293 | memcpy(preqparm->lv1.key_form, "OP ", 8); | ||
294 | switch (keytype) { | ||
295 | case PKEY_KEYTYPE_AES_128: | ||
296 | keysize = 16; | ||
297 | memcpy(preqparm->lv1.key_length, "KEYLN16 ", 8); | ||
298 | break; | ||
299 | case PKEY_KEYTYPE_AES_192: | ||
300 | keysize = 24; | ||
301 | memcpy(preqparm->lv1.key_length, "KEYLN24 ", 8); | ||
302 | break; | ||
303 | case PKEY_KEYTYPE_AES_256: | ||
304 | keysize = 32; | ||
305 | memcpy(preqparm->lv1.key_length, "KEYLN32 ", 8); | ||
306 | break; | ||
307 | default: | ||
308 | DEBUG_ERR( | ||
309 | "%s unknown/unsupported keytype %d\n", | ||
310 | __func__, keytype); | ||
311 | rc = -EINVAL; | ||
312 | goto out; | ||
313 | } | ||
314 | memcpy(preqparm->lv1.key_type1, "AESDATA ", 8); | ||
315 | preqparm->lv2.len = sizeof(struct lv2); | ||
316 | for (i = 0; i < 6; i++) { | ||
317 | preqparm->lv2.keyid[i].len = sizeof(struct keyid); | ||
318 | preqparm->lv2.keyid[i].attr = (i == 2 ? 0x30 : 0x10); | ||
319 | } | ||
320 | preqcblk->req_parml = sizeof(struct kgreqparm); | ||
321 | |||
322 | /* fill xcrb struct */ | ||
323 | prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); | ||
324 | |||
325 | /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ | ||
326 | rc = _zcrypt_send_cprb(&xcrb); | ||
327 | if (rc) { | ||
328 | DEBUG_ERR( | ||
329 | "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n", | ||
330 | __func__, (int) cardnr, (int) domain, rc); | ||
331 | goto out; | ||
332 | } | ||
333 | |||
334 | /* check response returncode and reasoncode */ | ||
335 | if (prepcblk->ccp_rtcode != 0) { | ||
336 | DEBUG_ERR( | ||
337 | "%s secure key generate failure, card response %d/%d\n", | ||
338 | __func__, | ||
339 | (int) prepcblk->ccp_rtcode, | ||
340 | (int) prepcblk->ccp_rscode); | ||
341 | rc = -EIO; | ||
342 | goto out; | ||
343 | } | ||
344 | |||
345 | /* process response cprb param block */ | ||
346 | prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
347 | prepparm = (struct kgrepparm *) prepcblk->rpl_parmb; | ||
348 | |||
349 | /* check length of the returned secure key token */ | ||
350 | seckeysize = prepparm->lv3.keyblock.toklen | ||
351 | - sizeof(prepparm->lv3.keyblock.toklen) | ||
352 | - sizeof(prepparm->lv3.keyblock.tokattr); | ||
353 | if (seckeysize != SECKEYBLOBSIZE) { | ||
354 | DEBUG_ERR( | ||
355 | "%s secure token size mismatch %d != %d bytes\n", | ||
356 | __func__, seckeysize, SECKEYBLOBSIZE); | ||
357 | rc = -EIO; | ||
358 | goto out; | ||
359 | } | ||
360 | |||
361 | /* check secure key token */ | ||
362 | rc = check_secaeskeytoken(prepparm->lv3.keyblock.tok, 8*keysize); | ||
363 | if (rc) { | ||
364 | rc = -EIO; | ||
365 | goto out; | ||
366 | } | ||
367 | |||
368 | /* copy the generated secure key token */ | ||
369 | memcpy(seckey->seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE); | ||
370 | |||
371 | out: | ||
372 | free_cprbmem(mem, PARMBSIZE, 0); | ||
373 | return rc; | ||
374 | } | ||
375 | EXPORT_SYMBOL(pkey_genseckey); | ||
376 | |||
377 | /* | ||
378 | * Generate an AES secure key with given key value. | ||
379 | */ | ||
380 | int pkey_clr2seckey(u16 cardnr, u16 domain, u32 keytype, | ||
381 | const struct pkey_clrkey *clrkey, | ||
382 | struct pkey_seckey *seckey) | ||
383 | { | ||
384 | int rc, keysize, seckeysize; | ||
385 | u8 *mem; | ||
386 | struct CPRBX *preqcblk, *prepcblk; | ||
387 | struct ica_xcRB xcrb; | ||
388 | struct cmreqparm { | ||
389 | u8 subfunc_code[2]; | ||
390 | u16 rule_array_len; | ||
391 | char rule_array[8]; | ||
392 | struct lv1 { | ||
393 | u16 len; | ||
394 | u8 clrkey[0]; | ||
395 | } lv1; | ||
396 | struct lv2 { | ||
397 | u16 len; | ||
398 | struct keyid { | ||
399 | u16 len; | ||
400 | u16 attr; | ||
401 | u8 data[SECKEYBLOBSIZE]; | ||
402 | } keyid; | ||
403 | } lv2; | ||
404 | } *preqparm; | ||
405 | struct lv2 *plv2; | ||
406 | struct cmrepparm { | ||
407 | u8 subfunc_code[2]; | ||
408 | u16 rule_array_len; | ||
409 | struct lv3 { | ||
410 | u16 len; | ||
411 | u16 keyblocklen; | ||
412 | struct { | ||
413 | u16 toklen; | ||
414 | u16 tokattr; | ||
415 | u8 tok[0]; | ||
416 | /* ... some more data ... */ | ||
417 | } keyblock; | ||
418 | } lv3; | ||
419 | } *prepparm; | ||
420 | |||
421 | /* get already prepared memory for 2 cprbs with param block each */ | ||
422 | rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); | ||
423 | if (rc) | ||
424 | return rc; | ||
425 | |||
426 | /* fill request cprb struct */ | ||
427 | preqcblk->domain = domain; | ||
428 | |||
429 | /* fill request cprb param block with CM request */ | ||
430 | preqparm = (struct cmreqparm *) preqcblk->req_parmb; | ||
431 | memcpy(preqparm->subfunc_code, "CM", 2); | ||
432 | memcpy(preqparm->rule_array, "AES ", 8); | ||
433 | preqparm->rule_array_len = | ||
434 | sizeof(preqparm->rule_array_len) + sizeof(preqparm->rule_array); | ||
435 | switch (keytype) { | ||
436 | case PKEY_KEYTYPE_AES_128: | ||
437 | keysize = 16; | ||
438 | break; | ||
439 | case PKEY_KEYTYPE_AES_192: | ||
440 | keysize = 24; | ||
441 | break; | ||
442 | case PKEY_KEYTYPE_AES_256: | ||
443 | keysize = 32; | ||
444 | break; | ||
445 | default: | ||
446 | DEBUG_ERR( | ||
447 | "%s unknown/unsupported keytype %d\n", | ||
448 | __func__, keytype); | ||
449 | rc = -EINVAL; | ||
450 | goto out; | ||
451 | } | ||
452 | preqparm->lv1.len = sizeof(struct lv1) + keysize; | ||
453 | memcpy(preqparm->lv1.clrkey, clrkey->clrkey, keysize); | ||
454 | plv2 = (struct lv2 *) (((u8 *) &preqparm->lv2) + keysize); | ||
455 | plv2->len = sizeof(struct lv2); | ||
456 | plv2->keyid.len = sizeof(struct keyid); | ||
457 | plv2->keyid.attr = 0x30; | ||
458 | preqcblk->req_parml = sizeof(struct cmreqparm) + keysize; | ||
459 | |||
460 | /* fill xcrb struct */ | ||
461 | prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); | ||
462 | |||
463 | /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ | ||
464 | rc = _zcrypt_send_cprb(&xcrb); | ||
465 | if (rc) { | ||
466 | DEBUG_ERR( | ||
467 | "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n", | ||
468 | __func__, (int) cardnr, (int) domain, rc); | ||
469 | goto out; | ||
470 | } | ||
471 | |||
472 | /* check response returncode and reasoncode */ | ||
473 | if (prepcblk->ccp_rtcode != 0) { | ||
474 | DEBUG_ERR( | ||
475 | "%s clear key import failure, card response %d/%d\n", | ||
476 | __func__, | ||
477 | (int) prepcblk->ccp_rtcode, | ||
478 | (int) prepcblk->ccp_rscode); | ||
479 | rc = -EIO; | ||
480 | goto out; | ||
481 | } | ||
482 | |||
483 | /* process response cprb param block */ | ||
484 | prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
485 | prepparm = (struct cmrepparm *) prepcblk->rpl_parmb; | ||
486 | |||
487 | /* check length of the returned secure key token */ | ||
488 | seckeysize = prepparm->lv3.keyblock.toklen | ||
489 | - sizeof(prepparm->lv3.keyblock.toklen) | ||
490 | - sizeof(prepparm->lv3.keyblock.tokattr); | ||
491 | if (seckeysize != SECKEYBLOBSIZE) { | ||
492 | DEBUG_ERR( | ||
493 | "%s secure token size mismatch %d != %d bytes\n", | ||
494 | __func__, seckeysize, SECKEYBLOBSIZE); | ||
495 | rc = -EIO; | ||
496 | goto out; | ||
497 | } | ||
498 | |||
499 | /* check secure key token */ | ||
500 | rc = check_secaeskeytoken(prepparm->lv3.keyblock.tok, 8*keysize); | ||
501 | if (rc) { | ||
502 | rc = -EIO; | ||
503 | goto out; | ||
504 | } | ||
505 | |||
506 | /* copy the generated secure key token */ | ||
507 | memcpy(seckey->seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE); | ||
508 | |||
509 | out: | ||
510 | free_cprbmem(mem, PARMBSIZE, 1); | ||
511 | return rc; | ||
512 | } | ||
513 | EXPORT_SYMBOL(pkey_clr2seckey); | ||
514 | |||
515 | /* | ||
516 | * Derive a proteced key from the secure key blob. | ||
517 | */ | ||
518 | int pkey_sec2protkey(u16 cardnr, u16 domain, | ||
519 | const struct pkey_seckey *seckey, | ||
520 | struct pkey_protkey *protkey) | ||
521 | { | ||
522 | int rc; | ||
523 | u8 *mem; | ||
524 | struct CPRBX *preqcblk, *prepcblk; | ||
525 | struct ica_xcRB xcrb; | ||
526 | struct uskreqparm { | ||
527 | u8 subfunc_code[2]; | ||
528 | u16 rule_array_len; | ||
529 | struct lv1 { | ||
530 | u16 len; | ||
531 | u16 attr_len; | ||
532 | u16 attr_flags; | ||
533 | } lv1; | ||
534 | struct lv2 { | ||
535 | u16 len; | ||
536 | u16 attr_len; | ||
537 | u16 attr_flags; | ||
538 | u8 token[0]; /* cca secure key token */ | ||
539 | } lv2 __packed; | ||
540 | } *preqparm; | ||
541 | struct uskrepparm { | ||
542 | u8 subfunc_code[2]; | ||
543 | u16 rule_array_len; | ||
544 | struct lv3 { | ||
545 | u16 len; | ||
546 | u16 attr_len; | ||
547 | u16 attr_flags; | ||
548 | struct cpacfkeyblock { | ||
549 | u8 version; /* version of this struct */ | ||
550 | u8 flags[2]; | ||
551 | u8 algo; | ||
552 | u8 form; | ||
553 | u8 pad1[3]; | ||
554 | u16 keylen; | ||
555 | u8 key[64]; /* the key (keylen bytes) */ | ||
556 | u16 keyattrlen; | ||
557 | u8 keyattr[32]; | ||
558 | u8 pad2[1]; | ||
559 | u8 vptype; | ||
560 | u8 vp[32]; /* verification pattern */ | ||
561 | } keyblock; | ||
562 | } lv3 __packed; | ||
563 | } *prepparm; | ||
564 | |||
565 | /* get already prepared memory for 2 cprbs with param block each */ | ||
566 | rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); | ||
567 | if (rc) | ||
568 | return rc; | ||
569 | |||
570 | /* fill request cprb struct */ | ||
571 | preqcblk->domain = domain; | ||
572 | |||
573 | /* fill request cprb param block with USK request */ | ||
574 | preqparm = (struct uskreqparm *) preqcblk->req_parmb; | ||
575 | memcpy(preqparm->subfunc_code, "US", 2); | ||
576 | preqparm->rule_array_len = sizeof(preqparm->rule_array_len); | ||
577 | preqparm->lv1.len = sizeof(struct lv1); | ||
578 | preqparm->lv1.attr_len = sizeof(struct lv1) - sizeof(preqparm->lv1.len); | ||
579 | preqparm->lv1.attr_flags = 0x0001; | ||
580 | preqparm->lv2.len = sizeof(struct lv2) + SECKEYBLOBSIZE; | ||
581 | preqparm->lv2.attr_len = sizeof(struct lv2) | ||
582 | - sizeof(preqparm->lv2.len) + SECKEYBLOBSIZE; | ||
583 | preqparm->lv2.attr_flags = 0x0000; | ||
584 | memcpy(preqparm->lv2.token, seckey->seckey, SECKEYBLOBSIZE); | ||
585 | preqcblk->req_parml = sizeof(struct uskreqparm) + SECKEYBLOBSIZE; | ||
586 | |||
587 | /* fill xcrb struct */ | ||
588 | prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); | ||
589 | |||
590 | /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ | ||
591 | rc = _zcrypt_send_cprb(&xcrb); | ||
592 | if (rc) { | ||
593 | DEBUG_ERR( | ||
594 | "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n", | ||
595 | __func__, (int) cardnr, (int) domain, rc); | ||
596 | goto out; | ||
597 | } | ||
598 | |||
599 | /* check response returncode and reasoncode */ | ||
600 | if (prepcblk->ccp_rtcode != 0) { | ||
601 | DEBUG_ERR( | ||
602 | "%s unwrap secure key failure, card response %d/%d\n", | ||
603 | __func__, | ||
604 | (int) prepcblk->ccp_rtcode, | ||
605 | (int) prepcblk->ccp_rscode); | ||
606 | rc = -EIO; | ||
607 | goto out; | ||
608 | } | ||
609 | if (prepcblk->ccp_rscode != 0) { | ||
610 | DEBUG_WARN( | ||
611 | "%s unwrap secure key warning, card response %d/%d\n", | ||
612 | __func__, | ||
613 | (int) prepcblk->ccp_rtcode, | ||
614 | (int) prepcblk->ccp_rscode); | ||
615 | } | ||
616 | |||
617 | /* process response cprb param block */ | ||
618 | prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
619 | prepparm = (struct uskrepparm *) prepcblk->rpl_parmb; | ||
620 | |||
621 | /* check the returned keyblock */ | ||
622 | if (prepparm->lv3.keyblock.version != 0x01) { | ||
623 | DEBUG_ERR( | ||
624 | "%s reply param keyblock version mismatch 0x%02x != 0x01\n", | ||
625 | __func__, (int) prepparm->lv3.keyblock.version); | ||
626 | rc = -EIO; | ||
627 | goto out; | ||
628 | } | ||
629 | |||
630 | /* copy the tanslated protected key */ | ||
631 | switch (prepparm->lv3.keyblock.keylen) { | ||
632 | case 16+32: | ||
633 | protkey->type = PKEY_KEYTYPE_AES_128; | ||
634 | break; | ||
635 | case 24+32: | ||
636 | protkey->type = PKEY_KEYTYPE_AES_192; | ||
637 | break; | ||
638 | case 32+32: | ||
639 | protkey->type = PKEY_KEYTYPE_AES_256; | ||
640 | break; | ||
641 | default: | ||
642 | DEBUG_ERR("%s unknown/unsupported keytype %d\n", | ||
643 | __func__, prepparm->lv3.keyblock.keylen); | ||
644 | rc = -EIO; | ||
645 | goto out; | ||
646 | } | ||
647 | protkey->len = prepparm->lv3.keyblock.keylen; | ||
648 | memcpy(protkey->protkey, prepparm->lv3.keyblock.key, protkey->len); | ||
649 | |||
650 | out: | ||
651 | free_cprbmem(mem, PARMBSIZE, 0); | ||
652 | return rc; | ||
653 | } | ||
654 | EXPORT_SYMBOL(pkey_sec2protkey); | ||
655 | |||
656 | /* | ||
657 | * Create a protected key from a clear key value. | 75 | * Create a protected key from a clear key value. |
658 | */ | 76 | */ |
659 | int pkey_clr2protkey(u32 keytype, | 77 | static int pkey_clr2protkey(u32 keytype, |
660 | const struct pkey_clrkey *clrkey, | 78 | const struct pkey_clrkey *clrkey, |
661 | struct pkey_protkey *protkey) | 79 | struct pkey_protkey *protkey) |
662 | { | 80 | { |
663 | long fc; | 81 | long fc; |
664 | int keysize; | 82 | int keysize; |
@@ -707,338 +125,43 @@ int pkey_clr2protkey(u32 keytype, | |||
707 | 125 | ||
708 | return 0; | 126 | return 0; |
709 | } | 127 | } |
710 | EXPORT_SYMBOL(pkey_clr2protkey); | ||
711 | |||
712 | /* | ||
713 | * query cryptographic facility from adapter | ||
714 | */ | ||
715 | static int query_crypto_facility(u16 cardnr, u16 domain, | ||
716 | const char *keyword, | ||
717 | u8 *rarray, size_t *rarraylen, | ||
718 | u8 *varray, size_t *varraylen) | ||
719 | { | ||
720 | int rc; | ||
721 | u16 len; | ||
722 | u8 *mem, *ptr; | ||
723 | struct CPRBX *preqcblk, *prepcblk; | ||
724 | struct ica_xcRB xcrb; | ||
725 | struct fqreqparm { | ||
726 | u8 subfunc_code[2]; | ||
727 | u16 rule_array_len; | ||
728 | char rule_array[8]; | ||
729 | struct lv1 { | ||
730 | u16 len; | ||
731 | u8 data[VARDATASIZE]; | ||
732 | } lv1; | ||
733 | u16 dummylen; | ||
734 | } *preqparm; | ||
735 | size_t parmbsize = sizeof(struct fqreqparm); | ||
736 | struct fqrepparm { | ||
737 | u8 subfunc_code[2]; | ||
738 | u8 lvdata[0]; | ||
739 | } *prepparm; | ||
740 | |||
741 | /* get already prepared memory for 2 cprbs with param block each */ | ||
742 | rc = alloc_and_prep_cprbmem(parmbsize, &mem, &preqcblk, &prepcblk); | ||
743 | if (rc) | ||
744 | return rc; | ||
745 | |||
746 | /* fill request cprb struct */ | ||
747 | preqcblk->domain = domain; | ||
748 | |||
749 | /* fill request cprb param block with FQ request */ | ||
750 | preqparm = (struct fqreqparm *) preqcblk->req_parmb; | ||
751 | memcpy(preqparm->subfunc_code, "FQ", 2); | ||
752 | memcpy(preqparm->rule_array, keyword, sizeof(preqparm->rule_array)); | ||
753 | preqparm->rule_array_len = | ||
754 | sizeof(preqparm->rule_array_len) + sizeof(preqparm->rule_array); | ||
755 | preqparm->lv1.len = sizeof(preqparm->lv1); | ||
756 | preqparm->dummylen = sizeof(preqparm->dummylen); | ||
757 | preqcblk->req_parml = parmbsize; | ||
758 | |||
759 | /* fill xcrb struct */ | ||
760 | prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); | ||
761 | |||
762 | /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ | ||
763 | rc = _zcrypt_send_cprb(&xcrb); | ||
764 | if (rc) { | ||
765 | DEBUG_ERR( | ||
766 | "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n", | ||
767 | __func__, (int) cardnr, (int) domain, rc); | ||
768 | goto out; | ||
769 | } | ||
770 | |||
771 | /* check response returncode and reasoncode */ | ||
772 | if (prepcblk->ccp_rtcode != 0) { | ||
773 | DEBUG_ERR( | ||
774 | "%s unwrap secure key failure, card response %d/%d\n", | ||
775 | __func__, | ||
776 | (int) prepcblk->ccp_rtcode, | ||
777 | (int) prepcblk->ccp_rscode); | ||
778 | rc = -EIO; | ||
779 | goto out; | ||
780 | } | ||
781 | |||
782 | /* process response cprb param block */ | ||
783 | prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
784 | prepparm = (struct fqrepparm *) prepcblk->rpl_parmb; | ||
785 | ptr = prepparm->lvdata; | ||
786 | |||
787 | /* check and possibly copy reply rule array */ | ||
788 | len = *((u16 *) ptr); | ||
789 | if (len > sizeof(u16)) { | ||
790 | ptr += sizeof(u16); | ||
791 | len -= sizeof(u16); | ||
792 | if (rarray && rarraylen && *rarraylen > 0) { | ||
793 | *rarraylen = (len > *rarraylen ? *rarraylen : len); | ||
794 | memcpy(rarray, ptr, *rarraylen); | ||
795 | } | ||
796 | ptr += len; | ||
797 | } | ||
798 | /* check and possible copy reply var array */ | ||
799 | len = *((u16 *) ptr); | ||
800 | if (len > sizeof(u16)) { | ||
801 | ptr += sizeof(u16); | ||
802 | len -= sizeof(u16); | ||
803 | if (varray && varraylen && *varraylen > 0) { | ||
804 | *varraylen = (len > *varraylen ? *varraylen : len); | ||
805 | memcpy(varray, ptr, *varraylen); | ||
806 | } | ||
807 | ptr += len; | ||
808 | } | ||
809 | |||
810 | out: | ||
811 | free_cprbmem(mem, parmbsize, 0); | ||
812 | return rc; | ||
813 | } | ||
814 | |||
815 | /* | ||
816 | * Fetch the current and old mkvp values via | ||
817 | * query_crypto_facility from adapter. | ||
818 | */ | ||
819 | static int fetch_mkvp(u16 cardnr, u16 domain, u64 mkvp[2]) | ||
820 | { | ||
821 | int rc, found = 0; | ||
822 | size_t rlen, vlen; | ||
823 | u8 *rarray, *varray, *pg; | ||
824 | |||
825 | pg = (u8 *) __get_free_page(GFP_KERNEL); | ||
826 | if (!pg) | ||
827 | return -ENOMEM; | ||
828 | rarray = pg; | ||
829 | varray = pg + PAGE_SIZE/2; | ||
830 | rlen = vlen = PAGE_SIZE/2; | ||
831 | |||
832 | rc = query_crypto_facility(cardnr, domain, "STATICSA", | ||
833 | rarray, &rlen, varray, &vlen); | ||
834 | if (rc == 0 && rlen > 8*8 && vlen > 184+8) { | ||
835 | if (rarray[8*8] == '2') { | ||
836 | /* current master key state is valid */ | ||
837 | mkvp[0] = *((u64 *)(varray + 184)); | ||
838 | mkvp[1] = *((u64 *)(varray + 172)); | ||
839 | found = 1; | ||
840 | } | ||
841 | } | ||
842 | |||
843 | free_page((unsigned long) pg); | ||
844 | |||
845 | return found ? 0 : -ENOENT; | ||
846 | } | ||
847 | |||
848 | /* struct to hold cached mkvp info for each card/domain */ | ||
849 | struct mkvp_info { | ||
850 | struct list_head list; | ||
851 | u16 cardnr; | ||
852 | u16 domain; | ||
853 | u64 mkvp[2]; | ||
854 | }; | ||
855 | |||
856 | /* a list with mkvp_info entries */ | ||
857 | static LIST_HEAD(mkvp_list); | ||
858 | static DEFINE_SPINLOCK(mkvp_list_lock); | ||
859 | |||
860 | static int mkvp_cache_fetch(u16 cardnr, u16 domain, u64 mkvp[2]) | ||
861 | { | ||
862 | int rc = -ENOENT; | ||
863 | struct mkvp_info *ptr; | ||
864 | |||
865 | spin_lock_bh(&mkvp_list_lock); | ||
866 | list_for_each_entry(ptr, &mkvp_list, list) { | ||
867 | if (ptr->cardnr == cardnr && | ||
868 | ptr->domain == domain) { | ||
869 | memcpy(mkvp, ptr->mkvp, 2 * sizeof(u64)); | ||
870 | rc = 0; | ||
871 | break; | ||
872 | } | ||
873 | } | ||
874 | spin_unlock_bh(&mkvp_list_lock); | ||
875 | |||
876 | return rc; | ||
877 | } | ||
878 | |||
879 | static void mkvp_cache_update(u16 cardnr, u16 domain, u64 mkvp[2]) | ||
880 | { | ||
881 | int found = 0; | ||
882 | struct mkvp_info *ptr; | ||
883 | |||
884 | spin_lock_bh(&mkvp_list_lock); | ||
885 | list_for_each_entry(ptr, &mkvp_list, list) { | ||
886 | if (ptr->cardnr == cardnr && | ||
887 | ptr->domain == domain) { | ||
888 | memcpy(ptr->mkvp, mkvp, 2 * sizeof(u64)); | ||
889 | found = 1; | ||
890 | break; | ||
891 | } | ||
892 | } | ||
893 | if (!found) { | ||
894 | ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC); | ||
895 | if (!ptr) { | ||
896 | spin_unlock_bh(&mkvp_list_lock); | ||
897 | return; | ||
898 | } | ||
899 | ptr->cardnr = cardnr; | ||
900 | ptr->domain = domain; | ||
901 | memcpy(ptr->mkvp, mkvp, 2 * sizeof(u64)); | ||
902 | list_add(&ptr->list, &mkvp_list); | ||
903 | } | ||
904 | spin_unlock_bh(&mkvp_list_lock); | ||
905 | } | ||
906 | |||
907 | static void mkvp_cache_scrub(u16 cardnr, u16 domain) | ||
908 | { | ||
909 | struct mkvp_info *ptr; | ||
910 | |||
911 | spin_lock_bh(&mkvp_list_lock); | ||
912 | list_for_each_entry(ptr, &mkvp_list, list) { | ||
913 | if (ptr->cardnr == cardnr && | ||
914 | ptr->domain == domain) { | ||
915 | list_del(&ptr->list); | ||
916 | kfree(ptr); | ||
917 | break; | ||
918 | } | ||
919 | } | ||
920 | spin_unlock_bh(&mkvp_list_lock); | ||
921 | } | ||
922 | |||
923 | static void __exit mkvp_cache_free(void) | ||
924 | { | ||
925 | struct mkvp_info *ptr, *pnext; | ||
926 | |||
927 | spin_lock_bh(&mkvp_list_lock); | ||
928 | list_for_each_entry_safe(ptr, pnext, &mkvp_list, list) { | ||
929 | list_del(&ptr->list); | ||
930 | kfree(ptr); | ||
931 | } | ||
932 | spin_unlock_bh(&mkvp_list_lock); | ||
933 | } | ||
934 | |||
935 | /* | ||
936 | * Search for a matching crypto card based on the Master Key | ||
937 | * Verification Pattern provided inside a secure key. | ||
938 | */ | ||
939 | int pkey_findcard(const struct pkey_seckey *seckey, | ||
940 | u16 *pcardnr, u16 *pdomain, int verify) | ||
941 | { | ||
942 | struct secaeskeytoken *t = (struct secaeskeytoken *) seckey; | ||
943 | struct zcrypt_device_status_ext *device_status; | ||
944 | u16 card, dom; | ||
945 | u64 mkvp[2]; | ||
946 | int i, rc, oi = -1; | ||
947 | |||
948 | /* mkvp must not be zero */ | ||
949 | if (t->mkvp == 0) | ||
950 | return -EINVAL; | ||
951 | |||
952 | /* fetch status of all crypto cards */ | ||
953 | device_status = kmalloc_array(MAX_ZDEV_ENTRIES_EXT, | ||
954 | sizeof(struct zcrypt_device_status_ext), | ||
955 | GFP_KERNEL); | ||
956 | if (!device_status) | ||
957 | return -ENOMEM; | ||
958 | zcrypt_device_status_mask_ext(device_status); | ||
959 | |||
960 | /* walk through all crypto cards */ | ||
961 | for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) { | ||
962 | card = AP_QID_CARD(device_status[i].qid); | ||
963 | dom = AP_QID_QUEUE(device_status[i].qid); | ||
964 | if (device_status[i].online && | ||
965 | device_status[i].functions & 0x04) { | ||
966 | /* an enabled CCA Coprocessor card */ | ||
967 | /* try cached mkvp */ | ||
968 | if (mkvp_cache_fetch(card, dom, mkvp) == 0 && | ||
969 | t->mkvp == mkvp[0]) { | ||
970 | if (!verify) | ||
971 | break; | ||
972 | /* verify: fetch mkvp from adapter */ | ||
973 | if (fetch_mkvp(card, dom, mkvp) == 0) { | ||
974 | mkvp_cache_update(card, dom, mkvp); | ||
975 | if (t->mkvp == mkvp[0]) | ||
976 | break; | ||
977 | } | ||
978 | } | ||
979 | } else { | ||
980 | /* Card is offline and/or not a CCA card. */ | ||
981 | /* del mkvp entry from cache if it exists */ | ||
982 | mkvp_cache_scrub(card, dom); | ||
983 | } | ||
984 | } | ||
985 | if (i >= MAX_ZDEV_ENTRIES_EXT) { | ||
986 | /* nothing found, so this time without cache */ | ||
987 | for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) { | ||
988 | if (!(device_status[i].online && | ||
989 | device_status[i].functions & 0x04)) | ||
990 | continue; | ||
991 | card = AP_QID_CARD(device_status[i].qid); | ||
992 | dom = AP_QID_QUEUE(device_status[i].qid); | ||
993 | /* fresh fetch mkvp from adapter */ | ||
994 | if (fetch_mkvp(card, dom, mkvp) == 0) { | ||
995 | mkvp_cache_update(card, dom, mkvp); | ||
996 | if (t->mkvp == mkvp[0]) | ||
997 | break; | ||
998 | if (t->mkvp == mkvp[1] && oi < 0) | ||
999 | oi = i; | ||
1000 | } | ||
1001 | } | ||
1002 | if (i >= MAX_ZDEV_ENTRIES_EXT && oi >= 0) { | ||
1003 | /* old mkvp matched, use this card then */ | ||
1004 | card = AP_QID_CARD(device_status[oi].qid); | ||
1005 | dom = AP_QID_QUEUE(device_status[oi].qid); | ||
1006 | } | ||
1007 | } | ||
1008 | if (i < MAX_ZDEV_ENTRIES_EXT || oi >= 0) { | ||
1009 | if (pcardnr) | ||
1010 | *pcardnr = card; | ||
1011 | if (pdomain) | ||
1012 | *pdomain = dom; | ||
1013 | rc = 0; | ||
1014 | } else | ||
1015 | rc = -ENODEV; | ||
1016 | |||
1017 | kfree(device_status); | ||
1018 | return rc; | ||
1019 | } | ||
1020 | EXPORT_SYMBOL(pkey_findcard); | ||
1021 | 128 | ||
1022 | /* | 129 | /* |
1023 | * Find card and transform secure key into protected key. | 130 | * Find card and transform secure key into protected key. |
1024 | */ | 131 | */ |
1025 | int pkey_skey2pkey(const struct pkey_seckey *seckey, | 132 | static int pkey_skey2pkey(const u8 *key, struct pkey_protkey *pkey) |
1026 | struct pkey_protkey *protkey) | ||
1027 | { | 133 | { |
1028 | u16 cardnr, domain; | ||
1029 | int rc, verify; | 134 | int rc, verify; |
135 | u16 cardnr, domain; | ||
136 | struct keytoken_header *hdr = (struct keytoken_header *)key; | ||
1030 | 137 | ||
1031 | /* | 138 | /* |
1032 | * The pkey_sec2protkey call may fail when a card has been | 139 | * The cca_xxx2protkey call may fail when a card has been |
1033 | * addressed where the master key was changed after last fetch | 140 | * addressed where the master key was changed after last fetch |
1034 | * of the mkvp into the cache. So first try without verify then | 141 | * of the mkvp into the cache. Try 3 times: First witout verify |
1035 | * with verify enabled (thus refreshing the mkvp for each card). | 142 | * then with verify and last round with verify and old master |
143 | * key verification pattern match not ignored. | ||
1036 | */ | 144 | */ |
1037 | for (verify = 0; verify < 2; verify++) { | 145 | for (verify = 0; verify < 3; verify++) { |
1038 | rc = pkey_findcard(seckey, &cardnr, &domain, verify); | 146 | rc = cca_findcard(key, &cardnr, &domain, verify); |
1039 | if (rc) | 147 | if (rc < 0) |
148 | continue; | ||
149 | if (rc > 0 && verify < 2) | ||
1040 | continue; | 150 | continue; |
1041 | rc = pkey_sec2protkey(cardnr, domain, seckey, protkey); | 151 | switch (hdr->version) { |
152 | case TOKVER_CCA_AES: | ||
153 | rc = cca_sec2protkey(cardnr, domain, | ||
154 | key, pkey->protkey, | ||
155 | &pkey->len, &pkey->type); | ||
156 | break; | ||
157 | case TOKVER_CCA_VLSC: | ||
158 | rc = cca_cipher2protkey(cardnr, domain, | ||
159 | key, pkey->protkey, | ||
160 | &pkey->len, &pkey->type); | ||
161 | break; | ||
162 | default: | ||
163 | return -EINVAL; | ||
164 | } | ||
1042 | if (rc == 0) | 165 | if (rc == 0) |
1043 | break; | 166 | break; |
1044 | } | 167 | } |
@@ -1048,22 +171,20 @@ int pkey_skey2pkey(const struct pkey_seckey *seckey, | |||
1048 | 171 | ||
1049 | return rc; | 172 | return rc; |
1050 | } | 173 | } |
1051 | EXPORT_SYMBOL(pkey_skey2pkey); | ||
1052 | 174 | ||
1053 | /* | 175 | /* |
1054 | * Verify key and give back some info about the key. | 176 | * Verify key and give back some info about the key. |
1055 | */ | 177 | */ |
1056 | int pkey_verifykey(const struct pkey_seckey *seckey, | 178 | static int pkey_verifykey(const struct pkey_seckey *seckey, |
1057 | u16 *pcardnr, u16 *pdomain, | 179 | u16 *pcardnr, u16 *pdomain, |
1058 | u16 *pkeysize, u32 *pattributes) | 180 | u16 *pkeysize, u32 *pattributes) |
1059 | { | 181 | { |
1060 | struct secaeskeytoken *t = (struct secaeskeytoken *) seckey; | 182 | struct secaeskeytoken *t = (struct secaeskeytoken *) seckey; |
1061 | u16 cardnr, domain; | 183 | u16 cardnr, domain; |
1062 | u64 mkvp[2]; | ||
1063 | int rc; | 184 | int rc; |
1064 | 185 | ||
1065 | /* check the secure key for valid AES secure key */ | 186 | /* check the secure key for valid AES secure key */ |
1066 | rc = check_secaeskeytoken((u8 *) seckey, 0); | 187 | rc = cca_check_secaeskeytoken(debug_info, 3, (u8 *) seckey, 0); |
1067 | if (rc) | 188 | if (rc) |
1068 | goto out; | 189 | goto out; |
1069 | if (pattributes) | 190 | if (pattributes) |
@@ -1072,18 +193,16 @@ int pkey_verifykey(const struct pkey_seckey *seckey, | |||
1072 | *pkeysize = t->bitsize; | 193 | *pkeysize = t->bitsize; |
1073 | 194 | ||
1074 | /* try to find a card which can handle this key */ | 195 | /* try to find a card which can handle this key */ |
1075 | rc = pkey_findcard(seckey, &cardnr, &domain, 1); | 196 | rc = cca_findcard(seckey->seckey, &cardnr, &domain, 1); |
1076 | if (rc) | 197 | if (rc < 0) |
1077 | goto out; | 198 | goto out; |
1078 | 199 | ||
1079 | /* check mkvp for old mkvp match */ | 200 | if (rc > 0) { |
1080 | rc = mkvp_cache_fetch(cardnr, domain, mkvp); | 201 | /* key mkvp matches to old master key mkvp */ |
1081 | if (rc) | ||
1082 | goto out; | ||
1083 | if (t->mkvp == mkvp[1] && t->mkvp != mkvp[0]) { | ||
1084 | DEBUG_DBG("%s secure key has old mkvp\n", __func__); | 202 | DEBUG_DBG("%s secure key has old mkvp\n", __func__); |
1085 | if (pattributes) | 203 | if (pattributes) |
1086 | *pattributes |= PKEY_VERIFY_ATTR_OLD_MKVP; | 204 | *pattributes |= PKEY_VERIFY_ATTR_OLD_MKVP; |
205 | rc = 0; | ||
1087 | } | 206 | } |
1088 | 207 | ||
1089 | if (pcardnr) | 208 | if (pcardnr) |
@@ -1095,12 +214,11 @@ out: | |||
1095 | DEBUG_DBG("%s rc=%d\n", __func__, rc); | 214 | DEBUG_DBG("%s rc=%d\n", __func__, rc); |
1096 | return rc; | 215 | return rc; |
1097 | } | 216 | } |
1098 | EXPORT_SYMBOL(pkey_verifykey); | ||
1099 | 217 | ||
1100 | /* | 218 | /* |
1101 | * Generate a random protected key | 219 | * Generate a random protected key |
1102 | */ | 220 | */ |
1103 | int pkey_genprotkey(__u32 keytype, struct pkey_protkey *protkey) | 221 | static int pkey_genprotkey(u32 keytype, struct pkey_protkey *protkey) |
1104 | { | 222 | { |
1105 | struct pkey_clrkey clrkey; | 223 | struct pkey_clrkey clrkey; |
1106 | int keysize; | 224 | int keysize; |
@@ -1135,12 +253,11 @@ int pkey_genprotkey(__u32 keytype, struct pkey_protkey *protkey) | |||
1135 | 253 | ||
1136 | return 0; | 254 | return 0; |
1137 | } | 255 | } |
1138 | EXPORT_SYMBOL(pkey_genprotkey); | ||
1139 | 256 | ||
1140 | /* | 257 | /* |
1141 | * Verify if a protected key is still valid | 258 | * Verify if a protected key is still valid |
1142 | */ | 259 | */ |
1143 | int pkey_verifyprotkey(const struct pkey_protkey *protkey) | 260 | static int pkey_verifyprotkey(const struct pkey_protkey *protkey) |
1144 | { | 261 | { |
1145 | unsigned long fc; | 262 | unsigned long fc; |
1146 | struct { | 263 | struct { |
@@ -1181,12 +298,11 @@ int pkey_verifyprotkey(const struct pkey_protkey *protkey) | |||
1181 | 298 | ||
1182 | return 0; | 299 | return 0; |
1183 | } | 300 | } |
1184 | EXPORT_SYMBOL(pkey_verifyprotkey); | ||
1185 | 301 | ||
1186 | /* | 302 | /* |
1187 | * Transform a non-CCA key token into a protected key | 303 | * Transform a non-CCA key token into a protected key |
1188 | */ | 304 | */ |
1189 | static int pkey_nonccatok2pkey(const __u8 *key, __u32 keylen, | 305 | static int pkey_nonccatok2pkey(const u8 *key, u32 keylen, |
1190 | struct pkey_protkey *protkey) | 306 | struct pkey_protkey *protkey) |
1191 | { | 307 | { |
1192 | struct keytoken_header *hdr = (struct keytoken_header *)key; | 308 | struct keytoken_header *hdr = (struct keytoken_header *)key; |
@@ -1214,7 +330,7 @@ static int pkey_nonccatok2pkey(const __u8 *key, __u32 keylen, | |||
1214 | /* | 330 | /* |
1215 | * Transform a CCA internal key token into a protected key | 331 | * Transform a CCA internal key token into a protected key |
1216 | */ | 332 | */ |
1217 | static int pkey_ccainttok2pkey(const __u8 *key, __u32 keylen, | 333 | static int pkey_ccainttok2pkey(const u8 *key, u32 keylen, |
1218 | struct pkey_protkey *protkey) | 334 | struct pkey_protkey *protkey) |
1219 | { | 335 | { |
1220 | struct keytoken_header *hdr = (struct keytoken_header *)key; | 336 | struct keytoken_header *hdr = (struct keytoken_header *)key; |
@@ -1223,44 +339,414 @@ static int pkey_ccainttok2pkey(const __u8 *key, __u32 keylen, | |||
1223 | case TOKVER_CCA_AES: | 339 | case TOKVER_CCA_AES: |
1224 | if (keylen != sizeof(struct secaeskeytoken)) | 340 | if (keylen != sizeof(struct secaeskeytoken)) |
1225 | return -EINVAL; | 341 | return -EINVAL; |
1226 | 342 | break; | |
1227 | return pkey_skey2pkey((struct pkey_seckey *)key, | 343 | case TOKVER_CCA_VLSC: |
1228 | protkey); | 344 | if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) |
345 | return -EINVAL; | ||
346 | break; | ||
1229 | default: | 347 | default: |
1230 | DEBUG_ERR("%s unknown/unsupported CCA internal token version %d\n", | 348 | DEBUG_ERR("%s unknown/unsupported CCA internal token version %d\n", |
1231 | __func__, hdr->version); | 349 | __func__, hdr->version); |
1232 | return -EINVAL; | 350 | return -EINVAL; |
1233 | } | 351 | } |
352 | |||
353 | return pkey_skey2pkey(key, protkey); | ||
1234 | } | 354 | } |
1235 | 355 | ||
1236 | /* | 356 | /* |
1237 | * Transform a key blob (of any type) into a protected key | 357 | * Transform a key blob (of any type) into a protected key |
1238 | */ | 358 | */ |
1239 | int pkey_keyblob2pkey(const __u8 *key, __u32 keylen, | 359 | int pkey_keyblob2pkey(const u8 *key, u32 keylen, |
1240 | struct pkey_protkey *protkey) | 360 | struct pkey_protkey *protkey) |
1241 | { | 361 | { |
362 | int rc; | ||
1242 | struct keytoken_header *hdr = (struct keytoken_header *)key; | 363 | struct keytoken_header *hdr = (struct keytoken_header *)key; |
1243 | 364 | ||
1244 | if (keylen < sizeof(struct keytoken_header)) | 365 | if (keylen < sizeof(struct keytoken_header)) { |
366 | DEBUG_ERR("%s invalid keylen %d\n", __func__, keylen); | ||
1245 | return -EINVAL; | 367 | return -EINVAL; |
368 | } | ||
1246 | 369 | ||
1247 | switch (hdr->type) { | 370 | switch (hdr->type) { |
1248 | case TOKTYPE_NON_CCA: | 371 | case TOKTYPE_NON_CCA: |
1249 | return pkey_nonccatok2pkey(key, keylen, protkey); | 372 | rc = pkey_nonccatok2pkey(key, keylen, protkey); |
373 | break; | ||
1250 | case TOKTYPE_CCA_INTERNAL: | 374 | case TOKTYPE_CCA_INTERNAL: |
1251 | return pkey_ccainttok2pkey(key, keylen, protkey); | 375 | rc = pkey_ccainttok2pkey(key, keylen, protkey); |
376 | break; | ||
1252 | default: | 377 | default: |
1253 | DEBUG_ERR("%s unknown/unsupported blob type %d\n", __func__, | 378 | DEBUG_ERR("%s unknown/unsupported blob type %d\n", |
1254 | hdr->type); | 379 | __func__, hdr->type); |
1255 | return -EINVAL; | 380 | return -EINVAL; |
1256 | } | 381 | } |
382 | |||
383 | DEBUG_DBG("%s rc=%d\n", __func__, rc); | ||
384 | return rc; | ||
385 | |||
1257 | } | 386 | } |
1258 | EXPORT_SYMBOL(pkey_keyblob2pkey); | 387 | EXPORT_SYMBOL(pkey_keyblob2pkey); |
1259 | 388 | ||
389 | static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns, | ||
390 | enum pkey_key_type ktype, enum pkey_key_size ksize, | ||
391 | u32 kflags, u8 *keybuf, size_t *keybufsize) | ||
392 | { | ||
393 | int i, card, dom, rc; | ||
394 | |||
395 | /* check for at least one apqn given */ | ||
396 | if (!apqns || !nr_apqns) | ||
397 | return -EINVAL; | ||
398 | |||
399 | /* check key type and size */ | ||
400 | switch (ktype) { | ||
401 | case PKEY_TYPE_CCA_DATA: | ||
402 | case PKEY_TYPE_CCA_CIPHER: | ||
403 | if (*keybufsize < SECKEYBLOBSIZE) | ||
404 | return -EINVAL; | ||
405 | break; | ||
406 | default: | ||
407 | return -EINVAL; | ||
408 | } | ||
409 | switch (ksize) { | ||
410 | case PKEY_SIZE_AES_128: | ||
411 | case PKEY_SIZE_AES_192: | ||
412 | case PKEY_SIZE_AES_256: | ||
413 | break; | ||
414 | default: | ||
415 | return -EINVAL; | ||
416 | } | ||
417 | |||
418 | /* simple try all apqns from the list */ | ||
419 | for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { | ||
420 | card = apqns[i].card; | ||
421 | dom = apqns[i].domain; | ||
422 | if (ktype == PKEY_TYPE_CCA_DATA) { | ||
423 | rc = cca_genseckey(card, dom, ksize, keybuf); | ||
424 | *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); | ||
425 | } else /* TOKVER_CCA_VLSC */ | ||
426 | rc = cca_gencipherkey(card, dom, ksize, kflags, | ||
427 | keybuf, keybufsize); | ||
428 | if (rc == 0) | ||
429 | break; | ||
430 | } | ||
431 | |||
432 | return rc; | ||
433 | } | ||
434 | |||
435 | static int pkey_clr2seckey2(const struct pkey_apqn *apqns, size_t nr_apqns, | ||
436 | enum pkey_key_type ktype, enum pkey_key_size ksize, | ||
437 | u32 kflags, const u8 *clrkey, | ||
438 | u8 *keybuf, size_t *keybufsize) | ||
439 | { | ||
440 | int i, card, dom, rc; | ||
441 | |||
442 | /* check for at least one apqn given */ | ||
443 | if (!apqns || !nr_apqns) | ||
444 | return -EINVAL; | ||
445 | |||
446 | /* check key type and size */ | ||
447 | switch (ktype) { | ||
448 | case PKEY_TYPE_CCA_DATA: | ||
449 | case PKEY_TYPE_CCA_CIPHER: | ||
450 | if (*keybufsize < SECKEYBLOBSIZE) | ||
451 | return -EINVAL; | ||
452 | break; | ||
453 | default: | ||
454 | return -EINVAL; | ||
455 | } | ||
456 | switch (ksize) { | ||
457 | case PKEY_SIZE_AES_128: | ||
458 | case PKEY_SIZE_AES_192: | ||
459 | case PKEY_SIZE_AES_256: | ||
460 | break; | ||
461 | default: | ||
462 | return -EINVAL; | ||
463 | } | ||
464 | |||
465 | /* simple try all apqns from the list */ | ||
466 | for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { | ||
467 | card = apqns[i].card; | ||
468 | dom = apqns[i].domain; | ||
469 | if (ktype == PKEY_TYPE_CCA_DATA) { | ||
470 | rc = cca_clr2seckey(card, dom, ksize, | ||
471 | clrkey, keybuf); | ||
472 | *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); | ||
473 | } else /* TOKVER_CCA_VLSC */ | ||
474 | rc = cca_clr2cipherkey(card, dom, ksize, kflags, | ||
475 | clrkey, keybuf, keybufsize); | ||
476 | if (rc == 0) | ||
477 | break; | ||
478 | } | ||
479 | |||
480 | return rc; | ||
481 | } | ||
482 | |||
483 | static int pkey_verifykey2(const u8 *key, size_t keylen, | ||
484 | u16 *cardnr, u16 *domain, | ||
485 | enum pkey_key_type *ktype, | ||
486 | enum pkey_key_size *ksize, u32 *flags) | ||
487 | { | ||
488 | int rc; | ||
489 | u32 _nr_apqns, *_apqns = NULL; | ||
490 | struct keytoken_header *hdr = (struct keytoken_header *)key; | ||
491 | |||
492 | if (keylen < sizeof(struct keytoken_header) || | ||
493 | hdr->type != TOKTYPE_CCA_INTERNAL) | ||
494 | return -EINVAL; | ||
495 | |||
496 | if (hdr->version == TOKVER_CCA_AES) { | ||
497 | struct secaeskeytoken *t = (struct secaeskeytoken *)key; | ||
498 | |||
499 | rc = cca_check_secaeskeytoken(debug_info, 3, key, 0); | ||
500 | if (rc) | ||
501 | goto out; | ||
502 | if (ktype) | ||
503 | *ktype = PKEY_TYPE_CCA_DATA; | ||
504 | if (ksize) | ||
505 | *ksize = (enum pkey_key_size) t->bitsize; | ||
506 | |||
507 | rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, | ||
508 | ZCRYPT_CEX3C, t->mkvp, 0, 1); | ||
509 | if (rc == 0 && flags) | ||
510 | *flags = PKEY_FLAGS_MATCH_CUR_MKVP; | ||
511 | if (rc == -ENODEV) { | ||
512 | rc = cca_findcard2(&_apqns, &_nr_apqns, | ||
513 | *cardnr, *domain, | ||
514 | ZCRYPT_CEX3C, 0, t->mkvp, 1); | ||
515 | if (rc == 0 && flags) | ||
516 | *flags = PKEY_FLAGS_MATCH_ALT_MKVP; | ||
517 | } | ||
518 | if (rc) | ||
519 | goto out; | ||
520 | |||
521 | *cardnr = ((struct pkey_apqn *)_apqns)->card; | ||
522 | *domain = ((struct pkey_apqn *)_apqns)->domain; | ||
523 | |||
524 | } else if (hdr->version == TOKVER_CCA_VLSC) { | ||
525 | struct cipherkeytoken *t = (struct cipherkeytoken *)key; | ||
526 | |||
527 | rc = cca_check_secaescipherkey(debug_info, 3, key, 0, 1); | ||
528 | if (rc) | ||
529 | goto out; | ||
530 | if (ktype) | ||
531 | *ktype = PKEY_TYPE_CCA_CIPHER; | ||
532 | if (ksize) { | ||
533 | *ksize = PKEY_SIZE_UNKNOWN; | ||
534 | if (!t->plfver && t->wpllen == 512) | ||
535 | *ksize = PKEY_SIZE_AES_128; | ||
536 | else if (!t->plfver && t->wpllen == 576) | ||
537 | *ksize = PKEY_SIZE_AES_192; | ||
538 | else if (!t->plfver && t->wpllen == 640) | ||
539 | *ksize = PKEY_SIZE_AES_256; | ||
540 | } | ||
541 | |||
542 | rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, | ||
543 | ZCRYPT_CEX6, t->mkvp0, 0, 1); | ||
544 | if (rc == 0 && flags) | ||
545 | *flags = PKEY_FLAGS_MATCH_CUR_MKVP; | ||
546 | if (rc == -ENODEV) { | ||
547 | rc = cca_findcard2(&_apqns, &_nr_apqns, | ||
548 | *cardnr, *domain, | ||
549 | ZCRYPT_CEX6, 0, t->mkvp0, 1); | ||
550 | if (rc == 0 && flags) | ||
551 | *flags = PKEY_FLAGS_MATCH_ALT_MKVP; | ||
552 | } | ||
553 | if (rc) | ||
554 | goto out; | ||
555 | |||
556 | *cardnr = ((struct pkey_apqn *)_apqns)->card; | ||
557 | *domain = ((struct pkey_apqn *)_apqns)->domain; | ||
558 | |||
559 | } else | ||
560 | rc = -EINVAL; | ||
561 | |||
562 | out: | ||
563 | kfree(_apqns); | ||
564 | return rc; | ||
565 | } | ||
566 | |||
567 | static int pkey_keyblob2pkey2(const struct pkey_apqn *apqns, size_t nr_apqns, | ||
568 | const u8 *key, size_t keylen, | ||
569 | struct pkey_protkey *pkey) | ||
570 | { | ||
571 | int i, card, dom, rc; | ||
572 | struct keytoken_header *hdr = (struct keytoken_header *)key; | ||
573 | |||
574 | /* check for at least one apqn given */ | ||
575 | if (!apqns || !nr_apqns) | ||
576 | return -EINVAL; | ||
577 | |||
578 | if (keylen < sizeof(struct keytoken_header)) | ||
579 | return -EINVAL; | ||
580 | |||
581 | switch (hdr->type) { | ||
582 | case TOKTYPE_NON_CCA: | ||
583 | return pkey_nonccatok2pkey(key, keylen, pkey); | ||
584 | case TOKTYPE_CCA_INTERNAL: | ||
585 | switch (hdr->version) { | ||
586 | case TOKVER_CCA_AES: | ||
587 | if (keylen != sizeof(struct secaeskeytoken)) | ||
588 | return -EINVAL; | ||
589 | if (cca_check_secaeskeytoken(debug_info, 3, key, 0)) | ||
590 | return -EINVAL; | ||
591 | break; | ||
592 | case TOKVER_CCA_VLSC: | ||
593 | if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE) | ||
594 | return -EINVAL; | ||
595 | if (cca_check_secaescipherkey(debug_info, 3, key, 0, 1)) | ||
596 | return -EINVAL; | ||
597 | break; | ||
598 | default: | ||
599 | DEBUG_ERR("%s unknown CCA internal token version %d\n", | ||
600 | __func__, hdr->version); | ||
601 | return -EINVAL; | ||
602 | } | ||
603 | break; | ||
604 | default: | ||
605 | DEBUG_ERR("%s unknown/unsupported blob type %d\n", | ||
606 | __func__, hdr->type); | ||
607 | return -EINVAL; | ||
608 | } | ||
609 | |||
610 | /* simple try all apqns from the list */ | ||
611 | for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { | ||
612 | card = apqns[i].card; | ||
613 | dom = apqns[i].domain; | ||
614 | if (hdr->version == TOKVER_CCA_AES) | ||
615 | rc = cca_sec2protkey(card, dom, key, pkey->protkey, | ||
616 | &pkey->len, &pkey->type); | ||
617 | else /* TOKVER_CCA_VLSC */ | ||
618 | rc = cca_cipher2protkey(card, dom, key, pkey->protkey, | ||
619 | &pkey->len, &pkey->type); | ||
620 | if (rc == 0) | ||
621 | break; | ||
622 | } | ||
623 | |||
624 | return rc; | ||
625 | } | ||
626 | |||
627 | static int pkey_apqns4key(const u8 *key, size_t keylen, u32 flags, | ||
628 | struct pkey_apqn *apqns, size_t *nr_apqns) | ||
629 | { | ||
630 | int rc = EINVAL; | ||
631 | u32 _nr_apqns, *_apqns = NULL; | ||
632 | struct keytoken_header *hdr = (struct keytoken_header *)key; | ||
633 | |||
634 | if (keylen < sizeof(struct keytoken_header) || | ||
635 | hdr->type != TOKTYPE_CCA_INTERNAL || | ||
636 | flags == 0) | ||
637 | return -EINVAL; | ||
638 | |||
639 | if (hdr->version == TOKVER_CCA_AES || hdr->version == TOKVER_CCA_VLSC) { | ||
640 | int minhwtype = ZCRYPT_CEX3C; | ||
641 | u64 cur_mkvp = 0, old_mkvp = 0; | ||
642 | |||
643 | if (hdr->version == TOKVER_CCA_AES) { | ||
644 | struct secaeskeytoken *t = (struct secaeskeytoken *)key; | ||
645 | |||
646 | if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) | ||
647 | cur_mkvp = t->mkvp; | ||
648 | if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) | ||
649 | old_mkvp = t->mkvp; | ||
650 | } else { | ||
651 | struct cipherkeytoken *t = (struct cipherkeytoken *)key; | ||
652 | |||
653 | minhwtype = ZCRYPT_CEX6; | ||
654 | if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) | ||
655 | cur_mkvp = t->mkvp0; | ||
656 | if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) | ||
657 | old_mkvp = t->mkvp0; | ||
658 | } | ||
659 | rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, | ||
660 | minhwtype, cur_mkvp, old_mkvp, 1); | ||
661 | if (rc) | ||
662 | goto out; | ||
663 | if (apqns) { | ||
664 | if (*nr_apqns < _nr_apqns) | ||
665 | rc = -ENOSPC; | ||
666 | else | ||
667 | memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); | ||
668 | } | ||
669 | *nr_apqns = _nr_apqns; | ||
670 | } | ||
671 | |||
672 | out: | ||
673 | kfree(_apqns); | ||
674 | return rc; | ||
675 | } | ||
676 | |||
677 | static int pkey_apqns4keytype(enum pkey_key_type ktype, | ||
678 | u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags, | ||
679 | struct pkey_apqn *apqns, size_t *nr_apqns) | ||
680 | { | ||
681 | int rc = -EINVAL; | ||
682 | u32 _nr_apqns, *_apqns = NULL; | ||
683 | |||
684 | if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) { | ||
685 | u64 cur_mkvp = 0, old_mkvp = 0; | ||
686 | int minhwtype = ZCRYPT_CEX3C; | ||
687 | |||
688 | if (flags & PKEY_FLAGS_MATCH_CUR_MKVP) | ||
689 | cur_mkvp = *((u64 *) cur_mkvp); | ||
690 | if (flags & PKEY_FLAGS_MATCH_ALT_MKVP) | ||
691 | old_mkvp = *((u64 *) alt_mkvp); | ||
692 | if (ktype == PKEY_TYPE_CCA_CIPHER) | ||
693 | minhwtype = ZCRYPT_CEX6; | ||
694 | rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF, | ||
695 | minhwtype, cur_mkvp, old_mkvp, 1); | ||
696 | if (rc) | ||
697 | goto out; | ||
698 | if (apqns) { | ||
699 | if (*nr_apqns < _nr_apqns) | ||
700 | rc = -ENOSPC; | ||
701 | else | ||
702 | memcpy(apqns, _apqns, _nr_apqns * sizeof(u32)); | ||
703 | } | ||
704 | *nr_apqns = _nr_apqns; | ||
705 | } | ||
706 | |||
707 | out: | ||
708 | kfree(_apqns); | ||
709 | return rc; | ||
710 | } | ||
711 | |||
1260 | /* | 712 | /* |
1261 | * File io functions | 713 | * File io functions |
1262 | */ | 714 | */ |
1263 | 715 | ||
716 | static void *_copy_key_from_user(void __user *ukey, size_t keylen) | ||
717 | { | ||
718 | void *kkey; | ||
719 | |||
720 | if (!ukey || keylen < MINKEYBLOBSIZE || keylen > KEYBLOBBUFSIZE) | ||
721 | return ERR_PTR(-EINVAL); | ||
722 | kkey = kmalloc(keylen, GFP_KERNEL); | ||
723 | if (!kkey) | ||
724 | return ERR_PTR(-ENOMEM); | ||
725 | if (copy_from_user(kkey, ukey, keylen)) { | ||
726 | kfree(kkey); | ||
727 | return ERR_PTR(-EFAULT); | ||
728 | } | ||
729 | |||
730 | return kkey; | ||
731 | } | ||
732 | |||
733 | static void *_copy_apqns_from_user(void __user *uapqns, size_t nr_apqns) | ||
734 | { | ||
735 | void *kapqns = NULL; | ||
736 | size_t nbytes; | ||
737 | |||
738 | if (uapqns && nr_apqns > 0) { | ||
739 | nbytes = nr_apqns * sizeof(struct pkey_apqn); | ||
740 | kapqns = kmalloc(nbytes, GFP_KERNEL); | ||
741 | if (!kapqns) | ||
742 | return ERR_PTR(-ENOMEM); | ||
743 | if (copy_from_user(kapqns, uapqns, nbytes)) | ||
744 | return ERR_PTR(-EFAULT); | ||
745 | } | ||
746 | |||
747 | return kapqns; | ||
748 | } | ||
749 | |||
1264 | static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, | 750 | static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, |
1265 | unsigned long arg) | 751 | unsigned long arg) |
1266 | { | 752 | { |
@@ -1273,9 +759,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
1273 | 759 | ||
1274 | if (copy_from_user(&kgs, ugs, sizeof(kgs))) | 760 | if (copy_from_user(&kgs, ugs, sizeof(kgs))) |
1275 | return -EFAULT; | 761 | return -EFAULT; |
1276 | rc = pkey_genseckey(kgs.cardnr, kgs.domain, | 762 | rc = cca_genseckey(kgs.cardnr, kgs.domain, |
1277 | kgs.keytype, &kgs.seckey); | 763 | kgs.keytype, kgs.seckey.seckey); |
1278 | DEBUG_DBG("%s pkey_genseckey()=%d\n", __func__, rc); | 764 | DEBUG_DBG("%s cca_genseckey()=%d\n", __func__, rc); |
1279 | if (rc) | 765 | if (rc) |
1280 | break; | 766 | break; |
1281 | if (copy_to_user(ugs, &kgs, sizeof(kgs))) | 767 | if (copy_to_user(ugs, &kgs, sizeof(kgs))) |
@@ -1288,9 +774,9 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
1288 | 774 | ||
1289 | if (copy_from_user(&kcs, ucs, sizeof(kcs))) | 775 | if (copy_from_user(&kcs, ucs, sizeof(kcs))) |
1290 | return -EFAULT; | 776 | return -EFAULT; |
1291 | rc = pkey_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype, | 777 | rc = cca_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype, |
1292 | &kcs.clrkey, &kcs.seckey); | 778 | kcs.clrkey.clrkey, kcs.seckey.seckey); |
1293 | DEBUG_DBG("%s pkey_clr2seckey()=%d\n", __func__, rc); | 779 | DEBUG_DBG("%s cca_clr2seckey()=%d\n", __func__, rc); |
1294 | if (rc) | 780 | if (rc) |
1295 | break; | 781 | break; |
1296 | if (copy_to_user(ucs, &kcs, sizeof(kcs))) | 782 | if (copy_to_user(ucs, &kcs, sizeof(kcs))) |
@@ -1304,9 +790,10 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
1304 | 790 | ||
1305 | if (copy_from_user(&ksp, usp, sizeof(ksp))) | 791 | if (copy_from_user(&ksp, usp, sizeof(ksp))) |
1306 | return -EFAULT; | 792 | return -EFAULT; |
1307 | rc = pkey_sec2protkey(ksp.cardnr, ksp.domain, | 793 | rc = cca_sec2protkey(ksp.cardnr, ksp.domain, |
1308 | &ksp.seckey, &ksp.protkey); | 794 | ksp.seckey.seckey, ksp.protkey.protkey, |
1309 | DEBUG_DBG("%s pkey_sec2protkey()=%d\n", __func__, rc); | 795 | NULL, &ksp.protkey.type); |
796 | DEBUG_DBG("%s cca_sec2protkey()=%d\n", __func__, rc); | ||
1310 | if (rc) | 797 | if (rc) |
1311 | break; | 798 | break; |
1312 | if (copy_to_user(usp, &ksp, sizeof(ksp))) | 799 | if (copy_to_user(usp, &ksp, sizeof(ksp))) |
@@ -1335,10 +822,10 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
1335 | 822 | ||
1336 | if (copy_from_user(&kfc, ufc, sizeof(kfc))) | 823 | if (copy_from_user(&kfc, ufc, sizeof(kfc))) |
1337 | return -EFAULT; | 824 | return -EFAULT; |
1338 | rc = pkey_findcard(&kfc.seckey, | 825 | rc = cca_findcard(kfc.seckey.seckey, |
1339 | &kfc.cardnr, &kfc.domain, 1); | 826 | &kfc.cardnr, &kfc.domain, 1); |
1340 | DEBUG_DBG("%s pkey_findcard()=%d\n", __func__, rc); | 827 | DEBUG_DBG("%s cca_findcard()=%d\n", __func__, rc); |
1341 | if (rc) | 828 | if (rc < 0) |
1342 | break; | 829 | break; |
1343 | if (copy_to_user(ufc, &kfc, sizeof(kfc))) | 830 | if (copy_to_user(ufc, &kfc, sizeof(kfc))) |
1344 | return -EFAULT; | 831 | return -EFAULT; |
@@ -1350,7 +837,7 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
1350 | 837 | ||
1351 | if (copy_from_user(&ksp, usp, sizeof(ksp))) | 838 | if (copy_from_user(&ksp, usp, sizeof(ksp))) |
1352 | return -EFAULT; | 839 | return -EFAULT; |
1353 | rc = pkey_skey2pkey(&ksp.seckey, &ksp.protkey); | 840 | rc = pkey_skey2pkey(ksp.seckey.seckey, &ksp.protkey); |
1354 | DEBUG_DBG("%s pkey_skey2pkey()=%d\n", __func__, rc); | 841 | DEBUG_DBG("%s pkey_skey2pkey()=%d\n", __func__, rc); |
1355 | if (rc) | 842 | if (rc) |
1356 | break; | 843 | break; |
@@ -1400,24 +887,148 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
1400 | case PKEY_KBLOB2PROTK: { | 887 | case PKEY_KBLOB2PROTK: { |
1401 | struct pkey_kblob2pkey __user *utp = (void __user *) arg; | 888 | struct pkey_kblob2pkey __user *utp = (void __user *) arg; |
1402 | struct pkey_kblob2pkey ktp; | 889 | struct pkey_kblob2pkey ktp; |
1403 | __u8 __user *ukey; | 890 | u8 *kkey; |
1404 | __u8 *kkey; | ||
1405 | 891 | ||
1406 | if (copy_from_user(&ktp, utp, sizeof(ktp))) | 892 | if (copy_from_user(&ktp, utp, sizeof(ktp))) |
1407 | return -EFAULT; | 893 | return -EFAULT; |
1408 | if (ktp.keylen < MINKEYBLOBSIZE || | 894 | kkey = _copy_key_from_user(ktp.key, ktp.keylen); |
1409 | ktp.keylen > MAXKEYBLOBSIZE) | 895 | if (IS_ERR(kkey)) |
1410 | return -EINVAL; | 896 | return PTR_ERR(kkey); |
1411 | ukey = ktp.key; | 897 | rc = pkey_keyblob2pkey(kkey, ktp.keylen, &ktp.protkey); |
1412 | kkey = kmalloc(ktp.keylen, GFP_KERNEL); | 898 | DEBUG_DBG("%s pkey_keyblob2pkey()=%d\n", __func__, rc); |
1413 | if (kkey == NULL) | 899 | kfree(kkey); |
900 | if (rc) | ||
901 | break; | ||
902 | if (copy_to_user(utp, &ktp, sizeof(ktp))) | ||
903 | return -EFAULT; | ||
904 | break; | ||
905 | } | ||
906 | case PKEY_GENSECK2: { | ||
907 | struct pkey_genseck2 __user *ugs = (void __user *) arg; | ||
908 | struct pkey_genseck2 kgs; | ||
909 | struct pkey_apqn *apqns; | ||
910 | size_t klen = KEYBLOBBUFSIZE; | ||
911 | u8 *kkey; | ||
912 | |||
913 | if (copy_from_user(&kgs, ugs, sizeof(kgs))) | ||
914 | return -EFAULT; | ||
915 | apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries); | ||
916 | if (IS_ERR(apqns)) | ||
917 | return PTR_ERR(apqns); | ||
918 | kkey = kmalloc(klen, GFP_KERNEL); | ||
919 | if (!kkey) { | ||
920 | kfree(apqns); | ||
1414 | return -ENOMEM; | 921 | return -ENOMEM; |
1415 | if (copy_from_user(kkey, ukey, ktp.keylen)) { | 922 | } |
923 | rc = pkey_genseckey2(apqns, kgs.apqn_entries, | ||
924 | kgs.type, kgs.size, kgs.keygenflags, | ||
925 | kkey, &klen); | ||
926 | DEBUG_DBG("%s pkey_genseckey2()=%d\n", __func__, rc); | ||
927 | kfree(apqns); | ||
928 | if (rc) { | ||
1416 | kfree(kkey); | 929 | kfree(kkey); |
930 | break; | ||
931 | } | ||
932 | if (kgs.key) { | ||
933 | if (kgs.keylen < klen) { | ||
934 | kfree(kkey); | ||
935 | return -EINVAL; | ||
936 | } | ||
937 | if (copy_to_user(kgs.key, kkey, klen)) { | ||
938 | kfree(kkey); | ||
939 | return -EFAULT; | ||
940 | } | ||
941 | } | ||
942 | kgs.keylen = klen; | ||
943 | if (copy_to_user(ugs, &kgs, sizeof(kgs))) | ||
944 | rc = -EFAULT; | ||
945 | kfree(kkey); | ||
946 | break; | ||
947 | } | ||
948 | case PKEY_CLR2SECK2: { | ||
949 | struct pkey_clr2seck2 __user *ucs = (void __user *) arg; | ||
950 | struct pkey_clr2seck2 kcs; | ||
951 | struct pkey_apqn *apqns; | ||
952 | size_t klen = KEYBLOBBUFSIZE; | ||
953 | u8 *kkey; | ||
954 | |||
955 | if (copy_from_user(&kcs, ucs, sizeof(kcs))) | ||
1417 | return -EFAULT; | 956 | return -EFAULT; |
957 | apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries); | ||
958 | if (IS_ERR(apqns)) | ||
959 | return PTR_ERR(apqns); | ||
960 | kkey = kmalloc(klen, GFP_KERNEL); | ||
961 | if (!kkey) { | ||
962 | kfree(apqns); | ||
963 | return -ENOMEM; | ||
1418 | } | 964 | } |
1419 | rc = pkey_keyblob2pkey(kkey, ktp.keylen, &ktp.protkey); | 965 | rc = pkey_clr2seckey2(apqns, kcs.apqn_entries, |
1420 | DEBUG_DBG("%s pkey_keyblob2pkey()=%d\n", __func__, rc); | 966 | kcs.type, kcs.size, kcs.keygenflags, |
967 | kcs.clrkey.clrkey, kkey, &klen); | ||
968 | DEBUG_DBG("%s pkey_clr2seckey2()=%d\n", __func__, rc); | ||
969 | kfree(apqns); | ||
970 | if (rc) { | ||
971 | kfree(kkey); | ||
972 | break; | ||
973 | } | ||
974 | if (kcs.key) { | ||
975 | if (kcs.keylen < klen) { | ||
976 | kfree(kkey); | ||
977 | return -EINVAL; | ||
978 | } | ||
979 | if (copy_to_user(kcs.key, kkey, klen)) { | ||
980 | kfree(kkey); | ||
981 | return -EFAULT; | ||
982 | } | ||
983 | } | ||
984 | kcs.keylen = klen; | ||
985 | if (copy_to_user(ucs, &kcs, sizeof(kcs))) | ||
986 | rc = -EFAULT; | ||
987 | memzero_explicit(&kcs, sizeof(kcs)); | ||
988 | kfree(kkey); | ||
989 | break; | ||
990 | } | ||
991 | case PKEY_VERIFYKEY2: { | ||
992 | struct pkey_verifykey2 __user *uvk = (void __user *) arg; | ||
993 | struct pkey_verifykey2 kvk; | ||
994 | u8 *kkey; | ||
995 | |||
996 | if (copy_from_user(&kvk, uvk, sizeof(kvk))) | ||
997 | return -EFAULT; | ||
998 | kkey = _copy_key_from_user(kvk.key, kvk.keylen); | ||
999 | if (IS_ERR(kkey)) | ||
1000 | return PTR_ERR(kkey); | ||
1001 | rc = pkey_verifykey2(kkey, kvk.keylen, | ||
1002 | &kvk.cardnr, &kvk.domain, | ||
1003 | &kvk.type, &kvk.size, &kvk.flags); | ||
1004 | DEBUG_DBG("%s pkey_verifykey2()=%d\n", __func__, rc); | ||
1005 | kfree(kkey); | ||
1006 | if (rc) | ||
1007 | break; | ||
1008 | if (copy_to_user(uvk, &kvk, sizeof(kvk))) | ||
1009 | return -EFAULT; | ||
1010 | break; | ||
1011 | } | ||
1012 | case PKEY_KBLOB2PROTK2: { | ||
1013 | struct pkey_kblob2pkey2 __user *utp = (void __user *) arg; | ||
1014 | struct pkey_kblob2pkey2 ktp; | ||
1015 | struct pkey_apqn *apqns = NULL; | ||
1016 | u8 *kkey; | ||
1017 | |||
1018 | if (copy_from_user(&ktp, utp, sizeof(ktp))) | ||
1019 | return -EFAULT; | ||
1020 | apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries); | ||
1021 | if (IS_ERR(apqns)) | ||
1022 | return PTR_ERR(apqns); | ||
1023 | kkey = _copy_key_from_user(ktp.key, ktp.keylen); | ||
1024 | if (IS_ERR(kkey)) { | ||
1025 | kfree(apqns); | ||
1026 | return PTR_ERR(kkey); | ||
1027 | } | ||
1028 | rc = pkey_keyblob2pkey2(apqns, ktp.apqn_entries, | ||
1029 | kkey, ktp.keylen, &ktp.protkey); | ||
1030 | DEBUG_DBG("%s pkey_keyblob2pkey2()=%d\n", __func__, rc); | ||
1031 | kfree(apqns); | ||
1421 | kfree(kkey); | 1032 | kfree(kkey); |
1422 | if (rc) | 1033 | if (rc) |
1423 | break; | 1034 | break; |
@@ -1425,6 +1036,97 @@ static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, | |||
1425 | return -EFAULT; | 1036 | return -EFAULT; |
1426 | break; | 1037 | break; |
1427 | } | 1038 | } |
1039 | case PKEY_APQNS4K: { | ||
1040 | struct pkey_apqns4key __user *uak = (void __user *) arg; | ||
1041 | struct pkey_apqns4key kak; | ||
1042 | struct pkey_apqn *apqns = NULL; | ||
1043 | size_t nr_apqns, len; | ||
1044 | u8 *kkey; | ||
1045 | |||
1046 | if (copy_from_user(&kak, uak, sizeof(kak))) | ||
1047 | return -EFAULT; | ||
1048 | nr_apqns = kak.apqn_entries; | ||
1049 | if (nr_apqns) { | ||
1050 | apqns = kmalloc_array(nr_apqns, | ||
1051 | sizeof(struct pkey_apqn), | ||
1052 | GFP_KERNEL); | ||
1053 | if (!apqns) | ||
1054 | return -ENOMEM; | ||
1055 | } | ||
1056 | kkey = _copy_key_from_user(kak.key, kak.keylen); | ||
1057 | if (IS_ERR(kkey)) { | ||
1058 | kfree(apqns); | ||
1059 | return PTR_ERR(kkey); | ||
1060 | } | ||
1061 | rc = pkey_apqns4key(kkey, kak.keylen, kak.flags, | ||
1062 | apqns, &nr_apqns); | ||
1063 | DEBUG_DBG("%s pkey_apqns4key()=%d\n", __func__, rc); | ||
1064 | kfree(kkey); | ||
1065 | if (rc && rc != -ENOSPC) { | ||
1066 | kfree(apqns); | ||
1067 | break; | ||
1068 | } | ||
1069 | if (!rc && kak.apqns) { | ||
1070 | if (nr_apqns > kak.apqn_entries) { | ||
1071 | kfree(apqns); | ||
1072 | return -EINVAL; | ||
1073 | } | ||
1074 | len = nr_apqns * sizeof(struct pkey_apqn); | ||
1075 | if (len) { | ||
1076 | if (copy_to_user(kak.apqns, apqns, len)) { | ||
1077 | kfree(apqns); | ||
1078 | return -EFAULT; | ||
1079 | } | ||
1080 | } | ||
1081 | } | ||
1082 | kak.apqn_entries = nr_apqns; | ||
1083 | if (copy_to_user(uak, &kak, sizeof(kak))) | ||
1084 | rc = -EFAULT; | ||
1085 | kfree(apqns); | ||
1086 | break; | ||
1087 | } | ||
1088 | case PKEY_APQNS4KT: { | ||
1089 | struct pkey_apqns4keytype __user *uat = (void __user *) arg; | ||
1090 | struct pkey_apqns4keytype kat; | ||
1091 | struct pkey_apqn *apqns = NULL; | ||
1092 | size_t nr_apqns, len; | ||
1093 | |||
1094 | if (copy_from_user(&kat, uat, sizeof(kat))) | ||
1095 | return -EFAULT; | ||
1096 | nr_apqns = kat.apqn_entries; | ||
1097 | if (nr_apqns) { | ||
1098 | apqns = kmalloc_array(nr_apqns, | ||
1099 | sizeof(struct pkey_apqn), | ||
1100 | GFP_KERNEL); | ||
1101 | if (!apqns) | ||
1102 | return -ENOMEM; | ||
1103 | } | ||
1104 | rc = pkey_apqns4keytype(kat.type, kat.cur_mkvp, kat.alt_mkvp, | ||
1105 | kat.flags, apqns, &nr_apqns); | ||
1106 | DEBUG_DBG("%s pkey_apqns4keytype()=%d\n", __func__, rc); | ||
1107 | if (rc && rc != -ENOSPC) { | ||
1108 | kfree(apqns); | ||
1109 | break; | ||
1110 | } | ||
1111 | if (!rc && kat.apqns) { | ||
1112 | if (nr_apqns > kat.apqn_entries) { | ||
1113 | kfree(apqns); | ||
1114 | return -EINVAL; | ||
1115 | } | ||
1116 | len = nr_apqns * sizeof(struct pkey_apqn); | ||
1117 | if (len) { | ||
1118 | if (copy_to_user(kat.apqns, apqns, len)) { | ||
1119 | kfree(apqns); | ||
1120 | return -EFAULT; | ||
1121 | } | ||
1122 | } | ||
1123 | } | ||
1124 | kat.apqn_entries = nr_apqns; | ||
1125 | if (copy_to_user(uat, &kat, sizeof(kat))) | ||
1126 | rc = -EFAULT; | ||
1127 | kfree(apqns); | ||
1128 | break; | ||
1129 | } | ||
1428 | default: | 1130 | default: |
1429 | /* unknown/unsupported ioctl cmd */ | 1131 | /* unknown/unsupported ioctl cmd */ |
1430 | return -ENOTTY; | 1132 | return -ENOTTY; |
@@ -1567,6 +1269,7 @@ static ssize_t pkey_ccadata_aes_attr_read(u32 keytype, bool is_xts, char *buf, | |||
1567 | loff_t off, size_t count) | 1269 | loff_t off, size_t count) |
1568 | { | 1270 | { |
1569 | int rc; | 1271 | int rc; |
1272 | struct pkey_seckey *seckey = (struct pkey_seckey *) buf; | ||
1570 | 1273 | ||
1571 | if (off != 0 || count < sizeof(struct secaeskeytoken)) | 1274 | if (off != 0 || count < sizeof(struct secaeskeytoken)) |
1572 | return -EINVAL; | 1275 | return -EINVAL; |
@@ -1574,13 +1277,13 @@ static ssize_t pkey_ccadata_aes_attr_read(u32 keytype, bool is_xts, char *buf, | |||
1574 | if (count < 2 * sizeof(struct secaeskeytoken)) | 1277 | if (count < 2 * sizeof(struct secaeskeytoken)) |
1575 | return -EINVAL; | 1278 | return -EINVAL; |
1576 | 1279 | ||
1577 | rc = pkey_genseckey(-1, -1, keytype, (struct pkey_seckey *)buf); | 1280 | rc = cca_genseckey(-1, -1, keytype, seckey->seckey); |
1578 | if (rc) | 1281 | if (rc) |
1579 | return rc; | 1282 | return rc; |
1580 | 1283 | ||
1581 | if (is_xts) { | 1284 | if (is_xts) { |
1582 | buf += sizeof(struct pkey_seckey); | 1285 | seckey++; |
1583 | rc = pkey_genseckey(-1, -1, keytype, (struct pkey_seckey *)buf); | 1286 | rc = cca_genseckey(-1, -1, keytype, seckey->seckey); |
1584 | if (rc) | 1287 | if (rc) |
1585 | return rc; | 1288 | return rc; |
1586 | 1289 | ||
@@ -1716,7 +1419,6 @@ static int __init pkey_init(void) | |||
1716 | static void __exit pkey_exit(void) | 1419 | static void __exit pkey_exit(void) |
1717 | { | 1420 | { |
1718 | misc_deregister(&pkey_dev); | 1421 | misc_deregister(&pkey_dev); |
1719 | mkvp_cache_free(); | ||
1720 | pkey_debug_exit(); | 1422 | pkey_debug_exit(); |
1721 | } | 1423 | } |
1722 | 1424 | ||
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 0604b49a4d32..5c0f53c6dde7 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c | |||
@@ -1143,7 +1143,7 @@ int vfio_ap_mdev_reset_queue(unsigned int apid, unsigned int apqi, | |||
1143 | msleep(20); | 1143 | msleep(20); |
1144 | status = ap_tapq(apqn, NULL); | 1144 | status = ap_tapq(apqn, NULL); |
1145 | } | 1145 | } |
1146 | WARN_ON_ONCE(retry <= 0); | 1146 | WARN_ON_ONCE(retry2 <= 0); |
1147 | return 0; | 1147 | return 0; |
1148 | case AP_RESPONSE_RESET_IN_PROGRESS: | 1148 | case AP_RESPONSE_RESET_IN_PROGRESS: |
1149 | case AP_RESPONSE_BUSY: | 1149 | case AP_RESPONSE_BUSY: |
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 1058b4b5cc1e..563801427fe4 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include "zcrypt_msgtype6.h" | 36 | #include "zcrypt_msgtype6.h" |
37 | #include "zcrypt_msgtype50.h" | 37 | #include "zcrypt_msgtype50.h" |
38 | #include "zcrypt_ccamisc.h" | ||
38 | 39 | ||
39 | /* | 40 | /* |
40 | * Module description. | 41 | * Module description. |
@@ -1160,6 +1161,34 @@ void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus) | |||
1160 | } | 1161 | } |
1161 | EXPORT_SYMBOL(zcrypt_device_status_mask_ext); | 1162 | EXPORT_SYMBOL(zcrypt_device_status_mask_ext); |
1162 | 1163 | ||
1164 | int zcrypt_device_status_ext(int card, int queue, | ||
1165 | struct zcrypt_device_status_ext *devstat) | ||
1166 | { | ||
1167 | struct zcrypt_card *zc; | ||
1168 | struct zcrypt_queue *zq; | ||
1169 | |||
1170 | memset(devstat, 0, sizeof(*devstat)); | ||
1171 | |||
1172 | spin_lock(&zcrypt_list_lock); | ||
1173 | for_each_zcrypt_card(zc) { | ||
1174 | for_each_zcrypt_queue(zq, zc) { | ||
1175 | if (card == AP_QID_CARD(zq->queue->qid) && | ||
1176 | queue == AP_QID_QUEUE(zq->queue->qid)) { | ||
1177 | devstat->hwtype = zc->card->ap_dev.device_type; | ||
1178 | devstat->functions = zc->card->functions >> 26; | ||
1179 | devstat->qid = zq->queue->qid; | ||
1180 | devstat->online = zq->online ? 0x01 : 0x00; | ||
1181 | spin_unlock(&zcrypt_list_lock); | ||
1182 | return 0; | ||
1183 | } | ||
1184 | } | ||
1185 | } | ||
1186 | spin_unlock(&zcrypt_list_lock); | ||
1187 | |||
1188 | return -ENODEV; | ||
1189 | } | ||
1190 | EXPORT_SYMBOL(zcrypt_device_status_ext); | ||
1191 | |||
1163 | static void zcrypt_status_mask(char status[], size_t max_adapters) | 1192 | static void zcrypt_status_mask(char status[], size_t max_adapters) |
1164 | { | 1193 | { |
1165 | struct zcrypt_card *zc; | 1194 | struct zcrypt_card *zc; |
@@ -1874,6 +1903,7 @@ void __exit zcrypt_api_exit(void) | |||
1874 | misc_deregister(&zcrypt_misc_device); | 1903 | misc_deregister(&zcrypt_misc_device); |
1875 | zcrypt_msgtype6_exit(); | 1904 | zcrypt_msgtype6_exit(); |
1876 | zcrypt_msgtype50_exit(); | 1905 | zcrypt_msgtype50_exit(); |
1906 | zcrypt_ccamisc_exit(); | ||
1877 | zcrypt_debug_exit(); | 1907 | zcrypt_debug_exit(); |
1878 | } | 1908 | } |
1879 | 1909 | ||
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h index af67a768a3fc..2d3f2732344f 100644 --- a/drivers/s390/crypto/zcrypt_api.h +++ b/drivers/s390/crypto/zcrypt_api.h | |||
@@ -121,9 +121,6 @@ void zcrypt_card_get(struct zcrypt_card *); | |||
121 | int zcrypt_card_put(struct zcrypt_card *); | 121 | int zcrypt_card_put(struct zcrypt_card *); |
122 | int zcrypt_card_register(struct zcrypt_card *); | 122 | int zcrypt_card_register(struct zcrypt_card *); |
123 | void zcrypt_card_unregister(struct zcrypt_card *); | 123 | void zcrypt_card_unregister(struct zcrypt_card *); |
124 | struct zcrypt_card *zcrypt_card_get_best(unsigned int *, | ||
125 | unsigned int, unsigned int); | ||
126 | void zcrypt_card_put_best(struct zcrypt_card *, unsigned int); | ||
127 | 124 | ||
128 | struct zcrypt_queue *zcrypt_queue_alloc(size_t); | 125 | struct zcrypt_queue *zcrypt_queue_alloc(size_t); |
129 | void zcrypt_queue_free(struct zcrypt_queue *); | 126 | void zcrypt_queue_free(struct zcrypt_queue *); |
@@ -132,8 +129,6 @@ int zcrypt_queue_put(struct zcrypt_queue *); | |||
132 | int zcrypt_queue_register(struct zcrypt_queue *); | 129 | int zcrypt_queue_register(struct zcrypt_queue *); |
133 | void zcrypt_queue_unregister(struct zcrypt_queue *); | 130 | void zcrypt_queue_unregister(struct zcrypt_queue *); |
134 | void zcrypt_queue_force_online(struct zcrypt_queue *, int); | 131 | void zcrypt_queue_force_online(struct zcrypt_queue *, int); |
135 | struct zcrypt_queue *zcrypt_queue_get_best(unsigned int, unsigned int); | ||
136 | void zcrypt_queue_put_best(struct zcrypt_queue *, unsigned int); | ||
137 | 132 | ||
138 | int zcrypt_rng_device_add(void); | 133 | int zcrypt_rng_device_add(void); |
139 | void zcrypt_rng_device_remove(void); | 134 | void zcrypt_rng_device_remove(void); |
@@ -145,5 +140,7 @@ int zcrypt_api_init(void); | |||
145 | void zcrypt_api_exit(void); | 140 | void zcrypt_api_exit(void); |
146 | long zcrypt_send_cprb(struct ica_xcRB *xcRB); | 141 | long zcrypt_send_cprb(struct ica_xcRB *xcRB); |
147 | void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus); | 142 | void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus); |
143 | int zcrypt_device_status_ext(int card, int queue, | ||
144 | struct zcrypt_device_status_ext *devstatus); | ||
148 | 145 | ||
149 | #endif /* _ZCRYPT_API_H_ */ | 146 | #endif /* _ZCRYPT_API_H_ */ |
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c new file mode 100644 index 000000000000..c1db64a2db21 --- /dev/null +++ b/drivers/s390/crypto/zcrypt_ccamisc.c | |||
@@ -0,0 +1,1765 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | /* | ||
3 | * Copyright IBM Corp. 2019 | ||
4 | * Author(s): Harald Freudenberger <freude@linux.ibm.com> | ||
5 | * Ingo Franzki <ifranzki@linux.ibm.com> | ||
6 | * | ||
7 | * Collection of CCA misc functions used by zcrypt and pkey | ||
8 | */ | ||
9 | |||
10 | #define KMSG_COMPONENT "zcrypt" | ||
11 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
12 | |||
13 | #include <linux/init.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/random.h> | ||
17 | #include <asm/zcrypt.h> | ||
18 | #include <asm/pkey.h> | ||
19 | |||
20 | #include "ap_bus.h" | ||
21 | #include "zcrypt_api.h" | ||
22 | #include "zcrypt_debug.h" | ||
23 | #include "zcrypt_msgtype6.h" | ||
24 | #include "zcrypt_ccamisc.h" | ||
25 | |||
26 | #define DEBUG_DBG(...) ZCRYPT_DBF(DBF_DEBUG, ##__VA_ARGS__) | ||
27 | #define DEBUG_INFO(...) ZCRYPT_DBF(DBF_INFO, ##__VA_ARGS__) | ||
28 | #define DEBUG_WARN(...) ZCRYPT_DBF(DBF_WARN, ##__VA_ARGS__) | ||
29 | #define DEBUG_ERR(...) ZCRYPT_DBF(DBF_ERR, ##__VA_ARGS__) | ||
30 | |||
31 | /* Size of parameter block used for all cca requests/replies */ | ||
32 | #define PARMBSIZE 512 | ||
33 | |||
34 | /* Size of vardata block used for some of the cca requests/replies */ | ||
35 | #define VARDATASIZE 4096 | ||
36 | |||
37 | struct cca_info_list_entry { | ||
38 | struct list_head list; | ||
39 | u16 cardnr; | ||
40 | u16 domain; | ||
41 | struct cca_info info; | ||
42 | }; | ||
43 | |||
44 | /* a list with cca_info_list_entry entries */ | ||
45 | static LIST_HEAD(cca_info_list); | ||
46 | static DEFINE_SPINLOCK(cca_info_list_lock); | ||
47 | |||
48 | /* | ||
49 | * Simple check if the token is a valid CCA secure AES data key | ||
50 | * token. If keybitsize is given, the bitsize of the key is | ||
51 | * also checked. Returns 0 on success or errno value on failure. | ||
52 | */ | ||
53 | int cca_check_secaeskeytoken(debug_info_t *dbg, int dbflvl, | ||
54 | const u8 *token, int keybitsize) | ||
55 | { | ||
56 | struct secaeskeytoken *t = (struct secaeskeytoken *) token; | ||
57 | |||
58 | #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__) | ||
59 | |||
60 | if (t->type != TOKTYPE_CCA_INTERNAL) { | ||
61 | if (dbg) | ||
62 | DBF("%s token check failed, type 0x%02x != 0x%02x\n", | ||
63 | __func__, (int) t->type, TOKTYPE_CCA_INTERNAL); | ||
64 | return -EINVAL; | ||
65 | } | ||
66 | if (t->version != TOKVER_CCA_AES) { | ||
67 | if (dbg) | ||
68 | DBF("%s token check failed, version 0x%02x != 0x%02x\n", | ||
69 | __func__, (int) t->version, TOKVER_CCA_AES); | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | if (keybitsize > 0 && t->bitsize != keybitsize) { | ||
73 | if (dbg) | ||
74 | DBF("%s token check failed, bitsize %d != %d\n", | ||
75 | __func__, (int) t->bitsize, keybitsize); | ||
76 | return -EINVAL; | ||
77 | } | ||
78 | |||
79 | #undef DBF | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | EXPORT_SYMBOL(cca_check_secaeskeytoken); | ||
84 | |||
85 | /* | ||
86 | * Simple check if the token is a valid CCA secure AES cipher key | ||
87 | * token. If keybitsize is given, the bitsize of the key is | ||
88 | * also checked. If checkcpacfexport is enabled, the key is also | ||
89 | * checked for the export flag to allow CPACF export. | ||
90 | * Returns 0 on success or errno value on failure. | ||
91 | */ | ||
92 | int cca_check_secaescipherkey(debug_info_t *dbg, int dbflvl, | ||
93 | const u8 *token, int keybitsize, | ||
94 | int checkcpacfexport) | ||
95 | { | ||
96 | struct cipherkeytoken *t = (struct cipherkeytoken *) token; | ||
97 | bool keybitsizeok = true; | ||
98 | |||
99 | #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__) | ||
100 | |||
101 | if (t->type != TOKTYPE_CCA_INTERNAL) { | ||
102 | if (dbg) | ||
103 | DBF("%s token check failed, type 0x%02x != 0x%02x\n", | ||
104 | __func__, (int) t->type, TOKTYPE_CCA_INTERNAL); | ||
105 | return -EINVAL; | ||
106 | } | ||
107 | if (t->version != TOKVER_CCA_VLSC) { | ||
108 | if (dbg) | ||
109 | DBF("%s token check failed, version 0x%02x != 0x%02x\n", | ||
110 | __func__, (int) t->version, TOKVER_CCA_VLSC); | ||
111 | return -EINVAL; | ||
112 | } | ||
113 | if (t->algtype != 0x02) { | ||
114 | if (dbg) | ||
115 | DBF("%s token check failed, algtype 0x%02x != 0x02\n", | ||
116 | __func__, (int) t->algtype); | ||
117 | return -EINVAL; | ||
118 | } | ||
119 | if (t->keytype != 0x0001) { | ||
120 | if (dbg) | ||
121 | DBF("%s token check failed, keytype 0x%04x != 0x0001\n", | ||
122 | __func__, (int) t->keytype); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | if (t->plfver != 0x00 && t->plfver != 0x01) { | ||
126 | if (dbg) | ||
127 | DBF("%s token check failed, unknown plfver 0x%02x\n", | ||
128 | __func__, (int) t->plfver); | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | if (t->wpllen != 512 && t->wpllen != 576 && t->wpllen != 640) { | ||
132 | if (dbg) | ||
133 | DBF("%s token check failed, unknown wpllen %d\n", | ||
134 | __func__, (int) t->wpllen); | ||
135 | return -EINVAL; | ||
136 | } | ||
137 | if (keybitsize > 0) { | ||
138 | switch (keybitsize) { | ||
139 | case 128: | ||
140 | if (t->wpllen != (t->plfver ? 640 : 512)) | ||
141 | keybitsizeok = false; | ||
142 | break; | ||
143 | case 192: | ||
144 | if (t->wpllen != (t->plfver ? 640 : 576)) | ||
145 | keybitsizeok = false; | ||
146 | break; | ||
147 | case 256: | ||
148 | if (t->wpllen != 640) | ||
149 | keybitsizeok = false; | ||
150 | break; | ||
151 | default: | ||
152 | keybitsizeok = false; | ||
153 | break; | ||
154 | } | ||
155 | if (!keybitsizeok) { | ||
156 | if (dbg) | ||
157 | DBF("%s token check failed, bitsize %d\n", | ||
158 | __func__, keybitsize); | ||
159 | return -EINVAL; | ||
160 | } | ||
161 | } | ||
162 | if (checkcpacfexport && !(t->kmf1 & KMF1_XPRT_CPAC)) { | ||
163 | if (dbg) | ||
164 | DBF("%s token check failed, XPRT_CPAC bit is 0\n", | ||
165 | __func__); | ||
166 | return -EINVAL; | ||
167 | } | ||
168 | |||
169 | #undef DBF | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | EXPORT_SYMBOL(cca_check_secaescipherkey); | ||
174 | |||
175 | /* | ||
176 | * Allocate consecutive memory for request CPRB, request param | ||
177 | * block, reply CPRB and reply param block and fill in values | ||
178 | * for the common fields. Returns 0 on success or errno value | ||
179 | * on failure. | ||
180 | */ | ||
181 | static int alloc_and_prep_cprbmem(size_t paramblen, | ||
182 | u8 **pcprbmem, | ||
183 | struct CPRBX **preqCPRB, | ||
184 | struct CPRBX **prepCPRB) | ||
185 | { | ||
186 | u8 *cprbmem; | ||
187 | size_t cprbplusparamblen = sizeof(struct CPRBX) + paramblen; | ||
188 | struct CPRBX *preqcblk, *prepcblk; | ||
189 | |||
190 | /* | ||
191 | * allocate consecutive memory for request CPRB, request param | ||
192 | * block, reply CPRB and reply param block | ||
193 | */ | ||
194 | cprbmem = kcalloc(2, cprbplusparamblen, GFP_KERNEL); | ||
195 | if (!cprbmem) | ||
196 | return -ENOMEM; | ||
197 | |||
198 | preqcblk = (struct CPRBX *) cprbmem; | ||
199 | prepcblk = (struct CPRBX *) (cprbmem + cprbplusparamblen); | ||
200 | |||
201 | /* fill request cprb struct */ | ||
202 | preqcblk->cprb_len = sizeof(struct CPRBX); | ||
203 | preqcblk->cprb_ver_id = 0x02; | ||
204 | memcpy(preqcblk->func_id, "T2", 2); | ||
205 | preqcblk->rpl_msgbl = cprbplusparamblen; | ||
206 | if (paramblen) { | ||
207 | preqcblk->req_parmb = | ||
208 | ((u8 *) preqcblk) + sizeof(struct CPRBX); | ||
209 | preqcblk->rpl_parmb = | ||
210 | ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
211 | } | ||
212 | |||
213 | *pcprbmem = cprbmem; | ||
214 | *preqCPRB = preqcblk; | ||
215 | *prepCPRB = prepcblk; | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | /* | ||
221 | * Free the cprb memory allocated with the function above. | ||
222 | * If the scrub value is not zero, the memory is filled | ||
223 | * with zeros before freeing (useful if there was some | ||
224 | * clear key material in there). | ||
225 | */ | ||
226 | static void free_cprbmem(void *mem, size_t paramblen, int scrub) | ||
227 | { | ||
228 | if (scrub) | ||
229 | memzero_explicit(mem, 2 * (sizeof(struct CPRBX) + paramblen)); | ||
230 | kfree(mem); | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * Helper function to prepare the xcrb struct | ||
235 | */ | ||
236 | static inline void prep_xcrb(struct ica_xcRB *pxcrb, | ||
237 | u16 cardnr, | ||
238 | struct CPRBX *preqcblk, | ||
239 | struct CPRBX *prepcblk) | ||
240 | { | ||
241 | memset(pxcrb, 0, sizeof(*pxcrb)); | ||
242 | pxcrb->agent_ID = 0x4341; /* 'CA' */ | ||
243 | pxcrb->user_defined = (cardnr == 0xFFFF ? AUTOSELECT : cardnr); | ||
244 | pxcrb->request_control_blk_length = | ||
245 | preqcblk->cprb_len + preqcblk->req_parml; | ||
246 | pxcrb->request_control_blk_addr = (void __user *) preqcblk; | ||
247 | pxcrb->reply_control_blk_length = preqcblk->rpl_msgbl; | ||
248 | pxcrb->reply_control_blk_addr = (void __user *) prepcblk; | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * Helper function which calls zcrypt_send_cprb with | ||
253 | * memory management segment adjusted to kernel space | ||
254 | * so that the copy_from_user called within this | ||
255 | * function do in fact copy from kernel space. | ||
256 | */ | ||
257 | static inline int _zcrypt_send_cprb(struct ica_xcRB *xcrb) | ||
258 | { | ||
259 | int rc; | ||
260 | mm_segment_t old_fs = get_fs(); | ||
261 | |||
262 | set_fs(KERNEL_DS); | ||
263 | rc = zcrypt_send_cprb(xcrb); | ||
264 | set_fs(old_fs); | ||
265 | |||
266 | return rc; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * Generate (random) CCA AES DATA secure key. | ||
271 | */ | ||
272 | int cca_genseckey(u16 cardnr, u16 domain, | ||
273 | u32 keybitsize, u8 seckey[SECKEYBLOBSIZE]) | ||
274 | { | ||
275 | int i, rc, keysize; | ||
276 | int seckeysize; | ||
277 | u8 *mem; | ||
278 | struct CPRBX *preqcblk, *prepcblk; | ||
279 | struct ica_xcRB xcrb; | ||
280 | struct kgreqparm { | ||
281 | u8 subfunc_code[2]; | ||
282 | u16 rule_array_len; | ||
283 | struct lv1 { | ||
284 | u16 len; | ||
285 | char key_form[8]; | ||
286 | char key_length[8]; | ||
287 | char key_type1[8]; | ||
288 | char key_type2[8]; | ||
289 | } lv1; | ||
290 | struct lv2 { | ||
291 | u16 len; | ||
292 | struct keyid { | ||
293 | u16 len; | ||
294 | u16 attr; | ||
295 | u8 data[SECKEYBLOBSIZE]; | ||
296 | } keyid[6]; | ||
297 | } lv2; | ||
298 | } __packed * preqparm; | ||
299 | struct kgrepparm { | ||
300 | u8 subfunc_code[2]; | ||
301 | u16 rule_array_len; | ||
302 | struct lv3 { | ||
303 | u16 len; | ||
304 | u16 keyblocklen; | ||
305 | struct { | ||
306 | u16 toklen; | ||
307 | u16 tokattr; | ||
308 | u8 tok[0]; | ||
309 | /* ... some more data ... */ | ||
310 | } keyblock; | ||
311 | } lv3; | ||
312 | } __packed * prepparm; | ||
313 | |||
314 | /* get already prepared memory for 2 cprbs with param block each */ | ||
315 | rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); | ||
316 | if (rc) | ||
317 | return rc; | ||
318 | |||
319 | /* fill request cprb struct */ | ||
320 | preqcblk->domain = domain; | ||
321 | |||
322 | /* fill request cprb param block with KG request */ | ||
323 | preqparm = (struct kgreqparm *) preqcblk->req_parmb; | ||
324 | memcpy(preqparm->subfunc_code, "KG", 2); | ||
325 | preqparm->rule_array_len = sizeof(preqparm->rule_array_len); | ||
326 | preqparm->lv1.len = sizeof(struct lv1); | ||
327 | memcpy(preqparm->lv1.key_form, "OP ", 8); | ||
328 | switch (keybitsize) { | ||
329 | case PKEY_SIZE_AES_128: | ||
330 | case PKEY_KEYTYPE_AES_128: /* older ioctls used this */ | ||
331 | keysize = 16; | ||
332 | memcpy(preqparm->lv1.key_length, "KEYLN16 ", 8); | ||
333 | break; | ||
334 | case PKEY_SIZE_AES_192: | ||
335 | case PKEY_KEYTYPE_AES_192: /* older ioctls used this */ | ||
336 | keysize = 24; | ||
337 | memcpy(preqparm->lv1.key_length, "KEYLN24 ", 8); | ||
338 | break; | ||
339 | case PKEY_SIZE_AES_256: | ||
340 | case PKEY_KEYTYPE_AES_256: /* older ioctls used this */ | ||
341 | keysize = 32; | ||
342 | memcpy(preqparm->lv1.key_length, "KEYLN32 ", 8); | ||
343 | break; | ||
344 | default: | ||
345 | DEBUG_ERR("%s unknown/unsupported keybitsize %d\n", | ||
346 | __func__, keybitsize); | ||
347 | rc = -EINVAL; | ||
348 | goto out; | ||
349 | } | ||
350 | memcpy(preqparm->lv1.key_type1, "AESDATA ", 8); | ||
351 | preqparm->lv2.len = sizeof(struct lv2); | ||
352 | for (i = 0; i < 6; i++) { | ||
353 | preqparm->lv2.keyid[i].len = sizeof(struct keyid); | ||
354 | preqparm->lv2.keyid[i].attr = (i == 2 ? 0x30 : 0x10); | ||
355 | } | ||
356 | preqcblk->req_parml = sizeof(struct kgreqparm); | ||
357 | |||
358 | /* fill xcrb struct */ | ||
359 | prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); | ||
360 | |||
361 | /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ | ||
362 | rc = _zcrypt_send_cprb(&xcrb); | ||
363 | if (rc) { | ||
364 | DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, errno %d\n", | ||
365 | __func__, (int) cardnr, (int) domain, rc); | ||
366 | goto out; | ||
367 | } | ||
368 | |||
369 | /* check response returncode and reasoncode */ | ||
370 | if (prepcblk->ccp_rtcode != 0) { | ||
371 | DEBUG_ERR("%s secure key generate failure, card response %d/%d\n", | ||
372 | __func__, | ||
373 | (int) prepcblk->ccp_rtcode, | ||
374 | (int) prepcblk->ccp_rscode); | ||
375 | rc = -EIO; | ||
376 | goto out; | ||
377 | } | ||
378 | |||
379 | /* process response cprb param block */ | ||
380 | prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
381 | prepparm = (struct kgrepparm *) prepcblk->rpl_parmb; | ||
382 | |||
383 | /* check length of the returned secure key token */ | ||
384 | seckeysize = prepparm->lv3.keyblock.toklen | ||
385 | - sizeof(prepparm->lv3.keyblock.toklen) | ||
386 | - sizeof(prepparm->lv3.keyblock.tokattr); | ||
387 | if (seckeysize != SECKEYBLOBSIZE) { | ||
388 | DEBUG_ERR("%s secure token size mismatch %d != %d bytes\n", | ||
389 | __func__, seckeysize, SECKEYBLOBSIZE); | ||
390 | rc = -EIO; | ||
391 | goto out; | ||
392 | } | ||
393 | |||
394 | /* check secure key token */ | ||
395 | rc = cca_check_secaeskeytoken(zcrypt_dbf_info, DBF_ERR, | ||
396 | prepparm->lv3.keyblock.tok, 8*keysize); | ||
397 | if (rc) { | ||
398 | rc = -EIO; | ||
399 | goto out; | ||
400 | } | ||
401 | |||
402 | /* copy the generated secure key token */ | ||
403 | memcpy(seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE); | ||
404 | |||
405 | out: | ||
406 | free_cprbmem(mem, PARMBSIZE, 0); | ||
407 | return rc; | ||
408 | } | ||
409 | EXPORT_SYMBOL(cca_genseckey); | ||
410 | |||
411 | /* | ||
412 | * Generate an CCA AES DATA secure key with given key value. | ||
413 | */ | ||
414 | int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize, | ||
415 | const u8 *clrkey, u8 seckey[SECKEYBLOBSIZE]) | ||
416 | { | ||
417 | int rc, keysize, seckeysize; | ||
418 | u8 *mem; | ||
419 | struct CPRBX *preqcblk, *prepcblk; | ||
420 | struct ica_xcRB xcrb; | ||
421 | struct cmreqparm { | ||
422 | u8 subfunc_code[2]; | ||
423 | u16 rule_array_len; | ||
424 | char rule_array[8]; | ||
425 | struct lv1 { | ||
426 | u16 len; | ||
427 | u8 clrkey[0]; | ||
428 | } lv1; | ||
429 | struct lv2 { | ||
430 | u16 len; | ||
431 | struct keyid { | ||
432 | u16 len; | ||
433 | u16 attr; | ||
434 | u8 data[SECKEYBLOBSIZE]; | ||
435 | } keyid; | ||
436 | } lv2; | ||
437 | } __packed * preqparm; | ||
438 | struct lv2 *plv2; | ||
439 | struct cmrepparm { | ||
440 | u8 subfunc_code[2]; | ||
441 | u16 rule_array_len; | ||
442 | struct lv3 { | ||
443 | u16 len; | ||
444 | u16 keyblocklen; | ||
445 | struct { | ||
446 | u16 toklen; | ||
447 | u16 tokattr; | ||
448 | u8 tok[0]; | ||
449 | /* ... some more data ... */ | ||
450 | } keyblock; | ||
451 | } lv3; | ||
452 | } __packed * prepparm; | ||
453 | |||
454 | /* get already prepared memory for 2 cprbs with param block each */ | ||
455 | rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); | ||
456 | if (rc) | ||
457 | return rc; | ||
458 | |||
459 | /* fill request cprb struct */ | ||
460 | preqcblk->domain = domain; | ||
461 | |||
462 | /* fill request cprb param block with CM request */ | ||
463 | preqparm = (struct cmreqparm *) preqcblk->req_parmb; | ||
464 | memcpy(preqparm->subfunc_code, "CM", 2); | ||
465 | memcpy(preqparm->rule_array, "AES ", 8); | ||
466 | preqparm->rule_array_len = | ||
467 | sizeof(preqparm->rule_array_len) + sizeof(preqparm->rule_array); | ||
468 | switch (keybitsize) { | ||
469 | case PKEY_SIZE_AES_128: | ||
470 | case PKEY_KEYTYPE_AES_128: /* older ioctls used this */ | ||
471 | keysize = 16; | ||
472 | break; | ||
473 | case PKEY_SIZE_AES_192: | ||
474 | case PKEY_KEYTYPE_AES_192: /* older ioctls used this */ | ||
475 | keysize = 24; | ||
476 | break; | ||
477 | case PKEY_SIZE_AES_256: | ||
478 | case PKEY_KEYTYPE_AES_256: /* older ioctls used this */ | ||
479 | keysize = 32; | ||
480 | break; | ||
481 | default: | ||
482 | DEBUG_ERR("%s unknown/unsupported keybitsize %d\n", | ||
483 | __func__, keybitsize); | ||
484 | rc = -EINVAL; | ||
485 | goto out; | ||
486 | } | ||
487 | preqparm->lv1.len = sizeof(struct lv1) + keysize; | ||
488 | memcpy(preqparm->lv1.clrkey, clrkey, keysize); | ||
489 | plv2 = (struct lv2 *) (((u8 *) &preqparm->lv2) + keysize); | ||
490 | plv2->len = sizeof(struct lv2); | ||
491 | plv2->keyid.len = sizeof(struct keyid); | ||
492 | plv2->keyid.attr = 0x30; | ||
493 | preqcblk->req_parml = sizeof(struct cmreqparm) + keysize; | ||
494 | |||
495 | /* fill xcrb struct */ | ||
496 | prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); | ||
497 | |||
498 | /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ | ||
499 | rc = _zcrypt_send_cprb(&xcrb); | ||
500 | if (rc) { | ||
501 | DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", | ||
502 | __func__, (int) cardnr, (int) domain, rc); | ||
503 | goto out; | ||
504 | } | ||
505 | |||
506 | /* check response returncode and reasoncode */ | ||
507 | if (prepcblk->ccp_rtcode != 0) { | ||
508 | DEBUG_ERR("%s clear key import failure, card response %d/%d\n", | ||
509 | __func__, | ||
510 | (int) prepcblk->ccp_rtcode, | ||
511 | (int) prepcblk->ccp_rscode); | ||
512 | rc = -EIO; | ||
513 | goto out; | ||
514 | } | ||
515 | |||
516 | /* process response cprb param block */ | ||
517 | prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
518 | prepparm = (struct cmrepparm *) prepcblk->rpl_parmb; | ||
519 | |||
520 | /* check length of the returned secure key token */ | ||
521 | seckeysize = prepparm->lv3.keyblock.toklen | ||
522 | - sizeof(prepparm->lv3.keyblock.toklen) | ||
523 | - sizeof(prepparm->lv3.keyblock.tokattr); | ||
524 | if (seckeysize != SECKEYBLOBSIZE) { | ||
525 | DEBUG_ERR("%s secure token size mismatch %d != %d bytes\n", | ||
526 | __func__, seckeysize, SECKEYBLOBSIZE); | ||
527 | rc = -EIO; | ||
528 | goto out; | ||
529 | } | ||
530 | |||
531 | /* check secure key token */ | ||
532 | rc = cca_check_secaeskeytoken(zcrypt_dbf_info, DBF_ERR, | ||
533 | prepparm->lv3.keyblock.tok, 8*keysize); | ||
534 | if (rc) { | ||
535 | rc = -EIO; | ||
536 | goto out; | ||
537 | } | ||
538 | |||
539 | /* copy the generated secure key token */ | ||
540 | if (seckey) | ||
541 | memcpy(seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE); | ||
542 | |||
543 | out: | ||
544 | free_cprbmem(mem, PARMBSIZE, 1); | ||
545 | return rc; | ||
546 | } | ||
547 | EXPORT_SYMBOL(cca_clr2seckey); | ||
548 | |||
549 | /* | ||
550 | * Derive proteced key from an CCA AES DATA secure key. | ||
551 | */ | ||
552 | int cca_sec2protkey(u16 cardnr, u16 domain, | ||
553 | const u8 seckey[SECKEYBLOBSIZE], | ||
554 | u8 *protkey, u32 *protkeylen, u32 *protkeytype) | ||
555 | { | ||
556 | int rc; | ||
557 | u8 *mem; | ||
558 | struct CPRBX *preqcblk, *prepcblk; | ||
559 | struct ica_xcRB xcrb; | ||
560 | struct uskreqparm { | ||
561 | u8 subfunc_code[2]; | ||
562 | u16 rule_array_len; | ||
563 | struct lv1 { | ||
564 | u16 len; | ||
565 | u16 attr_len; | ||
566 | u16 attr_flags; | ||
567 | } lv1; | ||
568 | struct lv2 { | ||
569 | u16 len; | ||
570 | u16 attr_len; | ||
571 | u16 attr_flags; | ||
572 | u8 token[0]; /* cca secure key token */ | ||
573 | } lv2; | ||
574 | } __packed * preqparm; | ||
575 | struct uskrepparm { | ||
576 | u8 subfunc_code[2]; | ||
577 | u16 rule_array_len; | ||
578 | struct lv3 { | ||
579 | u16 len; | ||
580 | u16 attr_len; | ||
581 | u16 attr_flags; | ||
582 | struct cpacfkeyblock { | ||
583 | u8 version; /* version of this struct */ | ||
584 | u8 flags[2]; | ||
585 | u8 algo; | ||
586 | u8 form; | ||
587 | u8 pad1[3]; | ||
588 | u16 len; | ||
589 | u8 key[64]; /* the key (len bytes) */ | ||
590 | u16 keyattrlen; | ||
591 | u8 keyattr[32]; | ||
592 | u8 pad2[1]; | ||
593 | u8 vptype; | ||
594 | u8 vp[32]; /* verification pattern */ | ||
595 | } keyblock; | ||
596 | } lv3; | ||
597 | } __packed * prepparm; | ||
598 | |||
599 | /* get already prepared memory for 2 cprbs with param block each */ | ||
600 | rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); | ||
601 | if (rc) | ||
602 | return rc; | ||
603 | |||
604 | /* fill request cprb struct */ | ||
605 | preqcblk->domain = domain; | ||
606 | |||
607 | /* fill request cprb param block with USK request */ | ||
608 | preqparm = (struct uskreqparm *) preqcblk->req_parmb; | ||
609 | memcpy(preqparm->subfunc_code, "US", 2); | ||
610 | preqparm->rule_array_len = sizeof(preqparm->rule_array_len); | ||
611 | preqparm->lv1.len = sizeof(struct lv1); | ||
612 | preqparm->lv1.attr_len = sizeof(struct lv1) - sizeof(preqparm->lv1.len); | ||
613 | preqparm->lv1.attr_flags = 0x0001; | ||
614 | preqparm->lv2.len = sizeof(struct lv2) + SECKEYBLOBSIZE; | ||
615 | preqparm->lv2.attr_len = sizeof(struct lv2) | ||
616 | - sizeof(preqparm->lv2.len) + SECKEYBLOBSIZE; | ||
617 | preqparm->lv2.attr_flags = 0x0000; | ||
618 | memcpy(preqparm->lv2.token, seckey, SECKEYBLOBSIZE); | ||
619 | preqcblk->req_parml = sizeof(struct uskreqparm) + SECKEYBLOBSIZE; | ||
620 | |||
621 | /* fill xcrb struct */ | ||
622 | prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); | ||
623 | |||
624 | /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ | ||
625 | rc = _zcrypt_send_cprb(&xcrb); | ||
626 | if (rc) { | ||
627 | DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", | ||
628 | __func__, (int) cardnr, (int) domain, rc); | ||
629 | goto out; | ||
630 | } | ||
631 | |||
632 | /* check response returncode and reasoncode */ | ||
633 | if (prepcblk->ccp_rtcode != 0) { | ||
634 | DEBUG_ERR("%s unwrap secure key failure, card response %d/%d\n", | ||
635 | __func__, | ||
636 | (int) prepcblk->ccp_rtcode, | ||
637 | (int) prepcblk->ccp_rscode); | ||
638 | rc = -EIO; | ||
639 | goto out; | ||
640 | } | ||
641 | if (prepcblk->ccp_rscode != 0) { | ||
642 | DEBUG_WARN("%s unwrap secure key warning, card response %d/%d\n", | ||
643 | __func__, | ||
644 | (int) prepcblk->ccp_rtcode, | ||
645 | (int) prepcblk->ccp_rscode); | ||
646 | } | ||
647 | |||
648 | /* process response cprb param block */ | ||
649 | prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
650 | prepparm = (struct uskrepparm *) prepcblk->rpl_parmb; | ||
651 | |||
652 | /* check the returned keyblock */ | ||
653 | if (prepparm->lv3.keyblock.version != 0x01) { | ||
654 | DEBUG_ERR("%s reply param keyblock version mismatch 0x%02x != 0x01\n", | ||
655 | __func__, (int) prepparm->lv3.keyblock.version); | ||
656 | rc = -EIO; | ||
657 | goto out; | ||
658 | } | ||
659 | |||
660 | /* copy the tanslated protected key */ | ||
661 | switch (prepparm->lv3.keyblock.len) { | ||
662 | case 16+32: | ||
663 | /* AES 128 protected key */ | ||
664 | if (protkeytype) | ||
665 | *protkeytype = PKEY_KEYTYPE_AES_128; | ||
666 | break; | ||
667 | case 24+32: | ||
668 | /* AES 192 protected key */ | ||
669 | if (protkeytype) | ||
670 | *protkeytype = PKEY_KEYTYPE_AES_192; | ||
671 | break; | ||
672 | case 32+32: | ||
673 | /* AES 256 protected key */ | ||
674 | if (protkeytype) | ||
675 | *protkeytype = PKEY_KEYTYPE_AES_256; | ||
676 | break; | ||
677 | default: | ||
678 | DEBUG_ERR("%s unknown/unsupported keylen %d\n", | ||
679 | __func__, prepparm->lv3.keyblock.len); | ||
680 | rc = -EIO; | ||
681 | goto out; | ||
682 | } | ||
683 | memcpy(protkey, prepparm->lv3.keyblock.key, prepparm->lv3.keyblock.len); | ||
684 | if (protkeylen) | ||
685 | *protkeylen = prepparm->lv3.keyblock.len; | ||
686 | |||
687 | out: | ||
688 | free_cprbmem(mem, PARMBSIZE, 0); | ||
689 | return rc; | ||
690 | } | ||
691 | EXPORT_SYMBOL(cca_sec2protkey); | ||
692 | |||
693 | /* | ||
694 | * AES cipher key skeleton created with CSNBKTB2 with these flags: | ||
695 | * INTERNAL, NO-KEY, AES, CIPHER, ANY-MODE, NOEX-SYM, NOEXAASY, | ||
696 | * NOEXUASY, XPRTCPAC, NOEX-RAW, NOEX-DES, NOEX-AES, NOEX-RSA | ||
697 | * used by cca_gencipherkey() and cca_clr2cipherkey(). | ||
698 | */ | ||
699 | static const u8 aes_cipher_key_skeleton[] = { | ||
700 | 0x01, 0x00, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00, | ||
701 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
702 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
703 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, | ||
704 | 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
705 | 0x00, 0x02, 0x00, 0x01, 0x02, 0xc0, 0x00, 0xff, | ||
706 | 0x00, 0x03, 0x08, 0xc8, 0x00, 0x00, 0x00, 0x00 }; | ||
707 | #define SIZEOF_SKELETON (sizeof(aes_cipher_key_skeleton)) | ||
708 | |||
709 | /* | ||
710 | * Generate (random) CCA AES CIPHER secure key. | ||
711 | */ | ||
712 | int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags, | ||
713 | u8 *keybuf, size_t *keybufsize) | ||
714 | { | ||
715 | int rc; | ||
716 | u8 *mem; | ||
717 | struct CPRBX *preqcblk, *prepcblk; | ||
718 | struct ica_xcRB xcrb; | ||
719 | struct gkreqparm { | ||
720 | u8 subfunc_code[2]; | ||
721 | u16 rule_array_len; | ||
722 | char rule_array[2*8]; | ||
723 | struct { | ||
724 | u16 len; | ||
725 | u8 key_type_1[8]; | ||
726 | u8 key_type_2[8]; | ||
727 | u16 clear_key_bit_len; | ||
728 | u16 key_name_1_len; | ||
729 | u16 key_name_2_len; | ||
730 | u16 user_data_1_len; | ||
731 | u16 user_data_2_len; | ||
732 | u8 key_name_1[0]; | ||
733 | u8 key_name_2[0]; | ||
734 | u8 user_data_1[0]; | ||
735 | u8 user_data_2[0]; | ||
736 | } vud; | ||
737 | struct { | ||
738 | u16 len; | ||
739 | struct { | ||
740 | u16 len; | ||
741 | u16 flag; | ||
742 | u8 kek_id_1[0]; | ||
743 | } tlv1; | ||
744 | struct { | ||
745 | u16 len; | ||
746 | u16 flag; | ||
747 | u8 kek_id_2[0]; | ||
748 | } tlv2; | ||
749 | struct { | ||
750 | u16 len; | ||
751 | u16 flag; | ||
752 | u8 gen_key_id_1[SIZEOF_SKELETON]; | ||
753 | } tlv3; | ||
754 | struct { | ||
755 | u16 len; | ||
756 | u16 flag; | ||
757 | u8 gen_key_id_1_label[0]; | ||
758 | } tlv4; | ||
759 | struct { | ||
760 | u16 len; | ||
761 | u16 flag; | ||
762 | u8 gen_key_id_2[0]; | ||
763 | } tlv5; | ||
764 | struct { | ||
765 | u16 len; | ||
766 | u16 flag; | ||
767 | u8 gen_key_id_2_label[0]; | ||
768 | } tlv6; | ||
769 | } kb; | ||
770 | } __packed * preqparm; | ||
771 | struct gkrepparm { | ||
772 | u8 subfunc_code[2]; | ||
773 | u16 rule_array_len; | ||
774 | struct { | ||
775 | u16 len; | ||
776 | } vud; | ||
777 | struct { | ||
778 | u16 len; | ||
779 | struct { | ||
780 | u16 len; | ||
781 | u16 flag; | ||
782 | u8 gen_key[0]; /* 120-136 bytes */ | ||
783 | } tlv1; | ||
784 | } kb; | ||
785 | } __packed * prepparm; | ||
786 | struct cipherkeytoken *t; | ||
787 | |||
788 | /* get already prepared memory for 2 cprbs with param block each */ | ||
789 | rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); | ||
790 | if (rc) | ||
791 | return rc; | ||
792 | |||
793 | /* fill request cprb struct */ | ||
794 | preqcblk->domain = domain; | ||
795 | preqcblk->req_parml = sizeof(struct gkreqparm); | ||
796 | |||
797 | /* prepare request param block with GK request */ | ||
798 | preqparm = (struct gkreqparm *) preqcblk->req_parmb; | ||
799 | memcpy(preqparm->subfunc_code, "GK", 2); | ||
800 | preqparm->rule_array_len = sizeof(uint16_t) + 2 * 8; | ||
801 | memcpy(preqparm->rule_array, "AES OP ", 2*8); | ||
802 | |||
803 | /* prepare vud block */ | ||
804 | preqparm->vud.len = sizeof(preqparm->vud); | ||
805 | switch (keybitsize) { | ||
806 | case 128: | ||
807 | case 192: | ||
808 | case 256: | ||
809 | break; | ||
810 | default: | ||
811 | DEBUG_ERR( | ||
812 | "%s unknown/unsupported keybitsize %d\n", | ||
813 | __func__, keybitsize); | ||
814 | rc = -EINVAL; | ||
815 | goto out; | ||
816 | } | ||
817 | preqparm->vud.clear_key_bit_len = keybitsize; | ||
818 | memcpy(preqparm->vud.key_type_1, "TOKEN ", 8); | ||
819 | memset(preqparm->vud.key_type_2, ' ', sizeof(preqparm->vud.key_type_2)); | ||
820 | |||
821 | /* prepare kb block */ | ||
822 | preqparm->kb.len = sizeof(preqparm->kb); | ||
823 | preqparm->kb.tlv1.len = sizeof(preqparm->kb.tlv1); | ||
824 | preqparm->kb.tlv1.flag = 0x0030; | ||
825 | preqparm->kb.tlv2.len = sizeof(preqparm->kb.tlv2); | ||
826 | preqparm->kb.tlv2.flag = 0x0030; | ||
827 | preqparm->kb.tlv3.len = sizeof(preqparm->kb.tlv3); | ||
828 | preqparm->kb.tlv3.flag = 0x0030; | ||
829 | memcpy(preqparm->kb.tlv3.gen_key_id_1, | ||
830 | aes_cipher_key_skeleton, SIZEOF_SKELETON); | ||
831 | preqparm->kb.tlv4.len = sizeof(preqparm->kb.tlv4); | ||
832 | preqparm->kb.tlv4.flag = 0x0030; | ||
833 | preqparm->kb.tlv5.len = sizeof(preqparm->kb.tlv5); | ||
834 | preqparm->kb.tlv5.flag = 0x0030; | ||
835 | preqparm->kb.tlv6.len = sizeof(preqparm->kb.tlv6); | ||
836 | preqparm->kb.tlv6.flag = 0x0030; | ||
837 | |||
838 | /* patch the skeleton key token export flags inside the kb block */ | ||
839 | if (keygenflags) { | ||
840 | t = (struct cipherkeytoken *) preqparm->kb.tlv3.gen_key_id_1; | ||
841 | t->kmf1 |= (u16) (keygenflags & 0x0000FF00); | ||
842 | t->kmf1 &= (u16) ~(keygenflags & 0x000000FF); | ||
843 | } | ||
844 | |||
845 | /* prepare xcrb struct */ | ||
846 | prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); | ||
847 | |||
848 | /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ | ||
849 | rc = _zcrypt_send_cprb(&xcrb); | ||
850 | if (rc) { | ||
851 | DEBUG_ERR( | ||
852 | "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", | ||
853 | __func__, (int) cardnr, (int) domain, rc); | ||
854 | goto out; | ||
855 | } | ||
856 | |||
857 | /* check response returncode and reasoncode */ | ||
858 | if (prepcblk->ccp_rtcode != 0) { | ||
859 | DEBUG_ERR( | ||
860 | "%s cipher key generate failure, card response %d/%d\n", | ||
861 | __func__, | ||
862 | (int) prepcblk->ccp_rtcode, | ||
863 | (int) prepcblk->ccp_rscode); | ||
864 | rc = -EIO; | ||
865 | goto out; | ||
866 | } | ||
867 | |||
868 | /* process response cprb param block */ | ||
869 | prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
870 | prepparm = (struct gkrepparm *) prepcblk->rpl_parmb; | ||
871 | |||
872 | /* do some plausibility checks on the key block */ | ||
873 | if (prepparm->kb.len < 120 + 5 * sizeof(uint16_t) || | ||
874 | prepparm->kb.len > 136 + 5 * sizeof(uint16_t)) { | ||
875 | DEBUG_ERR("%s reply with invalid or unknown key block\n", | ||
876 | __func__); | ||
877 | rc = -EIO; | ||
878 | goto out; | ||
879 | } | ||
880 | |||
881 | /* and some checks on the generated key */ | ||
882 | rc = cca_check_secaescipherkey(zcrypt_dbf_info, DBF_ERR, | ||
883 | prepparm->kb.tlv1.gen_key, | ||
884 | keybitsize, 1); | ||
885 | if (rc) { | ||
886 | rc = -EIO; | ||
887 | goto out; | ||
888 | } | ||
889 | |||
890 | /* copy the generated vlsc key token */ | ||
891 | t = (struct cipherkeytoken *) prepparm->kb.tlv1.gen_key; | ||
892 | if (keybuf) { | ||
893 | if (*keybufsize >= t->len) | ||
894 | memcpy(keybuf, t, t->len); | ||
895 | else | ||
896 | rc = -EINVAL; | ||
897 | } | ||
898 | *keybufsize = t->len; | ||
899 | |||
900 | out: | ||
901 | free_cprbmem(mem, PARMBSIZE, 0); | ||
902 | return rc; | ||
903 | } | ||
904 | EXPORT_SYMBOL(cca_gencipherkey); | ||
905 | |||
906 | /* | ||
907 | * Helper function, does a the CSNBKPI2 CPRB. | ||
908 | */ | ||
909 | static int _ip_cprb_helper(u16 cardnr, u16 domain, | ||
910 | const char *rule_array_1, | ||
911 | const char *rule_array_2, | ||
912 | const char *rule_array_3, | ||
913 | const u8 *clr_key_value, | ||
914 | int clr_key_bit_size, | ||
915 | u8 *key_token, | ||
916 | int *key_token_size) | ||
917 | { | ||
918 | int rc, n; | ||
919 | u8 *mem; | ||
920 | struct CPRBX *preqcblk, *prepcblk; | ||
921 | struct ica_xcRB xcrb; | ||
922 | struct rule_array_block { | ||
923 | u8 subfunc_code[2]; | ||
924 | u16 rule_array_len; | ||
925 | char rule_array[0]; | ||
926 | } __packed * preq_ra_block; | ||
927 | struct vud_block { | ||
928 | u16 len; | ||
929 | struct { | ||
930 | u16 len; | ||
931 | u16 flag; /* 0x0064 */ | ||
932 | u16 clr_key_bit_len; | ||
933 | } tlv1; | ||
934 | struct { | ||
935 | u16 len; | ||
936 | u16 flag; /* 0x0063 */ | ||
937 | u8 clr_key[0]; /* clear key value bytes */ | ||
938 | } tlv2; | ||
939 | } __packed * preq_vud_block; | ||
940 | struct key_block { | ||
941 | u16 len; | ||
942 | struct { | ||
943 | u16 len; | ||
944 | u16 flag; /* 0x0030 */ | ||
945 | u8 key_token[0]; /* key skeleton */ | ||
946 | } tlv1; | ||
947 | } __packed * preq_key_block; | ||
948 | struct iprepparm { | ||
949 | u8 subfunc_code[2]; | ||
950 | u16 rule_array_len; | ||
951 | struct { | ||
952 | u16 len; | ||
953 | } vud; | ||
954 | struct { | ||
955 | u16 len; | ||
956 | struct { | ||
957 | u16 len; | ||
958 | u16 flag; /* 0x0030 */ | ||
959 | u8 key_token[0]; /* key token */ | ||
960 | } tlv1; | ||
961 | } kb; | ||
962 | } __packed * prepparm; | ||
963 | struct cipherkeytoken *t; | ||
964 | int complete = strncmp(rule_array_2, "COMPLETE", 8) ? 0 : 1; | ||
965 | |||
966 | /* get already prepared memory for 2 cprbs with param block each */ | ||
967 | rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); | ||
968 | if (rc) | ||
969 | return rc; | ||
970 | |||
971 | /* fill request cprb struct */ | ||
972 | preqcblk->domain = domain; | ||
973 | preqcblk->req_parml = 0; | ||
974 | |||
975 | /* prepare request param block with IP request */ | ||
976 | preq_ra_block = (struct rule_array_block *) preqcblk->req_parmb; | ||
977 | memcpy(preq_ra_block->subfunc_code, "IP", 2); | ||
978 | preq_ra_block->rule_array_len = sizeof(uint16_t) + 2 * 8; | ||
979 | memcpy(preq_ra_block->rule_array, rule_array_1, 8); | ||
980 | memcpy(preq_ra_block->rule_array + 8, rule_array_2, 8); | ||
981 | preqcblk->req_parml = sizeof(struct rule_array_block) + 2 * 8; | ||
982 | if (rule_array_3) { | ||
983 | preq_ra_block->rule_array_len += 8; | ||
984 | memcpy(preq_ra_block->rule_array + 16, rule_array_3, 8); | ||
985 | preqcblk->req_parml += 8; | ||
986 | } | ||
987 | |||
988 | /* prepare vud block */ | ||
989 | preq_vud_block = (struct vud_block *) | ||
990 | (preqcblk->req_parmb + preqcblk->req_parml); | ||
991 | n = complete ? 0 : (clr_key_bit_size + 7) / 8; | ||
992 | preq_vud_block->len = sizeof(struct vud_block) + n; | ||
993 | preq_vud_block->tlv1.len = sizeof(preq_vud_block->tlv1); | ||
994 | preq_vud_block->tlv1.flag = 0x0064; | ||
995 | preq_vud_block->tlv1.clr_key_bit_len = complete ? 0 : clr_key_bit_size; | ||
996 | preq_vud_block->tlv2.len = sizeof(preq_vud_block->tlv2) + n; | ||
997 | preq_vud_block->tlv2.flag = 0x0063; | ||
998 | if (!complete) | ||
999 | memcpy(preq_vud_block->tlv2.clr_key, clr_key_value, n); | ||
1000 | preqcblk->req_parml += preq_vud_block->len; | ||
1001 | |||
1002 | /* prepare key block */ | ||
1003 | preq_key_block = (struct key_block *) | ||
1004 | (preqcblk->req_parmb + preqcblk->req_parml); | ||
1005 | n = *key_token_size; | ||
1006 | preq_key_block->len = sizeof(struct key_block) + n; | ||
1007 | preq_key_block->tlv1.len = sizeof(preq_key_block->tlv1) + n; | ||
1008 | preq_key_block->tlv1.flag = 0x0030; | ||
1009 | memcpy(preq_key_block->tlv1.key_token, key_token, *key_token_size); | ||
1010 | preqcblk->req_parml += preq_key_block->len; | ||
1011 | |||
1012 | /* prepare xcrb struct */ | ||
1013 | prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); | ||
1014 | |||
1015 | /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ | ||
1016 | rc = _zcrypt_send_cprb(&xcrb); | ||
1017 | if (rc) { | ||
1018 | DEBUG_ERR( | ||
1019 | "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", | ||
1020 | __func__, (int) cardnr, (int) domain, rc); | ||
1021 | goto out; | ||
1022 | } | ||
1023 | |||
1024 | /* check response returncode and reasoncode */ | ||
1025 | if (prepcblk->ccp_rtcode != 0) { | ||
1026 | DEBUG_ERR( | ||
1027 | "%s CSNBKPI2 failure, card response %d/%d\n", | ||
1028 | __func__, | ||
1029 | (int) prepcblk->ccp_rtcode, | ||
1030 | (int) prepcblk->ccp_rscode); | ||
1031 | rc = -EIO; | ||
1032 | goto out; | ||
1033 | } | ||
1034 | |||
1035 | /* process response cprb param block */ | ||
1036 | prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
1037 | prepparm = (struct iprepparm *) prepcblk->rpl_parmb; | ||
1038 | |||
1039 | /* do some plausibility checks on the key block */ | ||
1040 | if (prepparm->kb.len < 120 + 5 * sizeof(uint16_t) || | ||
1041 | prepparm->kb.len > 136 + 5 * sizeof(uint16_t)) { | ||
1042 | DEBUG_ERR("%s reply with invalid or unknown key block\n", | ||
1043 | __func__); | ||
1044 | rc = -EIO; | ||
1045 | goto out; | ||
1046 | } | ||
1047 | |||
1048 | /* do not check the key here, it may be incomplete */ | ||
1049 | |||
1050 | /* copy the vlsc key token back */ | ||
1051 | t = (struct cipherkeytoken *) prepparm->kb.tlv1.key_token; | ||
1052 | memcpy(key_token, t, t->len); | ||
1053 | *key_token_size = t->len; | ||
1054 | |||
1055 | out: | ||
1056 | free_cprbmem(mem, PARMBSIZE, 0); | ||
1057 | return rc; | ||
1058 | } | ||
1059 | |||
1060 | /* | ||
1061 | * Build CCA AES CIPHER secure key with a given clear key value. | ||
1062 | */ | ||
1063 | int cca_clr2cipherkey(u16 card, u16 dom, u32 keybitsize, u32 keygenflags, | ||
1064 | const u8 *clrkey, u8 *keybuf, size_t *keybufsize) | ||
1065 | { | ||
1066 | int rc; | ||
1067 | u8 *token; | ||
1068 | int tokensize; | ||
1069 | u8 exorbuf[32]; | ||
1070 | struct cipherkeytoken *t; | ||
1071 | |||
1072 | /* fill exorbuf with random data */ | ||
1073 | get_random_bytes(exorbuf, sizeof(exorbuf)); | ||
1074 | |||
1075 | /* allocate space for the key token to build */ | ||
1076 | token = kmalloc(MAXCCAVLSCTOKENSIZE, GFP_KERNEL); | ||
1077 | if (!token) | ||
1078 | return -ENOMEM; | ||
1079 | |||
1080 | /* prepare the token with the key skeleton */ | ||
1081 | tokensize = SIZEOF_SKELETON; | ||
1082 | memcpy(token, aes_cipher_key_skeleton, tokensize); | ||
1083 | |||
1084 | /* patch the skeleton key token export flags */ | ||
1085 | if (keygenflags) { | ||
1086 | t = (struct cipherkeytoken *) token; | ||
1087 | t->kmf1 |= (u16) (keygenflags & 0x0000FF00); | ||
1088 | t->kmf1 &= (u16) ~(keygenflags & 0x000000FF); | ||
1089 | } | ||
1090 | |||
1091 | /* | ||
1092 | * Do the key import with the clear key value in 4 steps: | ||
1093 | * 1/4 FIRST import with only random data | ||
1094 | * 2/4 EXOR the clear key | ||
1095 | * 3/4 EXOR the very same random data again | ||
1096 | * 4/4 COMPLETE the secure cipher key import | ||
1097 | */ | ||
1098 | rc = _ip_cprb_helper(card, dom, "AES ", "FIRST ", "MIN3PART", | ||
1099 | exorbuf, keybitsize, token, &tokensize); | ||
1100 | if (rc) { | ||
1101 | DEBUG_ERR( | ||
1102 | "%s clear key import 1/4 with CSNBKPI2 failed, rc=%d\n", | ||
1103 | __func__, rc); | ||
1104 | goto out; | ||
1105 | } | ||
1106 | rc = _ip_cprb_helper(card, dom, "AES ", "ADD-PART", NULL, | ||
1107 | clrkey, keybitsize, token, &tokensize); | ||
1108 | if (rc) { | ||
1109 | DEBUG_ERR( | ||
1110 | "%s clear key import 2/4 with CSNBKPI2 failed, rc=%d\n", | ||
1111 | __func__, rc); | ||
1112 | goto out; | ||
1113 | } | ||
1114 | rc = _ip_cprb_helper(card, dom, "AES ", "ADD-PART", NULL, | ||
1115 | exorbuf, keybitsize, token, &tokensize); | ||
1116 | if (rc) { | ||
1117 | DEBUG_ERR( | ||
1118 | "%s clear key import 3/4 with CSNBKPI2 failed, rc=%d\n", | ||
1119 | __func__, rc); | ||
1120 | goto out; | ||
1121 | } | ||
1122 | rc = _ip_cprb_helper(card, dom, "AES ", "COMPLETE", NULL, | ||
1123 | NULL, keybitsize, token, &tokensize); | ||
1124 | if (rc) { | ||
1125 | DEBUG_ERR( | ||
1126 | "%s clear key import 4/4 with CSNBKPI2 failed, rc=%d\n", | ||
1127 | __func__, rc); | ||
1128 | goto out; | ||
1129 | } | ||
1130 | |||
1131 | /* copy the generated key token */ | ||
1132 | if (keybuf) { | ||
1133 | if (tokensize > *keybufsize) | ||
1134 | rc = -EINVAL; | ||
1135 | else | ||
1136 | memcpy(keybuf, token, tokensize); | ||
1137 | } | ||
1138 | *keybufsize = tokensize; | ||
1139 | |||
1140 | out: | ||
1141 | kfree(token); | ||
1142 | return rc; | ||
1143 | } | ||
1144 | EXPORT_SYMBOL(cca_clr2cipherkey); | ||
1145 | |||
1146 | /* | ||
1147 | * Derive proteced key from CCA AES cipher secure key. | ||
1148 | */ | ||
1149 | int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey, | ||
1150 | u8 *protkey, u32 *protkeylen, u32 *protkeytype) | ||
1151 | { | ||
1152 | int rc; | ||
1153 | u8 *mem; | ||
1154 | struct CPRBX *preqcblk, *prepcblk; | ||
1155 | struct ica_xcRB xcrb; | ||
1156 | struct aureqparm { | ||
1157 | u8 subfunc_code[2]; | ||
1158 | u16 rule_array_len; | ||
1159 | u8 rule_array[8]; | ||
1160 | struct { | ||
1161 | u16 len; | ||
1162 | u16 tk_blob_len; | ||
1163 | u16 tk_blob_tag; | ||
1164 | u8 tk_blob[66]; | ||
1165 | } vud; | ||
1166 | struct { | ||
1167 | u16 len; | ||
1168 | u16 cca_key_token_len; | ||
1169 | u16 cca_key_token_flags; | ||
1170 | u8 cca_key_token[0]; // 64 or more | ||
1171 | } kb; | ||
1172 | } __packed * preqparm; | ||
1173 | struct aurepparm { | ||
1174 | u8 subfunc_code[2]; | ||
1175 | u16 rule_array_len; | ||
1176 | struct { | ||
1177 | u16 len; | ||
1178 | u16 sublen; | ||
1179 | u16 tag; | ||
1180 | struct cpacfkeyblock { | ||
1181 | u8 version; /* version of this struct */ | ||
1182 | u8 flags[2]; | ||
1183 | u8 algo; | ||
1184 | u8 form; | ||
1185 | u8 pad1[3]; | ||
1186 | u16 keylen; | ||
1187 | u8 key[64]; /* the key (keylen bytes) */ | ||
1188 | u16 keyattrlen; | ||
1189 | u8 keyattr[32]; | ||
1190 | u8 pad2[1]; | ||
1191 | u8 vptype; | ||
1192 | u8 vp[32]; /* verification pattern */ | ||
1193 | } ckb; | ||
1194 | } vud; | ||
1195 | struct { | ||
1196 | u16 len; | ||
1197 | } kb; | ||
1198 | } __packed * prepparm; | ||
1199 | int keytoklen = ((struct cipherkeytoken *)ckey)->len; | ||
1200 | |||
1201 | /* get already prepared memory for 2 cprbs with param block each */ | ||
1202 | rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); | ||
1203 | if (rc) | ||
1204 | return rc; | ||
1205 | |||
1206 | /* fill request cprb struct */ | ||
1207 | preqcblk->domain = domain; | ||
1208 | |||
1209 | /* fill request cprb param block with AU request */ | ||
1210 | preqparm = (struct aureqparm *) preqcblk->req_parmb; | ||
1211 | memcpy(preqparm->subfunc_code, "AU", 2); | ||
1212 | preqparm->rule_array_len = | ||
1213 | sizeof(preqparm->rule_array_len) | ||
1214 | + sizeof(preqparm->rule_array); | ||
1215 | memcpy(preqparm->rule_array, "EXPT-SK ", 8); | ||
1216 | /* vud, tk blob */ | ||
1217 | preqparm->vud.len = sizeof(preqparm->vud); | ||
1218 | preqparm->vud.tk_blob_len = sizeof(preqparm->vud.tk_blob) | ||
1219 | + 2 * sizeof(uint16_t); | ||
1220 | preqparm->vud.tk_blob_tag = 0x00C2; | ||
1221 | /* kb, cca token */ | ||
1222 | preqparm->kb.len = keytoklen + 3 * sizeof(uint16_t); | ||
1223 | preqparm->kb.cca_key_token_len = keytoklen + 2 * sizeof(uint16_t); | ||
1224 | memcpy(preqparm->kb.cca_key_token, ckey, keytoklen); | ||
1225 | /* now fill length of param block into cprb */ | ||
1226 | preqcblk->req_parml = sizeof(struct aureqparm) + keytoklen; | ||
1227 | |||
1228 | /* fill xcrb struct */ | ||
1229 | prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); | ||
1230 | |||
1231 | /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ | ||
1232 | rc = _zcrypt_send_cprb(&xcrb); | ||
1233 | if (rc) { | ||
1234 | DEBUG_ERR( | ||
1235 | "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", | ||
1236 | __func__, (int) cardnr, (int) domain, rc); | ||
1237 | goto out; | ||
1238 | } | ||
1239 | |||
1240 | /* check response returncode and reasoncode */ | ||
1241 | if (prepcblk->ccp_rtcode != 0) { | ||
1242 | DEBUG_ERR( | ||
1243 | "%s unwrap secure key failure, card response %d/%d\n", | ||
1244 | __func__, | ||
1245 | (int) prepcblk->ccp_rtcode, | ||
1246 | (int) prepcblk->ccp_rscode); | ||
1247 | rc = -EIO; | ||
1248 | goto out; | ||
1249 | } | ||
1250 | if (prepcblk->ccp_rscode != 0) { | ||
1251 | DEBUG_WARN( | ||
1252 | "%s unwrap secure key warning, card response %d/%d\n", | ||
1253 | __func__, | ||
1254 | (int) prepcblk->ccp_rtcode, | ||
1255 | (int) prepcblk->ccp_rscode); | ||
1256 | } | ||
1257 | |||
1258 | /* process response cprb param block */ | ||
1259 | prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
1260 | prepparm = (struct aurepparm *) prepcblk->rpl_parmb; | ||
1261 | |||
1262 | /* check the returned keyblock */ | ||
1263 | if (prepparm->vud.ckb.version != 0x01) { | ||
1264 | DEBUG_ERR( | ||
1265 | "%s reply param keyblock version mismatch 0x%02x != 0x01\n", | ||
1266 | __func__, (int) prepparm->vud.ckb.version); | ||
1267 | rc = -EIO; | ||
1268 | goto out; | ||
1269 | } | ||
1270 | if (prepparm->vud.ckb.algo != 0x02) { | ||
1271 | DEBUG_ERR( | ||
1272 | "%s reply param keyblock algo mismatch 0x%02x != 0x02\n", | ||
1273 | __func__, (int) prepparm->vud.ckb.algo); | ||
1274 | rc = -EIO; | ||
1275 | goto out; | ||
1276 | } | ||
1277 | |||
1278 | /* copy the translated protected key */ | ||
1279 | switch (prepparm->vud.ckb.keylen) { | ||
1280 | case 16+32: | ||
1281 | /* AES 128 protected key */ | ||
1282 | if (protkeytype) | ||
1283 | *protkeytype = PKEY_KEYTYPE_AES_128; | ||
1284 | break; | ||
1285 | case 24+32: | ||
1286 | /* AES 192 protected key */ | ||
1287 | if (protkeytype) | ||
1288 | *protkeytype = PKEY_KEYTYPE_AES_192; | ||
1289 | break; | ||
1290 | case 32+32: | ||
1291 | /* AES 256 protected key */ | ||
1292 | if (protkeytype) | ||
1293 | *protkeytype = PKEY_KEYTYPE_AES_256; | ||
1294 | break; | ||
1295 | default: | ||
1296 | DEBUG_ERR("%s unknown/unsupported keylen %d\n", | ||
1297 | __func__, prepparm->vud.ckb.keylen); | ||
1298 | rc = -EIO; | ||
1299 | goto out; | ||
1300 | } | ||
1301 | memcpy(protkey, prepparm->vud.ckb.key, prepparm->vud.ckb.keylen); | ||
1302 | if (protkeylen) | ||
1303 | *protkeylen = prepparm->vud.ckb.keylen; | ||
1304 | |||
1305 | out: | ||
1306 | free_cprbmem(mem, PARMBSIZE, 0); | ||
1307 | return rc; | ||
1308 | } | ||
1309 | EXPORT_SYMBOL(cca_cipher2protkey); | ||
1310 | |||
1311 | /* | ||
1312 | * query cryptographic facility from CCA adapter | ||
1313 | */ | ||
1314 | int cca_query_crypto_facility(u16 cardnr, u16 domain, | ||
1315 | const char *keyword, | ||
1316 | u8 *rarray, size_t *rarraylen, | ||
1317 | u8 *varray, size_t *varraylen) | ||
1318 | { | ||
1319 | int rc; | ||
1320 | u16 len; | ||
1321 | u8 *mem, *ptr; | ||
1322 | struct CPRBX *preqcblk, *prepcblk; | ||
1323 | struct ica_xcRB xcrb; | ||
1324 | struct fqreqparm { | ||
1325 | u8 subfunc_code[2]; | ||
1326 | u16 rule_array_len; | ||
1327 | char rule_array[8]; | ||
1328 | struct lv1 { | ||
1329 | u16 len; | ||
1330 | u8 data[VARDATASIZE]; | ||
1331 | } lv1; | ||
1332 | u16 dummylen; | ||
1333 | } __packed * preqparm; | ||
1334 | size_t parmbsize = sizeof(struct fqreqparm); | ||
1335 | struct fqrepparm { | ||
1336 | u8 subfunc_code[2]; | ||
1337 | u8 lvdata[0]; | ||
1338 | } __packed * prepparm; | ||
1339 | |||
1340 | /* get already prepared memory for 2 cprbs with param block each */ | ||
1341 | rc = alloc_and_prep_cprbmem(parmbsize, &mem, &preqcblk, &prepcblk); | ||
1342 | if (rc) | ||
1343 | return rc; | ||
1344 | |||
1345 | /* fill request cprb struct */ | ||
1346 | preqcblk->domain = domain; | ||
1347 | |||
1348 | /* fill request cprb param block with FQ request */ | ||
1349 | preqparm = (struct fqreqparm *) preqcblk->req_parmb; | ||
1350 | memcpy(preqparm->subfunc_code, "FQ", 2); | ||
1351 | memcpy(preqparm->rule_array, keyword, sizeof(preqparm->rule_array)); | ||
1352 | preqparm->rule_array_len = | ||
1353 | sizeof(preqparm->rule_array_len) + sizeof(preqparm->rule_array); | ||
1354 | preqparm->lv1.len = sizeof(preqparm->lv1); | ||
1355 | preqparm->dummylen = sizeof(preqparm->dummylen); | ||
1356 | preqcblk->req_parml = parmbsize; | ||
1357 | |||
1358 | /* fill xcrb struct */ | ||
1359 | prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); | ||
1360 | |||
1361 | /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ | ||
1362 | rc = _zcrypt_send_cprb(&xcrb); | ||
1363 | if (rc) { | ||
1364 | DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n", | ||
1365 | __func__, (int) cardnr, (int) domain, rc); | ||
1366 | goto out; | ||
1367 | } | ||
1368 | |||
1369 | /* check response returncode and reasoncode */ | ||
1370 | if (prepcblk->ccp_rtcode != 0) { | ||
1371 | DEBUG_ERR("%s unwrap secure key failure, card response %d/%d\n", | ||
1372 | __func__, | ||
1373 | (int) prepcblk->ccp_rtcode, | ||
1374 | (int) prepcblk->ccp_rscode); | ||
1375 | rc = -EIO; | ||
1376 | goto out; | ||
1377 | } | ||
1378 | |||
1379 | /* process response cprb param block */ | ||
1380 | prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); | ||
1381 | prepparm = (struct fqrepparm *) prepcblk->rpl_parmb; | ||
1382 | ptr = prepparm->lvdata; | ||
1383 | |||
1384 | /* check and possibly copy reply rule array */ | ||
1385 | len = *((u16 *) ptr); | ||
1386 | if (len > sizeof(u16)) { | ||
1387 | ptr += sizeof(u16); | ||
1388 | len -= sizeof(u16); | ||
1389 | if (rarray && rarraylen && *rarraylen > 0) { | ||
1390 | *rarraylen = (len > *rarraylen ? *rarraylen : len); | ||
1391 | memcpy(rarray, ptr, *rarraylen); | ||
1392 | } | ||
1393 | ptr += len; | ||
1394 | } | ||
1395 | /* check and possible copy reply var array */ | ||
1396 | len = *((u16 *) ptr); | ||
1397 | if (len > sizeof(u16)) { | ||
1398 | ptr += sizeof(u16); | ||
1399 | len -= sizeof(u16); | ||
1400 | if (varray && varraylen && *varraylen > 0) { | ||
1401 | *varraylen = (len > *varraylen ? *varraylen : len); | ||
1402 | memcpy(varray, ptr, *varraylen); | ||
1403 | } | ||
1404 | ptr += len; | ||
1405 | } | ||
1406 | |||
1407 | out: | ||
1408 | free_cprbmem(mem, parmbsize, 0); | ||
1409 | return rc; | ||
1410 | } | ||
1411 | EXPORT_SYMBOL(cca_query_crypto_facility); | ||
1412 | |||
1413 | static int cca_info_cache_fetch(u16 cardnr, u16 domain, struct cca_info *ci) | ||
1414 | { | ||
1415 | int rc = -ENOENT; | ||
1416 | struct cca_info_list_entry *ptr; | ||
1417 | |||
1418 | spin_lock_bh(&cca_info_list_lock); | ||
1419 | list_for_each_entry(ptr, &cca_info_list, list) { | ||
1420 | if (ptr->cardnr == cardnr && ptr->domain == domain) { | ||
1421 | memcpy(ci, &ptr->info, sizeof(*ci)); | ||
1422 | rc = 0; | ||
1423 | break; | ||
1424 | } | ||
1425 | } | ||
1426 | spin_unlock_bh(&cca_info_list_lock); | ||
1427 | |||
1428 | return rc; | ||
1429 | } | ||
1430 | |||
1431 | static void cca_info_cache_update(u16 cardnr, u16 domain, | ||
1432 | const struct cca_info *ci) | ||
1433 | { | ||
1434 | int found = 0; | ||
1435 | struct cca_info_list_entry *ptr; | ||
1436 | |||
1437 | spin_lock_bh(&cca_info_list_lock); | ||
1438 | list_for_each_entry(ptr, &cca_info_list, list) { | ||
1439 | if (ptr->cardnr == cardnr && | ||
1440 | ptr->domain == domain) { | ||
1441 | memcpy(&ptr->info, ci, sizeof(*ci)); | ||
1442 | found = 1; | ||
1443 | break; | ||
1444 | } | ||
1445 | } | ||
1446 | if (!found) { | ||
1447 | ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC); | ||
1448 | if (!ptr) { | ||
1449 | spin_unlock_bh(&cca_info_list_lock); | ||
1450 | return; | ||
1451 | } | ||
1452 | ptr->cardnr = cardnr; | ||
1453 | ptr->domain = domain; | ||
1454 | memcpy(&ptr->info, ci, sizeof(*ci)); | ||
1455 | list_add(&ptr->list, &cca_info_list); | ||
1456 | } | ||
1457 | spin_unlock_bh(&cca_info_list_lock); | ||
1458 | } | ||
1459 | |||
1460 | static void cca_info_cache_scrub(u16 cardnr, u16 domain) | ||
1461 | { | ||
1462 | struct cca_info_list_entry *ptr; | ||
1463 | |||
1464 | spin_lock_bh(&cca_info_list_lock); | ||
1465 | list_for_each_entry(ptr, &cca_info_list, list) { | ||
1466 | if (ptr->cardnr == cardnr && | ||
1467 | ptr->domain == domain) { | ||
1468 | list_del(&ptr->list); | ||
1469 | kfree(ptr); | ||
1470 | break; | ||
1471 | } | ||
1472 | } | ||
1473 | spin_unlock_bh(&cca_info_list_lock); | ||
1474 | } | ||
1475 | |||
1476 | static void __exit mkvp_cache_free(void) | ||
1477 | { | ||
1478 | struct cca_info_list_entry *ptr, *pnext; | ||
1479 | |||
1480 | spin_lock_bh(&cca_info_list_lock); | ||
1481 | list_for_each_entry_safe(ptr, pnext, &cca_info_list, list) { | ||
1482 | list_del(&ptr->list); | ||
1483 | kfree(ptr); | ||
1484 | } | ||
1485 | spin_unlock_bh(&cca_info_list_lock); | ||
1486 | } | ||
1487 | |||
1488 | /* | ||
1489 | * Fetch cca_info values via query_crypto_facility from adapter. | ||
1490 | */ | ||
1491 | static int fetch_cca_info(u16 cardnr, u16 domain, struct cca_info *ci) | ||
1492 | { | ||
1493 | int rc, found = 0; | ||
1494 | size_t rlen, vlen; | ||
1495 | u8 *rarray, *varray, *pg; | ||
1496 | struct zcrypt_device_status_ext devstat; | ||
1497 | |||
1498 | memset(ci, 0, sizeof(*ci)); | ||
1499 | |||
1500 | /* get first info from zcrypt device driver about this apqn */ | ||
1501 | rc = zcrypt_device_status_ext(cardnr, domain, &devstat); | ||
1502 | if (rc) | ||
1503 | return rc; | ||
1504 | ci->hwtype = devstat.hwtype; | ||
1505 | |||
1506 | /* prep page for rule array and var array use */ | ||
1507 | pg = (u8 *) __get_free_page(GFP_KERNEL); | ||
1508 | if (!pg) | ||
1509 | return -ENOMEM; | ||
1510 | rarray = pg; | ||
1511 | varray = pg + PAGE_SIZE/2; | ||
1512 | rlen = vlen = PAGE_SIZE/2; | ||
1513 | |||
1514 | /* QF for this card/domain */ | ||
1515 | rc = cca_query_crypto_facility(cardnr, domain, "STATICSA", | ||
1516 | rarray, &rlen, varray, &vlen); | ||
1517 | if (rc == 0 && rlen >= 10*8 && vlen >= 204) { | ||
1518 | memcpy(ci->serial, rarray, 8); | ||
1519 | ci->new_mk_state = (char) rarray[7*8]; | ||
1520 | ci->cur_mk_state = (char) rarray[8*8]; | ||
1521 | ci->old_mk_state = (char) rarray[9*8]; | ||
1522 | if (ci->old_mk_state == '2') | ||
1523 | memcpy(&ci->old_mkvp, varray + 172, 8); | ||
1524 | if (ci->cur_mk_state == '2') | ||
1525 | memcpy(&ci->cur_mkvp, varray + 184, 8); | ||
1526 | if (ci->new_mk_state == '3') | ||
1527 | memcpy(&ci->new_mkvp, varray + 196, 8); | ||
1528 | found = 1; | ||
1529 | } | ||
1530 | |||
1531 | free_page((unsigned long) pg); | ||
1532 | |||
1533 | return found ? 0 : -ENOENT; | ||
1534 | } | ||
1535 | |||
1536 | /* | ||
1537 | * Fetch cca information about a CCA queue. | ||
1538 | */ | ||
1539 | int cca_get_info(u16 card, u16 dom, struct cca_info *ci, int verify) | ||
1540 | { | ||
1541 | int rc; | ||
1542 | |||
1543 | rc = cca_info_cache_fetch(card, dom, ci); | ||
1544 | if (rc || verify) { | ||
1545 | rc = fetch_cca_info(card, dom, ci); | ||
1546 | if (rc == 0) | ||
1547 | cca_info_cache_update(card, dom, ci); | ||
1548 | } | ||
1549 | |||
1550 | return rc; | ||
1551 | } | ||
1552 | EXPORT_SYMBOL(cca_get_info); | ||
1553 | |||
1554 | /* | ||
1555 | * Search for a matching crypto card based on the | ||
1556 | * Master Key Verification Pattern given. | ||
1557 | */ | ||
1558 | static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain, | ||
1559 | int verify, int minhwtype) | ||
1560 | { | ||
1561 | struct zcrypt_device_status_ext *device_status; | ||
1562 | u16 card, dom; | ||
1563 | struct cca_info ci; | ||
1564 | int i, rc, oi = -1; | ||
1565 | |||
1566 | /* mkvp must not be zero, minhwtype needs to be >= 0 */ | ||
1567 | if (mkvp == 0 || minhwtype < 0) | ||
1568 | return -EINVAL; | ||
1569 | |||
1570 | /* fetch status of all crypto cards */ | ||
1571 | device_status = kmalloc_array(MAX_ZDEV_ENTRIES_EXT, | ||
1572 | sizeof(struct zcrypt_device_status_ext), | ||
1573 | GFP_KERNEL); | ||
1574 | if (!device_status) | ||
1575 | return -ENOMEM; | ||
1576 | zcrypt_device_status_mask_ext(device_status); | ||
1577 | |||
1578 | /* walk through all crypto cards */ | ||
1579 | for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) { | ||
1580 | card = AP_QID_CARD(device_status[i].qid); | ||
1581 | dom = AP_QID_QUEUE(device_status[i].qid); | ||
1582 | if (device_status[i].online && | ||
1583 | device_status[i].functions & 0x04) { | ||
1584 | /* enabled CCA card, check current mkvp from cache */ | ||
1585 | if (cca_info_cache_fetch(card, dom, &ci) == 0 && | ||
1586 | ci.hwtype >= minhwtype && | ||
1587 | ci.cur_mk_state == '2' && | ||
1588 | ci.cur_mkvp == mkvp) { | ||
1589 | if (!verify) | ||
1590 | break; | ||
1591 | /* verify: refresh card info */ | ||
1592 | if (fetch_cca_info(card, dom, &ci) == 0) { | ||
1593 | cca_info_cache_update(card, dom, &ci); | ||
1594 | if (ci.hwtype >= minhwtype && | ||
1595 | ci.cur_mk_state == '2' && | ||
1596 | ci.cur_mkvp == mkvp) | ||
1597 | break; | ||
1598 | } | ||
1599 | } | ||
1600 | } else { | ||
1601 | /* Card is offline and/or not a CCA card. */ | ||
1602 | /* del mkvp entry from cache if it exists */ | ||
1603 | cca_info_cache_scrub(card, dom); | ||
1604 | } | ||
1605 | } | ||
1606 | if (i >= MAX_ZDEV_ENTRIES_EXT) { | ||
1607 | /* nothing found, so this time without cache */ | ||
1608 | for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) { | ||
1609 | if (!(device_status[i].online && | ||
1610 | device_status[i].functions & 0x04)) | ||
1611 | continue; | ||
1612 | card = AP_QID_CARD(device_status[i].qid); | ||
1613 | dom = AP_QID_QUEUE(device_status[i].qid); | ||
1614 | /* fresh fetch mkvp from adapter */ | ||
1615 | if (fetch_cca_info(card, dom, &ci) == 0) { | ||
1616 | cca_info_cache_update(card, dom, &ci); | ||
1617 | if (ci.hwtype >= minhwtype && | ||
1618 | ci.cur_mk_state == '2' && | ||
1619 | ci.cur_mkvp == mkvp) | ||
1620 | break; | ||
1621 | if (ci.hwtype >= minhwtype && | ||
1622 | ci.old_mk_state == '2' && | ||
1623 | ci.old_mkvp == mkvp && | ||
1624 | oi < 0) | ||
1625 | oi = i; | ||
1626 | } | ||
1627 | } | ||
1628 | if (i >= MAX_ZDEV_ENTRIES_EXT && oi >= 0) { | ||
1629 | /* old mkvp matched, use this card then */ | ||
1630 | card = AP_QID_CARD(device_status[oi].qid); | ||
1631 | dom = AP_QID_QUEUE(device_status[oi].qid); | ||
1632 | } | ||
1633 | } | ||
1634 | if (i < MAX_ZDEV_ENTRIES_EXT || oi >= 0) { | ||
1635 | if (pcardnr) | ||
1636 | *pcardnr = card; | ||
1637 | if (pdomain) | ||
1638 | *pdomain = dom; | ||
1639 | rc = (i < MAX_ZDEV_ENTRIES_EXT ? 0 : 1); | ||
1640 | } else | ||
1641 | rc = -ENODEV; | ||
1642 | |||
1643 | kfree(device_status); | ||
1644 | return rc; | ||
1645 | } | ||
1646 | |||
1647 | /* | ||
1648 | * Search for a matching crypto card based on the Master Key | ||
1649 | * Verification Pattern provided inside a secure key token. | ||
1650 | */ | ||
1651 | int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify) | ||
1652 | { | ||
1653 | u64 mkvp; | ||
1654 | int minhwtype = 0; | ||
1655 | const struct keytoken_header *hdr = (struct keytoken_header *) key; | ||
1656 | |||
1657 | if (hdr->type != TOKTYPE_CCA_INTERNAL) | ||
1658 | return -EINVAL; | ||
1659 | |||
1660 | switch (hdr->version) { | ||
1661 | case TOKVER_CCA_AES: | ||
1662 | mkvp = ((struct secaeskeytoken *)key)->mkvp; | ||
1663 | break; | ||
1664 | case TOKVER_CCA_VLSC: | ||
1665 | mkvp = ((struct cipherkeytoken *)key)->mkvp0; | ||
1666 | minhwtype = AP_DEVICE_TYPE_CEX6; | ||
1667 | break; | ||
1668 | default: | ||
1669 | return -EINVAL; | ||
1670 | } | ||
1671 | |||
1672 | return findcard(mkvp, pcardnr, pdomain, verify, minhwtype); | ||
1673 | } | ||
1674 | EXPORT_SYMBOL(cca_findcard); | ||
1675 | |||
1676 | int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, | ||
1677 | int minhwtype, u64 cur_mkvp, u64 old_mkvp, int verify) | ||
1678 | { | ||
1679 | struct zcrypt_device_status_ext *device_status; | ||
1680 | int i, n, card, dom, curmatch, oldmatch, rc = 0; | ||
1681 | struct cca_info ci; | ||
1682 | |||
1683 | *apqns = NULL; | ||
1684 | *nr_apqns = 0; | ||
1685 | |||
1686 | /* fetch status of all crypto cards */ | ||
1687 | device_status = kmalloc_array(MAX_ZDEV_ENTRIES_EXT, | ||
1688 | sizeof(struct zcrypt_device_status_ext), | ||
1689 | GFP_KERNEL); | ||
1690 | if (!device_status) | ||
1691 | return -ENOMEM; | ||
1692 | zcrypt_device_status_mask_ext(device_status); | ||
1693 | |||
1694 | /* loop two times: first gather eligible apqns, then store them */ | ||
1695 | while (1) { | ||
1696 | n = 0; | ||
1697 | /* walk through all the crypto cards */ | ||
1698 | for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) { | ||
1699 | card = AP_QID_CARD(device_status[i].qid); | ||
1700 | dom = AP_QID_QUEUE(device_status[i].qid); | ||
1701 | /* check online state */ | ||
1702 | if (!device_status[i].online) | ||
1703 | continue; | ||
1704 | /* check for cca functions */ | ||
1705 | if (!(device_status[i].functions & 0x04)) | ||
1706 | continue; | ||
1707 | /* check cardnr */ | ||
1708 | if (cardnr != 0xFFFF && card != cardnr) | ||
1709 | continue; | ||
1710 | /* check domain */ | ||
1711 | if (domain != 0xFFFF && dom != domain) | ||
1712 | continue; | ||
1713 | /* get cca info on this apqn */ | ||
1714 | if (cca_get_info(card, dom, &ci, verify)) | ||
1715 | continue; | ||
1716 | /* current master key needs to be valid */ | ||
1717 | if (ci.cur_mk_state != '2') | ||
1718 | continue; | ||
1719 | /* check min hardware type */ | ||
1720 | if (minhwtype > 0 && minhwtype > ci.hwtype) | ||
1721 | continue; | ||
1722 | if (cur_mkvp || old_mkvp) { | ||
1723 | /* check mkvps */ | ||
1724 | curmatch = oldmatch = 0; | ||
1725 | if (cur_mkvp && cur_mkvp == ci.cur_mkvp) | ||
1726 | curmatch = 1; | ||
1727 | if (old_mkvp && ci.old_mk_state == '2' && | ||
1728 | old_mkvp == ci.old_mkvp) | ||
1729 | oldmatch = 1; | ||
1730 | if ((cur_mkvp || old_mkvp) && | ||
1731 | (curmatch + oldmatch < 1)) | ||
1732 | continue; | ||
1733 | } | ||
1734 | /* apqn passed all filtering criterons */ | ||
1735 | if (*apqns && n < *nr_apqns) | ||
1736 | (*apqns)[n] = (((u16)card) << 16) | ((u16) dom); | ||
1737 | n++; | ||
1738 | } | ||
1739 | /* loop 2nd time: array has been filled */ | ||
1740 | if (*apqns) | ||
1741 | break; | ||
1742 | /* loop 1st time: have # of eligible apqns in n */ | ||
1743 | if (!n) { | ||
1744 | rc = -ENODEV; /* no eligible apqns found */ | ||
1745 | break; | ||
1746 | } | ||
1747 | *nr_apqns = n; | ||
1748 | /* allocate array to store n apqns into */ | ||
1749 | *apqns = kmalloc_array(n, sizeof(u32), GFP_KERNEL); | ||
1750 | if (!*apqns) { | ||
1751 | rc = -ENOMEM; | ||
1752 | break; | ||
1753 | } | ||
1754 | verify = 0; | ||
1755 | } | ||
1756 | |||
1757 | kfree(device_status); | ||
1758 | return rc; | ||
1759 | } | ||
1760 | EXPORT_SYMBOL(cca_findcard2); | ||
1761 | |||
1762 | void __exit zcrypt_ccamisc_exit(void) | ||
1763 | { | ||
1764 | mkvp_cache_free(); | ||
1765 | } | ||
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.h b/drivers/s390/crypto/zcrypt_ccamisc.h new file mode 100644 index 000000000000..77b6cc7b8f82 --- /dev/null +++ b/drivers/s390/crypto/zcrypt_ccamisc.h | |||
@@ -0,0 +1,217 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0+ */ | ||
2 | /* | ||
3 | * Copyright IBM Corp. 2019 | ||
4 | * Author(s): Harald Freudenberger <freude@linux.ibm.com> | ||
5 | * Ingo Franzki <ifranzki@linux.ibm.com> | ||
6 | * | ||
7 | * Collection of CCA misc functions used by zcrypt and pkey | ||
8 | */ | ||
9 | |||
10 | #ifndef _ZCRYPT_CCAMISC_H_ | ||
11 | #define _ZCRYPT_CCAMISC_H_ | ||
12 | |||
13 | #include <asm/zcrypt.h> | ||
14 | #include <asm/pkey.h> | ||
15 | |||
16 | /* Key token types */ | ||
17 | #define TOKTYPE_NON_CCA 0x00 /* Non-CCA key token */ | ||
18 | #define TOKTYPE_CCA_INTERNAL 0x01 /* CCA internal key token */ | ||
19 | |||
20 | /* For TOKTYPE_NON_CCA: */ | ||
21 | #define TOKVER_PROTECTED_KEY 0x01 /* Protected key token */ | ||
22 | |||
23 | /* For TOKTYPE_CCA_INTERNAL: */ | ||
24 | #define TOKVER_CCA_AES 0x04 /* CCA AES key token */ | ||
25 | #define TOKVER_CCA_VLSC 0x05 /* var length sym cipher key token */ | ||
26 | |||
27 | /* Max size of a cca variable length cipher key token */ | ||
28 | #define MAXCCAVLSCTOKENSIZE 725 | ||
29 | |||
30 | /* header part of a CCA key token */ | ||
31 | struct keytoken_header { | ||
32 | u8 type; /* one of the TOKTYPE values */ | ||
33 | u8 res0[1]; | ||
34 | u16 len; /* vlsc token: total length in bytes */ | ||
35 | u8 version; /* one of the TOKVER values */ | ||
36 | u8 res1[3]; | ||
37 | } __packed; | ||
38 | |||
39 | /* inside view of a CCA secure key token (only type 0x01 version 0x04) */ | ||
40 | struct secaeskeytoken { | ||
41 | u8 type; /* 0x01 for internal key token */ | ||
42 | u8 res0[3]; | ||
43 | u8 version; /* should be 0x04 */ | ||
44 | u8 res1[1]; | ||
45 | u8 flag; /* key flags */ | ||
46 | u8 res2[1]; | ||
47 | u64 mkvp; /* master key verification pattern */ | ||
48 | u8 key[32]; /* key value (encrypted) */ | ||
49 | u8 cv[8]; /* control vector */ | ||
50 | u16 bitsize; /* key bit size */ | ||
51 | u16 keysize; /* key byte size */ | ||
52 | u8 tvv[4]; /* token validation value */ | ||
53 | } __packed; | ||
54 | |||
55 | /* inside view of a variable length symmetric cipher AES key token */ | ||
56 | struct cipherkeytoken { | ||
57 | u8 type; /* 0x01 for internal key token */ | ||
58 | u8 res0[1]; | ||
59 | u16 len; /* total key token length in bytes */ | ||
60 | u8 version; /* should be 0x05 */ | ||
61 | u8 res1[3]; | ||
62 | u8 kms; /* key material state, 0x03 means wrapped with MK */ | ||
63 | u8 kvpt; /* key verification pattern type, should be 0x01 */ | ||
64 | u64 mkvp0; /* master key verification pattern, lo part */ | ||
65 | u64 mkvp1; /* master key verification pattern, hi part (unused) */ | ||
66 | u8 eskwm; /* encrypted section key wrapping method */ | ||
67 | u8 hashalg; /* hash algorithmus used for wrapping key */ | ||
68 | u8 plfver; /* pay load format version */ | ||
69 | u8 res2[1]; | ||
70 | u8 adsver; /* associated data section version */ | ||
71 | u8 res3[1]; | ||
72 | u16 adslen; /* associated data section length */ | ||
73 | u8 kllen; /* optional key label length */ | ||
74 | u8 ieaslen; /* optional extended associated data length */ | ||
75 | u8 uadlen; /* optional user definable associated data length */ | ||
76 | u8 res4[1]; | ||
77 | u16 wpllen; /* wrapped payload length in bits: */ | ||
78 | /* plfver 0x00 0x01 */ | ||
79 | /* AES-128 512 640 */ | ||
80 | /* AES-192 576 640 */ | ||
81 | /* AES-256 640 640 */ | ||
82 | u8 res5[1]; | ||
83 | u8 algtype; /* 0x02 for AES cipher */ | ||
84 | u16 keytype; /* 0x0001 for 'cipher' */ | ||
85 | u8 kufc; /* key usage field count */ | ||
86 | u16 kuf1; /* key usage field 1 */ | ||
87 | u16 kuf2; /* key usage field 2 */ | ||
88 | u8 kmfc; /* key management field count */ | ||
89 | u16 kmf1; /* key management field 1 */ | ||
90 | u16 kmf2; /* key management field 2 */ | ||
91 | u16 kmf3; /* key management field 3 */ | ||
92 | u8 vdata[0]; /* variable part data follows */ | ||
93 | } __packed; | ||
94 | |||
95 | /* Some defines for the CCA AES cipherkeytoken kmf1 field */ | ||
96 | #define KMF1_XPRT_SYM 0x8000 | ||
97 | #define KMF1_XPRT_UASY 0x4000 | ||
98 | #define KMF1_XPRT_AASY 0x2000 | ||
99 | #define KMF1_XPRT_RAW 0x1000 | ||
100 | #define KMF1_XPRT_CPAC 0x0800 | ||
101 | #define KMF1_XPRT_DES 0x0080 | ||
102 | #define KMF1_XPRT_AES 0x0040 | ||
103 | #define KMF1_XPRT_RSA 0x0008 | ||
104 | |||
105 | /* | ||
106 | * Simple check if the token is a valid CCA secure AES data key | ||
107 | * token. If keybitsize is given, the bitsize of the key is | ||
108 | * also checked. Returns 0 on success or errno value on failure. | ||
109 | */ | ||
110 | int cca_check_secaeskeytoken(debug_info_t *dbg, int dbflvl, | ||
111 | const u8 *token, int keybitsize); | ||
112 | |||
113 | /* | ||
114 | * Simple check if the token is a valid CCA secure AES cipher key | ||
115 | * token. If keybitsize is given, the bitsize of the key is | ||
116 | * also checked. If checkcpacfexport is enabled, the key is also | ||
117 | * checked for the export flag to allow CPACF export. | ||
118 | * Returns 0 on success or errno value on failure. | ||
119 | */ | ||
120 | int cca_check_secaescipherkey(debug_info_t *dbg, int dbflvl, | ||
121 | const u8 *token, int keybitsize, | ||
122 | int checkcpacfexport); | ||
123 | |||
124 | /* | ||
125 | * Generate (random) CCA AES DATA secure key. | ||
126 | */ | ||
127 | int cca_genseckey(u16 cardnr, u16 domain, u32 keybitsize, u8 *seckey); | ||
128 | |||
129 | /* | ||
130 | * Generate CCA AES DATA secure key with given clear key value. | ||
131 | */ | ||
132 | int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize, | ||
133 | const u8 *clrkey, u8 *seckey); | ||
134 | |||
135 | /* | ||
136 | * Derive proteced key from an CCA AES DATA secure key. | ||
137 | */ | ||
138 | int cca_sec2protkey(u16 cardnr, u16 domain, | ||
139 | const u8 seckey[SECKEYBLOBSIZE], | ||
140 | u8 *protkey, u32 *protkeylen, u32 *protkeytype); | ||
141 | |||
142 | /* | ||
143 | * Generate (random) CCA AES CIPHER secure key. | ||
144 | */ | ||
145 | int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags, | ||
146 | u8 *keybuf, size_t *keybufsize); | ||
147 | |||
148 | /* | ||
149 | * Derive proteced key from CCA AES cipher secure key. | ||
150 | */ | ||
151 | int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey, | ||
152 | u8 *protkey, u32 *protkeylen, u32 *protkeytype); | ||
153 | |||
154 | /* | ||
155 | * Build CCA AES CIPHER secure key with a given clear key value. | ||
156 | */ | ||
157 | int cca_clr2cipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags, | ||
158 | const u8 *clrkey, u8 *keybuf, size_t *keybufsize); | ||
159 | |||
160 | /* | ||
161 | * Query cryptographic facility from CCA adapter | ||
162 | */ | ||
163 | int cca_query_crypto_facility(u16 cardnr, u16 domain, | ||
164 | const char *keyword, | ||
165 | u8 *rarray, size_t *rarraylen, | ||
166 | u8 *varray, size_t *varraylen); | ||
167 | |||
168 | /* | ||
169 | * Search for a matching crypto card based on the Master Key | ||
170 | * Verification Pattern provided inside a secure key. | ||
171 | * Works with CCA AES data and cipher keys. | ||
172 | * Returns < 0 on failure, 0 if CURRENT MKVP matches and | ||
173 | * 1 if OLD MKVP matches. | ||
174 | */ | ||
175 | int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify); | ||
176 | |||
177 | /* | ||
178 | * Build a list of cca apqns meeting the following constrains: | ||
179 | * - apqn is online and is in fact a CCA apqn | ||
180 | * - if cardnr is not FFFF only apqns with this cardnr | ||
181 | * - if domain is not FFFF only apqns with this domainnr | ||
182 | * - if minhwtype > 0 only apqns with hwtype >= minhwtype | ||
183 | * - if cur_mkvp != 0 only apqns where cur_mkvp == mkvp | ||
184 | * - if old_mkvp != 0 only apqns where old_mkvp == mkvp | ||
185 | * - if verify is enabled and a cur_mkvp and/or old_mkvp | ||
186 | * value is given, then refetch the cca_info and make sure the current | ||
187 | * cur_mkvp or old_mkvp values of the apqn are used. | ||
188 | * The array of apqn entries is allocated with kmalloc and returned in *apqns; | ||
189 | * the number of apqns stored into the list is returned in *nr_apqns. One apqn | ||
190 | * entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and | ||
191 | * may be casted to struct pkey_apqn. The return value is either 0 for success | ||
192 | * or a negative errno value. If no apqn meeting the criterias is found, | ||
193 | * -ENODEV is returned. | ||
194 | */ | ||
195 | int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain, | ||
196 | int minhwtype, u64 cur_mkvp, u64 old_mkvp, int verify); | ||
197 | |||
198 | /* struct to hold info for each CCA queue */ | ||
199 | struct cca_info { | ||
200 | int hwtype; /* one of the defined AP_DEVICE_TYPE_* */ | ||
201 | char new_mk_state; /* '1' empty, '2' partially full, '3' full */ | ||
202 | char cur_mk_state; /* '1' invalid, '2' valid */ | ||
203 | char old_mk_state; /* '1' invalid, '2' valid */ | ||
204 | u64 new_mkvp; /* truncated sha256 hash of new master key */ | ||
205 | u64 cur_mkvp; /* truncated sha256 hash of current master key */ | ||
206 | u64 old_mkvp; /* truncated sha256 hash of old master key */ | ||
207 | char serial[9]; /* serial number string (8 ascii numbers + 0x00) */ | ||
208 | }; | ||
209 | |||
210 | /* | ||
211 | * Fetch cca information about an CCA queue. | ||
212 | */ | ||
213 | int cca_get_info(u16 card, u16 dom, struct cca_info *ci, int verify); | ||
214 | |||
215 | void zcrypt_ccamisc_exit(void); | ||
216 | |||
217 | #endif /* _ZCRYPT_CCAMISC_H_ */ | ||
diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c index 582ffa7e0f18..f58d8dec19dc 100644 --- a/drivers/s390/crypto/zcrypt_cex4.c +++ b/drivers/s390/crypto/zcrypt_cex4.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "zcrypt_msgtype50.h" | 18 | #include "zcrypt_msgtype50.h" |
19 | #include "zcrypt_error.h" | 19 | #include "zcrypt_error.h" |
20 | #include "zcrypt_cex4.h" | 20 | #include "zcrypt_cex4.h" |
21 | #include "zcrypt_ccamisc.h" | ||
21 | 22 | ||
22 | #define CEX4A_MIN_MOD_SIZE 1 /* 8 bits */ | 23 | #define CEX4A_MIN_MOD_SIZE 1 /* 8 bits */ |
23 | #define CEX4A_MAX_MOD_SIZE_2K 256 /* 2048 bits */ | 24 | #define CEX4A_MAX_MOD_SIZE_2K 256 /* 2048 bits */ |
@@ -65,6 +66,85 @@ static struct ap_device_id zcrypt_cex4_queue_ids[] = { | |||
65 | 66 | ||
66 | MODULE_DEVICE_TABLE(ap, zcrypt_cex4_queue_ids); | 67 | MODULE_DEVICE_TABLE(ap, zcrypt_cex4_queue_ids); |
67 | 68 | ||
69 | /* | ||
70 | * CCA card addditional device attributes | ||
71 | */ | ||
72 | static ssize_t serialnr_show(struct device *dev, | ||
73 | struct device_attribute *attr, | ||
74 | char *buf) | ||
75 | { | ||
76 | struct cca_info ci; | ||
77 | struct ap_card *ac = to_ap_card(dev); | ||
78 | struct zcrypt_card *zc = ac->private; | ||
79 | |||
80 | memset(&ci, 0, sizeof(ci)); | ||
81 | |||
82 | if (ap_domain_index >= 0) | ||
83 | cca_get_info(ac->id, ap_domain_index, &ci, zc->online); | ||
84 | |||
85 | return snprintf(buf, PAGE_SIZE, "%s\n", ci.serial); | ||
86 | } | ||
87 | static DEVICE_ATTR_RO(serialnr); | ||
88 | |||
89 | static struct attribute *cca_card_attrs[] = { | ||
90 | &dev_attr_serialnr.attr, | ||
91 | NULL, | ||
92 | }; | ||
93 | |||
94 | static const struct attribute_group cca_card_attr_group = { | ||
95 | .attrs = cca_card_attrs, | ||
96 | }; | ||
97 | |||
98 | /* | ||
99 | * CCA queue addditional device attributes | ||
100 | */ | ||
101 | static ssize_t mkvps_show(struct device *dev, | ||
102 | struct device_attribute *attr, | ||
103 | char *buf) | ||
104 | { | ||
105 | int n = 0; | ||
106 | struct cca_info ci; | ||
107 | struct zcrypt_queue *zq = to_ap_queue(dev)->private; | ||
108 | static const char * const cao_state[] = { "invalid", "valid" }; | ||
109 | static const char * const new_state[] = { "empty", "partial", "full" }; | ||
110 | |||
111 | memset(&ci, 0, sizeof(ci)); | ||
112 | |||
113 | cca_get_info(AP_QID_CARD(zq->queue->qid), | ||
114 | AP_QID_QUEUE(zq->queue->qid), | ||
115 | &ci, zq->online); | ||
116 | |||
117 | if (ci.new_mk_state >= '1' && ci.new_mk_state <= '3') | ||
118 | n = snprintf(buf, PAGE_SIZE, "AES NEW: %s 0x%016llx\n", | ||
119 | new_state[ci.new_mk_state - '1'], ci.new_mkvp); | ||
120 | else | ||
121 | n = snprintf(buf, PAGE_SIZE, "AES NEW: - -\n"); | ||
122 | |||
123 | if (ci.cur_mk_state >= '1' && ci.cur_mk_state <= '2') | ||
124 | n += snprintf(buf + n, PAGE_SIZE - n, "AES CUR: %s 0x%016llx\n", | ||
125 | cao_state[ci.cur_mk_state - '1'], ci.cur_mkvp); | ||
126 | else | ||
127 | n += snprintf(buf + n, PAGE_SIZE - n, "AES CUR: - -\n"); | ||
128 | |||
129 | if (ci.old_mk_state >= '1' && ci.old_mk_state <= '2') | ||
130 | n += snprintf(buf + n, PAGE_SIZE - n, "AES OLD: %s 0x%016llx\n", | ||
131 | cao_state[ci.old_mk_state - '1'], ci.old_mkvp); | ||
132 | else | ||
133 | n += snprintf(buf + n, PAGE_SIZE - n, "AES OLD: - -\n"); | ||
134 | |||
135 | return n; | ||
136 | } | ||
137 | static DEVICE_ATTR_RO(mkvps); | ||
138 | |||
139 | static struct attribute *cca_queue_attrs[] = { | ||
140 | &dev_attr_mkvps.attr, | ||
141 | NULL, | ||
142 | }; | ||
143 | |||
144 | static const struct attribute_group cca_queue_attr_group = { | ||
145 | .attrs = cca_queue_attrs, | ||
146 | }; | ||
147 | |||
68 | /** | 148 | /** |
69 | * Probe function for CEX4/CEX5/CEX6 card device. It always | 149 | * Probe function for CEX4/CEX5/CEX6 card device. It always |
70 | * accepts the AP device since the bus_match already checked | 150 | * accepts the AP device since the bus_match already checked |
@@ -194,8 +274,17 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev) | |||
194 | if (rc) { | 274 | if (rc) { |
195 | ac->private = NULL; | 275 | ac->private = NULL; |
196 | zcrypt_card_free(zc); | 276 | zcrypt_card_free(zc); |
277 | goto out; | ||
197 | } | 278 | } |
198 | 279 | ||
280 | if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) { | ||
281 | rc = sysfs_create_group(&ap_dev->device.kobj, | ||
282 | &cca_card_attr_group); | ||
283 | if (rc) | ||
284 | zcrypt_card_unregister(zc); | ||
285 | } | ||
286 | |||
287 | out: | ||
199 | return rc; | 288 | return rc; |
200 | } | 289 | } |
201 | 290 | ||
@@ -205,8 +294,11 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev) | |||
205 | */ | 294 | */ |
206 | static void zcrypt_cex4_card_remove(struct ap_device *ap_dev) | 295 | static void zcrypt_cex4_card_remove(struct ap_device *ap_dev) |
207 | { | 296 | { |
208 | struct zcrypt_card *zc = to_ap_card(&ap_dev->device)->private; | 297 | struct ap_card *ac = to_ap_card(&ap_dev->device); |
298 | struct zcrypt_card *zc = ac->private; | ||
209 | 299 | ||
300 | if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) | ||
301 | sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_group); | ||
210 | if (zc) | 302 | if (zc) |
211 | zcrypt_card_unregister(zc); | 303 | zcrypt_card_unregister(zc); |
212 | } | 304 | } |
@@ -251,6 +343,7 @@ static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev) | |||
251 | } else { | 343 | } else { |
252 | return -ENODEV; | 344 | return -ENODEV; |
253 | } | 345 | } |
346 | |||
254 | zq->queue = aq; | 347 | zq->queue = aq; |
255 | zq->online = 1; | 348 | zq->online = 1; |
256 | atomic_set(&zq->load, 0); | 349 | atomic_set(&zq->load, 0); |
@@ -261,8 +354,17 @@ static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev) | |||
261 | if (rc) { | 354 | if (rc) { |
262 | aq->private = NULL; | 355 | aq->private = NULL; |
263 | zcrypt_queue_free(zq); | 356 | zcrypt_queue_free(zq); |
357 | goto out; | ||
358 | } | ||
359 | |||
360 | if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) { | ||
361 | rc = sysfs_create_group(&ap_dev->device.kobj, | ||
362 | &cca_queue_attr_group); | ||
363 | if (rc) | ||
364 | zcrypt_queue_unregister(zq); | ||
264 | } | 365 | } |
265 | 366 | ||
367 | out: | ||
266 | return rc; | 368 | return rc; |
267 | } | 369 | } |
268 | 370 | ||
@@ -275,6 +377,8 @@ static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev) | |||
275 | struct ap_queue *aq = to_ap_queue(&ap_dev->device); | 377 | struct ap_queue *aq = to_ap_queue(&ap_dev->device); |
276 | struct zcrypt_queue *zq = aq->private; | 378 | struct zcrypt_queue *zq = aq->private; |
277 | 379 | ||
380 | if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) | ||
381 | sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_group); | ||
278 | if (zq) | 382 | if (zq) |
279 | zcrypt_queue_unregister(zq); | 383 | zcrypt_queue_unregister(zq); |
280 | } | 384 | } |