diff options
82 files changed, 1640 insertions, 1030 deletions
diff --git a/Documentation/s390/Debugging390.txt b/Documentation/s390/Debugging390.txt index 08911b5c6b0e..3df8babcdc41 100644 --- a/Documentation/s390/Debugging390.txt +++ b/Documentation/s390/Debugging390.txt | |||
@@ -1,14 +1,14 @@ | |||
1 | 1 | ||
2 | Debugging on Linux for s/390 & z/Architecture | 2 | Debugging on Linux for s/390 & z/Architecture |
3 | by | 3 | by |
4 | Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) | 4 | Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) |
5 | Copyright (C) 2000-2001 IBM Deutschland Entwicklung GmbH, IBM Corporation | 5 | Copyright (C) 2000-2001 IBM Deutschland Entwicklung GmbH, IBM Corporation |
6 | Best viewed with fixed width fonts | 6 | Best viewed with fixed width fonts |
7 | 7 | ||
8 | Overview of Document: | 8 | Overview of Document: |
9 | ===================== | 9 | ===================== |
10 | This document is intended to give a good overview of how to debug | 10 | This document is intended to give a good overview of how to debug Linux for |
11 | Linux for s/390 & z/Architecture. It isn't intended as a complete reference & not a | 11 | s/390 and z/Architecture. It is not intended as a complete reference and not a |
12 | tutorial on the fundamentals of C & assembly. It doesn't go into | 12 | tutorial on the fundamentals of C & assembly. It doesn't go into |
13 | 390 IO in any detail. It is intended to complement the documents in the | 13 | 390 IO in any detail. It is intended to complement the documents in the |
14 | reference section below & any other worthwhile references you get. | 14 | reference section below & any other worthwhile references you get. |
@@ -35,7 +35,6 @@ Examining core dumps | |||
35 | ldd | 35 | ldd |
36 | Debugging modules | 36 | Debugging modules |
37 | The proc file system | 37 | The proc file system |
38 | Starting points for debugging scripting languages etc. | ||
39 | SysRq | 38 | SysRq |
40 | References | 39 | References |
41 | Special Thanks | 40 | Special Thanks |
@@ -44,18 +43,20 @@ Register Set | |||
44 | ============ | 43 | ============ |
45 | The current architectures have the following registers. | 44 | The current architectures have the following registers. |
46 | 45 | ||
47 | 16 General propose registers, 32 bit on s/390 64 bit on z/Architecture, r0-r15 or gpr0-gpr15 used for arithmetic & addressing. | 46 | 16 General propose registers, 32 bit on s/390 and 64 bit on z/Architecture, |
48 | 47 | r0-r15 (or gpr0-gpr15), used for arithmetic and addressing. | |
49 | 16 Control registers, 32 bit on s/390 64 bit on z/Architecture, ( cr0-cr15 kernel usage only ) used for memory management, | 48 | |
50 | interrupt control,debugging control etc. | 49 | 16 Control registers, 32 bit on s/390 and 64 bit on z/Architecture, cr0-cr15, |
51 | 50 | kernel usage only, used for memory management, interrupt control, debugging | |
52 | 16 Access registers ( ar0-ar15 ) 32 bit on s/390 & z/Architecture | 51 | control etc. |
53 | not used by normal programs but potentially could | 52 | |
54 | be used as temporary storage. Their main purpose is their 1 to 1 | 53 | 16 Access registers (ar0-ar15), 32 bit on both s/390 and z/Architecture, |
55 | association with general purpose registers and are used in | 54 | normally not used by normal programs but potentially could be used as |
56 | the kernel for copying data between kernel & user address spaces. | 55 | temporary storage. These registers have a 1:1 association with general |
57 | Access register 0 ( & access register 1 on z/Architecture ( needs 64 bit | 56 | purpose registers and are designed to be used in the so-called access |
58 | pointer ) ) is currently used by the pthread library as a pointer to | 57 | register mode to select different address spaces. |
58 | Access register 0 (and access register 1 on z/Architecture, which needs a | ||
59 | 64 bit pointer) is currently used by the pthread library as a pointer to | ||
59 | the current running threads private area. | 60 | the current running threads private area. |
60 | 61 | ||
61 | 16 64 bit floating point registers (fp0-fp15 ) IEEE & HFP floating | 62 | 16 64 bit floating point registers (fp0-fp15 ) IEEE & HFP floating |
@@ -90,18 +91,19 @@ s/390 z/Architecture | |||
90 | 91 | ||
91 | 6 6 Input/Output interrupt Mask | 92 | 6 6 Input/Output interrupt Mask |
92 | 93 | ||
93 | 7 7 External interrupt Mask used primarily for interprocessor signalling & | 94 | 7 7 External interrupt Mask used primarily for interprocessor |
94 | clock interrupts. | 95 | signalling and clock interrupts. |
95 | 96 | ||
96 | 8-11 8-11 PSW Key used for complex memory protection mechanism not used under linux | 97 | 8-11 8-11 PSW Key used for complex memory protection mechanism |
98 | (not used under linux) | ||
97 | 99 | ||
98 | 12 12 1 on s/390 0 on z/Architecture | 100 | 12 12 1 on s/390 0 on z/Architecture |
99 | 101 | ||
100 | 13 13 Machine Check Mask 1=enable machine check interrupts | 102 | 13 13 Machine Check Mask 1=enable machine check interrupts |
101 | 103 | ||
102 | 14 14 Wait State set this to 1 to stop the processor except for interrupts & give | 104 | 14 14 Wait State. Set this to 1 to stop the processor except for |
103 | time to other LPARS used in CPU idle in the kernel to increase overall | 105 | interrupts and give time to other LPARS. Used in CPU idle in |
104 | usage of processor resources. | 106 | the kernel to increase overall usage of processor resources. |
105 | 107 | ||
106 | 15 15 Problem state ( if set to 1 certain instructions are disabled ) | 108 | 15 15 Problem state ( if set to 1 certain instructions are disabled ) |
107 | all linux user programs run with this bit 1 | 109 | all linux user programs run with this bit 1 |
@@ -165,21 +167,23 @@ s/390 z/Architecture | |||
165 | when loading the address with LPSWE otherwise a | 167 | when loading the address with LPSWE otherwise a |
166 | specification exception occurs, LPSW is fully backward | 168 | specification exception occurs, LPSW is fully backward |
167 | compatible. | 169 | compatible. |
168 | 170 | ||
169 | 171 | ||
170 | Prefix Page(s) | 172 | Prefix Page(s) |
171 | -------------- | 173 | -------------- |
172 | This per cpu memory area is too intimately tied to the processor not to mention. | 174 | This per cpu memory area is too intimately tied to the processor not to mention. |
173 | It exists between the real addresses 0-4096 on s/390 & 0-8192 z/Architecture & is exchanged | 175 | It exists between the real addresses 0-4096 on s/390 and between 0-8192 on |
174 | with a 1 page on s/390 or 2 pages on z/Architecture in absolute storage by the set | 176 | z/Architecture and is exchanged with one page on s/390 or two pages on |
175 | prefix instruction in linux'es startup. | 177 | z/Architecture in absolute storage by the set prefix instruction during Linux |
176 | This page is mapped to a different prefix for each processor in an SMP configuration | 178 | startup. |
177 | ( assuming the os designer is sane of course :-) ). | 179 | This page is mapped to a different prefix for each processor in an SMP |
178 | Bytes 0-512 ( 200 hex ) on s/390 & 0-512,4096-4544,4604-5119 currently on z/Architecture | 180 | configuration (assuming the OS designer is sane of course). |
179 | are used by the processor itself for holding such information as exception indications & | 181 | Bytes 0-512 (200 hex) on s/390 and 0-512, 4096-4544, 4604-5119 currently on |
180 | entry points for exceptions. | 182 | z/Architecture are used by the processor itself for holding such information |
181 | Bytes after 0xc00 hex are used by linux for per processor globals on s/390 & z/Architecture | 183 | as exception indications and entry points for exceptions. |
182 | ( there is a gap on z/Architecture too currently between 0xc00 & 1000 which linux uses ). | 184 | Bytes after 0xc00 hex are used by linux for per processor globals on s/390 and |
185 | z/Architecture (there is a gap on z/Architecture currently between 0xc00 and | ||
186 | 0x1000, too, which is used by Linux). | ||
183 | The closest thing to this on traditional architectures is the interrupt | 187 | The closest thing to this on traditional architectures is the interrupt |
184 | vector table. This is a good thing & does simplify some of the kernel coding | 188 | vector table. This is a good thing & does simplify some of the kernel coding |
185 | however it means that we now cannot catch stray NULL pointers in the | 189 | however it means that we now cannot catch stray NULL pointers in the |
@@ -192,26 +196,26 @@ Address Spaces on Intel Linux | |||
192 | 196 | ||
193 | The traditional Intel Linux is approximately mapped as follows forgive | 197 | The traditional Intel Linux is approximately mapped as follows forgive |
194 | the ascii art. | 198 | the ascii art. |
195 | 0xFFFFFFFF 4GB Himem ***************** | 199 | 0xFFFFFFFF 4GB Himem ***************** |
196 | * * | 200 | * * |
197 | * Kernel Space * | 201 | * Kernel Space * |
198 | * * | 202 | * * |
199 | ***************** **************** | 203 | ***************** **************** |
200 | User Space Himem (typically 0xC0000000 3GB )* User Stack * * * | 204 | User Space Himem * User Stack * * * |
201 | ***************** * * | 205 | (typically 0xC0000000 3GB ) ***************** * * |
202 | * Shared Libs * * Next Process * | 206 | * Shared Libs * * Next Process * |
203 | ***************** * to * | 207 | ***************** * to * |
204 | * * <== * Run * <== | 208 | * * <== * Run * <== |
205 | * User Program * * * | 209 | * User Program * * * |
206 | * Data BSS * * * | 210 | * Data BSS * * * |
207 | * Text * * * | 211 | * Text * * * |
208 | * Sections * * * | 212 | * Sections * * * |
209 | 0x00000000 ***************** **************** | 213 | 0x00000000 ***************** **************** |
210 | 214 | ||
211 | Now it is easy to see that on Intel it is quite easy to recognise a kernel address | 215 | Now it is easy to see that on Intel it is quite easy to recognise a kernel |
212 | as being one greater than user space himem ( in this case 0xC0000000). | 216 | address as being one greater than user space himem (in this case 0xC0000000), |
213 | & addresses of less than this are the ones in the current running program on this | 217 | and addresses of less than this are the ones in the current running program on |
214 | processor ( if an smp box ). | 218 | this processor (if an smp box). |
215 | If using the virtual machine ( VM ) as a debugger it is quite difficult to | 219 | If using the virtual machine ( VM ) as a debugger it is quite difficult to |
216 | know which user process is running as the address space you are looking at | 220 | know which user process is running as the address space you are looking at |
217 | could be from any process in the run queue. | 221 | could be from any process in the run queue. |
@@ -247,8 +251,8 @@ Our addressing scheme is basically as follows: | |||
247 | Himem 0x7fffffff 2GB on s/390 ***************** **************** | 251 | Himem 0x7fffffff 2GB on s/390 ***************** **************** |
248 | currently 0x3ffffffffff (2^42)-1 * User Stack * * * | 252 | currently 0x3ffffffffff (2^42)-1 * User Stack * * * |
249 | on z/Architecture. ***************** * * | 253 | on z/Architecture. ***************** * * |
250 | * Shared Libs * * * | 254 | * Shared Libs * * * |
251 | ***************** * * | 255 | ***************** * * |
252 | * * * Kernel * | 256 | * * * Kernel * |
253 | * User Program * * * | 257 | * User Program * * * |
254 | * Data BSS * * * | 258 | * Data BSS * * * |
@@ -301,10 +305,10 @@ Virtual Addresses on s/390 & z/Architecture | |||
301 | =========================================== | 305 | =========================================== |
302 | 306 | ||
303 | A virtual address on s/390 is made up of 3 parts | 307 | A virtual address on s/390 is made up of 3 parts |
304 | The SX ( segment index, roughly corresponding to the PGD & PMD in linux terminology ) | 308 | The SX (segment index, roughly corresponding to the PGD & PMD in Linux |
305 | being bits 1-11. | 309 | terminology) being bits 1-11. |
306 | The PX ( page index, corresponding to the page table entry (pte) in linux terminology ) | 310 | The PX (page index, corresponding to the page table entry (pte) in Linux |
307 | being bits 12-19. | 311 | terminology) being bits 12-19. |
308 | The remaining bits BX (the byte index are the offset in the page ) | 312 | The remaining bits BX (the byte index are the offset in the page ) |
309 | i.e. bits 20 to 31. | 313 | i.e. bits 20 to 31. |
310 | 314 | ||
@@ -368,9 +372,9 @@ each processor as follows. | |||
368 | * ( 8K ) * | 372 | * ( 8K ) * |
369 | 16K aligned ************************ | 373 | 16K aligned ************************ |
370 | 374 | ||
371 | What this means is that we don't need to dedicate any register or global variable | 375 | What this means is that we don't need to dedicate any register or global |
372 | to point to the current running process & can retrieve it with the following | 376 | variable to point to the current running process & can retrieve it with the |
373 | very simple construct for s/390 & one very similar for z/Architecture. | 377 | following very simple construct for s/390 & one very similar for z/Architecture. |
374 | 378 | ||
375 | static inline struct task_struct * get_current(void) | 379 | static inline struct task_struct * get_current(void) |
376 | { | 380 | { |
@@ -403,8 +407,8 @@ Note: To follow stackframes requires a knowledge of C or Pascal & | |||
403 | limited knowledge of one assembly language. | 407 | limited knowledge of one assembly language. |
404 | 408 | ||
405 | It should be noted that there are some differences between the | 409 | It should be noted that there are some differences between the |
406 | s/390 & z/Architecture stack layouts as the z/Architecture stack layout didn't have | 410 | s/390 and z/Architecture stack layouts as the z/Architecture stack layout |
407 | to maintain compatibility with older linkage formats. | 411 | didn't have to maintain compatibility with older linkage formats. |
408 | 412 | ||
409 | Glossary: | 413 | Glossary: |
410 | --------- | 414 | --------- |
@@ -440,7 +444,7 @@ The code generated by the compiler to return to the caller. | |||
440 | 444 | ||
441 | frameless-function | 445 | frameless-function |
442 | A frameless function in Linux for s390 & z/Architecture is one which doesn't | 446 | A frameless function in Linux for s390 & z/Architecture is one which doesn't |
443 | need more than the register save area ( 96 bytes on s/390, 160 on z/Architecture ) | 447 | need more than the register save area (96 bytes on s/390, 160 on z/Architecture) |
444 | given to it by the caller. | 448 | given to it by the caller. |
445 | A frameless function never: | 449 | A frameless function never: |
446 | 1) Sets up a back chain. | 450 | 1) Sets up a back chain. |
@@ -588,8 +592,8 @@ A sample program with comments. | |||
588 | 592 | ||
589 | Comments on the function test | 593 | Comments on the function test |
590 | ----------------------------- | 594 | ----------------------------- |
591 | 1) It didn't need to set up a pointer to the constant pool gpr13 as it isn't used | 595 | 1) It didn't need to set up a pointer to the constant pool gpr13 as it is not |
592 | ( :-( ). | 596 | used ( :-( ). |
593 | 2) This is a frameless function & no stack is bought. | 597 | 2) This is a frameless function & no stack is bought. |
594 | 3) The compiler was clever enough to recognise that it could return the | 598 | 3) The compiler was clever enough to recognise that it could return the |
595 | value in r2 as well as use it for the passed in parameter ( :-) ). | 599 | value in r2 as well as use it for the passed in parameter ( :-) ). |
@@ -743,35 +747,34 @@ Debugging under VM | |||
743 | Notes | 747 | Notes |
744 | ----- | 748 | ----- |
745 | Addresses & values in the VM debugger are always hex never decimal | 749 | Addresses & values in the VM debugger are always hex never decimal |
746 | Address ranges are of the format <HexValue1>-<HexValue2> or <HexValue1>.<HexValue2> | 750 | Address ranges are of the format <HexValue1>-<HexValue2> or |
747 | e.g. The address range 0x2000 to 0x3000 can be described as 2000-3000 or 2000.1000 | 751 | <HexValue1>.<HexValue2> |
752 | For example, the address range 0x2000 to 0x3000 can be described as 2000-3000 | ||
753 | or 2000.1000 | ||
748 | 754 | ||
749 | The VM Debugger is case insensitive. | 755 | The VM Debugger is case insensitive. |
750 | 756 | ||
751 | VM's strengths are usually other debuggers weaknesses you can get at any resource | 757 | VM's strengths are usually other debuggers weaknesses you can get at any |
752 | no matter how sensitive e.g. memory management resources,change address translation | 758 | resource no matter how sensitive e.g. memory management resources, change |
753 | in the PSW. For kernel hacking you will reap dividends if you get good at it. | 759 | address translation in the PSW. For kernel hacking you will reap dividends if |
754 | 760 | you get good at it. | |
755 | The VM Debugger displays operators but not operands, probably because some | 761 | |
756 | of it was written when memory was expensive & the programmer was probably proud that | 762 | The VM Debugger displays operators but not operands, and also the debugger |
757 | it fitted into 2k of memory & the programmers & didn't want to shock hardcore VM'ers by | 763 | displays useful information on the same line as the author of the code probably |
758 | changing the interface :-), also the debugger displays useful information on the same line & | 764 | felt that it was a good idea not to go over the 80 columns on the screen. |
759 | the author of the code probably felt that it was a good idea not to go over | 765 | This isn't as unintuitive as it may seem as the s/390 instructions are easy to |
760 | the 80 columns on the screen. | 766 | decode mentally and you can make a good guess at a lot of them as all the |
761 | 767 | operands are nibble (half byte aligned). | |
762 | As some of you are probably in a panic now this isn't as unintuitive as it may seem | 768 | So if you have an objdump listing by hand, it is quite easy to follow, and if |
763 | as the 390 instructions are easy to decode mentally & you can make a good guess at a lot | 769 | you don't have an objdump listing keep a copy of the s/390 Reference Summary |
764 | of them as all the operands are nibble ( half byte aligned ) & if you have an objdump listing | 770 | or alternatively the s/390 principles of operation next to you. |
765 | also it is quite easy to follow, if you don't have an objdump listing keep a copy of | ||
766 | the s/390 Reference Summary & look at between pages 2 & 7 or alternatively the | ||
767 | s/390 principles of operation. | ||
768 | e.g. even I can guess that | 771 | e.g. even I can guess that |
769 | 0001AFF8' LR 180F CC 0 | 772 | 0001AFF8' LR 180F CC 0 |
770 | is a ( load register ) lr r0,r15 | 773 | is a ( load register ) lr r0,r15 |
771 | 774 | ||
772 | Also it is very easy to tell the length of a 390 instruction from the 2 most significant | 775 | Also it is very easy to tell the length of a 390 instruction from the 2 most |
773 | bits in the instruction ( not that this info is really useful except if you are trying to | 776 | significant bits in the instruction (not that this info is really useful except |
774 | make sense of a hexdump of code ). | 777 | if you are trying to make sense of a hexdump of code). |
775 | Here is a table | 778 | Here is a table |
776 | Bits Instruction Length | 779 | Bits Instruction Length |
777 | ------------------------------------------ | 780 | ------------------------------------------ |
@@ -780,9 +783,6 @@ Bits Instruction Length | |||
780 | 10 4 Bytes | 783 | 10 4 Bytes |
781 | 11 6 Bytes | 784 | 11 6 Bytes |
782 | 785 | ||
783 | |||
784 | |||
785 | |||
786 | The debugger also displays other useful info on the same line such as the | 786 | The debugger also displays other useful info on the same line such as the |
787 | addresses being operated on destination addresses of branches & condition codes. | 787 | addresses being operated on destination addresses of branches & condition codes. |
788 | e.g. | 788 | e.g. |
@@ -853,8 +853,8 @@ Displaying & modifying Registers | |||
853 | -------------------------------- | 853 | -------------------------------- |
854 | D G will display all the gprs | 854 | D G will display all the gprs |
855 | Adding a extra G to all the commands is necessary to access the full 64 bit | 855 | Adding a extra G to all the commands is necessary to access the full 64 bit |
856 | content in VM on z/Architecture obviously this isn't required for access registers | 856 | content in VM on z/Architecture. Obviously this isn't required for access |
857 | as these are still 32 bit. | 857 | registers as these are still 32 bit. |
858 | e.g. DGG instead of DG | 858 | e.g. DGG instead of DG |
859 | D X will display all the control registers | 859 | D X will display all the control registers |
860 | D AR will display all the access registers | 860 | D AR will display all the access registers |
@@ -870,10 +870,11 @@ Displaying Memory | |||
870 | ----------------- | 870 | ----------------- |
871 | To display memory mapped using the current PSW's mapping try | 871 | To display memory mapped using the current PSW's mapping try |
872 | D <range> | 872 | D <range> |
873 | To make VM display a message each time it hits a particular address & continue try | 873 | To make VM display a message each time it hits a particular address and |
874 | continue try | ||
874 | D I<range> will disassemble/display a range of instructions. | 875 | D I<range> will disassemble/display a range of instructions. |
875 | ST addr 32 bit word will store a 32 bit aligned address | 876 | ST addr 32 bit word will store a 32 bit aligned address |
876 | D T<range> will display the EBCDIC in an address ( if you are that way inclined ) | 877 | D T<range> will display the EBCDIC in an address (if you are that way inclined) |
877 | D R<range> will display real addresses ( without DAT ) but with prefixing. | 878 | D R<range> will display real addresses ( without DAT ) but with prefixing. |
878 | There are other complex options to display if you need to get at say home space | 879 | There are other complex options to display if you need to get at say home space |
879 | but are in primary space the easiest thing to do is to temporarily | 880 | but are in primary space the easiest thing to do is to temporarily |
@@ -884,8 +885,8 @@ restore it. | |||
884 | 885 | ||
885 | Hints | 886 | Hints |
886 | ----- | 887 | ----- |
887 | If you want to issue a debugger command without halting your virtual machine with the | 888 | If you want to issue a debugger command without halting your virtual machine |
888 | PA1 key try prefixing the command with #CP e.g. | 889 | with the PA1 key try prefixing the command with #CP e.g. |
889 | #cp tr i pswa 2000 | 890 | #cp tr i pswa 2000 |
890 | also suffixing most debugger commands with RUN will cause them not | 891 | also suffixing most debugger commands with RUN will cause them not |
891 | to stop just display the mnemonic at the current instruction on the console. | 892 | to stop just display the mnemonic at the current instruction on the console. |
@@ -903,9 +904,10 @@ This sends a message to your own console each time do_signal is entered. | |||
903 | script with breakpoints on every kernel procedure, this isn't a good idea | 904 | script with breakpoints on every kernel procedure, this isn't a good idea |
904 | because there are thousands of these routines & VM can only set 255 breakpoints | 905 | because there are thousands of these routines & VM can only set 255 breakpoints |
905 | at a time so you nearly had to spend as long pruning the file down as you would | 906 | at a time so you nearly had to spend as long pruning the file down as you would |
906 | entering the msg's by hand ),however, the trick might be useful for a single object file. | 907 | entering the msgs by hand), however, the trick might be useful for a single |
907 | On linux'es 3270 emulator x3270 there is a very useful option under the file ment | 908 | object file. In the 3270 terminal emulator x3270 there is a very useful option |
908 | Save Screens In File this is very good of keeping a copy of traces. | 909 | in the file menu called "Save Screen In File" - this is very good for keeping a |
910 | copy of traces. | ||
909 | 911 | ||
910 | From CMS help <command name> will give you online help on a particular command. | 912 | From CMS help <command name> will give you online help on a particular command. |
911 | e.g. | 913 | e.g. |
@@ -920,7 +922,8 @@ SET PF9 IMM B | |||
920 | This does a single step in VM on pressing F8. | 922 | This does a single step in VM on pressing F8. |
921 | SET PF10 ^ | 923 | SET PF10 ^ |
922 | This sets up the ^ key. | 924 | This sets up the ^ key. |
923 | which can be used for ^c (ctrl-c),^z (ctrl-z) which can't be typed directly into some 3270 consoles. | 925 | which can be used for ^c (ctrl-c),^z (ctrl-z) which can't be typed directly |
926 | into some 3270 consoles. | ||
924 | SET PF11 ^- | 927 | SET PF11 ^- |
925 | This types the starting keystrokes for a sysrq see SysRq below. | 928 | This types the starting keystrokes for a sysrq see SysRq below. |
926 | SET PF12 RETRIEVE | 929 | SET PF12 RETRIEVE |
@@ -1014,8 +1017,8 @@ Tracing Program Exceptions | |||
1014 | -------------------------- | 1017 | -------------------------- |
1015 | If you get a crash which says something like | 1018 | If you get a crash which says something like |
1016 | illegal operation or specification exception followed by a register dump | 1019 | illegal operation or specification exception followed by a register dump |
1017 | You can restart linux & trace these using the tr prog <range or value> trace option. | 1020 | You can restart linux & trace these using the tr prog <range or value> trace |
1018 | 1021 | option. | |
1019 | 1022 | ||
1020 | 1023 | ||
1021 | The most common ones you will normally be tracing for is | 1024 | The most common ones you will normally be tracing for is |
@@ -1057,9 +1060,10 @@ TR GOTO INITIAL | |||
1057 | 1060 | ||
1058 | Tracing linux syscalls under VM | 1061 | Tracing linux syscalls under VM |
1059 | ------------------------------- | 1062 | ------------------------------- |
1060 | Syscalls are implemented on Linux for S390 by the Supervisor call instruction (SVC) there 256 | 1063 | Syscalls are implemented on Linux for S390 by the Supervisor call instruction |
1061 | possibilities of these as the instruction is made up of a 0xA opcode & the second byte being | 1064 | (SVC). There 256 possibilities of these as the instruction is made up of a 0xA |
1062 | the syscall number. They are traced using the simple command. | 1065 | opcode and the second byte being the syscall number. They are traced using the |
1066 | simple command: | ||
1063 | TR SVC <Optional value or range> | 1067 | TR SVC <Optional value or range> |
1064 | the syscalls are defined in linux/arch/s390/include/asm/unistd.h | 1068 | the syscalls are defined in linux/arch/s390/include/asm/unistd.h |
1065 | e.g. to trace all file opens just do | 1069 | e.g. to trace all file opens just do |
@@ -1070,12 +1074,12 @@ SMP Specific commands | |||
1070 | --------------------- | 1074 | --------------------- |
1071 | To find out how many cpus you have | 1075 | To find out how many cpus you have |
1072 | Q CPUS displays all the CPU's available to your virtual machine | 1076 | Q CPUS displays all the CPU's available to your virtual machine |
1073 | To find the cpu that the current cpu VM debugger commands are being directed at do | 1077 | To find the cpu that the current cpu VM debugger commands are being directed at |
1074 | Q CPU to change the current cpu VM debugger commands are being directed at do | 1078 | do Q CPU to change the current cpu VM debugger commands are being directed at do |
1075 | CPU <desired cpu no> | 1079 | CPU <desired cpu no> |
1076 | 1080 | ||
1077 | On a SMP guest issue a command to all CPUs try prefixing the command with cpu all. | 1081 | On a SMP guest issue a command to all CPUs try prefixing the command with cpu |
1078 | To issue a command to a particular cpu try cpu <cpu number> e.g. | 1082 | all. To issue a command to a particular cpu try cpu <cpu number> e.g. |
1079 | CPU 01 TR I R 2000.3000 | 1083 | CPU 01 TR I R 2000.3000 |
1080 | If you are running on a guest with several cpus & you have a IO related problem | 1084 | If you are running on a guest with several cpus & you have a IO related problem |
1081 | & cannot follow the flow of code but you know it isn't smp related. | 1085 | & cannot follow the flow of code but you know it isn't smp related. |
@@ -1101,10 +1105,10 @@ D TX0.100 | |||
1101 | 1105 | ||
1102 | Alternatively | 1106 | Alternatively |
1103 | ============= | 1107 | ============= |
1104 | Under older VM debuggers ( I love EBDIC too ) you can use this little program I wrote which | 1108 | Under older VM debuggers (I love EBDIC too) you can use following little |
1105 | will convert a command line of hex digits to ascii text which can be compiled under linux & | 1109 | program which converts a command line of hex digits to ascii text. It can be |
1106 | you can copy the hex digits from your x3270 terminal to your xterm if you are debugging | 1110 | compiled under linux and you can copy the hex digits from your x3270 terminal |
1107 | from a linuxbox. | 1111 | to your xterm if you are debugging from a linuxbox. |
1108 | 1112 | ||
1109 | This is quite useful when looking at a parameter passed in as a text string | 1113 | This is quite useful when looking at a parameter passed in as a text string |
1110 | under VM ( unless you are good at decoding ASCII in your head ). | 1114 | under VM ( unless you are good at decoding ASCII in your head ). |
@@ -1114,14 +1118,14 @@ TR SVC 5 | |||
1114 | We have stopped at a breakpoint | 1118 | We have stopped at a breakpoint |
1115 | 000151B0' SVC 0A05 -> 0001909A' CC 0 | 1119 | 000151B0' SVC 0A05 -> 0001909A' CC 0 |
1116 | 1120 | ||
1117 | D 20.8 to check the SVC old psw in the prefix area & see was it from userspace | 1121 | D 20.8 to check the SVC old psw in the prefix area and see was it from userspace |
1118 | ( for the layout of the prefix area consult P18 of the s/390 390 Reference Summary | 1122 | (for the layout of the prefix area consult the "Fixed Storage Locations" |
1119 | if you have it available ). | 1123 | chapter of the s/390 Reference Summary if you have it available). |
1120 | V00000020 070C2000 800151B2 | 1124 | V00000020 070C2000 800151B2 |
1121 | The problem state bit wasn't set & it's also too early in the boot sequence | 1125 | The problem state bit wasn't set & it's also too early in the boot sequence |
1122 | for it to be a userspace SVC if it was we would have to temporarily switch the | 1126 | for it to be a userspace SVC if it was we would have to temporarily switch the |
1123 | psw to user space addressing so we could get at the first parameter of the open in | 1127 | psw to user space addressing so we could get at the first parameter of the open |
1124 | gpr2. | 1128 | in gpr2. |
1125 | Next do a | 1129 | Next do a |
1126 | D G2 | 1130 | D G2 |
1127 | GPR 2 = 00014CB4 | 1131 | GPR 2 = 00014CB4 |
@@ -1208,9 +1212,9 @@ Here are the tricks I use 9 out of 10 times it works pretty well, | |||
1208 | 1212 | ||
1209 | When your backchain reaches a dead end | 1213 | When your backchain reaches a dead end |
1210 | -------------------------------------- | 1214 | -------------------------------------- |
1211 | This can happen when an exception happens in the kernel & the kernel is entered twice | 1215 | This can happen when an exception happens in the kernel and the kernel is |
1212 | if you reach the NULL pointer at the end of the back chain you should be | 1216 | entered twice. If you reach the NULL pointer at the end of the back chain you |
1213 | able to sniff further back if you follow the following tricks. | 1217 | should be able to sniff further back if you follow the following tricks. |
1214 | 1) A kernel address should be easy to recognise since it is in | 1218 | 1) A kernel address should be easy to recognise since it is in |
1215 | primary space & the problem state bit isn't set & also | 1219 | primary space & the problem state bit isn't set & also |
1216 | The Hi bit of the address is set. | 1220 | The Hi bit of the address is set. |
@@ -1260,8 +1264,8 @@ V000FFFD0 00010400 80010802 8001085A 000FFFA0 | |||
1260 | 1264 | ||
1261 | our 3rd return address is 8001085A | 1265 | our 3rd return address is 8001085A |
1262 | 1266 | ||
1263 | as the 04B52002 looks suspiciously like rubbish it is fair to assume that the kernel entry routines | 1267 | as the 04B52002 looks suspiciously like rubbish it is fair to assume that the |
1264 | for the sake of optimisation don't set up a backchain. | 1268 | kernel entry routines for the sake of optimisation don't set up a backchain. |
1265 | 1269 | ||
1266 | now look at System.map to see if the addresses make any sense. | 1270 | now look at System.map to see if the addresses make any sense. |
1267 | 1271 | ||
@@ -1289,67 +1293,75 @@ Congrats you've done your first backchain. | |||
1289 | s/390 & z/Architecture IO Overview | 1293 | s/390 & z/Architecture IO Overview |
1290 | ================================== | 1294 | ================================== |
1291 | 1295 | ||
1292 | I am not going to give a course in 390 IO architecture as this would take me quite a | 1296 | I am not going to give a course in 390 IO architecture as this would take me |
1293 | while & I'm no expert. Instead I'll give a 390 IO architecture summary for Dummies if you have | 1297 | quite a while and I'm no expert. Instead I'll give a 390 IO architecture |
1294 | the s/390 principles of operation available read this instead. If nothing else you may find a few | 1298 | summary for Dummies. If you have the s/390 principles of operation available |
1295 | useful keywords in here & be able to use them on a web search engine like altavista to find | 1299 | read this instead. If nothing else you may find a few useful keywords in here |
1296 | more useful information. | 1300 | and be able to use them on a web search engine to find more useful information. |
1297 | 1301 | ||
1298 | Unlike other bus architectures modern 390 systems do their IO using mostly | 1302 | Unlike other bus architectures modern 390 systems do their IO using mostly |
1299 | fibre optics & devices such as tapes & disks can be shared between several mainframes, | 1303 | fibre optics and devices such as tapes and disks can be shared between several |
1300 | also S390 can support up to 65536 devices while a high end PC based system might be choking | 1304 | mainframes. Also S390 can support up to 65536 devices while a high end PC based |
1301 | with around 64. Here is some of the common IO terminology | 1305 | system might be choking with around 64. |
1302 | 1306 | ||
1303 | Subchannel: | 1307 | Here is some of the common IO terminology: |
1304 | This is the logical number most IO commands use to talk to an IO device there can be up to | ||
1305 | 0x10000 (65536) of these in a configuration typically there is a few hundred. Under VM | ||
1306 | for simplicity they are allocated contiguously, however on the native hardware they are not | ||
1307 | they typically stay consistent between boots provided no new hardware is inserted or removed. | ||
1308 | Under Linux for 390 we use these as IRQ's & also when issuing an IO command (CLEAR SUBCHANNEL, | ||
1309 | HALT SUBCHANNEL,MODIFY SUBCHANNEL,RESUME SUBCHANNEL,START SUBCHANNEL,STORE SUBCHANNEL & | ||
1310 | TEST SUBCHANNEL ) we use this as the ID of the device we wish to talk to, the most | ||
1311 | important of these instructions are START SUBCHANNEL ( to start IO ), TEST SUBCHANNEL ( to check | ||
1312 | whether the IO completed successfully ), & HALT SUBCHANNEL ( to kill IO ), a subchannel | ||
1313 | can have up to 8 channel paths to a device this offers redundancy if one is not available. | ||
1314 | 1308 | ||
1309 | Subchannel: | ||
1310 | This is the logical number most IO commands use to talk to an IO device. There | ||
1311 | can be up to 0x10000 (65536) of these in a configuration, typically there are a | ||
1312 | few hundred. Under VM for simplicity they are allocated contiguously, however | ||
1313 | on the native hardware they are not. They typically stay consistent between | ||
1314 | boots provided no new hardware is inserted or removed. | ||
1315 | Under Linux for s390 we use these as IRQ's and also when issuing an IO command | ||
1316 | (CLEAR SUBCHANNEL, HALT SUBCHANNEL, MODIFY SUBCHANNEL, RESUME SUBCHANNEL, | ||
1317 | START SUBCHANNEL, STORE SUBCHANNEL and TEST SUBCHANNEL). We use this as the ID | ||
1318 | of the device we wish to talk to. The most important of these instructions are | ||
1319 | START SUBCHANNEL (to start IO), TEST SUBCHANNEL (to check whether the IO | ||
1320 | completed successfully) and HALT SUBCHANNEL (to kill IO). A subchannel can have | ||
1321 | up to 8 channel paths to a device, this offers redundancy if one is not | ||
1322 | available. | ||
1315 | 1323 | ||
1316 | Device Number: | 1324 | Device Number: |
1317 | This number remains static & Is closely tied to the hardware, there are 65536 of these | 1325 | This number remains static and is closely tied to the hardware. There are 65536 |
1318 | also they are made up of a CHPID ( Channel Path ID, the most significant 8 bits ) | 1326 | of these, made up of a CHPID (Channel Path ID, the most significant 8 bits) and |
1319 | & another lsb 8 bits. These remain static even if more devices are inserted or removed | 1327 | another lsb 8 bits. These remain static even if more devices are inserted or |
1320 | from the hardware, there is a 1 to 1 mapping between Subchannels & Device Numbers provided | 1328 | removed from the hardware. There is a 1 to 1 mapping between subchannels and |
1321 | devices aren't inserted or removed. | 1329 | device numbers, provided devices aren't inserted or removed. |
1322 | 1330 | ||
1323 | Channel Control Words: | 1331 | Channel Control Words: |
1324 | CCWS are linked lists of instructions initially pointed to by an operation request block (ORB), | 1332 | CCWs are linked lists of instructions initially pointed to by an operation |
1325 | which is initially given to Start Subchannel (SSCH) command along with the subchannel number | 1333 | request block (ORB), which is initially given to Start Subchannel (SSCH) |
1326 | for the IO subsystem to process while the CPU continues executing normal code. | 1334 | command along with the subchannel number for the IO subsystem to process |
1327 | These come in two flavours, Format 0 ( 24 bit for backward ) | 1335 | while the CPU continues executing normal code. |
1328 | compatibility & Format 1 ( 31 bit ). These are typically used to issue read & write | 1336 | CCWs come in two flavours, Format 0 (24 bit for backward compatibility) and |
1329 | ( & many other instructions ) they consist of a length field & an absolute address field. | 1337 | Format 1 (31 bit). These are typically used to issue read and write (and many |
1330 | For each IO typically get 1 or 2 interrupts one for channel end ( primary status ) when the | 1338 | other) instructions. They consist of a length field and an absolute address |
1331 | channel is idle & the second for device end ( secondary status ) sometimes you get both | 1339 | field. |
1332 | concurrently, you check how the IO went on by issuing a TEST SUBCHANNEL at each interrupt, | 1340 | Each IO typically gets 1 or 2 interrupts, one for channel end (primary status) |
1333 | from which you receive an Interruption response block (IRB). If you get channel & device end | 1341 | when the channel is idle, and the second for device end (secondary status). |
1334 | status in the IRB without channel checks etc. your IO probably went okay. If you didn't you | 1342 | Sometimes you get both concurrently. You check how the IO went on by issuing a |
1335 | probably need a doctor to examine the IRB & extended status word etc. | 1343 | TEST SUBCHANNEL at each interrupt, from which you receive an Interruption |
1344 | response block (IRB). If you get channel and device end status in the IRB | ||
1345 | without channel checks etc. your IO probably went okay. If you didn't you | ||
1346 | probably need to examine the IRB, extended status word etc. | ||
1336 | If an error occurs, more sophisticated control units have a facility known as | 1347 | If an error occurs, more sophisticated control units have a facility known as |
1337 | concurrent sense this means that if an error occurs Extended sense information will | 1348 | concurrent sense. This means that if an error occurs Extended sense information |
1338 | be presented in the Extended status word in the IRB if not you have to issue a | 1349 | will be presented in the Extended status word in the IRB. If not you have to |
1339 | subsequent SENSE CCW command after the test subchannel. | 1350 | issue a subsequent SENSE CCW command after the test subchannel. |
1340 | 1351 | ||
1341 | 1352 | ||
1342 | TPI( Test pending interrupt) can also be used for polled IO but in multitasking multiprocessor | 1353 | TPI (Test pending interrupt) can also be used for polled IO, but in |
1343 | systems it isn't recommended except for checking special cases ( i.e. non looping checks for | 1354 | multitasking multiprocessor systems it isn't recommended except for |
1344 | pending IO etc. ). | 1355 | checking special cases (i.e. non looping checks for pending IO etc.). |
1345 | 1356 | ||
1346 | Store Subchannel & Modify Subchannel can be used to examine & modify operating characteristics | 1357 | Store Subchannel and Modify Subchannel can be used to examine and modify |
1347 | of a subchannel ( e.g. channel paths ). | 1358 | operating characteristics of a subchannel (e.g. channel paths). |
1348 | 1359 | ||
1349 | Other IO related Terms: | 1360 | Other IO related Terms: |
1350 | Sysplex: S390's Clustering Technology | 1361 | Sysplex: S390's Clustering Technology |
1351 | QDIO: S390's new high speed IO architecture to support devices such as gigabit ethernet, | 1362 | QDIO: S390's new high speed IO architecture to support devices such as gigabit |
1352 | this architecture is also designed to be forward compatible with up & coming 64 bit machines. | 1363 | ethernet, this architecture is also designed to be forward compatible with |
1364 | upcoming 64 bit machines. | ||
1353 | 1365 | ||
1354 | 1366 | ||
1355 | General Concepts | 1367 | General Concepts |
@@ -1406,37 +1418,40 @@ sometimes called Bus-and Tag & sometimes Original Equipment Manufacturers | |||
1406 | Interface (OEMI). | 1418 | Interface (OEMI). |
1407 | 1419 | ||
1408 | This byte wide Parallel channel path/bus has parity & data on the "Bus" cable | 1420 | This byte wide Parallel channel path/bus has parity & data on the "Bus" cable |
1409 | & control lines on the "Tag" cable. These can operate in byte multiplex mode for | 1421 | and control lines on the "Tag" cable. These can operate in byte multiplex mode |
1410 | sharing between several slow devices or burst mode & monopolize the channel for the | 1422 | for sharing between several slow devices or burst mode and monopolize the |
1411 | whole burst. Up to 256 devices can be addressed on one of these cables. These cables are | 1423 | channel for the whole burst. Up to 256 devices can be addressed on one of these |
1412 | about one inch in diameter. The maximum unextended length supported by these cables is | 1424 | cables. These cables are about one inch in diameter. The maximum unextended |
1413 | 125 Meters but this can be extended up to 2km with a fibre optic channel extended | 1425 | length supported by these cables is 125 Meters but this can be extended up to |
1414 | such as a 3044. The maximum burst speed supported is 4.5 megabytes per second however | 1426 | 2km with a fibre optic channel extended such as a 3044. The maximum burst speed |
1415 | some really old processors support only transfer rates of 3.0, 2.0 & 1.0 MB/sec. | 1427 | supported is 4.5 megabytes per second. However, some really old processors |
1428 | support only transfer rates of 3.0, 2.0 & 1.0 MB/sec. | ||
1416 | One of these paths can be daisy chained to up to 8 control units. | 1429 | One of these paths can be daisy chained to up to 8 control units. |
1417 | 1430 | ||
1418 | 1431 | ||
1419 | ESCON if fibre optic it is also called FICON | 1432 | ESCON if fibre optic it is also called FICON |
1420 | Was introduced by IBM in 1990. Has 2 fibre optic cables & uses either leds or lasers | 1433 | Was introduced by IBM in 1990. Has 2 fibre optic cables and uses either leds or |
1421 | for communication at a signaling rate of up to 200 megabits/sec. As 10bits are transferred | 1434 | lasers for communication at a signaling rate of up to 200 megabits/sec. As |
1422 | for every 8 bits info this drops to 160 megabits/sec & to 18.6 Megabytes/sec once | 1435 | 10bits are transferred for every 8 bits info this drops to 160 megabits/sec |
1423 | control info & CRC are added. ESCON only operates in burst mode. | 1436 | and to 18.6 Megabytes/sec once control info and CRC are added. ESCON only |
1437 | operates in burst mode. | ||
1424 | 1438 | ||
1425 | ESCONs typical max cable length is 3km for the led version & 20km for the laser version | 1439 | ESCONs typical max cable length is 3km for the led version and 20km for the |
1426 | known as XDF ( extended distance facility ). This can be further extended by using an | 1440 | laser version known as XDF (extended distance facility). This can be further |
1427 | ESCON director which triples the above mentioned ranges. Unlike Bus & Tag as ESCON is | 1441 | extended by using an ESCON director which triples the above mentioned ranges. |
1428 | serial it uses a packet switching architecture the standard Bus & Tag control protocol | 1442 | Unlike Bus & Tag as ESCON is serial it uses a packet switching architecture, |
1429 | is however present within the packets. Up to 256 devices can be attached to each control | 1443 | the standard Bus & Tag control protocol is however present within the packets. |
1430 | unit that uses one of these interfaces. | 1444 | Up to 256 devices can be attached to each control unit that uses one of these |
1445 | interfaces. | ||
1431 | 1446 | ||
1432 | Common 390 Devices include: | 1447 | Common 390 Devices include: |
1433 | Network adapters typically OSA2,3172's,2116's & OSA-E gigabit ethernet adapters, | 1448 | Network adapters typically OSA2,3172's,2116's & OSA-E gigabit ethernet adapters, |
1434 | Consoles 3270 & 3215 ( a teletype emulated under linux for a line mode console ). | 1449 | Consoles 3270 & 3215 (a teletype emulated under linux for a line mode console). |
1435 | DASD's direct access storage devices ( otherwise known as hard disks ). | 1450 | DASD's direct access storage devices ( otherwise known as hard disks ). |
1436 | Tape Drives. | 1451 | Tape Drives. |
1437 | CTC ( Channel to Channel Adapters ), | 1452 | CTC ( Channel to Channel Adapters ), |
1438 | ESCON or Parallel Cables used as a very high speed serial link | 1453 | ESCON or Parallel Cables used as a very high speed serial link |
1439 | between 2 machines. We use 2 cables under linux to do a bi-directional serial link. | 1454 | between 2 machines. |
1440 | 1455 | ||
1441 | 1456 | ||
1442 | Debugging IO on s/390 & z/Architecture under VM | 1457 | Debugging IO on s/390 & z/Architecture under VM |
@@ -1475,9 +1490,9 @@ or the halt subchannels | |||
1475 | or TR HSCH 7C08-7C09 | 1490 | or TR HSCH 7C08-7C09 |
1476 | MSCH's ,STSCH's I think you can guess the rest | 1491 | MSCH's ,STSCH's I think you can guess the rest |
1477 | 1492 | ||
1478 | Ingo's favourite trick is tracing all the IO's & CCWS & spooling them into the reader of another | 1493 | A good trick is tracing all the IO's and CCWS and spooling them into the reader |
1479 | VM guest so he can ftp the logfile back to his own machine.I'll do a small bit of this & give you | 1494 | of another VM guest so he can ftp the logfile back to his own machine. I'll do |
1480 | a look at the output. | 1495 | a small bit of this and give you a look at the output. |
1481 | 1496 | ||
1482 | 1) Spool stdout to VM reader | 1497 | 1) Spool stdout to VM reader |
1483 | SP PRT TO (another vm guest ) or * for the local vm guest | 1498 | SP PRT TO (another vm guest ) or * for the local vm guest |
@@ -1593,8 +1608,8 @@ undisplay : undo's display's | |||
1593 | 1608 | ||
1594 | info breakpoints: shows all current breakpoints | 1609 | info breakpoints: shows all current breakpoints |
1595 | 1610 | ||
1596 | info stack: shows stack back trace ( if this doesn't work too well, I'll show you the | 1611 | info stack: shows stack back trace (if this doesn't work too well, I'll show |
1597 | stacktrace by hand below ). | 1612 | you the stacktrace by hand below). |
1598 | 1613 | ||
1599 | info locals: displays local variables. | 1614 | info locals: displays local variables. |
1600 | 1615 | ||
@@ -1619,7 +1634,8 @@ next: like step except this will not step into subroutines | |||
1619 | stepi: steps a single machine code instruction. | 1634 | stepi: steps a single machine code instruction. |
1620 | e.g. stepi 100 | 1635 | e.g. stepi 100 |
1621 | 1636 | ||
1622 | nexti: steps a single machine code instruction but will not step into subroutines. | 1637 | nexti: steps a single machine code instruction but will not step into |
1638 | subroutines. | ||
1623 | 1639 | ||
1624 | finish: will run until exit of the current routine | 1640 | finish: will run until exit of the current routine |
1625 | 1641 | ||
@@ -1721,7 +1737,8 @@ e.g. | |||
1721 | outputs: | 1737 | outputs: |
1722 | $1 = 11 | 1738 | $1 = 11 |
1723 | 1739 | ||
1724 | You might now be thinking that the line above didn't work, something extra had to be done. | 1740 | You might now be thinking that the line above didn't work, something extra had |
1741 | to be done. | ||
1725 | (gdb) call fflush(stdout) | 1742 | (gdb) call fflush(stdout) |
1726 | hello world$2 = 0 | 1743 | hello world$2 = 0 |
1727 | As an aside the debugger also calls malloc & free under the hood | 1744 | As an aside the debugger also calls malloc & free under the hood |
@@ -1804,26 +1821,17 @@ man gdb or info gdb. | |||
1804 | core dumps | 1821 | core dumps |
1805 | ---------- | 1822 | ---------- |
1806 | What a core dump ?, | 1823 | What a core dump ?, |
1807 | A core dump is a file generated by the kernel ( if allowed ) which contains the registers, | 1824 | A core dump is a file generated by the kernel (if allowed) which contains the |
1808 | & all active pages of the program which has crashed. | 1825 | registers and all active pages of the program which has crashed. |
1809 | From this file gdb will allow you to look at the registers & stack trace & memory of the | 1826 | From this file gdb will allow you to look at the registers, stack trace and |
1810 | program as if it just crashed on your system, it is usually called core & created in the | 1827 | memory of the program as if it just crashed on your system. It is usually |
1811 | current working directory. | 1828 | called core and created in the current working directory. |
1812 | This is very useful in that a customer can mail a core dump to a technical support department | 1829 | This is very useful in that a customer can mail a core dump to a technical |
1813 | & the technical support department can reconstruct what happened. | 1830 | support department and the technical support department can reconstruct what |
1814 | Provided they have an identical copy of this program with debugging symbols compiled in & | 1831 | happened. Provided they have an identical copy of this program with debugging |
1815 | the source base of this build is available. | 1832 | symbols compiled in and the source base of this build is available. |
1816 | In short it is far more useful than something like a crash log could ever hope to be. | 1833 | In short it is far more useful than something like a crash log could ever hope |
1817 | 1834 | to be. | |
1818 | In theory all that is missing to restart a core dumped program is a kernel patch which | ||
1819 | will do the following. | ||
1820 | 1) Make a new kernel task structure | ||
1821 | 2) Reload all the dumped pages back into the kernel's memory management structures. | ||
1822 | 3) Do the required clock fixups | ||
1823 | 4) Get all files & network connections for the process back into an identical state ( really difficult ). | ||
1824 | 5) A few more difficult things I haven't thought of. | ||
1825 | |||
1826 | |||
1827 | 1835 | ||
1828 | Why have I never seen one ?. | 1836 | Why have I never seen one ?. |
1829 | Probably because you haven't used the command | 1837 | Probably because you haven't used the command |
@@ -1868,7 +1876,7 @@ Breakpoint 2 at 0x4d87a4: file top.c, line 2609. | |||
1868 | #3 0x5167e6 in readline_internal_char () at readline.c:454 | 1876 | #3 0x5167e6 in readline_internal_char () at readline.c:454 |
1869 | #4 0x5168ee in readline_internal_charloop () at readline.c:507 | 1877 | #4 0x5168ee in readline_internal_charloop () at readline.c:507 |
1870 | #5 0x51692c in readline_internal () at readline.c:521 | 1878 | #5 0x51692c in readline_internal () at readline.c:521 |
1871 | #6 0x5164fe in readline (prompt=0x7ffff810 "\177ÿøx\177ÿ÷Ø\177ÿøxÀ") | 1879 | #6 0x5164fe in readline (prompt=0x7ffff810) |
1872 | at readline.c:349 | 1880 | at readline.c:349 |
1873 | #7 0x4d7a8a in command_line_input (prompt=0x564420 "(gdb) ", repeat=1, | 1881 | #7 0x4d7a8a in command_line_input (prompt=0x564420 "(gdb) ", repeat=1, |
1874 | annotation_suffix=0x4d6b44 "prompt") at top.c:2091 | 1882 | annotation_suffix=0x4d6b44 "prompt") at top.c:2091 |
@@ -1929,8 +1937,8 @@ cat /proc/sys/net/ipv4/ip_forward | |||
1929 | On my machine now outputs | 1937 | On my machine now outputs |
1930 | 1 | 1938 | 1 |
1931 | IP forwarding is on. | 1939 | IP forwarding is on. |
1932 | There is a lot of useful info in here best found by going in & having a look around, | 1940 | There is a lot of useful info in here best found by going in and having a look |
1933 | so I'll take you through some entries I consider important. | 1941 | around, so I'll take you through some entries I consider important. |
1934 | 1942 | ||
1935 | All the processes running on the machine have their own entry defined by | 1943 | All the processes running on the machine have their own entry defined by |
1936 | /proc/<pid> | 1944 | /proc/<pid> |
@@ -2060,7 +2068,8 @@ if the device doesn't say up | |||
2060 | try | 2068 | try |
2061 | /etc/rc.d/init.d/network start | 2069 | /etc/rc.d/init.d/network start |
2062 | ( this starts the network stack & hopefully calls ifconfig tr0 up ). | 2070 | ( this starts the network stack & hopefully calls ifconfig tr0 up ). |
2063 | ifconfig looks at the output of /proc/net/dev & presents it in a more presentable form | 2071 | ifconfig looks at the output of /proc/net/dev and presents it in a more |
2072 | presentable form. | ||
2064 | Now ping the device from a machine in the same subnet. | 2073 | Now ping the device from a machine in the same subnet. |
2065 | if the RX packets count & TX packets counts don't increment you probably | 2074 | if the RX packets count & TX packets counts don't increment you probably |
2066 | have problems. | 2075 | have problems. |
@@ -2086,34 +2095,6 @@ of the device. | |||
2086 | See the manpage chandev.8 &type cat /proc/chandev for more info. | 2095 | See the manpage chandev.8 &type cat /proc/chandev for more info. |
2087 | 2096 | ||
2088 | 2097 | ||
2089 | |||
2090 | Starting points for debugging scripting languages etc. | ||
2091 | ====================================================== | ||
2092 | |||
2093 | bash/sh | ||
2094 | |||
2095 | bash -x <scriptname> | ||
2096 | e.g. bash -x /usr/bin/bashbug | ||
2097 | displays the following lines as it executes them. | ||
2098 | + MACHINE=i586 | ||
2099 | + OS=linux-gnu | ||
2100 | + CC=gcc | ||
2101 | + CFLAGS= -DPROGRAM='bash' -DHOSTTYPE='i586' -DOSTYPE='linux-gnu' -DMACHTYPE='i586-pc-linux-gnu' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./lib -O2 -pipe | ||
2102 | + RELEASE=2.01 | ||
2103 | + PATCHLEVEL=1 | ||
2104 | + RELSTATUS=release | ||
2105 | + MACHTYPE=i586-pc-linux-gnu | ||
2106 | |||
2107 | perl -d <scriptname> runs the perlscript in a fully interactive debugger | ||
2108 | <like gdb>. | ||
2109 | Type 'h' in the debugger for help. | ||
2110 | |||
2111 | for debugging java type | ||
2112 | jdb <filename> another fully interactive gdb style debugger. | ||
2113 | & type ? in the debugger for help. | ||
2114 | |||
2115 | |||
2116 | |||
2117 | SysRq | 2098 | SysRq |
2118 | ===== | 2099 | ===== |
2119 | This is now supported by linux for s/390 & z/Architecture. | 2100 | This is now supported by linux for s/390 & z/Architecture. |
@@ -726,10 +726,14 @@ KBUILD_CFLAGS += $(call cc-option, -femit-struct-debug-baseonly) \ | |||
726 | endif | 726 | endif |
727 | 727 | ||
728 | ifdef CONFIG_FUNCTION_TRACER | 728 | ifdef CONFIG_FUNCTION_TRACER |
729 | ifndef CC_FLAGS_FTRACE | ||
730 | CC_FLAGS_FTRACE := -pg | ||
731 | endif | ||
732 | export CC_FLAGS_FTRACE | ||
729 | ifdef CONFIG_HAVE_FENTRY | 733 | ifdef CONFIG_HAVE_FENTRY |
730 | CC_USING_FENTRY := $(call cc-option, -mfentry -DCC_USING_FENTRY) | 734 | CC_USING_FENTRY := $(call cc-option, -mfentry -DCC_USING_FENTRY) |
731 | endif | 735 | endif |
732 | KBUILD_CFLAGS += -pg $(CC_USING_FENTRY) | 736 | KBUILD_CFLAGS += $(CC_FLAGS_FTRACE) $(CC_USING_FENTRY) |
733 | KBUILD_AFLAGS += $(CC_USING_FENTRY) | 737 | KBUILD_AFLAGS += $(CC_USING_FENTRY) |
734 | ifdef CONFIG_DYNAMIC_FTRACE | 738 | ifdef CONFIG_DYNAMIC_FTRACE |
735 | ifdef CONFIG_HAVE_C_RECORDMCOUNT | 739 | ifdef CONFIG_HAVE_C_RECORDMCOUNT |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 68b68d755fdf..373cd5badf1c 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -66,6 +66,7 @@ config S390 | |||
66 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE | 66 | select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE |
67 | select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS | 67 | select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS |
68 | select ARCH_HAS_GCOV_PROFILE_ALL | 68 | select ARCH_HAS_GCOV_PROFILE_ALL |
69 | select ARCH_HAS_SG_CHAIN | ||
69 | select ARCH_HAVE_NMI_SAFE_CMPXCHG | 70 | select ARCH_HAVE_NMI_SAFE_CMPXCHG |
70 | select ARCH_INLINE_READ_LOCK | 71 | select ARCH_INLINE_READ_LOCK |
71 | select ARCH_INLINE_READ_LOCK_BH | 72 | select ARCH_INLINE_READ_LOCK_BH |
@@ -116,7 +117,6 @@ config S390 | |||
116 | select HAVE_BPF_JIT if 64BIT && PACK_STACK | 117 | select HAVE_BPF_JIT if 64BIT && PACK_STACK |
117 | select HAVE_CMPXCHG_DOUBLE | 118 | select HAVE_CMPXCHG_DOUBLE |
118 | select HAVE_CMPXCHG_LOCAL | 119 | select HAVE_CMPXCHG_LOCAL |
119 | select HAVE_C_RECORDMCOUNT | ||
120 | select HAVE_DEBUG_KMEMLEAK | 120 | select HAVE_DEBUG_KMEMLEAK |
121 | select HAVE_DYNAMIC_FTRACE if 64BIT | 121 | select HAVE_DYNAMIC_FTRACE if 64BIT |
122 | select HAVE_DYNAMIC_FTRACE_WITH_REGS if 64BIT | 122 | select HAVE_DYNAMIC_FTRACE_WITH_REGS if 64BIT |
@@ -151,7 +151,6 @@ config S390 | |||
151 | select TTY | 151 | select TTY |
152 | select VIRT_CPU_ACCOUNTING | 152 | select VIRT_CPU_ACCOUNTING |
153 | select VIRT_TO_BUS | 153 | select VIRT_TO_BUS |
154 | select ARCH_HAS_SG_CHAIN | ||
155 | 154 | ||
156 | config SCHED_OMIT_FRAME_POINTER | 155 | config SCHED_OMIT_FRAME_POINTER |
157 | def_bool y | 156 | def_bool y |
@@ -185,6 +184,10 @@ config HAVE_MARCH_ZEC12_FEATURES | |||
185 | def_bool n | 184 | def_bool n |
186 | select HAVE_MARCH_Z196_FEATURES | 185 | select HAVE_MARCH_Z196_FEATURES |
187 | 186 | ||
187 | config HAVE_MARCH_Z13_FEATURES | ||
188 | def_bool n | ||
189 | select HAVE_MARCH_ZEC12_FEATURES | ||
190 | |||
188 | choice | 191 | choice |
189 | prompt "Processor type" | 192 | prompt "Processor type" |
190 | default MARCH_G5 | 193 | default MARCH_G5 |
@@ -244,6 +247,14 @@ config MARCH_ZEC12 | |||
244 | 2827 series). The kernel will be slightly faster but will not work on | 247 | 2827 series). The kernel will be slightly faster but will not work on |
245 | older machines. | 248 | older machines. |
246 | 249 | ||
250 | config MARCH_Z13 | ||
251 | bool "IBM z13" | ||
252 | select HAVE_MARCH_Z13_FEATURES if 64BIT | ||
253 | help | ||
254 | Select this to enable optimizations for IBM z13 (2964 series). | ||
255 | The kernel will be slightly faster but will not work on older | ||
256 | machines. | ||
257 | |||
247 | endchoice | 258 | endchoice |
248 | 259 | ||
249 | config MARCH_G5_TUNE | 260 | config MARCH_G5_TUNE |
@@ -267,6 +278,9 @@ config MARCH_Z196_TUNE | |||
267 | config MARCH_ZEC12_TUNE | 278 | config MARCH_ZEC12_TUNE |
268 | def_bool TUNE_ZEC12 || MARCH_ZEC12 && TUNE_DEFAULT | 279 | def_bool TUNE_ZEC12 || MARCH_ZEC12 && TUNE_DEFAULT |
269 | 280 | ||
281 | config MARCH_Z13_TUNE | ||
282 | def_bool TUNE_Z13 || MARCH_Z13 && TUNE_DEFAULT | ||
283 | |||
270 | choice | 284 | choice |
271 | prompt "Tune code generation" | 285 | prompt "Tune code generation" |
272 | default TUNE_DEFAULT | 286 | default TUNE_DEFAULT |
@@ -305,6 +319,9 @@ config TUNE_Z196 | |||
305 | config TUNE_ZEC12 | 319 | config TUNE_ZEC12 |
306 | bool "IBM zBC12 and zEC12" | 320 | bool "IBM zBC12 and zEC12" |
307 | 321 | ||
322 | config TUNE_Z13 | ||
323 | bool "IBM z13" | ||
324 | |||
308 | endchoice | 325 | endchoice |
309 | 326 | ||
310 | config 64BIT | 327 | config 64BIT |
@@ -356,14 +373,14 @@ config SMP | |||
356 | Even if you don't know what to do here, say Y. | 373 | Even if you don't know what to do here, say Y. |
357 | 374 | ||
358 | config NR_CPUS | 375 | config NR_CPUS |
359 | int "Maximum number of CPUs (2-256)" | 376 | int "Maximum number of CPUs (2-512)" |
360 | range 2 256 | 377 | range 2 512 |
361 | depends on SMP | 378 | depends on SMP |
362 | default "32" if !64BIT | 379 | default "32" if !64BIT |
363 | default "64" if 64BIT | 380 | default "64" if 64BIT |
364 | help | 381 | help |
365 | This allows you to specify the maximum number of CPUs which this | 382 | This allows you to specify the maximum number of CPUs which this |
366 | kernel will support. The maximum supported value is 256 and the | 383 | kernel will support. The maximum supported value is 512 and the |
367 | minimum value which makes sense is 2. | 384 | minimum value which makes sense is 2. |
368 | 385 | ||
369 | This is purely to save memory - each supported CPU adds | 386 | This is purely to save memory - each supported CPU adds |
@@ -378,17 +395,26 @@ config HOTPLUG_CPU | |||
378 | can be controlled through /sys/devices/system/cpu/cpu#. | 395 | can be controlled through /sys/devices/system/cpu/cpu#. |
379 | Say N if you want to disable CPU hotplug. | 396 | Say N if you want to disable CPU hotplug. |
380 | 397 | ||
398 | config SCHED_SMT | ||
399 | def_bool n | ||
400 | |||
381 | config SCHED_MC | 401 | config SCHED_MC |
382 | def_bool n | 402 | def_bool n |
383 | 403 | ||
384 | config SCHED_BOOK | 404 | config SCHED_BOOK |
405 | def_bool n | ||
406 | |||
407 | config SCHED_TOPOLOGY | ||
385 | def_bool y | 408 | def_bool y |
386 | prompt "Book scheduler support" | 409 | prompt "Topology scheduler support" |
387 | depends on SMP | 410 | depends on SMP |
411 | select SCHED_SMT | ||
388 | select SCHED_MC | 412 | select SCHED_MC |
413 | select SCHED_BOOK | ||
389 | help | 414 | help |
390 | Book scheduler support improves the CPU scheduler's decision making | 415 | Topology scheduler support improves the CPU scheduler's decision |
391 | when dealing with machines that have several books. | 416 | making when dealing with machines that have multi-threading, |
417 | multiple cores or multiple books. | ||
392 | 418 | ||
393 | source kernel/Kconfig.preempt | 419 | source kernel/Kconfig.preempt |
394 | 420 | ||
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 878e67973151..acb6859c6a95 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
@@ -42,6 +42,7 @@ mflags-$(CONFIG_MARCH_Z9_109) := -march=z9-109 | |||
42 | mflags-$(CONFIG_MARCH_Z10) := -march=z10 | 42 | mflags-$(CONFIG_MARCH_Z10) := -march=z10 |
43 | mflags-$(CONFIG_MARCH_Z196) := -march=z196 | 43 | mflags-$(CONFIG_MARCH_Z196) := -march=z196 |
44 | mflags-$(CONFIG_MARCH_ZEC12) := -march=zEC12 | 44 | mflags-$(CONFIG_MARCH_ZEC12) := -march=zEC12 |
45 | mflags-$(CONFIG_MARCH_Z13) := -march=z13 | ||
45 | 46 | ||
46 | aflags-y += $(mflags-y) | 47 | aflags-y += $(mflags-y) |
47 | cflags-y += $(mflags-y) | 48 | cflags-y += $(mflags-y) |
@@ -53,6 +54,7 @@ cflags-$(CONFIG_MARCH_Z9_109_TUNE) += -mtune=z9-109 | |||
53 | cflags-$(CONFIG_MARCH_Z10_TUNE) += -mtune=z10 | 54 | cflags-$(CONFIG_MARCH_Z10_TUNE) += -mtune=z10 |
54 | cflags-$(CONFIG_MARCH_Z196_TUNE) += -mtune=z196 | 55 | cflags-$(CONFIG_MARCH_Z196_TUNE) += -mtune=z196 |
55 | cflags-$(CONFIG_MARCH_ZEC12_TUNE) += -mtune=zEC12 | 56 | cflags-$(CONFIG_MARCH_ZEC12_TUNE) += -mtune=zEC12 |
57 | cflags-$(CONFIG_MARCH_Z13_TUNE) += -mtune=z13 | ||
56 | 58 | ||
57 | #KBUILD_IMAGE is necessary for make rpm | 59 | #KBUILD_IMAGE is necessary for make rpm |
58 | KBUILD_IMAGE :=arch/s390/boot/image | 60 | KBUILD_IMAGE :=arch/s390/boot/image |
@@ -85,6 +87,16 @@ ifeq ($(call cc-option-yn,-mwarn-dynamicstack),y) | |||
85 | cflags-$(CONFIG_WARN_DYNAMIC_STACK) += -mwarn-dynamicstack | 87 | cflags-$(CONFIG_WARN_DYNAMIC_STACK) += -mwarn-dynamicstack |
86 | endif | 88 | endif |
87 | 89 | ||
90 | ifdef CONFIG_FUNCTION_TRACER | ||
91 | # make use of hotpatch feature if the compiler supports it | ||
92 | cc_hotpatch := -mhotpatch=0,3 | ||
93 | ifeq ($(call cc-option-yn,$(cc_hotpatch)),y) | ||
94 | CC_FLAGS_FTRACE := $(cc_hotpatch) | ||
95 | KBUILD_AFLAGS += -DCC_USING_HOTPATCH | ||
96 | KBUILD_CFLAGS += -DCC_USING_HOTPATCH | ||
97 | endif | ||
98 | endif | ||
99 | |||
88 | KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y) | 100 | KBUILD_CFLAGS += -mbackchain -msoft-float $(cflags-y) |
89 | KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare | 101 | KBUILD_CFLAGS += -pipe -fno-strength-reduce -Wno-sign-compare |
90 | KBUILD_AFLAGS += $(aflags-y) | 102 | KBUILD_AFLAGS += $(aflags-y) |
diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c index 57cbaff1f397..42506b371b74 100644 --- a/arch/s390/boot/compressed/misc.c +++ b/arch/s390/boot/compressed/misc.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <asm/uaccess.h> | 9 | #include <asm/uaccess.h> |
10 | #include <asm/page.h> | 10 | #include <asm/page.h> |
11 | #include <asm/sclp.h> | ||
11 | #include <asm/ipl.h> | 12 | #include <asm/ipl.h> |
12 | #include "sizes.h" | 13 | #include "sizes.h" |
13 | 14 | ||
@@ -63,8 +64,6 @@ static unsigned long free_mem_end_ptr; | |||
63 | #include "../../../../lib/decompress_unxz.c" | 64 | #include "../../../../lib/decompress_unxz.c" |
64 | #endif | 65 | #endif |
65 | 66 | ||
66 | extern _sclp_print_early(const char *); | ||
67 | |||
68 | static int puts(const char *s) | 67 | static int puts(const char *s) |
69 | { | 68 | { |
70 | _sclp_print_early(s); | 69 | _sclp_print_early(s); |
diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig index 9432d0f202ef..64707750c780 100644 --- a/arch/s390/configs/default_defconfig +++ b/arch/s390/configs/default_defconfig | |||
@@ -555,7 +555,6 @@ CONFIG_DEBUG_OBJECTS_RCU_HEAD=y | |||
555 | CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y | 555 | CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y |
556 | CONFIG_SLUB_DEBUG_ON=y | 556 | CONFIG_SLUB_DEBUG_ON=y |
557 | CONFIG_SLUB_STATS=y | 557 | CONFIG_SLUB_STATS=y |
558 | CONFIG_DEBUG_KMEMLEAK=y | ||
559 | CONFIG_DEBUG_STACK_USAGE=y | 558 | CONFIG_DEBUG_STACK_USAGE=y |
560 | CONFIG_DEBUG_VM=y | 559 | CONFIG_DEBUG_VM=y |
561 | CONFIG_DEBUG_VM_RB=y | 560 | CONFIG_DEBUG_VM_RB=y |
@@ -563,6 +562,7 @@ CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m | |||
563 | CONFIG_DEBUG_PER_CPU_MAPS=y | 562 | CONFIG_DEBUG_PER_CPU_MAPS=y |
564 | CONFIG_DEBUG_SHIRQ=y | 563 | CONFIG_DEBUG_SHIRQ=y |
565 | CONFIG_DETECT_HUNG_TASK=y | 564 | CONFIG_DETECT_HUNG_TASK=y |
565 | CONFIG_PANIC_ON_OOPS=y | ||
566 | CONFIG_TIMER_STATS=y | 566 | CONFIG_TIMER_STATS=y |
567 | CONFIG_DEBUG_RT_MUTEXES=y | 567 | CONFIG_DEBUG_RT_MUTEXES=y |
568 | CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y | 568 | CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y |
diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig index 219dca6ea926..5c3097272cd8 100644 --- a/arch/s390/configs/gcov_defconfig +++ b/arch/s390/configs/gcov_defconfig | |||
@@ -540,6 +540,7 @@ CONFIG_UNUSED_SYMBOLS=y | |||
540 | CONFIG_MAGIC_SYSRQ=y | 540 | CONFIG_MAGIC_SYSRQ=y |
541 | CONFIG_DEBUG_KERNEL=y | 541 | CONFIG_DEBUG_KERNEL=y |
542 | CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m | 542 | CONFIG_MEMORY_NOTIFIER_ERROR_INJECT=m |
543 | CONFIG_PANIC_ON_OOPS=y | ||
543 | CONFIG_TIMER_STATS=y | 544 | CONFIG_TIMER_STATS=y |
544 | CONFIG_RCU_TORTURE_TEST=m | 545 | CONFIG_RCU_TORTURE_TEST=m |
545 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 546 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig index 822c2f2e0c25..bda70f1ffd2c 100644 --- a/arch/s390/configs/performance_defconfig +++ b/arch/s390/configs/performance_defconfig | |||
@@ -537,6 +537,7 @@ CONFIG_FRAME_WARN=1024 | |||
537 | CONFIG_UNUSED_SYMBOLS=y | 537 | CONFIG_UNUSED_SYMBOLS=y |
538 | CONFIG_MAGIC_SYSRQ=y | 538 | CONFIG_MAGIC_SYSRQ=y |
539 | CONFIG_DEBUG_KERNEL=y | 539 | CONFIG_DEBUG_KERNEL=y |
540 | CONFIG_PANIC_ON_OOPS=y | ||
540 | CONFIG_TIMER_STATS=y | 541 | CONFIG_TIMER_STATS=y |
541 | CONFIG_RCU_TORTURE_TEST=m | 542 | CONFIG_RCU_TORTURE_TEST=m |
542 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 543 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig index 9d63051ebec4..1b0184a0f7f2 100644 --- a/arch/s390/configs/zfcpdump_defconfig +++ b/arch/s390/configs/zfcpdump_defconfig | |||
@@ -71,6 +71,7 @@ CONFIG_PRINTK_TIME=y | |||
71 | CONFIG_DEBUG_INFO=y | 71 | CONFIG_DEBUG_INFO=y |
72 | CONFIG_DEBUG_FS=y | 72 | CONFIG_DEBUG_FS=y |
73 | CONFIG_DEBUG_KERNEL=y | 73 | CONFIG_DEBUG_KERNEL=y |
74 | CONFIG_PANIC_ON_OOPS=y | ||
74 | # CONFIG_SCHED_DEBUG is not set | 75 | # CONFIG_SCHED_DEBUG is not set |
75 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 76 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
76 | # CONFIG_FTRACE is not set | 77 | # CONFIG_FTRACE is not set |
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 1f272b24fc0b..5566ce80abdb 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c | |||
@@ -134,7 +134,7 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | |||
134 | 134 | ||
135 | static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) | 135 | static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) |
136 | { | 136 | { |
137 | const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); | 137 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); |
138 | 138 | ||
139 | if (unlikely(need_fallback(sctx->key_len))) { | 139 | if (unlikely(need_fallback(sctx->key_len))) { |
140 | crypto_cipher_encrypt_one(sctx->fallback.cip, out, in); | 140 | crypto_cipher_encrypt_one(sctx->fallback.cip, out, in); |
@@ -159,7 +159,7 @@ static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) | |||
159 | 159 | ||
160 | static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) | 160 | static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) |
161 | { | 161 | { |
162 | const struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); | 162 | struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm); |
163 | 163 | ||
164 | if (unlikely(need_fallback(sctx->key_len))) { | 164 | if (unlikely(need_fallback(sctx->key_len))) { |
165 | crypto_cipher_decrypt_one(sctx->fallback.cip, out, in); | 165 | crypto_cipher_decrypt_one(sctx->fallback.cip, out, in); |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 785c5f24d6f9..83ef702d2403 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -14,7 +14,6 @@ CONFIG_IKCONFIG_PROC=y | |||
14 | CONFIG_CGROUPS=y | 14 | CONFIG_CGROUPS=y |
15 | CONFIG_CPUSETS=y | 15 | CONFIG_CPUSETS=y |
16 | CONFIG_CGROUP_CPUACCT=y | 16 | CONFIG_CGROUP_CPUACCT=y |
17 | CONFIG_RESOURCE_COUNTERS=y | ||
18 | CONFIG_MEMCG=y | 17 | CONFIG_MEMCG=y |
19 | CONFIG_MEMCG_SWAP=y | 18 | CONFIG_MEMCG_SWAP=y |
20 | CONFIG_CGROUP_SCHED=y | 19 | CONFIG_CGROUP_SCHED=y |
@@ -22,12 +21,8 @@ CONFIG_RT_GROUP_SCHED=y | |||
22 | CONFIG_BLK_CGROUP=y | 21 | CONFIG_BLK_CGROUP=y |
23 | CONFIG_NAMESPACES=y | 22 | CONFIG_NAMESPACES=y |
24 | CONFIG_BLK_DEV_INITRD=y | 23 | CONFIG_BLK_DEV_INITRD=y |
25 | CONFIG_RD_BZIP2=y | ||
26 | CONFIG_RD_LZMA=y | ||
27 | CONFIG_RD_XZ=y | ||
28 | CONFIG_RD_LZO=y | ||
29 | CONFIG_RD_LZ4=y | ||
30 | CONFIG_EXPERT=y | 24 | CONFIG_EXPERT=y |
25 | CONFIG_BPF_SYSCALL=y | ||
31 | # CONFIG_COMPAT_BRK is not set | 26 | # CONFIG_COMPAT_BRK is not set |
32 | CONFIG_PROFILING=y | 27 | CONFIG_PROFILING=y |
33 | CONFIG_OPROFILE=y | 28 | CONFIG_OPROFILE=y |
diff --git a/arch/s390/hypfs/Makefile b/arch/s390/hypfs/Makefile index 06f8d95a16cd..2ee25ba252d6 100644 --- a/arch/s390/hypfs/Makefile +++ b/arch/s390/hypfs/Makefile | |||
@@ -5,3 +5,4 @@ | |||
5 | obj-$(CONFIG_S390_HYPFS_FS) += s390_hypfs.o | 5 | obj-$(CONFIG_S390_HYPFS_FS) += s390_hypfs.o |
6 | 6 | ||
7 | s390_hypfs-objs := inode.o hypfs_diag.o hypfs_vm.o hypfs_dbfs.o hypfs_sprp.o | 7 | s390_hypfs-objs := inode.o hypfs_diag.o hypfs_vm.o hypfs_dbfs.o hypfs_sprp.o |
8 | s390_hypfs-objs += hypfs_diag0c.o | ||
diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h index b34b5ab90a31..eecde500ed49 100644 --- a/arch/s390/hypfs/hypfs.h +++ b/arch/s390/hypfs/hypfs.h | |||
@@ -37,6 +37,10 @@ extern int hypfs_vm_init(void); | |||
37 | extern void hypfs_vm_exit(void); | 37 | extern void hypfs_vm_exit(void); |
38 | extern int hypfs_vm_create_files(struct dentry *root); | 38 | extern int hypfs_vm_create_files(struct dentry *root); |
39 | 39 | ||
40 | /* VM diagnose 0c */ | ||
41 | int hypfs_diag0c_init(void); | ||
42 | void hypfs_diag0c_exit(void); | ||
43 | |||
40 | /* Set Partition-Resource Parameter */ | 44 | /* Set Partition-Resource Parameter */ |
41 | int hypfs_sprp_init(void); | 45 | int hypfs_sprp_init(void); |
42 | void hypfs_sprp_exit(void); | 46 | void hypfs_sprp_exit(void); |
@@ -49,7 +53,6 @@ struct hypfs_dbfs_data { | |||
49 | void *buf_free_ptr; | 53 | void *buf_free_ptr; |
50 | size_t size; | 54 | size_t size; |
51 | struct hypfs_dbfs_file *dbfs_file; | 55 | struct hypfs_dbfs_file *dbfs_file; |
52 | struct kref kref; | ||
53 | }; | 56 | }; |
54 | 57 | ||
55 | struct hypfs_dbfs_file { | 58 | struct hypfs_dbfs_file { |
@@ -61,8 +64,6 @@ struct hypfs_dbfs_file { | |||
61 | unsigned long); | 64 | unsigned long); |
62 | 65 | ||
63 | /* Private data for hypfs_dbfs.c */ | 66 | /* Private data for hypfs_dbfs.c */ |
64 | struct hypfs_dbfs_data *data; | ||
65 | struct delayed_work data_free_work; | ||
66 | struct mutex lock; | 67 | struct mutex lock; |
67 | struct dentry *dentry; | 68 | struct dentry *dentry; |
68 | }; | 69 | }; |
diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index 47fe1055c714..752f6df3e697 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c | |||
@@ -17,33 +17,16 @@ static struct hypfs_dbfs_data *hypfs_dbfs_data_alloc(struct hypfs_dbfs_file *f) | |||
17 | data = kmalloc(sizeof(*data), GFP_KERNEL); | 17 | data = kmalloc(sizeof(*data), GFP_KERNEL); |
18 | if (!data) | 18 | if (!data) |
19 | return NULL; | 19 | return NULL; |
20 | kref_init(&data->kref); | ||
21 | data->dbfs_file = f; | 20 | data->dbfs_file = f; |
22 | return data; | 21 | return data; |
23 | } | 22 | } |
24 | 23 | ||
25 | static void hypfs_dbfs_data_free(struct kref *kref) | 24 | static void hypfs_dbfs_data_free(struct hypfs_dbfs_data *data) |
26 | { | 25 | { |
27 | struct hypfs_dbfs_data *data; | ||
28 | |||
29 | data = container_of(kref, struct hypfs_dbfs_data, kref); | ||
30 | data->dbfs_file->data_free(data->buf_free_ptr); | 26 | data->dbfs_file->data_free(data->buf_free_ptr); |
31 | kfree(data); | 27 | kfree(data); |
32 | } | 28 | } |
33 | 29 | ||
34 | static void data_free_delayed(struct work_struct *work) | ||
35 | { | ||
36 | struct hypfs_dbfs_data *data; | ||
37 | struct hypfs_dbfs_file *df; | ||
38 | |||
39 | df = container_of(work, struct hypfs_dbfs_file, data_free_work.work); | ||
40 | mutex_lock(&df->lock); | ||
41 | data = df->data; | ||
42 | df->data = NULL; | ||
43 | mutex_unlock(&df->lock); | ||
44 | kref_put(&data->kref, hypfs_dbfs_data_free); | ||
45 | } | ||
46 | |||
47 | static ssize_t dbfs_read(struct file *file, char __user *buf, | 30 | static ssize_t dbfs_read(struct file *file, char __user *buf, |
48 | size_t size, loff_t *ppos) | 31 | size_t size, loff_t *ppos) |
49 | { | 32 | { |
@@ -56,28 +39,21 @@ static ssize_t dbfs_read(struct file *file, char __user *buf, | |||
56 | 39 | ||
57 | df = file_inode(file)->i_private; | 40 | df = file_inode(file)->i_private; |
58 | mutex_lock(&df->lock); | 41 | mutex_lock(&df->lock); |
59 | if (!df->data) { | 42 | data = hypfs_dbfs_data_alloc(df); |
60 | data = hypfs_dbfs_data_alloc(df); | 43 | if (!data) { |
61 | if (!data) { | 44 | mutex_unlock(&df->lock); |
62 | mutex_unlock(&df->lock); | 45 | return -ENOMEM; |
63 | return -ENOMEM; | 46 | } |
64 | } | 47 | rc = df->data_create(&data->buf, &data->buf_free_ptr, &data->size); |
65 | rc = df->data_create(&data->buf, &data->buf_free_ptr, | 48 | if (rc) { |
66 | &data->size); | 49 | mutex_unlock(&df->lock); |
67 | if (rc) { | 50 | kfree(data); |
68 | mutex_unlock(&df->lock); | 51 | return rc; |
69 | kfree(data); | ||
70 | return rc; | ||
71 | } | ||
72 | df->data = data; | ||
73 | schedule_delayed_work(&df->data_free_work, HZ); | ||
74 | } | 52 | } |
75 | data = df->data; | ||
76 | kref_get(&data->kref); | ||
77 | mutex_unlock(&df->lock); | 53 | mutex_unlock(&df->lock); |
78 | 54 | ||
79 | rc = simple_read_from_buffer(buf, size, ppos, data->buf, data->size); | 55 | rc = simple_read_from_buffer(buf, size, ppos, data->buf, data->size); |
80 | kref_put(&data->kref, hypfs_dbfs_data_free); | 56 | hypfs_dbfs_data_free(data); |
81 | return rc; | 57 | return rc; |
82 | } | 58 | } |
83 | 59 | ||
@@ -108,7 +84,6 @@ int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df) | |||
108 | if (IS_ERR(df->dentry)) | 84 | if (IS_ERR(df->dentry)) |
109 | return PTR_ERR(df->dentry); | 85 | return PTR_ERR(df->dentry); |
110 | mutex_init(&df->lock); | 86 | mutex_init(&df->lock); |
111 | INIT_DELAYED_WORK(&df->data_free_work, data_free_delayed); | ||
112 | return 0; | 87 | return 0; |
113 | } | 88 | } |
114 | 89 | ||
diff --git a/arch/s390/hypfs/hypfs_diag0c.c b/arch/s390/hypfs/hypfs_diag0c.c new file mode 100644 index 000000000000..d4c0d3717543 --- /dev/null +++ b/arch/s390/hypfs/hypfs_diag0c.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * Hypervisor filesystem for Linux on s390 | ||
3 | * | ||
4 | * Diag 0C implementation | ||
5 | * | ||
6 | * Copyright IBM Corp. 2014 | ||
7 | */ | ||
8 | |||
9 | #include <linux/slab.h> | ||
10 | #include <linux/cpu.h> | ||
11 | #include <asm/hypfs.h> | ||
12 | #include "hypfs.h" | ||
13 | |||
14 | #define DBFS_D0C_HDR_VERSION 0 | ||
15 | |||
16 | /* | ||
17 | * Execute diagnose 0c in 31 bit mode | ||
18 | */ | ||
19 | static void diag0c(struct hypfs_diag0c_entry *entry) | ||
20 | { | ||
21 | asm volatile ( | ||
22 | #ifdef CONFIG_64BIT | ||
23 | " sam31\n" | ||
24 | " diag %0,%0,0x0c\n" | ||
25 | " sam64\n" | ||
26 | #else | ||
27 | " diag %0,%0,0x0c\n" | ||
28 | #endif | ||
29 | : /* no output register */ | ||
30 | : "a" (entry) | ||
31 | : "memory"); | ||
32 | } | ||
33 | |||
34 | /* | ||
35 | * Get hypfs_diag0c_entry from CPU vector and store diag0c data | ||
36 | */ | ||
37 | static void diag0c_fn(void *data) | ||
38 | { | ||
39 | diag0c(((void **) data)[smp_processor_id()]); | ||
40 | } | ||
41 | |||
42 | /* | ||
43 | * Allocate buffer and store diag 0c data | ||
44 | */ | ||
45 | static void *diag0c_store(unsigned int *count) | ||
46 | { | ||
47 | struct hypfs_diag0c_data *diag0c_data; | ||
48 | unsigned int cpu_count, cpu, i; | ||
49 | void **cpu_vec; | ||
50 | |||
51 | get_online_cpus(); | ||
52 | cpu_count = num_online_cpus(); | ||
53 | cpu_vec = kmalloc(sizeof(*cpu_vec) * num_possible_cpus(), GFP_KERNEL); | ||
54 | if (!cpu_vec) | ||
55 | goto fail_put_online_cpus; | ||
56 | /* Note: Diag 0c needs 8 byte alignment and real storage */ | ||
57 | diag0c_data = kzalloc(sizeof(struct hypfs_diag0c_hdr) + | ||
58 | cpu_count * sizeof(struct hypfs_diag0c_entry), | ||
59 | GFP_KERNEL | GFP_DMA); | ||
60 | if (!diag0c_data) | ||
61 | goto fail_kfree_cpu_vec; | ||
62 | i = 0; | ||
63 | /* Fill CPU vector for each online CPU */ | ||
64 | for_each_online_cpu(cpu) { | ||
65 | diag0c_data->entry[i].cpu = cpu; | ||
66 | cpu_vec[cpu] = &diag0c_data->entry[i++]; | ||
67 | } | ||
68 | /* Collect data all CPUs */ | ||
69 | on_each_cpu(diag0c_fn, cpu_vec, 1); | ||
70 | *count = cpu_count; | ||
71 | kfree(cpu_vec); | ||
72 | put_online_cpus(); | ||
73 | return diag0c_data; | ||
74 | |||
75 | fail_kfree_cpu_vec: | ||
76 | kfree(cpu_vec); | ||
77 | fail_put_online_cpus: | ||
78 | put_online_cpus(); | ||
79 | return ERR_PTR(-ENOMEM); | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * Hypfs DBFS callback: Free diag 0c data | ||
84 | */ | ||
85 | static void dbfs_diag0c_free(const void *data) | ||
86 | { | ||
87 | kfree(data); | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Hypfs DBFS callback: Create diag 0c data | ||
92 | */ | ||
93 | static int dbfs_diag0c_create(void **data, void **data_free_ptr, size_t *size) | ||
94 | { | ||
95 | struct hypfs_diag0c_data *diag0c_data; | ||
96 | unsigned int count; | ||
97 | |||
98 | diag0c_data = diag0c_store(&count); | ||
99 | if (IS_ERR(diag0c_data)) | ||
100 | return PTR_ERR(diag0c_data); | ||
101 | memset(&diag0c_data->hdr, 0, sizeof(diag0c_data->hdr)); | ||
102 | get_tod_clock_ext(diag0c_data->hdr.tod_ext); | ||
103 | diag0c_data->hdr.len = count * sizeof(struct hypfs_diag0c_entry); | ||
104 | diag0c_data->hdr.version = DBFS_D0C_HDR_VERSION; | ||
105 | diag0c_data->hdr.count = count; | ||
106 | *data = diag0c_data; | ||
107 | *data_free_ptr = diag0c_data; | ||
108 | *size = diag0c_data->hdr.len + sizeof(struct hypfs_diag0c_hdr); | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * Hypfs DBFS file structure | ||
114 | */ | ||
115 | static struct hypfs_dbfs_file dbfs_file_0c = { | ||
116 | .name = "diag_0c", | ||
117 | .data_create = dbfs_diag0c_create, | ||
118 | .data_free = dbfs_diag0c_free, | ||
119 | }; | ||
120 | |||
121 | /* | ||
122 | * Initialize diag 0c interface for z/VM | ||
123 | */ | ||
124 | int __init hypfs_diag0c_init(void) | ||
125 | { | ||
126 | if (!MACHINE_IS_VM) | ||
127 | return 0; | ||
128 | return hypfs_dbfs_create_file(&dbfs_file_0c); | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * Shutdown diag 0c interface for z/VM | ||
133 | */ | ||
134 | void hypfs_diag0c_exit(void) | ||
135 | { | ||
136 | if (!MACHINE_IS_VM) | ||
137 | return; | ||
138 | hypfs_dbfs_remove_file(&dbfs_file_0c); | ||
139 | } | ||
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index c952b981e4f2..4c8008dd938e 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c | |||
@@ -482,10 +482,14 @@ static int __init hypfs_init(void) | |||
482 | rc = -ENODATA; | 482 | rc = -ENODATA; |
483 | goto fail_hypfs_vm_exit; | 483 | goto fail_hypfs_vm_exit; |
484 | } | 484 | } |
485 | if (hypfs_diag0c_init()) { | ||
486 | rc = -ENODATA; | ||
487 | goto fail_hypfs_sprp_exit; | ||
488 | } | ||
485 | s390_kobj = kobject_create_and_add("s390", hypervisor_kobj); | 489 | s390_kobj = kobject_create_and_add("s390", hypervisor_kobj); |
486 | if (!s390_kobj) { | 490 | if (!s390_kobj) { |
487 | rc = -ENOMEM; | 491 | rc = -ENOMEM; |
488 | goto fail_hypfs_sprp_exit; | 492 | goto fail_hypfs_diag0c_exit; |
489 | } | 493 | } |
490 | rc = register_filesystem(&hypfs_type); | 494 | rc = register_filesystem(&hypfs_type); |
491 | if (rc) | 495 | if (rc) |
@@ -494,6 +498,8 @@ static int __init hypfs_init(void) | |||
494 | 498 | ||
495 | fail_filesystem: | 499 | fail_filesystem: |
496 | kobject_put(s390_kobj); | 500 | kobject_put(s390_kobj); |
501 | fail_hypfs_diag0c_exit: | ||
502 | hypfs_diag0c_exit(); | ||
497 | fail_hypfs_sprp_exit: | 503 | fail_hypfs_sprp_exit: |
498 | hypfs_sprp_exit(); | 504 | hypfs_sprp_exit(); |
499 | fail_hypfs_vm_exit: | 505 | fail_hypfs_vm_exit: |
@@ -510,6 +516,7 @@ static void __exit hypfs_exit(void) | |||
510 | { | 516 | { |
511 | unregister_filesystem(&hypfs_type); | 517 | unregister_filesystem(&hypfs_type); |
512 | kobject_put(s390_kobj); | 518 | kobject_put(s390_kobj); |
519 | hypfs_diag0c_exit(); | ||
513 | hypfs_sprp_exit(); | 520 | hypfs_sprp_exit(); |
514 | hypfs_vm_exit(); | 521 | hypfs_vm_exit(); |
515 | hypfs_diag_exit(); | 522 | hypfs_diag_exit(); |
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h index cb700d54bd83..5243a8679a1d 100644 --- a/arch/s390/include/asm/cpu_mf.h +++ b/arch/s390/include/asm/cpu_mf.h | |||
@@ -189,6 +189,20 @@ static inline int ecctr(u64 ctr, u64 *val) | |||
189 | return cc; | 189 | return cc; |
190 | } | 190 | } |
191 | 191 | ||
192 | /* Store CPU counter multiple for the MT utilization counter set */ | ||
193 | static inline int stcctm5(u64 num, u64 *val) | ||
194 | { | ||
195 | typedef struct { u64 _[num]; } addrtype; | ||
196 | int cc; | ||
197 | |||
198 | asm volatile ( | ||
199 | " .insn rsy,0xeb0000000017,%2,5,%1\n" | ||
200 | " ipm %0\n" | ||
201 | " srl %0,28\n" | ||
202 | : "=d" (cc), "=Q" (*(addrtype *) val) : "d" (num) : "cc"); | ||
203 | return cc; | ||
204 | } | ||
205 | |||
192 | /* Query sampling information */ | 206 | /* Query sampling information */ |
193 | static inline int qsi(struct hws_qsi_info_block *info) | 207 | static inline int qsi(struct hws_qsi_info_block *info) |
194 | { | 208 | { |
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index f6e43d39e3d8..c9df40b5c0ac 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h | |||
@@ -163,8 +163,8 @@ extern unsigned int vdso_enabled; | |||
163 | the loader. We need to make sure that it is out of the way of the program | 163 | the loader. We need to make sure that it is out of the way of the program |
164 | that it will "exec", and that there is sufficient room for the brk. */ | 164 | that it will "exec", and that there is sufficient room for the brk. */ |
165 | 165 | ||
166 | extern unsigned long randomize_et_dyn(unsigned long base); | 166 | extern unsigned long randomize_et_dyn(void); |
167 | #define ELF_ET_DYN_BASE (randomize_et_dyn(STACK_TOP / 3 * 2)) | 167 | #define ELF_ET_DYN_BASE randomize_et_dyn() |
168 | 168 | ||
169 | /* This yields a mask that user programs can use to figure out what | 169 | /* This yields a mask that user programs can use to figure out what |
170 | instruction set this CPU supports. */ | 170 | instruction set this CPU supports. */ |
@@ -209,7 +209,9 @@ do { \ | |||
209 | } while (0) | 209 | } while (0) |
210 | #endif /* CONFIG_COMPAT */ | 210 | #endif /* CONFIG_COMPAT */ |
211 | 211 | ||
212 | #define STACK_RND_MASK 0x7ffUL | 212 | extern unsigned long mmap_rnd_mask; |
213 | |||
214 | #define STACK_RND_MASK (mmap_rnd_mask) | ||
213 | 215 | ||
214 | #define ARCH_DLINFO \ | 216 | #define ARCH_DLINFO \ |
215 | do { \ | 217 | do { \ |
diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h index abb618f1ead2..836c56290499 100644 --- a/arch/s390/include/asm/ftrace.h +++ b/arch/s390/include/asm/ftrace.h | |||
@@ -3,8 +3,12 @@ | |||
3 | 3 | ||
4 | #define ARCH_SUPPORTS_FTRACE_OPS 1 | 4 | #define ARCH_SUPPORTS_FTRACE_OPS 1 |
5 | 5 | ||
6 | #ifdef CC_USING_HOTPATCH | ||
7 | #define MCOUNT_INSN_SIZE 6 | ||
8 | #else | ||
6 | #define MCOUNT_INSN_SIZE 24 | 9 | #define MCOUNT_INSN_SIZE 24 |
7 | #define MCOUNT_RETURN_FIXUP 18 | 10 | #define MCOUNT_RETURN_FIXUP 18 |
11 | #endif | ||
8 | 12 | ||
9 | #ifndef __ASSEMBLY__ | 13 | #ifndef __ASSEMBLY__ |
10 | 14 | ||
@@ -37,18 +41,29 @@ struct ftrace_insn { | |||
37 | static inline void ftrace_generate_nop_insn(struct ftrace_insn *insn) | 41 | static inline void ftrace_generate_nop_insn(struct ftrace_insn *insn) |
38 | { | 42 | { |
39 | #ifdef CONFIG_FUNCTION_TRACER | 43 | #ifdef CONFIG_FUNCTION_TRACER |
44 | #ifdef CC_USING_HOTPATCH | ||
45 | /* brcl 0,0 */ | ||
46 | insn->opc = 0xc004; | ||
47 | insn->disp = 0; | ||
48 | #else | ||
40 | /* jg .+24 */ | 49 | /* jg .+24 */ |
41 | insn->opc = 0xc0f4; | 50 | insn->opc = 0xc0f4; |
42 | insn->disp = MCOUNT_INSN_SIZE / 2; | 51 | insn->disp = MCOUNT_INSN_SIZE / 2; |
43 | #endif | 52 | #endif |
53 | #endif | ||
44 | } | 54 | } |
45 | 55 | ||
46 | static inline int is_ftrace_nop(struct ftrace_insn *insn) | 56 | static inline int is_ftrace_nop(struct ftrace_insn *insn) |
47 | { | 57 | { |
48 | #ifdef CONFIG_FUNCTION_TRACER | 58 | #ifdef CONFIG_FUNCTION_TRACER |
59 | #ifdef CC_USING_HOTPATCH | ||
60 | if (insn->disp == 0) | ||
61 | return 1; | ||
62 | #else | ||
49 | if (insn->disp == MCOUNT_INSN_SIZE / 2) | 63 | if (insn->disp == MCOUNT_INSN_SIZE / 2) |
50 | return 1; | 64 | return 1; |
51 | #endif | 65 | #endif |
66 | #endif | ||
52 | return 0; | 67 | return 0; |
53 | } | 68 | } |
54 | 69 | ||
diff --git a/arch/s390/include/asm/jump_label.h b/arch/s390/include/asm/jump_label.h index 346b1c85ffb4..58642fd29c87 100644 --- a/arch/s390/include/asm/jump_label.h +++ b/arch/s390/include/asm/jump_label.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | 5 | ||
6 | #define JUMP_LABEL_NOP_SIZE 6 | 6 | #define JUMP_LABEL_NOP_SIZE 6 |
7 | #define JUMP_LABEL_NOP_OFFSET 2 | ||
7 | 8 | ||
8 | #ifdef CONFIG_64BIT | 9 | #ifdef CONFIG_64BIT |
9 | #define ASM_PTR ".quad" | 10 | #define ASM_PTR ".quad" |
@@ -13,9 +14,13 @@ | |||
13 | #define ASM_ALIGN ".balign 4" | 14 | #define ASM_ALIGN ".balign 4" |
14 | #endif | 15 | #endif |
15 | 16 | ||
17 | /* | ||
18 | * We use a brcl 0,2 instruction for jump labels at compile time so it | ||
19 | * can be easily distinguished from a hotpatch generated instruction. | ||
20 | */ | ||
16 | static __always_inline bool arch_static_branch(struct static_key *key) | 21 | static __always_inline bool arch_static_branch(struct static_key *key) |
17 | { | 22 | { |
18 | asm_volatile_goto("0: brcl 0,0\n" | 23 | asm_volatile_goto("0: brcl 0,"__stringify(JUMP_LABEL_NOP_OFFSET)"\n" |
19 | ".pushsection __jump_table, \"aw\"\n" | 24 | ".pushsection __jump_table, \"aw\"\n" |
20 | ASM_ALIGN "\n" | 25 | ASM_ALIGN "\n" |
21 | ASM_PTR " 0b, %l[label], %0\n" | 26 | ASM_PTR " 0b, %l[label], %0\n" |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index ffb1d8ce97ae..0441ec24ae87 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -1758,6 +1758,10 @@ extern int s390_enable_sie(void); | |||
1758 | extern int s390_enable_skey(void); | 1758 | extern int s390_enable_skey(void); |
1759 | extern void s390_reset_cmma(struct mm_struct *mm); | 1759 | extern void s390_reset_cmma(struct mm_struct *mm); |
1760 | 1760 | ||
1761 | /* s390 has a private copy of get unmapped area to deal with cache synonyms */ | ||
1762 | #define HAVE_ARCH_UNMAPPED_AREA | ||
1763 | #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN | ||
1764 | |||
1761 | /* | 1765 | /* |
1762 | * No page table caches to initialise | 1766 | * No page table caches to initialise |
1763 | */ | 1767 | */ |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index bed05ea7ec27..e7cbbdcdee13 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
@@ -215,10 +215,7 @@ static inline unsigned short stap(void) | |||
215 | /* | 215 | /* |
216 | * Give up the time slice of the virtual PU. | 216 | * Give up the time slice of the virtual PU. |
217 | */ | 217 | */ |
218 | static inline void cpu_relax(void) | 218 | void cpu_relax(void); |
219 | { | ||
220 | barrier(); | ||
221 | } | ||
222 | 219 | ||
223 | #define cpu_relax_lowlatency() barrier() | 220 | #define cpu_relax_lowlatency() barrier() |
224 | 221 | ||
diff --git a/arch/s390/include/asm/reset.h b/arch/s390/include/asm/reset.h index 804578587a7a..72786067b300 100644 --- a/arch/s390/include/asm/reset.h +++ b/arch/s390/include/asm/reset.h | |||
@@ -15,5 +15,6 @@ struct reset_call { | |||
15 | 15 | ||
16 | extern void register_reset_call(struct reset_call *reset); | 16 | extern void register_reset_call(struct reset_call *reset); |
17 | extern void unregister_reset_call(struct reset_call *reset); | 17 | extern void unregister_reset_call(struct reset_call *reset); |
18 | extern void s390_reset_system(void (*func)(void *), void *data); | 18 | extern void s390_reset_system(void (*fn_pre)(void), |
19 | void (*fn_post)(void *), void *data); | ||
19 | #endif /* _ASM_S390_RESET_H */ | 20 | #endif /* _ASM_S390_RESET_H */ |
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index 1aba89b53cb9..edb453cfc2c6 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h | |||
@@ -27,7 +27,7 @@ struct sclp_ipl_info { | |||
27 | }; | 27 | }; |
28 | 28 | ||
29 | struct sclp_cpu_entry { | 29 | struct sclp_cpu_entry { |
30 | u8 address; | 30 | u8 core_id; |
31 | u8 reserved0[2]; | 31 | u8 reserved0[2]; |
32 | u8 : 3; | 32 | u8 : 3; |
33 | u8 siif : 1; | 33 | u8 siif : 1; |
@@ -51,6 +51,9 @@ int sclp_cpu_deconfigure(u8 cpu); | |||
51 | unsigned long long sclp_get_rnmax(void); | 51 | unsigned long long sclp_get_rnmax(void); |
52 | unsigned long long sclp_get_rzm(void); | 52 | unsigned long long sclp_get_rzm(void); |
53 | unsigned int sclp_get_max_cpu(void); | 53 | unsigned int sclp_get_max_cpu(void); |
54 | unsigned int sclp_get_mtid(u8 cpu_type); | ||
55 | unsigned int sclp_get_mtid_max(void); | ||
56 | unsigned int sclp_get_mtid_prev(void); | ||
54 | int sclp_sdias_blk_count(void); | 57 | int sclp_sdias_blk_count(void); |
55 | int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); | 58 | int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); |
56 | int sclp_chp_configure(struct chp_id chpid); | 59 | int sclp_chp_configure(struct chp_id chpid); |
@@ -68,4 +71,6 @@ void sclp_early_detect(void); | |||
68 | int sclp_has_siif(void); | 71 | int sclp_has_siif(void); |
69 | unsigned int sclp_get_ibc(void); | 72 | unsigned int sclp_get_ibc(void); |
70 | 73 | ||
74 | long _sclp_print_early(const char *); | ||
75 | |||
71 | #endif /* _ASM_S390_SCLP_H */ | 76 | #endif /* _ASM_S390_SCLP_H */ |
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 7736fdd72595..b8d1e54b4733 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h | |||
@@ -57,6 +57,7 @@ extern void detect_memory_memblock(void); | |||
57 | #define MACHINE_FLAG_TE (1UL << 15) | 57 | #define MACHINE_FLAG_TE (1UL << 15) |
58 | #define MACHINE_FLAG_TLB_LC (1UL << 17) | 58 | #define MACHINE_FLAG_TLB_LC (1UL << 17) |
59 | #define MACHINE_FLAG_VX (1UL << 18) | 59 | #define MACHINE_FLAG_VX (1UL << 18) |
60 | #define MACHINE_FLAG_CAD (1UL << 19) | ||
60 | 61 | ||
61 | #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) | 62 | #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) |
62 | #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) | 63 | #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) |
@@ -80,6 +81,7 @@ extern void detect_memory_memblock(void); | |||
80 | #define MACHINE_HAS_TE (0) | 81 | #define MACHINE_HAS_TE (0) |
81 | #define MACHINE_HAS_TLB_LC (0) | 82 | #define MACHINE_HAS_TLB_LC (0) |
82 | #define MACHINE_HAS_VX (0) | 83 | #define MACHINE_HAS_VX (0) |
84 | #define MACHINE_HAS_CAD (0) | ||
83 | #else /* CONFIG_64BIT */ | 85 | #else /* CONFIG_64BIT */ |
84 | #define MACHINE_HAS_IEEE (1) | 86 | #define MACHINE_HAS_IEEE (1) |
85 | #define MACHINE_HAS_CSP (1) | 87 | #define MACHINE_HAS_CSP (1) |
@@ -93,6 +95,7 @@ extern void detect_memory_memblock(void); | |||
93 | #define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE) | 95 | #define MACHINE_HAS_TE (S390_lowcore.machine_flags & MACHINE_FLAG_TE) |
94 | #define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC) | 96 | #define MACHINE_HAS_TLB_LC (S390_lowcore.machine_flags & MACHINE_FLAG_TLB_LC) |
95 | #define MACHINE_HAS_VX (S390_lowcore.machine_flags & MACHINE_FLAG_VX) | 97 | #define MACHINE_HAS_VX (S390_lowcore.machine_flags & MACHINE_FLAG_VX) |
98 | #define MACHINE_HAS_CAD (S390_lowcore.machine_flags & MACHINE_FLAG_CAD) | ||
96 | #endif /* CONFIG_64BIT */ | 99 | #endif /* CONFIG_64BIT */ |
97 | 100 | ||
98 | /* | 101 | /* |
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index fad4ae23ece0..ec60cf7fa0a2 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #define SIGP_SET_ARCHITECTURE 18 | 16 | #define SIGP_SET_ARCHITECTURE 18 |
17 | #define SIGP_COND_EMERGENCY_SIGNAL 19 | 17 | #define SIGP_COND_EMERGENCY_SIGNAL 19 |
18 | #define SIGP_SENSE_RUNNING 21 | 18 | #define SIGP_SENSE_RUNNING 21 |
19 | #define SIGP_SET_MULTI_THREADING 22 | ||
19 | #define SIGP_STORE_ADDITIONAL_STATUS 23 | 20 | #define SIGP_STORE_ADDITIONAL_STATUS 23 |
20 | 21 | ||
21 | /* SIGP condition codes */ | 22 | /* SIGP condition codes */ |
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 762d4f88af5a..b3bd0282dd98 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #define raw_smp_processor_id() (S390_lowcore.cpu_nr) | 16 | #define raw_smp_processor_id() (S390_lowcore.cpu_nr) |
17 | 17 | ||
18 | extern struct mutex smp_cpu_state_mutex; | 18 | extern struct mutex smp_cpu_state_mutex; |
19 | extern unsigned int smp_cpu_mt_shift; | ||
20 | extern unsigned int smp_cpu_mtid; | ||
19 | 21 | ||
20 | extern int __cpu_up(unsigned int cpu, struct task_struct *tidle); | 22 | extern int __cpu_up(unsigned int cpu, struct task_struct *tidle); |
21 | 23 | ||
@@ -35,6 +37,8 @@ extern void smp_fill_possible_mask(void); | |||
35 | 37 | ||
36 | #else /* CONFIG_SMP */ | 38 | #else /* CONFIG_SMP */ |
37 | 39 | ||
40 | #define smp_cpu_mtid 0 | ||
41 | |||
38 | static inline void smp_call_ipl_cpu(void (*func)(void *), void *data) | 42 | static inline void smp_call_ipl_cpu(void (*func)(void *), void *data) |
39 | { | 43 | { |
40 | func(data); | 44 | func(data); |
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h index f92428e459f8..73f12d21af4d 100644 --- a/arch/s390/include/asm/sysinfo.h +++ b/arch/s390/include/asm/sysinfo.h | |||
@@ -90,7 +90,11 @@ struct sysinfo_2_2_2 { | |||
90 | unsigned short cpus_reserved; | 90 | unsigned short cpus_reserved; |
91 | char name[8]; | 91 | char name[8]; |
92 | unsigned int caf; | 92 | unsigned int caf; |
93 | char reserved_2[16]; | 93 | char reserved_2[8]; |
94 | unsigned char mt_installed; | ||
95 | unsigned char mt_general; | ||
96 | unsigned char mt_psmtid; | ||
97 | char reserved_3[5]; | ||
94 | unsigned short cpus_dedicated; | 98 | unsigned short cpus_dedicated; |
95 | unsigned short cpus_shared; | 99 | unsigned short cpus_shared; |
96 | }; | 100 | }; |
@@ -120,26 +124,28 @@ struct sysinfo_3_2_2 { | |||
120 | 124 | ||
121 | extern int topology_max_mnest; | 125 | extern int topology_max_mnest; |
122 | 126 | ||
123 | #define TOPOLOGY_CPU_BITS 64 | 127 | #define TOPOLOGY_CORE_BITS 64 |
124 | #define TOPOLOGY_NR_MAG 6 | 128 | #define TOPOLOGY_NR_MAG 6 |
125 | 129 | ||
126 | struct topology_cpu { | 130 | struct topology_core { |
127 | unsigned char reserved0[4]; | 131 | unsigned char nl; |
132 | unsigned char reserved0[3]; | ||
128 | unsigned char :6; | 133 | unsigned char :6; |
129 | unsigned char pp:2; | 134 | unsigned char pp:2; |
130 | unsigned char reserved1; | 135 | unsigned char reserved1; |
131 | unsigned short origin; | 136 | unsigned short origin; |
132 | unsigned long mask[TOPOLOGY_CPU_BITS / BITS_PER_LONG]; | 137 | unsigned long mask[TOPOLOGY_CORE_BITS / BITS_PER_LONG]; |
133 | }; | 138 | }; |
134 | 139 | ||
135 | struct topology_container { | 140 | struct topology_container { |
136 | unsigned char reserved[7]; | 141 | unsigned char nl; |
142 | unsigned char reserved[6]; | ||
137 | unsigned char id; | 143 | unsigned char id; |
138 | }; | 144 | }; |
139 | 145 | ||
140 | union topology_entry { | 146 | union topology_entry { |
141 | unsigned char nl; | 147 | unsigned char nl; |
142 | struct topology_cpu cpu; | 148 | struct topology_core cpu; |
143 | struct topology_container container; | 149 | struct topology_container container; |
144 | }; | 150 | }; |
145 | 151 | ||
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index 56af53093d24..c4fbb9527c5c 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h | |||
@@ -9,9 +9,11 @@ struct cpu; | |||
9 | #ifdef CONFIG_SCHED_BOOK | 9 | #ifdef CONFIG_SCHED_BOOK |
10 | 10 | ||
11 | struct cpu_topology_s390 { | 11 | struct cpu_topology_s390 { |
12 | unsigned short thread_id; | ||
12 | unsigned short core_id; | 13 | unsigned short core_id; |
13 | unsigned short socket_id; | 14 | unsigned short socket_id; |
14 | unsigned short book_id; | 15 | unsigned short book_id; |
16 | cpumask_t thread_mask; | ||
15 | cpumask_t core_mask; | 17 | cpumask_t core_mask; |
16 | cpumask_t book_mask; | 18 | cpumask_t book_mask; |
17 | }; | 19 | }; |
@@ -19,6 +21,8 @@ struct cpu_topology_s390 { | |||
19 | extern struct cpu_topology_s390 cpu_topology[NR_CPUS]; | 21 | extern struct cpu_topology_s390 cpu_topology[NR_CPUS]; |
20 | 22 | ||
21 | #define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id) | 23 | #define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id) |
24 | #define topology_thread_id(cpu) (cpu_topology[cpu].thread_id) | ||
25 | #define topology_thread_cpumask(cpu) (&cpu_topology[cpu].thread_mask) | ||
22 | #define topology_core_id(cpu) (cpu_topology[cpu].core_id) | 26 | #define topology_core_id(cpu) (cpu_topology[cpu].core_id) |
23 | #define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_mask) | 27 | #define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_mask) |
24 | #define topology_book_id(cpu) (cpu_topology[cpu].book_id) | 28 | #define topology_book_id(cpu) (cpu_topology[cpu].book_id) |
diff --git a/arch/s390/include/uapi/asm/hypfs.h b/arch/s390/include/uapi/asm/hypfs.h index 37998b449531..b3fe12d8dd87 100644 --- a/arch/s390/include/uapi/asm/hypfs.h +++ b/arch/s390/include/uapi/asm/hypfs.h | |||
@@ -1,16 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * IOCTL interface for hypfs | 2 | * Structures for hypfs interface |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2013 | 4 | * Copyright IBM Corp. 2013 |
5 | * | 5 | * |
6 | * Author: Martin Schwidefsky <schwidefsky@de.ibm.com> | 6 | * Author: Martin Schwidefsky <schwidefsky@de.ibm.com> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _ASM_HYPFS_CTL_H | 9 | #ifndef _ASM_HYPFS_H |
10 | #define _ASM_HYPFS_CTL_H | 10 | #define _ASM_HYPFS_H |
11 | 11 | ||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | 13 | ||
14 | /* | ||
15 | * IOCTL for binary interface /sys/kernel/debug/diag_304 | ||
16 | */ | ||
14 | struct hypfs_diag304 { | 17 | struct hypfs_diag304 { |
15 | __u32 args[2]; | 18 | __u32 args[2]; |
16 | __u64 data; | 19 | __u64 data; |
@@ -22,4 +25,30 @@ struct hypfs_diag304 { | |||
22 | #define HYPFS_DIAG304 \ | 25 | #define HYPFS_DIAG304 \ |
23 | _IOWR(HYPFS_IOCTL_MAGIC, 0x20, struct hypfs_diag304) | 26 | _IOWR(HYPFS_IOCTL_MAGIC, 0x20, struct hypfs_diag304) |
24 | 27 | ||
28 | /* | ||
29 | * Structures for binary interface /sys/kernel/debug/diag_0c | ||
30 | */ | ||
31 | struct hypfs_diag0c_hdr { | ||
32 | __u64 len; /* Length of diag0c buffer without header */ | ||
33 | __u16 version; /* Version of header */ | ||
34 | char reserved1[6]; /* Reserved */ | ||
35 | char tod_ext[16]; /* TOD clock for diag0c */ | ||
36 | __u64 count; /* Number of entries (CPUs) in diag0c array */ | ||
37 | char reserved2[24]; /* Reserved */ | ||
38 | }; | ||
39 | |||
40 | struct hypfs_diag0c_entry { | ||
41 | char date[8]; /* MM/DD/YY in EBCDIC */ | ||
42 | char time[8]; /* HH:MM:SS in EBCDIC */ | ||
43 | __u64 virtcpu; /* Virtual time consumed by the virt CPU (us) */ | ||
44 | __u64 totalproc; /* Total of virtual and simulation time (us) */ | ||
45 | __u32 cpu; /* Linux logical CPU number */ | ||
46 | __u32 reserved; /* Align to 8 byte */ | ||
47 | }; | ||
48 | |||
49 | struct hypfs_diag0c_data { | ||
50 | struct hypfs_diag0c_hdr hdr; /* 64 byte header */ | ||
51 | struct hypfs_diag0c_entry entry[]; /* diag0c entry array */ | ||
52 | }; | ||
53 | |||
25 | #endif | 54 | #endif |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 204c43a4c245..31fab2676fe9 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -4,8 +4,8 @@ | |||
4 | 4 | ||
5 | ifdef CONFIG_FUNCTION_TRACER | 5 | ifdef CONFIG_FUNCTION_TRACER |
6 | # Don't trace early setup code and tracing code | 6 | # Don't trace early setup code and tracing code |
7 | CFLAGS_REMOVE_early.o = -pg | 7 | CFLAGS_REMOVE_early.o = $(CC_FLAGS_FTRACE) |
8 | CFLAGS_REMOVE_ftrace.o = -pg | 8 | CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) |
9 | endif | 9 | endif |
10 | 10 | ||
11 | # | 11 | # |
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S index 797a823a2275..f74a53d339b0 100644 --- a/arch/s390/kernel/base.S +++ b/arch/s390/kernel/base.S | |||
@@ -97,7 +97,8 @@ ENTRY(diag308_reset) | |||
97 | lg %r4,0(%r4) # Save PSW | 97 | lg %r4,0(%r4) # Save PSW |
98 | sturg %r4,%r3 # Use sturg, because of large pages | 98 | sturg %r4,%r3 # Use sturg, because of large pages |
99 | lghi %r1,1 | 99 | lghi %r1,1 |
100 | diag %r1,%r1,0x308 | 100 | lghi %r0,0 |
101 | diag %r0,%r1,0x308 | ||
101 | .Lrestart_part2: | 102 | .Lrestart_part2: |
102 | lhi %r0,0 # Load r0 with zero | 103 | lhi %r0,0 # Load r0 with zero |
103 | lhi %r1,2 # Use mode 2 = ESAME (dump) | 104 | lhi %r1,2 # Use mode 2 = ESAME (dump) |
diff --git a/arch/s390/kernel/cache.c b/arch/s390/kernel/cache.c index c0b03c28d157..632fa06ea162 100644 --- a/arch/s390/kernel/cache.c +++ b/arch/s390/kernel/cache.c | |||
@@ -5,37 +5,11 @@ | |||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | 5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/notifier.h> | ||
9 | #include <linux/seq_file.h> | 8 | #include <linux/seq_file.h> |
10 | #include <linux/init.h> | ||
11 | #include <linux/list.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/cpu.h> | 9 | #include <linux/cpu.h> |
10 | #include <linux/cacheinfo.h> | ||
14 | #include <asm/facility.h> | 11 | #include <asm/facility.h> |
15 | 12 | ||
16 | struct cache { | ||
17 | unsigned long size; | ||
18 | unsigned int line_size; | ||
19 | unsigned int associativity; | ||
20 | unsigned int nr_sets; | ||
21 | unsigned int level : 3; | ||
22 | unsigned int type : 2; | ||
23 | unsigned int private : 1; | ||
24 | struct list_head list; | ||
25 | }; | ||
26 | |||
27 | struct cache_dir { | ||
28 | struct kobject *kobj; | ||
29 | struct cache_index_dir *index; | ||
30 | }; | ||
31 | |||
32 | struct cache_index_dir { | ||
33 | struct kobject kobj; | ||
34 | int cpu; | ||
35 | struct cache *cache; | ||
36 | struct cache_index_dir *next; | ||
37 | }; | ||
38 | |||
39 | enum { | 13 | enum { |
40 | CACHE_SCOPE_NOTEXISTS, | 14 | CACHE_SCOPE_NOTEXISTS, |
41 | CACHE_SCOPE_PRIVATE, | 15 | CACHE_SCOPE_PRIVATE, |
@@ -44,10 +18,10 @@ enum { | |||
44 | }; | 18 | }; |
45 | 19 | ||
46 | enum { | 20 | enum { |
47 | CACHE_TYPE_SEPARATE, | 21 | CTYPE_SEPARATE, |
48 | CACHE_TYPE_DATA, | 22 | CTYPE_DATA, |
49 | CACHE_TYPE_INSTRUCTION, | 23 | CTYPE_INSTRUCTION, |
50 | CACHE_TYPE_UNIFIED, | 24 | CTYPE_UNIFIED, |
51 | }; | 25 | }; |
52 | 26 | ||
53 | enum { | 27 | enum { |
@@ -70,37 +44,60 @@ struct cache_info { | |||
70 | }; | 44 | }; |
71 | 45 | ||
72 | #define CACHE_MAX_LEVEL 8 | 46 | #define CACHE_MAX_LEVEL 8 |
73 | |||
74 | union cache_topology { | 47 | union cache_topology { |
75 | struct cache_info ci[CACHE_MAX_LEVEL]; | 48 | struct cache_info ci[CACHE_MAX_LEVEL]; |
76 | unsigned long long raw; | 49 | unsigned long long raw; |
77 | }; | 50 | }; |
78 | 51 | ||
79 | static const char * const cache_type_string[] = { | 52 | static const char * const cache_type_string[] = { |
80 | "Data", | 53 | "", |
81 | "Instruction", | 54 | "Instruction", |
55 | "Data", | ||
56 | "", | ||
82 | "Unified", | 57 | "Unified", |
83 | }; | 58 | }; |
84 | 59 | ||
85 | static struct cache_dir *cache_dir_cpu[NR_CPUS]; | 60 | static const enum cache_type cache_type_map[] = { |
86 | static LIST_HEAD(cache_list); | 61 | [CTYPE_SEPARATE] = CACHE_TYPE_SEPARATE, |
62 | [CTYPE_DATA] = CACHE_TYPE_DATA, | ||
63 | [CTYPE_INSTRUCTION] = CACHE_TYPE_INST, | ||
64 | [CTYPE_UNIFIED] = CACHE_TYPE_UNIFIED, | ||
65 | }; | ||
87 | 66 | ||
88 | void show_cacheinfo(struct seq_file *m) | 67 | void show_cacheinfo(struct seq_file *m) |
89 | { | 68 | { |
90 | struct cache *cache; | 69 | struct cpu_cacheinfo *this_cpu_ci; |
91 | int index = 0; | 70 | struct cacheinfo *cache; |
71 | int idx; | ||
92 | 72 | ||
93 | list_for_each_entry(cache, &cache_list, list) { | 73 | get_online_cpus(); |
94 | seq_printf(m, "cache%-11d: ", index); | 74 | this_cpu_ci = get_cpu_cacheinfo(cpumask_any(cpu_online_mask)); |
75 | for (idx = 0; idx < this_cpu_ci->num_leaves; idx++) { | ||
76 | cache = this_cpu_ci->info_list + idx; | ||
77 | seq_printf(m, "cache%-11d: ", idx); | ||
95 | seq_printf(m, "level=%d ", cache->level); | 78 | seq_printf(m, "level=%d ", cache->level); |
96 | seq_printf(m, "type=%s ", cache_type_string[cache->type]); | 79 | seq_printf(m, "type=%s ", cache_type_string[cache->type]); |
97 | seq_printf(m, "scope=%s ", cache->private ? "Private" : "Shared"); | 80 | seq_printf(m, "scope=%s ", |
98 | seq_printf(m, "size=%luK ", cache->size >> 10); | 81 | cache->disable_sysfs ? "Shared" : "Private"); |
99 | seq_printf(m, "line_size=%u ", cache->line_size); | 82 | seq_printf(m, "size=%dK ", cache->size >> 10); |
100 | seq_printf(m, "associativity=%d", cache->associativity); | 83 | seq_printf(m, "line_size=%u ", cache->coherency_line_size); |
84 | seq_printf(m, "associativity=%d", cache->ways_of_associativity); | ||
101 | seq_puts(m, "\n"); | 85 | seq_puts(m, "\n"); |
102 | index++; | ||
103 | } | 86 | } |
87 | put_online_cpus(); | ||
88 | } | ||
89 | |||
90 | static inline enum cache_type get_cache_type(struct cache_info *ci, int level) | ||
91 | { | ||
92 | if (level >= CACHE_MAX_LEVEL) | ||
93 | return CACHE_TYPE_NOCACHE; | ||
94 | |||
95 | ci += level; | ||
96 | |||
97 | if (ci->scope != CACHE_SCOPE_SHARED && ci->scope != CACHE_SCOPE_PRIVATE) | ||
98 | return CACHE_TYPE_NOCACHE; | ||
99 | |||
100 | return cache_type_map[ci->type]; | ||
104 | } | 101 | } |
105 | 102 | ||
106 | static inline unsigned long ecag(int ai, int li, int ti) | 103 | static inline unsigned long ecag(int ai, int li, int ti) |
@@ -113,277 +110,79 @@ static inline unsigned long ecag(int ai, int li, int ti) | |||
113 | return val; | 110 | return val; |
114 | } | 111 | } |
115 | 112 | ||
116 | static int __init cache_add(int level, int private, int type) | 113 | static void ci_leaf_init(struct cacheinfo *this_leaf, int private, |
114 | enum cache_type type, unsigned int level) | ||
117 | { | 115 | { |
118 | struct cache *cache; | 116 | int ti, num_sets; |
119 | int ti; | 117 | int cpu = smp_processor_id(); |
120 | 118 | ||
121 | cache = kzalloc(sizeof(*cache), GFP_KERNEL); | 119 | if (type == CACHE_TYPE_INST) |
122 | if (!cache) | ||
123 | return -ENOMEM; | ||
124 | if (type == CACHE_TYPE_INSTRUCTION) | ||
125 | ti = CACHE_TI_INSTRUCTION; | 120 | ti = CACHE_TI_INSTRUCTION; |
126 | else | 121 | else |
127 | ti = CACHE_TI_UNIFIED; | 122 | ti = CACHE_TI_UNIFIED; |
128 | cache->size = ecag(EXTRACT_SIZE, level, ti); | ||
129 | cache->line_size = ecag(EXTRACT_LINE_SIZE, level, ti); | ||
130 | cache->associativity = ecag(EXTRACT_ASSOCIATIVITY, level, ti); | ||
131 | cache->nr_sets = cache->size / cache->associativity; | ||
132 | cache->nr_sets /= cache->line_size; | ||
133 | cache->private = private; | ||
134 | cache->level = level + 1; | ||
135 | cache->type = type - 1; | ||
136 | list_add_tail(&cache->list, &cache_list); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static void __init cache_build_info(void) | ||
141 | { | ||
142 | struct cache *cache, *next; | ||
143 | union cache_topology ct; | ||
144 | int level, private, rc; | ||
145 | |||
146 | ct.raw = ecag(EXTRACT_TOPOLOGY, 0, 0); | ||
147 | for (level = 0; level < CACHE_MAX_LEVEL; level++) { | ||
148 | switch (ct.ci[level].scope) { | ||
149 | case CACHE_SCOPE_SHARED: | ||
150 | private = 0; | ||
151 | break; | ||
152 | case CACHE_SCOPE_PRIVATE: | ||
153 | private = 1; | ||
154 | break; | ||
155 | default: | ||
156 | return; | ||
157 | } | ||
158 | if (ct.ci[level].type == CACHE_TYPE_SEPARATE) { | ||
159 | rc = cache_add(level, private, CACHE_TYPE_DATA); | ||
160 | rc |= cache_add(level, private, CACHE_TYPE_INSTRUCTION); | ||
161 | } else { | ||
162 | rc = cache_add(level, private, ct.ci[level].type); | ||
163 | } | ||
164 | if (rc) | ||
165 | goto error; | ||
166 | } | ||
167 | return; | ||
168 | error: | ||
169 | list_for_each_entry_safe(cache, next, &cache_list, list) { | ||
170 | list_del(&cache->list); | ||
171 | kfree(cache); | ||
172 | } | ||
173 | } | ||
174 | |||
175 | static struct cache_dir *cache_create_cache_dir(int cpu) | ||
176 | { | ||
177 | struct cache_dir *cache_dir; | ||
178 | struct kobject *kobj = NULL; | ||
179 | struct device *dev; | ||
180 | |||
181 | dev = get_cpu_device(cpu); | ||
182 | if (!dev) | ||
183 | goto out; | ||
184 | kobj = kobject_create_and_add("cache", &dev->kobj); | ||
185 | if (!kobj) | ||
186 | goto out; | ||
187 | cache_dir = kzalloc(sizeof(*cache_dir), GFP_KERNEL); | ||
188 | if (!cache_dir) | ||
189 | goto out; | ||
190 | cache_dir->kobj = kobj; | ||
191 | cache_dir_cpu[cpu] = cache_dir; | ||
192 | return cache_dir; | ||
193 | out: | ||
194 | kobject_put(kobj); | ||
195 | return NULL; | ||
196 | } | ||
197 | |||
198 | static struct cache_index_dir *kobj_to_cache_index_dir(struct kobject *kobj) | ||
199 | { | ||
200 | return container_of(kobj, struct cache_index_dir, kobj); | ||
201 | } | ||
202 | |||
203 | static void cache_index_release(struct kobject *kobj) | ||
204 | { | ||
205 | struct cache_index_dir *index; | ||
206 | |||
207 | index = kobj_to_cache_index_dir(kobj); | ||
208 | kfree(index); | ||
209 | } | ||
210 | |||
211 | static ssize_t cache_index_show(struct kobject *kobj, | ||
212 | struct attribute *attr, char *buf) | ||
213 | { | ||
214 | struct kobj_attribute *kobj_attr; | ||
215 | |||
216 | kobj_attr = container_of(attr, struct kobj_attribute, attr); | ||
217 | return kobj_attr->show(kobj, kobj_attr, buf); | ||
218 | } | ||
219 | |||
220 | #define DEFINE_CACHE_ATTR(_name, _format, _value) \ | ||
221 | static ssize_t cache_##_name##_show(struct kobject *kobj, \ | ||
222 | struct kobj_attribute *attr, \ | ||
223 | char *buf) \ | ||
224 | { \ | ||
225 | struct cache_index_dir *index; \ | ||
226 | \ | ||
227 | index = kobj_to_cache_index_dir(kobj); \ | ||
228 | return sprintf(buf, _format, _value); \ | ||
229 | } \ | ||
230 | static struct kobj_attribute cache_##_name##_attr = \ | ||
231 | __ATTR(_name, 0444, cache_##_name##_show, NULL); | ||
232 | 123 | ||
233 | DEFINE_CACHE_ATTR(size, "%luK\n", index->cache->size >> 10); | 124 | this_leaf->level = level + 1; |
234 | DEFINE_CACHE_ATTR(coherency_line_size, "%u\n", index->cache->line_size); | 125 | this_leaf->type = type; |
235 | DEFINE_CACHE_ATTR(number_of_sets, "%u\n", index->cache->nr_sets); | 126 | this_leaf->coherency_line_size = ecag(EXTRACT_LINE_SIZE, level, ti); |
236 | DEFINE_CACHE_ATTR(ways_of_associativity, "%u\n", index->cache->associativity); | 127 | this_leaf->ways_of_associativity = ecag(EXTRACT_ASSOCIATIVITY, |
237 | DEFINE_CACHE_ATTR(type, "%s\n", cache_type_string[index->cache->type]); | 128 | level, ti); |
238 | DEFINE_CACHE_ATTR(level, "%d\n", index->cache->level); | 129 | this_leaf->size = ecag(EXTRACT_SIZE, level, ti); |
239 | 130 | ||
240 | static ssize_t shared_cpu_map_func(struct kobject *kobj, int type, char *buf) | 131 | num_sets = this_leaf->size / this_leaf->coherency_line_size; |
241 | { | 132 | num_sets /= this_leaf->ways_of_associativity; |
242 | struct cache_index_dir *index; | 133 | this_leaf->number_of_sets = num_sets; |
243 | int len; | 134 | cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); |
244 | 135 | if (!private) | |
245 | index = kobj_to_cache_index_dir(kobj); | 136 | this_leaf->disable_sysfs = true; |
246 | len = type ? | ||
247 | cpulist_scnprintf(buf, PAGE_SIZE - 2, cpumask_of(index->cpu)) : | ||
248 | cpumask_scnprintf(buf, PAGE_SIZE - 2, cpumask_of(index->cpu)); | ||
249 | len += sprintf(&buf[len], "\n"); | ||
250 | return len; | ||
251 | } | ||
252 | |||
253 | static ssize_t shared_cpu_map_show(struct kobject *kobj, | ||
254 | struct kobj_attribute *attr, char *buf) | ||
255 | { | ||
256 | return shared_cpu_map_func(kobj, 0, buf); | ||
257 | } | 137 | } |
258 | static struct kobj_attribute cache_shared_cpu_map_attr = | ||
259 | __ATTR(shared_cpu_map, 0444, shared_cpu_map_show, NULL); | ||
260 | 138 | ||
261 | static ssize_t shared_cpu_list_show(struct kobject *kobj, | 139 | int init_cache_level(unsigned int cpu) |
262 | struct kobj_attribute *attr, char *buf) | ||
263 | { | 140 | { |
264 | return shared_cpu_map_func(kobj, 1, buf); | 141 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); |
265 | } | 142 | unsigned int level = 0, leaves = 0; |
266 | static struct kobj_attribute cache_shared_cpu_list_attr = | 143 | union cache_topology ct; |
267 | __ATTR(shared_cpu_list, 0444, shared_cpu_list_show, NULL); | 144 | enum cache_type ctype; |
268 | |||
269 | static struct attribute *cache_index_default_attrs[] = { | ||
270 | &cache_type_attr.attr, | ||
271 | &cache_size_attr.attr, | ||
272 | &cache_number_of_sets_attr.attr, | ||
273 | &cache_ways_of_associativity_attr.attr, | ||
274 | &cache_level_attr.attr, | ||
275 | &cache_coherency_line_size_attr.attr, | ||
276 | &cache_shared_cpu_map_attr.attr, | ||
277 | &cache_shared_cpu_list_attr.attr, | ||
278 | NULL, | ||
279 | }; | ||
280 | |||
281 | static const struct sysfs_ops cache_index_ops = { | ||
282 | .show = cache_index_show, | ||
283 | }; | ||
284 | |||
285 | static struct kobj_type cache_index_type = { | ||
286 | .sysfs_ops = &cache_index_ops, | ||
287 | .release = cache_index_release, | ||
288 | .default_attrs = cache_index_default_attrs, | ||
289 | }; | ||
290 | |||
291 | static int cache_create_index_dir(struct cache_dir *cache_dir, | ||
292 | struct cache *cache, int index, int cpu) | ||
293 | { | ||
294 | struct cache_index_dir *index_dir; | ||
295 | int rc; | ||
296 | |||
297 | index_dir = kzalloc(sizeof(*index_dir), GFP_KERNEL); | ||
298 | if (!index_dir) | ||
299 | return -ENOMEM; | ||
300 | index_dir->cache = cache; | ||
301 | index_dir->cpu = cpu; | ||
302 | rc = kobject_init_and_add(&index_dir->kobj, &cache_index_type, | ||
303 | cache_dir->kobj, "index%d", index); | ||
304 | if (rc) | ||
305 | goto out; | ||
306 | index_dir->next = cache_dir->index; | ||
307 | cache_dir->index = index_dir; | ||
308 | return 0; | ||
309 | out: | ||
310 | kfree(index_dir); | ||
311 | return rc; | ||
312 | } | ||
313 | 145 | ||
314 | static int cache_add_cpu(int cpu) | 146 | if (!this_cpu_ci) |
315 | { | 147 | return -EINVAL; |
316 | struct cache_dir *cache_dir; | ||
317 | struct cache *cache; | ||
318 | int rc, index = 0; | ||
319 | 148 | ||
320 | if (list_empty(&cache_list)) | 149 | ct.raw = ecag(EXTRACT_TOPOLOGY, 0, 0); |
321 | return 0; | 150 | do { |
322 | cache_dir = cache_create_cache_dir(cpu); | 151 | ctype = get_cache_type(&ct.ci[0], level); |
323 | if (!cache_dir) | 152 | if (ctype == CACHE_TYPE_NOCACHE) |
324 | return -ENOMEM; | ||
325 | list_for_each_entry(cache, &cache_list, list) { | ||
326 | if (!cache->private) | ||
327 | break; | 153 | break; |
328 | rc = cache_create_index_dir(cache_dir, cache, index, cpu); | 154 | /* Separate instruction and data caches */ |
329 | if (rc) | 155 | leaves += (ctype == CACHE_TYPE_SEPARATE) ? 2 : 1; |
330 | return rc; | 156 | } while (++level < CACHE_MAX_LEVEL); |
331 | index++; | ||
332 | } | ||
333 | return 0; | ||
334 | } | ||
335 | 157 | ||
336 | static void cache_remove_cpu(int cpu) | 158 | this_cpu_ci->num_levels = level; |
337 | { | 159 | this_cpu_ci->num_leaves = leaves; |
338 | struct cache_index_dir *index, *next; | ||
339 | struct cache_dir *cache_dir; | ||
340 | 160 | ||
341 | cache_dir = cache_dir_cpu[cpu]; | 161 | return 0; |
342 | if (!cache_dir) | ||
343 | return; | ||
344 | index = cache_dir->index; | ||
345 | while (index) { | ||
346 | next = index->next; | ||
347 | kobject_put(&index->kobj); | ||
348 | index = next; | ||
349 | } | ||
350 | kobject_put(cache_dir->kobj); | ||
351 | kfree(cache_dir); | ||
352 | cache_dir_cpu[cpu] = NULL; | ||
353 | } | 162 | } |
354 | 163 | ||
355 | static int cache_hotplug(struct notifier_block *nfb, unsigned long action, | 164 | int populate_cache_leaves(unsigned int cpu) |
356 | void *hcpu) | ||
357 | { | 165 | { |
358 | int cpu = (long)hcpu; | 166 | unsigned int level, idx, pvt; |
359 | int rc = 0; | 167 | union cache_topology ct; |
168 | enum cache_type ctype; | ||
169 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); | ||
170 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; | ||
360 | 171 | ||
361 | switch (action & ~CPU_TASKS_FROZEN) { | 172 | ct.raw = ecag(EXTRACT_TOPOLOGY, 0, 0); |
362 | case CPU_ONLINE: | 173 | for (idx = 0, level = 0; level < this_cpu_ci->num_levels && |
363 | rc = cache_add_cpu(cpu); | 174 | idx < this_cpu_ci->num_leaves; idx++, level++) { |
364 | if (rc) | 175 | if (!this_leaf) |
365 | cache_remove_cpu(cpu); | 176 | return -EINVAL; |
366 | break; | 177 | |
367 | case CPU_DEAD: | 178 | pvt = (ct.ci[level].scope == CACHE_SCOPE_PRIVATE) ? 1 : 0; |
368 | cache_remove_cpu(cpu); | 179 | ctype = get_cache_type(&ct.ci[0], level); |
369 | break; | 180 | if (ctype == CACHE_TYPE_SEPARATE) { |
181 | ci_leaf_init(this_leaf++, pvt, CACHE_TYPE_DATA, level); | ||
182 | ci_leaf_init(this_leaf++, pvt, CACHE_TYPE_INST, level); | ||
183 | } else { | ||
184 | ci_leaf_init(this_leaf++, pvt, ctype, level); | ||
185 | } | ||
370 | } | 186 | } |
371 | return rc ? NOTIFY_BAD : NOTIFY_OK; | ||
372 | } | ||
373 | |||
374 | static int __init cache_init(void) | ||
375 | { | ||
376 | int cpu; | ||
377 | |||
378 | if (!test_facility(34)) | ||
379 | return 0; | ||
380 | cache_build_info(); | ||
381 | |||
382 | cpu_notifier_register_begin(); | ||
383 | for_each_online_cpu(cpu) | ||
384 | cache_add_cpu(cpu); | ||
385 | __hotcpu_notifier(cache_hotplug, 0); | ||
386 | cpu_notifier_register_done(); | ||
387 | return 0; | 187 | return 0; |
388 | } | 188 | } |
389 | device_initcall(cache_init); | ||
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index f3762937dd82..533430307da8 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c | |||
@@ -137,7 +137,7 @@ enum { | |||
137 | INSTR_RSI_RRP, | 137 | INSTR_RSI_RRP, |
138 | INSTR_RSL_LRDFU, INSTR_RSL_R0RD, | 138 | INSTR_RSL_LRDFU, INSTR_RSL_R0RD, |
139 | INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, INSTR_RSY_RURD, | 139 | INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, INSTR_RSY_RURD, |
140 | INSTR_RSY_RDRM, | 140 | INSTR_RSY_RDRM, INSTR_RSY_RMRD, |
141 | INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, INSTR_RS_RRRD, | 141 | INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, INSTR_RS_RRRD, |
142 | INSTR_RS_RURD, | 142 | INSTR_RS_RURD, |
143 | INSTR_RXE_FRRD, INSTR_RXE_RRRD, INSTR_RXE_RRRDM, | 143 | INSTR_RXE_FRRD, INSTR_RXE_RRRD, INSTR_RXE_RRRDM, |
@@ -226,7 +226,6 @@ static const struct s390_operand operands[] = | |||
226 | [U16_32] = { 16, 32, 0 }, | 226 | [U16_32] = { 16, 32, 0 }, |
227 | [J16_16] = { 16, 16, OPERAND_PCREL }, | 227 | [J16_16] = { 16, 16, OPERAND_PCREL }, |
228 | [J16_32] = { 16, 32, OPERAND_PCREL }, | 228 | [J16_32] = { 16, 32, OPERAND_PCREL }, |
229 | [I16_32] = { 16, 32, OPERAND_SIGNED }, | ||
230 | [I24_24] = { 24, 24, OPERAND_SIGNED }, | 229 | [I24_24] = { 24, 24, OPERAND_SIGNED }, |
231 | [J32_16] = { 32, 16, OPERAND_PCREL }, | 230 | [J32_16] = { 32, 16, OPERAND_PCREL }, |
232 | [I32_16] = { 32, 16, OPERAND_SIGNED }, | 231 | [I32_16] = { 32, 16, OPERAND_SIGNED }, |
@@ -308,6 +307,7 @@ static const unsigned char formats[][7] = { | |||
308 | [INSTR_RSY_AARD] = { 0xff, A_8,A_12,D20_20,B_16,0,0 }, | 307 | [INSTR_RSY_AARD] = { 0xff, A_8,A_12,D20_20,B_16,0,0 }, |
309 | [INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 }, | 308 | [INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 }, |
310 | [INSTR_RSY_RDRM] = { 0xff, R_8,D20_20,B_16,U4_12,0,0 }, | 309 | [INSTR_RSY_RDRM] = { 0xff, R_8,D20_20,B_16,U4_12,0,0 }, |
310 | [INSTR_RSY_RMRD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 }, | ||
311 | [INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 }, | 311 | [INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 }, |
312 | [INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 }, | 312 | [INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 }, |
313 | [INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 }, | 313 | [INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 }, |
@@ -451,7 +451,8 @@ enum { | |||
451 | LONG_INSN_VERLLV, | 451 | LONG_INSN_VERLLV, |
452 | LONG_INSN_VESRAV, | 452 | LONG_INSN_VESRAV, |
453 | LONG_INSN_VESRLV, | 453 | LONG_INSN_VESRLV, |
454 | LONG_INSN_VSBCBI | 454 | LONG_INSN_VSBCBI, |
455 | LONG_INSN_STCCTM | ||
455 | }; | 456 | }; |
456 | 457 | ||
457 | static char *long_insn_name[] = { | 458 | static char *long_insn_name[] = { |
@@ -531,6 +532,7 @@ static char *long_insn_name[] = { | |||
531 | [LONG_INSN_VESRAV] = "vesrav", | 532 | [LONG_INSN_VESRAV] = "vesrav", |
532 | [LONG_INSN_VESRLV] = "vesrlv", | 533 | [LONG_INSN_VESRLV] = "vesrlv", |
533 | [LONG_INSN_VSBCBI] = "vsbcbi", | 534 | [LONG_INSN_VSBCBI] = "vsbcbi", |
535 | [LONG_INSN_STCCTM] = "stcctm", | ||
534 | }; | 536 | }; |
535 | 537 | ||
536 | static struct s390_insn opcode[] = { | 538 | static struct s390_insn opcode[] = { |
@@ -1656,6 +1658,7 @@ static struct s390_insn opcode_eb[] = { | |||
1656 | { "lric", 0x60, INSTR_RSY_RDRM }, | 1658 | { "lric", 0x60, INSTR_RSY_RDRM }, |
1657 | { "stric", 0x61, INSTR_RSY_RDRM }, | 1659 | { "stric", 0x61, INSTR_RSY_RDRM }, |
1658 | { "mric", 0x62, INSTR_RSY_RDRM }, | 1660 | { "mric", 0x62, INSTR_RSY_RDRM }, |
1661 | { { 0, LONG_INSN_STCCTM }, 0x17, INSTR_RSY_RMRD }, | ||
1659 | #endif | 1662 | #endif |
1660 | { "rll", 0x1d, INSTR_RSY_RRRD }, | 1663 | { "rll", 0x1d, INSTR_RSY_RRRD }, |
1661 | { "mvclu", 0x8e, INSTR_RSY_RRRD }, | 1664 | { "mvclu", 0x8e, INSTR_RSY_RRRD }, |
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 302ac1f7f8e7..70a329450901 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -393,9 +393,27 @@ static __init void detect_machine_facilities(void) | |||
393 | S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_LC; | 393 | S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_LC; |
394 | if (test_facility(129)) | 394 | if (test_facility(129)) |
395 | S390_lowcore.machine_flags |= MACHINE_FLAG_VX; | 395 | S390_lowcore.machine_flags |= MACHINE_FLAG_VX; |
396 | if (test_facility(128)) | ||
397 | S390_lowcore.machine_flags |= MACHINE_FLAG_CAD; | ||
396 | #endif | 398 | #endif |
397 | } | 399 | } |
398 | 400 | ||
401 | static int __init nocad_setup(char *str) | ||
402 | { | ||
403 | S390_lowcore.machine_flags &= ~MACHINE_FLAG_CAD; | ||
404 | return 0; | ||
405 | } | ||
406 | early_param("nocad", nocad_setup); | ||
407 | |||
408 | static int __init cad_init(void) | ||
409 | { | ||
410 | if (MACHINE_HAS_CAD) | ||
411 | /* Enable problem state CAD. */ | ||
412 | __ctl_set_bit(2, 3); | ||
413 | return 0; | ||
414 | } | ||
415 | early_initcall(cad_init); | ||
416 | |||
399 | static __init void rescue_initrd(void) | 417 | static __init void rescue_initrd(void) |
400 | { | 418 | { |
401 | #ifdef CONFIG_BLK_DEV_INITRD | 419 | #ifdef CONFIG_BLK_DEV_INITRD |
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index 8e61393c8275..834df047d35f 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h | |||
@@ -71,9 +71,11 @@ struct s390_mmap_arg_struct; | |||
71 | struct fadvise64_64_args; | 71 | struct fadvise64_64_args; |
72 | struct old_sigaction; | 72 | struct old_sigaction; |
73 | 73 | ||
74 | long sys_rt_sigreturn(void); | ||
75 | long sys_sigreturn(void); | ||
76 | |||
74 | long sys_s390_personality(unsigned int personality); | 77 | long sys_s390_personality(unsigned int personality); |
75 | long sys_s390_runtime_instr(int command, int signum); | 78 | long sys_s390_runtime_instr(int command, int signum); |
76 | |||
77 | long sys_s390_pci_mmio_write(unsigned long, const void __user *, size_t); | 79 | long sys_s390_pci_mmio_write(unsigned long, const void __user *, size_t); |
78 | long sys_s390_pci_mmio_read(unsigned long, void __user *, size_t); | 80 | long sys_s390_pci_mmio_read(unsigned long, void __user *, size_t); |
79 | #endif /* _ENTRY_H */ | 81 | #endif /* _ENTRY_H */ |
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index b86bb8823f15..82c19899574f 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c | |||
@@ -46,6 +46,13 @@ | |||
46 | * lg %r14,8(%r15) # offset 18 | 46 | * lg %r14,8(%r15) # offset 18 |
47 | * The jg instruction branches to offset 24 to skip as many instructions | 47 | * The jg instruction branches to offset 24 to skip as many instructions |
48 | * as possible. | 48 | * as possible. |
49 | * In case we use gcc's hotpatch feature the original and also the disabled | ||
50 | * function prologue contains only a single six byte instruction and looks | ||
51 | * like this: | ||
52 | * > brcl 0,0 # offset 0 | ||
53 | * To enable ftrace the code gets patched like above and afterwards looks | ||
54 | * like this: | ||
55 | * > brasl %r0,ftrace_caller # offset 0 | ||
49 | */ | 56 | */ |
50 | 57 | ||
51 | unsigned long ftrace_plt; | 58 | unsigned long ftrace_plt; |
@@ -59,62 +66,71 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, | |||
59 | int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, | 66 | int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, |
60 | unsigned long addr) | 67 | unsigned long addr) |
61 | { | 68 | { |
62 | struct ftrace_insn insn; | 69 | struct ftrace_insn orig, new, old; |
63 | unsigned short op; | 70 | |
64 | void *from, *to; | 71 | if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) |
65 | size_t size; | ||
66 | |||
67 | ftrace_generate_nop_insn(&insn); | ||
68 | size = sizeof(insn); | ||
69 | from = &insn; | ||
70 | to = (void *) rec->ip; | ||
71 | if (probe_kernel_read(&op, (void *) rec->ip, sizeof(op))) | ||
72 | return -EFAULT; | 72 | return -EFAULT; |
73 | /* | 73 | if (addr == MCOUNT_ADDR) { |
74 | * If we find a breakpoint instruction, a kprobe has been placed | 74 | /* Initial code replacement */ |
75 | * at the beginning of the function. We write the constant | 75 | #ifdef CC_USING_HOTPATCH |
76 | * KPROBE_ON_FTRACE_NOP into the remaining four bytes of the original | 76 | /* We expect to see brcl 0,0 */ |
77 | * instruction so that the kprobes handler can execute a nop, if it | 77 | ftrace_generate_nop_insn(&orig); |
78 | * reaches this breakpoint. | 78 | #else |
79 | */ | 79 | /* We expect to see stg r14,8(r15) */ |
80 | if (op == BREAKPOINT_INSTRUCTION) { | 80 | orig.opc = 0xe3e0; |
81 | size -= 2; | 81 | orig.disp = 0xf0080024; |
82 | from += 2; | 82 | #endif |
83 | to += 2; | 83 | ftrace_generate_nop_insn(&new); |
84 | insn.disp = KPROBE_ON_FTRACE_NOP; | 84 | } else if (old.opc == BREAKPOINT_INSTRUCTION) { |
85 | /* | ||
86 | * If we find a breakpoint instruction, a kprobe has been | ||
87 | * placed at the beginning of the function. We write the | ||
88 | * constant KPROBE_ON_FTRACE_NOP into the remaining four | ||
89 | * bytes of the original instruction so that the kprobes | ||
90 | * handler can execute a nop, if it reaches this breakpoint. | ||
91 | */ | ||
92 | new.opc = orig.opc = BREAKPOINT_INSTRUCTION; | ||
93 | orig.disp = KPROBE_ON_FTRACE_CALL; | ||
94 | new.disp = KPROBE_ON_FTRACE_NOP; | ||
95 | } else { | ||
96 | /* Replace ftrace call with a nop. */ | ||
97 | ftrace_generate_call_insn(&orig, rec->ip); | ||
98 | ftrace_generate_nop_insn(&new); | ||
85 | } | 99 | } |
86 | if (probe_kernel_write(to, from, size)) | 100 | /* Verify that the to be replaced code matches what we expect. */ |
101 | if (memcmp(&orig, &old, sizeof(old))) | ||
102 | return -EINVAL; | ||
103 | if (probe_kernel_write((void *) rec->ip, &new, sizeof(new))) | ||
87 | return -EPERM; | 104 | return -EPERM; |
88 | return 0; | 105 | return 0; |
89 | } | 106 | } |
90 | 107 | ||
91 | int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | 108 | int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) |
92 | { | 109 | { |
93 | struct ftrace_insn insn; | 110 | struct ftrace_insn orig, new, old; |
94 | unsigned short op; | 111 | |
95 | void *from, *to; | 112 | if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old))) |
96 | size_t size; | ||
97 | |||
98 | ftrace_generate_call_insn(&insn, rec->ip); | ||
99 | size = sizeof(insn); | ||
100 | from = &insn; | ||
101 | to = (void *) rec->ip; | ||
102 | if (probe_kernel_read(&op, (void *) rec->ip, sizeof(op))) | ||
103 | return -EFAULT; | 113 | return -EFAULT; |
104 | /* | 114 | if (old.opc == BREAKPOINT_INSTRUCTION) { |
105 | * If we find a breakpoint instruction, a kprobe has been placed | 115 | /* |
106 | * at the beginning of the function. We write the constant | 116 | * If we find a breakpoint instruction, a kprobe has been |
107 | * KPROBE_ON_FTRACE_CALL into the remaining four bytes of the original | 117 | * placed at the beginning of the function. We write the |
108 | * instruction so that the kprobes handler can execute a brasl if it | 118 | * constant KPROBE_ON_FTRACE_CALL into the remaining four |
109 | * reaches this breakpoint. | 119 | * bytes of the original instruction so that the kprobes |
110 | */ | 120 | * handler can execute a brasl if it reaches this breakpoint. |
111 | if (op == BREAKPOINT_INSTRUCTION) { | 121 | */ |
112 | size -= 2; | 122 | new.opc = orig.opc = BREAKPOINT_INSTRUCTION; |
113 | from += 2; | 123 | orig.disp = KPROBE_ON_FTRACE_NOP; |
114 | to += 2; | 124 | new.disp = KPROBE_ON_FTRACE_CALL; |
115 | insn.disp = KPROBE_ON_FTRACE_CALL; | 125 | } else { |
126 | /* Replace nop with an ftrace call. */ | ||
127 | ftrace_generate_nop_insn(&orig); | ||
128 | ftrace_generate_call_insn(&new, rec->ip); | ||
116 | } | 129 | } |
117 | if (probe_kernel_write(to, from, size)) | 130 | /* Verify that the to be replaced code matches what we expect. */ |
131 | if (memcmp(&orig, &old, sizeof(old))) | ||
132 | return -EINVAL; | ||
133 | if (probe_kernel_write((void *) rec->ip, &new, sizeof(new))) | ||
118 | return -EPERM; | 134 | return -EPERM; |
119 | return 0; | 135 | return 0; |
120 | } | 136 | } |
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index d62eee11f0b5..132f4c9ade60 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S | |||
@@ -436,7 +436,9 @@ ENTRY(startup_kdump) | |||
436 | # followed by the facility words. | 436 | # followed by the facility words. |
437 | 437 | ||
438 | #if defined(CONFIG_64BIT) | 438 | #if defined(CONFIG_64BIT) |
439 | #if defined(CONFIG_MARCH_ZEC12) | 439 | #if defined(CONFIG_MARCH_Z13) |
440 | .long 3, 0xc100eff2, 0xf46ce800, 0x00400000 | ||
441 | #elif defined(CONFIG_MARCH_ZEC12) | ||
440 | .long 3, 0xc100eff2, 0xf46ce800, 0x00400000 | 442 | .long 3, 0xc100eff2, 0xf46ce800, 0x00400000 |
441 | #elif defined(CONFIG_MARCH_Z196) | 443 | #elif defined(CONFIG_MARCH_Z196) |
442 | .long 2, 0xc100eff2, 0xf46c0000 | 444 | .long 2, 0xc100eff2, 0xf46c0000 |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 39badb9ca0b3..5c8651f36509 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -2074,7 +2074,8 @@ static void do_reset_calls(void) | |||
2074 | 2074 | ||
2075 | u32 dump_prefix_page; | 2075 | u32 dump_prefix_page; |
2076 | 2076 | ||
2077 | void s390_reset_system(void (*func)(void *), void *data) | 2077 | void s390_reset_system(void (*fn_pre)(void), |
2078 | void (*fn_post)(void *), void *data) | ||
2078 | { | 2079 | { |
2079 | struct _lowcore *lc; | 2080 | struct _lowcore *lc; |
2080 | 2081 | ||
@@ -2112,7 +2113,11 @@ void s390_reset_system(void (*func)(void *), void *data) | |||
2112 | /* Store status at absolute zero */ | 2113 | /* Store status at absolute zero */ |
2113 | store_status(); | 2114 | store_status(); |
2114 | 2115 | ||
2116 | /* Call function before reset */ | ||
2117 | if (fn_pre) | ||
2118 | fn_pre(); | ||
2115 | do_reset_calls(); | 2119 | do_reset_calls(); |
2116 | if (func) | 2120 | /* Call function after reset */ |
2117 | func(data); | 2121 | if (fn_post) |
2122 | fn_post(data); | ||
2118 | } | 2123 | } |
diff --git a/arch/s390/kernel/jump_label.c b/arch/s390/kernel/jump_label.c index b987ab2c1541..cb2d51e779df 100644 --- a/arch/s390/kernel/jump_label.c +++ b/arch/s390/kernel/jump_label.c | |||
@@ -22,31 +22,66 @@ struct insn_args { | |||
22 | enum jump_label_type type; | 22 | enum jump_label_type type; |
23 | }; | 23 | }; |
24 | 24 | ||
25 | static void jump_label_make_nop(struct jump_entry *entry, struct insn *insn) | ||
26 | { | ||
27 | /* brcl 0,0 */ | ||
28 | insn->opcode = 0xc004; | ||
29 | insn->offset = 0; | ||
30 | } | ||
31 | |||
32 | static void jump_label_make_branch(struct jump_entry *entry, struct insn *insn) | ||
33 | { | ||
34 | /* brcl 15,offset */ | ||
35 | insn->opcode = 0xc0f4; | ||
36 | insn->offset = (entry->target - entry->code) >> 1; | ||
37 | } | ||
38 | |||
39 | static void jump_label_bug(struct jump_entry *entry, struct insn *insn) | ||
40 | { | ||
41 | unsigned char *ipc = (unsigned char *)entry->code; | ||
42 | unsigned char *ipe = (unsigned char *)insn; | ||
43 | |||
44 | pr_emerg("Jump label code mismatch at %pS [%p]\n", ipc, ipc); | ||
45 | pr_emerg("Found: %02x %02x %02x %02x %02x %02x\n", | ||
46 | ipc[0], ipc[1], ipc[2], ipc[3], ipc[4], ipc[5]); | ||
47 | pr_emerg("Expected: %02x %02x %02x %02x %02x %02x\n", | ||
48 | ipe[0], ipe[1], ipe[2], ipe[3], ipe[4], ipe[5]); | ||
49 | panic("Corrupted kernel text"); | ||
50 | } | ||
51 | |||
52 | static struct insn orignop = { | ||
53 | .opcode = 0xc004, | ||
54 | .offset = JUMP_LABEL_NOP_OFFSET >> 1, | ||
55 | }; | ||
56 | |||
25 | static void __jump_label_transform(struct jump_entry *entry, | 57 | static void __jump_label_transform(struct jump_entry *entry, |
26 | enum jump_label_type type) | 58 | enum jump_label_type type, |
59 | int init) | ||
27 | { | 60 | { |
28 | struct insn insn; | 61 | struct insn old, new; |
29 | int rc; | ||
30 | 62 | ||
31 | if (type == JUMP_LABEL_ENABLE) { | 63 | if (type == JUMP_LABEL_ENABLE) { |
32 | /* brcl 15,offset */ | 64 | jump_label_make_nop(entry, &old); |
33 | insn.opcode = 0xc0f4; | 65 | jump_label_make_branch(entry, &new); |
34 | insn.offset = (entry->target - entry->code) >> 1; | ||
35 | } else { | 66 | } else { |
36 | /* brcl 0,0 */ | 67 | jump_label_make_branch(entry, &old); |
37 | insn.opcode = 0xc004; | 68 | jump_label_make_nop(entry, &new); |
38 | insn.offset = 0; | ||
39 | } | 69 | } |
40 | 70 | if (init) { | |
41 | rc = probe_kernel_write((void *)entry->code, &insn, JUMP_LABEL_NOP_SIZE); | 71 | if (memcmp((void *)entry->code, &orignop, sizeof(orignop))) |
42 | WARN_ON_ONCE(rc < 0); | 72 | jump_label_bug(entry, &old); |
73 | } else { | ||
74 | if (memcmp((void *)entry->code, &old, sizeof(old))) | ||
75 | jump_label_bug(entry, &old); | ||
76 | } | ||
77 | probe_kernel_write((void *)entry->code, &new, sizeof(new)); | ||
43 | } | 78 | } |
44 | 79 | ||
45 | static int __sm_arch_jump_label_transform(void *data) | 80 | static int __sm_arch_jump_label_transform(void *data) |
46 | { | 81 | { |
47 | struct insn_args *args = data; | 82 | struct insn_args *args = data; |
48 | 83 | ||
49 | __jump_label_transform(args->entry, args->type); | 84 | __jump_label_transform(args->entry, args->type, 0); |
50 | return 0; | 85 | return 0; |
51 | } | 86 | } |
52 | 87 | ||
@@ -64,7 +99,7 @@ void arch_jump_label_transform(struct jump_entry *entry, | |||
64 | void arch_jump_label_transform_static(struct jump_entry *entry, | 99 | void arch_jump_label_transform_static(struct jump_entry *entry, |
65 | enum jump_label_type type) | 100 | enum jump_label_type type) |
66 | { | 101 | { |
67 | __jump_label_transform(entry, type); | 102 | __jump_label_transform(entry, type, 1); |
68 | } | 103 | } |
69 | 104 | ||
70 | #endif | 105 | #endif |
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 1e4c710dfb92..f516edc1fbe3 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c | |||
@@ -69,7 +69,8 @@ static void copy_instruction(struct kprobe *p) | |||
69 | /* | 69 | /* |
70 | * If kprobes patches the instruction that is morphed by | 70 | * If kprobes patches the instruction that is morphed by |
71 | * ftrace make sure that kprobes always sees the branch | 71 | * ftrace make sure that kprobes always sees the branch |
72 | * "jg .+24" that skips the mcount block | 72 | * "jg .+24" that skips the mcount block or the "brcl 0,0" |
73 | * in case of hotpatch. | ||
73 | */ | 74 | */ |
74 | ftrace_generate_nop_insn((struct ftrace_insn *)p->ainsn.insn); | 75 | ftrace_generate_nop_insn((struct ftrace_insn *)p->ainsn.insn); |
75 | p->ainsn.is_ftrace_insn = 1; | 76 | p->ainsn.is_ftrace_insn = 1; |
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index 4685337fa7c6..fb0901ec4306 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c | |||
@@ -103,21 +103,18 @@ static int __init machine_kdump_pm_init(void) | |||
103 | return 0; | 103 | return 0; |
104 | } | 104 | } |
105 | arch_initcall(machine_kdump_pm_init); | 105 | arch_initcall(machine_kdump_pm_init); |
106 | #endif | ||
107 | 106 | ||
108 | /* | 107 | /* |
109 | * Start kdump: We expect here that a store status has been done on our CPU | 108 | * Start kdump: We expect here that a store status has been done on our CPU |
110 | */ | 109 | */ |
111 | static void __do_machine_kdump(void *image) | 110 | static void __do_machine_kdump(void *image) |
112 | { | 111 | { |
113 | #ifdef CONFIG_CRASH_DUMP | ||
114 | int (*start_kdump)(int) = (void *)((struct kimage *) image)->start; | 112 | int (*start_kdump)(int) = (void *)((struct kimage *) image)->start; |
115 | 113 | ||
116 | setup_regs(); | ||
117 | __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA); | 114 | __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA); |
118 | start_kdump(1); | 115 | start_kdump(1); |
119 | #endif | ||
120 | } | 116 | } |
117 | #endif | ||
121 | 118 | ||
122 | /* | 119 | /* |
123 | * Check if kdump checksums are valid: We call purgatory with parameter "0" | 120 | * Check if kdump checksums are valid: We call purgatory with parameter "0" |
@@ -249,18 +246,18 @@ static void __do_machine_kexec(void *data) | |||
249 | */ | 246 | */ |
250 | static void __machine_kexec(void *data) | 247 | static void __machine_kexec(void *data) |
251 | { | 248 | { |
252 | struct kimage *image = data; | ||
253 | |||
254 | __arch_local_irq_stosm(0x04); /* enable DAT */ | 249 | __arch_local_irq_stosm(0x04); /* enable DAT */ |
255 | pfault_fini(); | 250 | pfault_fini(); |
256 | tracing_off(); | 251 | tracing_off(); |
257 | debug_locks_off(); | 252 | debug_locks_off(); |
258 | if (image->type == KEXEC_TYPE_CRASH) { | 253 | #ifdef CONFIG_CRASH_DUMP |
254 | if (((struct kimage *) data)->type == KEXEC_TYPE_CRASH) { | ||
255 | |||
259 | lgr_info_log(); | 256 | lgr_info_log(); |
260 | s390_reset_system(__do_machine_kdump, data); | 257 | s390_reset_system(setup_regs, __do_machine_kdump, data); |
261 | } else { | 258 | } else |
262 | s390_reset_system(__do_machine_kexec, data); | 259 | #endif |
263 | } | 260 | s390_reset_system(NULL, __do_machine_kexec, data); |
264 | disabled_wait((unsigned long) __builtin_return_address(0)); | 261 | disabled_wait((unsigned long) __builtin_return_address(0)); |
265 | } | 262 | } |
266 | 263 | ||
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index b6dfc5bfcb89..e499370fbccb 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S | |||
@@ -27,7 +27,9 @@ ENTRY(ftrace_caller) | |||
27 | .globl ftrace_regs_caller | 27 | .globl ftrace_regs_caller |
28 | .set ftrace_regs_caller,ftrace_caller | 28 | .set ftrace_regs_caller,ftrace_caller |
29 | lgr %r1,%r15 | 29 | lgr %r1,%r15 |
30 | #ifndef CC_USING_HOTPATCH | ||
30 | aghi %r0,MCOUNT_RETURN_FIXUP | 31 | aghi %r0,MCOUNT_RETURN_FIXUP |
32 | #endif | ||
31 | aghi %r15,-STACK_FRAME_SIZE | 33 | aghi %r15,-STACK_FRAME_SIZE |
32 | stg %r1,__SF_BACKCHAIN(%r15) | 34 | stg %r1,__SF_BACKCHAIN(%r15) |
33 | stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15) | 35 | stg %r1,(STACK_PTREGS_GPRS+15*8)(%r15) |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index aa7a83948c7b..13fc0978ca7e 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -79,6 +79,14 @@ void release_thread(struct task_struct *dead_task) | |||
79 | { | 79 | { |
80 | } | 80 | } |
81 | 81 | ||
82 | #ifdef CONFIG_64BIT | ||
83 | void arch_release_task_struct(struct task_struct *tsk) | ||
84 | { | ||
85 | if (tsk->thread.vxrs) | ||
86 | kfree(tsk->thread.vxrs); | ||
87 | } | ||
88 | #endif | ||
89 | |||
82 | int copy_thread(unsigned long clone_flags, unsigned long new_stackp, | 90 | int copy_thread(unsigned long clone_flags, unsigned long new_stackp, |
83 | unsigned long arg, struct task_struct *p) | 91 | unsigned long arg, struct task_struct *p) |
84 | { | 92 | { |
@@ -243,13 +251,3 @@ unsigned long arch_randomize_brk(struct mm_struct *mm) | |||
243 | ret = PAGE_ALIGN(mm->brk + brk_rnd()); | 251 | ret = PAGE_ALIGN(mm->brk + brk_rnd()); |
244 | return (ret > mm->brk) ? ret : mm->brk; | 252 | return (ret > mm->brk) ? ret : mm->brk; |
245 | } | 253 | } |
246 | |||
247 | unsigned long randomize_et_dyn(unsigned long base) | ||
248 | { | ||
249 | unsigned long ret; | ||
250 | |||
251 | if (!(current->flags & PF_RANDOMIZE)) | ||
252 | return base; | ||
253 | ret = PAGE_ALIGN(base + brk_rnd()); | ||
254 | return (ret > base) ? ret : base; | ||
255 | } | ||
diff --git a/arch/s390/kernel/processor.c b/arch/s390/kernel/processor.c index dbdd33ee0102..26108232fcaa 100644 --- a/arch/s390/kernel/processor.c +++ b/arch/s390/kernel/processor.c | |||
@@ -8,16 +8,24 @@ | |||
8 | 8 | ||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/smp.h> | ||
12 | #include <linux/seq_file.h> | 11 | #include <linux/seq_file.h> |
13 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
14 | #include <linux/cpu.h> | 13 | #include <linux/cpu.h> |
15 | #include <asm/elf.h> | 14 | #include <asm/elf.h> |
16 | #include <asm/lowcore.h> | 15 | #include <asm/lowcore.h> |
17 | #include <asm/param.h> | 16 | #include <asm/param.h> |
17 | #include <asm/smp.h> | ||
18 | 18 | ||
19 | static DEFINE_PER_CPU(struct cpuid, cpu_id); | 19 | static DEFINE_PER_CPU(struct cpuid, cpu_id); |
20 | 20 | ||
21 | void cpu_relax(void) | ||
22 | { | ||
23 | if (!smp_cpu_mtid && MACHINE_HAS_DIAG44) | ||
24 | asm volatile("diag 0,0,0x44"); | ||
25 | barrier(); | ||
26 | } | ||
27 | EXPORT_SYMBOL(cpu_relax); | ||
28 | |||
21 | /* | 29 | /* |
22 | * cpu_init - initializes state that is per-CPU. | 30 | * cpu_init - initializes state that is per-CPU. |
23 | */ | 31 | */ |
diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S index a41f2c99dcc8..7e77e03378f3 100644 --- a/arch/s390/kernel/sclp.S +++ b/arch/s390/kernel/sclp.S | |||
@@ -294,7 +294,8 @@ ENTRY(_sclp_print_early) | |||
294 | #ifdef CONFIG_64BIT | 294 | #ifdef CONFIG_64BIT |
295 | tm LC_AR_MODE_ID,1 | 295 | tm LC_AR_MODE_ID,1 |
296 | jno .Lesa3 | 296 | jno .Lesa3 |
297 | lmh %r6,%r15,96(%r15) # store upper register halves | 297 | lgfr %r2,%r2 # sign extend return value |
298 | lmh %r6,%r15,96(%r15) # restore upper register halves | ||
298 | ahi %r15,80 | 299 | ahi %r15,80 |
299 | .Lesa3: | 300 | .Lesa3: |
300 | #endif | 301 | #endif |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 4e532c67832f..bfac77ada4f2 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -810,6 +810,9 @@ static void __init setup_hwcaps(void) | |||
810 | case 0x2828: | 810 | case 0x2828: |
811 | strcpy(elf_platform, "zEC12"); | 811 | strcpy(elf_platform, "zEC12"); |
812 | break; | 812 | break; |
813 | case 0x2964: | ||
814 | strcpy(elf_platform, "z13"); | ||
815 | break; | ||
813 | } | 816 | } |
814 | } | 817 | } |
815 | 818 | ||
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 0b499f5cbe19..a668993ff577 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -71,9 +71,30 @@ struct pcpu { | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | static u8 boot_cpu_type; | 73 | static u8 boot_cpu_type; |
74 | static u16 boot_cpu_address; | ||
75 | static struct pcpu pcpu_devices[NR_CPUS]; | 74 | static struct pcpu pcpu_devices[NR_CPUS]; |
76 | 75 | ||
76 | unsigned int smp_cpu_mt_shift; | ||
77 | EXPORT_SYMBOL(smp_cpu_mt_shift); | ||
78 | |||
79 | unsigned int smp_cpu_mtid; | ||
80 | EXPORT_SYMBOL(smp_cpu_mtid); | ||
81 | |||
82 | static unsigned int smp_max_threads __initdata = -1U; | ||
83 | |||
84 | static int __init early_nosmt(char *s) | ||
85 | { | ||
86 | smp_max_threads = 1; | ||
87 | return 0; | ||
88 | } | ||
89 | early_param("nosmt", early_nosmt); | ||
90 | |||
91 | static int __init early_smt(char *s) | ||
92 | { | ||
93 | get_option(&s, &smp_max_threads); | ||
94 | return 0; | ||
95 | } | ||
96 | early_param("smt", early_smt); | ||
97 | |||
77 | /* | 98 | /* |
78 | * The smp_cpu_state_mutex must be held when changing the state or polarization | 99 | * The smp_cpu_state_mutex must be held when changing the state or polarization |
79 | * member of a pcpu data structure within the pcpu_devices arreay. | 100 | * member of a pcpu data structure within the pcpu_devices arreay. |
@@ -132,7 +153,7 @@ static inline int pcpu_running(struct pcpu *pcpu) | |||
132 | /* | 153 | /* |
133 | * Find struct pcpu by cpu address. | 154 | * Find struct pcpu by cpu address. |
134 | */ | 155 | */ |
135 | static struct pcpu *pcpu_find_address(const struct cpumask *mask, int address) | 156 | static struct pcpu *pcpu_find_address(const struct cpumask *mask, u16 address) |
136 | { | 157 | { |
137 | int cpu; | 158 | int cpu; |
138 | 159 | ||
@@ -299,6 +320,32 @@ static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), | |||
299 | } | 320 | } |
300 | 321 | ||
301 | /* | 322 | /* |
323 | * Enable additional logical cpus for multi-threading. | ||
324 | */ | ||
325 | static int pcpu_set_smt(unsigned int mtid) | ||
326 | { | ||
327 | register unsigned long reg1 asm ("1") = (unsigned long) mtid; | ||
328 | int cc; | ||
329 | |||
330 | if (smp_cpu_mtid == mtid) | ||
331 | return 0; | ||
332 | asm volatile( | ||
333 | " sigp %1,0,%2 # sigp set multi-threading\n" | ||
334 | " ipm %0\n" | ||
335 | " srl %0,28\n" | ||
336 | : "=d" (cc) : "d" (reg1), "K" (SIGP_SET_MULTI_THREADING) | ||
337 | : "cc"); | ||
338 | if (cc == 0) { | ||
339 | smp_cpu_mtid = mtid; | ||
340 | smp_cpu_mt_shift = 0; | ||
341 | while (smp_cpu_mtid >= (1U << smp_cpu_mt_shift)) | ||
342 | smp_cpu_mt_shift++; | ||
343 | pcpu_devices[0].address = stap(); | ||
344 | } | ||
345 | return cc; | ||
346 | } | ||
347 | |||
348 | /* | ||
302 | * Call function on an online CPU. | 349 | * Call function on an online CPU. |
303 | */ | 350 | */ |
304 | void smp_call_online_cpu(void (*func)(void *), void *data) | 351 | void smp_call_online_cpu(void (*func)(void *), void *data) |
@@ -512,22 +559,17 @@ EXPORT_SYMBOL(smp_ctl_clear_bit); | |||
512 | 559 | ||
513 | #ifdef CONFIG_CRASH_DUMP | 560 | #ifdef CONFIG_CRASH_DUMP |
514 | 561 | ||
515 | static void __init smp_get_save_area(int cpu, u16 address) | 562 | static inline void __smp_store_cpu_state(int cpu, u16 address, int is_boot_cpu) |
516 | { | 563 | { |
517 | void *lc = pcpu_devices[0].lowcore; | 564 | void *lc = pcpu_devices[0].lowcore; |
518 | struct save_area_ext *sa_ext; | 565 | struct save_area_ext *sa_ext; |
519 | unsigned long vx_sa; | 566 | unsigned long vx_sa; |
520 | 567 | ||
521 | if (is_kdump_kernel()) | ||
522 | return; | ||
523 | if (!OLDMEM_BASE && (address == boot_cpu_address || | ||
524 | ipl_info.type != IPL_TYPE_FCP_DUMP)) | ||
525 | return; | ||
526 | sa_ext = dump_save_area_create(cpu); | 568 | sa_ext = dump_save_area_create(cpu); |
527 | if (!sa_ext) | 569 | if (!sa_ext) |
528 | panic("could not allocate memory for save area\n"); | 570 | panic("could not allocate memory for save area\n"); |
529 | if (address == boot_cpu_address) { | 571 | if (is_boot_cpu) { |
530 | /* Copy the registers of the boot cpu. */ | 572 | /* Copy the registers of the boot CPU. */ |
531 | copy_oldmem_page(1, (void *) &sa_ext->sa, sizeof(sa_ext->sa), | 573 | copy_oldmem_page(1, (void *) &sa_ext->sa, sizeof(sa_ext->sa), |
532 | SAVE_AREA_BASE - PAGE_SIZE, 0); | 574 | SAVE_AREA_BASE - PAGE_SIZE, 0); |
533 | if (MACHINE_HAS_VX) | 575 | if (MACHINE_HAS_VX) |
@@ -548,6 +590,64 @@ static void __init smp_get_save_area(int cpu, u16 address) | |||
548 | free_page(vx_sa); | 590 | free_page(vx_sa); |
549 | } | 591 | } |
550 | 592 | ||
593 | /* | ||
594 | * Collect CPU state of the previous, crashed system. | ||
595 | * There are four cases: | ||
596 | * 1) standard zfcp dump | ||
597 | * condition: OLDMEM_BASE == NULL && ipl_info.type == IPL_TYPE_FCP_DUMP | ||
598 | * The state for all CPUs except the boot CPU needs to be collected | ||
599 | * with sigp stop-and-store-status. The boot CPU state is located in | ||
600 | * the absolute lowcore of the memory stored in the HSA. The zcore code | ||
601 | * will allocate the save area and copy the boot CPU state from the HSA. | ||
602 | * 2) stand-alone kdump for SCSI (zfcp dump with swapped memory) | ||
603 | * condition: OLDMEM_BASE != NULL && ipl_info.type == IPL_TYPE_FCP_DUMP | ||
604 | * The state for all CPUs except the boot CPU needs to be collected | ||
605 | * with sigp stop-and-store-status. The firmware or the boot-loader | ||
606 | * stored the registers of the boot CPU in the absolute lowcore in the | ||
607 | * memory of the old system. | ||
608 | * 3) kdump and the old kernel did not store the CPU state, | ||
609 | * or stand-alone kdump for DASD | ||
610 | * condition: OLDMEM_BASE != NULL && !is_kdump_kernel() | ||
611 | * The state for all CPUs except the boot CPU needs to be collected | ||
612 | * with sigp stop-and-store-status. The kexec code or the boot-loader | ||
613 | * stored the registers of the boot CPU in the memory of the old system. | ||
614 | * 4) kdump and the old kernel stored the CPU state | ||
615 | * condition: OLDMEM_BASE != NULL && is_kdump_kernel() | ||
616 | * The state of all CPUs is stored in ELF sections in the memory of the | ||
617 | * old system. The ELF sections are picked up by the crash_dump code | ||
618 | * via elfcorehdr_addr. | ||
619 | */ | ||
620 | static void __init smp_store_cpu_states(struct sclp_cpu_info *info) | ||
621 | { | ||
622 | unsigned int cpu, address, i, j; | ||
623 | int is_boot_cpu; | ||
624 | |||
625 | if (is_kdump_kernel()) | ||
626 | /* Previous system stored the CPU states. Nothing to do. */ | ||
627 | return; | ||
628 | if (!(OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP)) | ||
629 | /* No previous system present, normal boot. */ | ||
630 | return; | ||
631 | /* Set multi-threading state to the previous system. */ | ||
632 | pcpu_set_smt(sclp_get_mtid_prev()); | ||
633 | /* Collect CPU states. */ | ||
634 | cpu = 0; | ||
635 | for (i = 0; i < info->configured; i++) { | ||
636 | /* Skip CPUs with different CPU type. */ | ||
637 | if (info->has_cpu_type && info->cpu[i].type != boot_cpu_type) | ||
638 | continue; | ||
639 | for (j = 0; j <= smp_cpu_mtid; j++, cpu++) { | ||
640 | address = (info->cpu[i].core_id << smp_cpu_mt_shift) + j; | ||
641 | is_boot_cpu = (address == pcpu_devices[0].address); | ||
642 | if (is_boot_cpu && !OLDMEM_BASE) | ||
643 | /* Skip boot CPU for standard zfcp dump. */ | ||
644 | continue; | ||
645 | /* Get state for this CPu. */ | ||
646 | __smp_store_cpu_state(cpu, address, is_boot_cpu); | ||
647 | } | ||
648 | } | ||
649 | } | ||
650 | |||
551 | int smp_store_status(int cpu) | 651 | int smp_store_status(int cpu) |
552 | { | 652 | { |
553 | unsigned long vx_sa; | 653 | unsigned long vx_sa; |
@@ -565,10 +665,6 @@ int smp_store_status(int cpu) | |||
565 | return 0; | 665 | return 0; |
566 | } | 666 | } |
567 | 667 | ||
568 | #else /* CONFIG_CRASH_DUMP */ | ||
569 | |||
570 | static inline void smp_get_save_area(int cpu, u16 address) { } | ||
571 | |||
572 | #endif /* CONFIG_CRASH_DUMP */ | 668 | #endif /* CONFIG_CRASH_DUMP */ |
573 | 669 | ||
574 | void smp_cpu_set_polarization(int cpu, int val) | 670 | void smp_cpu_set_polarization(int cpu, int val) |
@@ -590,11 +686,13 @@ static struct sclp_cpu_info *smp_get_cpu_info(void) | |||
590 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 686 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
591 | if (info && (use_sigp_detection || sclp_get_cpu_info(info))) { | 687 | if (info && (use_sigp_detection || sclp_get_cpu_info(info))) { |
592 | use_sigp_detection = 1; | 688 | use_sigp_detection = 1; |
593 | for (address = 0; address <= MAX_CPU_ADDRESS; address++) { | 689 | for (address = 0; address <= MAX_CPU_ADDRESS; |
690 | address += (1U << smp_cpu_mt_shift)) { | ||
594 | if (__pcpu_sigp_relax(address, SIGP_SENSE, 0, NULL) == | 691 | if (__pcpu_sigp_relax(address, SIGP_SENSE, 0, NULL) == |
595 | SIGP_CC_NOT_OPERATIONAL) | 692 | SIGP_CC_NOT_OPERATIONAL) |
596 | continue; | 693 | continue; |
597 | info->cpu[info->configured].address = address; | 694 | info->cpu[info->configured].core_id = |
695 | address >> smp_cpu_mt_shift; | ||
598 | info->configured++; | 696 | info->configured++; |
599 | } | 697 | } |
600 | info->combined = info->configured; | 698 | info->combined = info->configured; |
@@ -608,7 +706,8 @@ static int __smp_rescan_cpus(struct sclp_cpu_info *info, int sysfs_add) | |||
608 | { | 706 | { |
609 | struct pcpu *pcpu; | 707 | struct pcpu *pcpu; |
610 | cpumask_t avail; | 708 | cpumask_t avail; |
611 | int cpu, nr, i; | 709 | int cpu, nr, i, j; |
710 | u16 address; | ||
612 | 711 | ||
613 | nr = 0; | 712 | nr = 0; |
614 | cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask); | 713 | cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask); |
@@ -616,51 +715,76 @@ static int __smp_rescan_cpus(struct sclp_cpu_info *info, int sysfs_add) | |||
616 | for (i = 0; (i < info->combined) && (cpu < nr_cpu_ids); i++) { | 715 | for (i = 0; (i < info->combined) && (cpu < nr_cpu_ids); i++) { |
617 | if (info->has_cpu_type && info->cpu[i].type != boot_cpu_type) | 716 | if (info->has_cpu_type && info->cpu[i].type != boot_cpu_type) |
618 | continue; | 717 | continue; |
619 | if (pcpu_find_address(cpu_present_mask, info->cpu[i].address)) | 718 | address = info->cpu[i].core_id << smp_cpu_mt_shift; |
620 | continue; | 719 | for (j = 0; j <= smp_cpu_mtid; j++) { |
621 | pcpu = pcpu_devices + cpu; | 720 | if (pcpu_find_address(cpu_present_mask, address + j)) |
622 | pcpu->address = info->cpu[i].address; | 721 | continue; |
623 | pcpu->state = (i >= info->configured) ? | 722 | pcpu = pcpu_devices + cpu; |
624 | CPU_STATE_STANDBY : CPU_STATE_CONFIGURED; | 723 | pcpu->address = address + j; |
625 | smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); | 724 | pcpu->state = |
626 | set_cpu_present(cpu, true); | 725 | (cpu >= info->configured*(smp_cpu_mtid + 1)) ? |
627 | if (sysfs_add && smp_add_present_cpu(cpu) != 0) | 726 | CPU_STATE_STANDBY : CPU_STATE_CONFIGURED; |
628 | set_cpu_present(cpu, false); | 727 | smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); |
629 | else | 728 | set_cpu_present(cpu, true); |
630 | nr++; | 729 | if (sysfs_add && smp_add_present_cpu(cpu) != 0) |
631 | cpu = cpumask_next(cpu, &avail); | 730 | set_cpu_present(cpu, false); |
731 | else | ||
732 | nr++; | ||
733 | cpu = cpumask_next(cpu, &avail); | ||
734 | if (cpu >= nr_cpu_ids) | ||
735 | break; | ||
736 | } | ||
632 | } | 737 | } |
633 | return nr; | 738 | return nr; |
634 | } | 739 | } |
635 | 740 | ||
636 | static void __init smp_detect_cpus(void) | 741 | static void __init smp_detect_cpus(void) |
637 | { | 742 | { |
638 | unsigned int cpu, c_cpus, s_cpus; | 743 | unsigned int cpu, mtid, c_cpus, s_cpus; |
639 | struct sclp_cpu_info *info; | 744 | struct sclp_cpu_info *info; |
745 | u16 address; | ||
640 | 746 | ||
747 | /* Get CPU information */ | ||
641 | info = smp_get_cpu_info(); | 748 | info = smp_get_cpu_info(); |
642 | if (!info) | 749 | if (!info) |
643 | panic("smp_detect_cpus failed to allocate memory\n"); | 750 | panic("smp_detect_cpus failed to allocate memory\n"); |
751 | |||
752 | /* Find boot CPU type */ | ||
644 | if (info->has_cpu_type) { | 753 | if (info->has_cpu_type) { |
645 | for (cpu = 0; cpu < info->combined; cpu++) { | 754 | address = stap(); |
646 | if (info->cpu[cpu].address != boot_cpu_address) | 755 | for (cpu = 0; cpu < info->combined; cpu++) |
647 | continue; | 756 | if (info->cpu[cpu].core_id == address) { |
648 | /* The boot cpu dictates the cpu type. */ | 757 | /* The boot cpu dictates the cpu type. */ |
649 | boot_cpu_type = info->cpu[cpu].type; | 758 | boot_cpu_type = info->cpu[cpu].type; |
650 | break; | 759 | break; |
651 | } | 760 | } |
761 | if (cpu >= info->combined) | ||
762 | panic("Could not find boot CPU type"); | ||
652 | } | 763 | } |
764 | |||
765 | #ifdef CONFIG_CRASH_DUMP | ||
766 | /* Collect CPU state of previous system */ | ||
767 | smp_store_cpu_states(info); | ||
768 | #endif | ||
769 | |||
770 | /* Set multi-threading state for the current system */ | ||
771 | mtid = sclp_get_mtid(boot_cpu_type); | ||
772 | mtid = (mtid < smp_max_threads) ? mtid : smp_max_threads - 1; | ||
773 | pcpu_set_smt(mtid); | ||
774 | |||
775 | /* Print number of CPUs */ | ||
653 | c_cpus = s_cpus = 0; | 776 | c_cpus = s_cpus = 0; |
654 | for (cpu = 0; cpu < info->combined; cpu++) { | 777 | for (cpu = 0; cpu < info->combined; cpu++) { |
655 | if (info->has_cpu_type && info->cpu[cpu].type != boot_cpu_type) | 778 | if (info->has_cpu_type && info->cpu[cpu].type != boot_cpu_type) |
656 | continue; | 779 | continue; |
657 | if (cpu < info->configured) { | 780 | if (cpu < info->configured) |
658 | smp_get_save_area(c_cpus, info->cpu[cpu].address); | 781 | c_cpus += smp_cpu_mtid + 1; |
659 | c_cpus++; | 782 | else |
660 | } else | 783 | s_cpus += smp_cpu_mtid + 1; |
661 | s_cpus++; | ||
662 | } | 784 | } |
663 | pr_info("%d configured CPUs, %d standby CPUs\n", c_cpus, s_cpus); | 785 | pr_info("%d configured CPUs, %d standby CPUs\n", c_cpus, s_cpus); |
786 | |||
787 | /* Add CPUs present at boot */ | ||
664 | get_online_cpus(); | 788 | get_online_cpus(); |
665 | __smp_rescan_cpus(info, 0); | 789 | __smp_rescan_cpus(info, 0); |
666 | put_online_cpus(); | 790 | put_online_cpus(); |
@@ -696,12 +820,23 @@ static void smp_start_secondary(void *cpuvoid) | |||
696 | int __cpu_up(unsigned int cpu, struct task_struct *tidle) | 820 | int __cpu_up(unsigned int cpu, struct task_struct *tidle) |
697 | { | 821 | { |
698 | struct pcpu *pcpu; | 822 | struct pcpu *pcpu; |
699 | int rc; | 823 | int base, i, rc; |
700 | 824 | ||
701 | pcpu = pcpu_devices + cpu; | 825 | pcpu = pcpu_devices + cpu; |
702 | if (pcpu->state != CPU_STATE_CONFIGURED) | 826 | if (pcpu->state != CPU_STATE_CONFIGURED) |
703 | return -EIO; | 827 | return -EIO; |
704 | if (pcpu_sigp_retry(pcpu, SIGP_INITIAL_CPU_RESET, 0) != | 828 | base = cpu - (cpu % (smp_cpu_mtid + 1)); |
829 | for (i = 0; i <= smp_cpu_mtid; i++) { | ||
830 | if (base + i < nr_cpu_ids) | ||
831 | if (cpu_online(base + i)) | ||
832 | break; | ||
833 | } | ||
834 | /* | ||
835 | * If this is the first CPU of the core to get online | ||
836 | * do an initial CPU reset. | ||
837 | */ | ||
838 | if (i > smp_cpu_mtid && | ||
839 | pcpu_sigp_retry(pcpu_devices + base, SIGP_INITIAL_CPU_RESET, 0) != | ||
705 | SIGP_CC_ORDER_CODE_ACCEPTED) | 840 | SIGP_CC_ORDER_CODE_ACCEPTED) |
706 | return -EIO; | 841 | return -EIO; |
707 | 842 | ||
@@ -774,7 +909,8 @@ void __init smp_fill_possible_mask(void) | |||
774 | { | 909 | { |
775 | unsigned int possible, sclp, cpu; | 910 | unsigned int possible, sclp, cpu; |
776 | 911 | ||
777 | sclp = sclp_get_max_cpu() ?: nr_cpu_ids; | 912 | sclp = min(smp_max_threads, sclp_get_mtid_max() + 1); |
913 | sclp = sclp_get_max_cpu()*sclp ?: nr_cpu_ids; | ||
778 | possible = setup_possible_cpus ?: nr_cpu_ids; | 914 | possible = setup_possible_cpus ?: nr_cpu_ids; |
779 | possible = min(possible, sclp); | 915 | possible = min(possible, sclp); |
780 | for (cpu = 0; cpu < possible && cpu < nr_cpu_ids; cpu++) | 916 | for (cpu = 0; cpu < possible && cpu < nr_cpu_ids; cpu++) |
@@ -796,9 +932,8 @@ void __init smp_prepare_boot_cpu(void) | |||
796 | { | 932 | { |
797 | struct pcpu *pcpu = pcpu_devices; | 933 | struct pcpu *pcpu = pcpu_devices; |
798 | 934 | ||
799 | boot_cpu_address = stap(); | ||
800 | pcpu->state = CPU_STATE_CONFIGURED; | 935 | pcpu->state = CPU_STATE_CONFIGURED; |
801 | pcpu->address = boot_cpu_address; | 936 | pcpu->address = stap(); |
802 | pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); | 937 | pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); |
803 | pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE | 938 | pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE |
804 | + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); | 939 | + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); |
@@ -848,7 +983,7 @@ static ssize_t cpu_configure_store(struct device *dev, | |||
848 | const char *buf, size_t count) | 983 | const char *buf, size_t count) |
849 | { | 984 | { |
850 | struct pcpu *pcpu; | 985 | struct pcpu *pcpu; |
851 | int cpu, val, rc; | 986 | int cpu, val, rc, i; |
852 | char delim; | 987 | char delim; |
853 | 988 | ||
854 | if (sscanf(buf, "%d %c", &val, &delim) != 1) | 989 | if (sscanf(buf, "%d %c", &val, &delim) != 1) |
@@ -860,29 +995,43 @@ static ssize_t cpu_configure_store(struct device *dev, | |||
860 | rc = -EBUSY; | 995 | rc = -EBUSY; |
861 | /* disallow configuration changes of online cpus and cpu 0 */ | 996 | /* disallow configuration changes of online cpus and cpu 0 */ |
862 | cpu = dev->id; | 997 | cpu = dev->id; |
863 | if (cpu_online(cpu) || cpu == 0) | 998 | cpu -= cpu % (smp_cpu_mtid + 1); |
999 | if (cpu == 0) | ||
864 | goto out; | 1000 | goto out; |
1001 | for (i = 0; i <= smp_cpu_mtid; i++) | ||
1002 | if (cpu_online(cpu + i)) | ||
1003 | goto out; | ||
865 | pcpu = pcpu_devices + cpu; | 1004 | pcpu = pcpu_devices + cpu; |
866 | rc = 0; | 1005 | rc = 0; |
867 | switch (val) { | 1006 | switch (val) { |
868 | case 0: | 1007 | case 0: |
869 | if (pcpu->state != CPU_STATE_CONFIGURED) | 1008 | if (pcpu->state != CPU_STATE_CONFIGURED) |
870 | break; | 1009 | break; |
871 | rc = sclp_cpu_deconfigure(pcpu->address); | 1010 | rc = sclp_cpu_deconfigure(pcpu->address >> smp_cpu_mt_shift); |
872 | if (rc) | 1011 | if (rc) |
873 | break; | 1012 | break; |
874 | pcpu->state = CPU_STATE_STANDBY; | 1013 | for (i = 0; i <= smp_cpu_mtid; i++) { |
875 | smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); | 1014 | if (cpu + i >= nr_cpu_ids || !cpu_present(cpu + i)) |
1015 | continue; | ||
1016 | pcpu[i].state = CPU_STATE_STANDBY; | ||
1017 | smp_cpu_set_polarization(cpu + i, | ||
1018 | POLARIZATION_UNKNOWN); | ||
1019 | } | ||
876 | topology_expect_change(); | 1020 | topology_expect_change(); |
877 | break; | 1021 | break; |
878 | case 1: | 1022 | case 1: |
879 | if (pcpu->state != CPU_STATE_STANDBY) | 1023 | if (pcpu->state != CPU_STATE_STANDBY) |
880 | break; | 1024 | break; |
881 | rc = sclp_cpu_configure(pcpu->address); | 1025 | rc = sclp_cpu_configure(pcpu->address >> smp_cpu_mt_shift); |
882 | if (rc) | 1026 | if (rc) |
883 | break; | 1027 | break; |
884 | pcpu->state = CPU_STATE_CONFIGURED; | 1028 | for (i = 0; i <= smp_cpu_mtid; i++) { |
885 | smp_cpu_set_polarization(cpu, POLARIZATION_UNKNOWN); | 1029 | if (cpu + i >= nr_cpu_ids || !cpu_present(cpu + i)) |
1030 | continue; | ||
1031 | pcpu[i].state = CPU_STATE_CONFIGURED; | ||
1032 | smp_cpu_set_polarization(cpu + i, | ||
1033 | POLARIZATION_UNKNOWN); | ||
1034 | } | ||
886 | topology_expect_change(); | 1035 | topology_expect_change(); |
887 | break; | 1036 | break; |
888 | default: | 1037 | default: |
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index 811f542b8ed4..85565f1ff474 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c | |||
@@ -194,6 +194,14 @@ static void stsi_2_2_2(struct seq_file *m, struct sysinfo_2_2_2 *info) | |||
194 | seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved); | 194 | seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved); |
195 | seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated); | 195 | seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated); |
196 | seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared); | 196 | seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared); |
197 | if (info->mt_installed & 0x80) { | ||
198 | seq_printf(m, "LPAR CPUs G-MTID: %d\n", | ||
199 | info->mt_general & 0x1f); | ||
200 | seq_printf(m, "LPAR CPUs S-MTID: %d\n", | ||
201 | info->mt_installed & 0x1f); | ||
202 | seq_printf(m, "LPAR CPUs PS-MTID: %d\n", | ||
203 | info->mt_psmtid & 0x1f); | ||
204 | } | ||
197 | } | 205 | } |
198 | 206 | ||
199 | static void stsi_3_2_2(struct seq_file *m, struct sysinfo_3_2_2 *info) | 207 | static void stsi_3_2_2(struct seq_file *m, struct sysinfo_3_2_2 *info) |
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c index b93bed76ea94..24ee33f1af24 100644 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c | |||
@@ -59,32 +59,50 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) | |||
59 | return mask; | 59 | return mask; |
60 | } | 60 | } |
61 | 61 | ||
62 | static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, | 62 | static cpumask_t cpu_thread_map(unsigned int cpu) |
63 | { | ||
64 | cpumask_t mask; | ||
65 | int i; | ||
66 | |||
67 | cpumask_copy(&mask, cpumask_of(cpu)); | ||
68 | if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) | ||
69 | return mask; | ||
70 | cpu -= cpu % (smp_cpu_mtid + 1); | ||
71 | for (i = 0; i <= smp_cpu_mtid; i++) | ||
72 | if (cpu_present(cpu + i)) | ||
73 | cpumask_set_cpu(cpu + i, &mask); | ||
74 | return mask; | ||
75 | } | ||
76 | |||
77 | static struct mask_info *add_cpus_to_mask(struct topology_core *tl_core, | ||
63 | struct mask_info *book, | 78 | struct mask_info *book, |
64 | struct mask_info *socket, | 79 | struct mask_info *socket, |
65 | int one_socket_per_cpu) | 80 | int one_socket_per_cpu) |
66 | { | 81 | { |
67 | unsigned int cpu; | 82 | unsigned int core; |
68 | 83 | ||
69 | for_each_set_bit(cpu, &tl_cpu->mask[0], TOPOLOGY_CPU_BITS) { | 84 | for_each_set_bit(core, &tl_core->mask[0], TOPOLOGY_CORE_BITS) { |
70 | unsigned int rcpu; | 85 | unsigned int rcore; |
71 | int lcpu; | 86 | int lcpu, i; |
72 | 87 | ||
73 | rcpu = TOPOLOGY_CPU_BITS - 1 - cpu + tl_cpu->origin; | 88 | rcore = TOPOLOGY_CORE_BITS - 1 - core + tl_core->origin; |
74 | lcpu = smp_find_processor_id(rcpu); | 89 | lcpu = smp_find_processor_id(rcore << smp_cpu_mt_shift); |
75 | if (lcpu < 0) | 90 | if (lcpu < 0) |
76 | continue; | 91 | continue; |
77 | cpumask_set_cpu(lcpu, &book->mask); | 92 | for (i = 0; i <= smp_cpu_mtid; i++) { |
78 | cpu_topology[lcpu].book_id = book->id; | 93 | cpu_topology[lcpu + i].book_id = book->id; |
79 | cpumask_set_cpu(lcpu, &socket->mask); | 94 | cpu_topology[lcpu + i].core_id = rcore; |
80 | cpu_topology[lcpu].core_id = rcpu; | 95 | cpu_topology[lcpu + i].thread_id = lcpu + i; |
81 | if (one_socket_per_cpu) { | 96 | cpumask_set_cpu(lcpu + i, &book->mask); |
82 | cpu_topology[lcpu].socket_id = rcpu; | 97 | cpumask_set_cpu(lcpu + i, &socket->mask); |
83 | socket = socket->next; | 98 | if (one_socket_per_cpu) |
84 | } else { | 99 | cpu_topology[lcpu + i].socket_id = rcore; |
85 | cpu_topology[lcpu].socket_id = socket->id; | 100 | else |
101 | cpu_topology[lcpu + i].socket_id = socket->id; | ||
102 | smp_cpu_set_polarization(lcpu + i, tl_core->pp); | ||
86 | } | 103 | } |
87 | smp_cpu_set_polarization(lcpu, tl_cpu->pp); | 104 | if (one_socket_per_cpu) |
105 | socket = socket->next; | ||
88 | } | 106 | } |
89 | return socket; | 107 | return socket; |
90 | } | 108 | } |
@@ -108,7 +126,7 @@ static void clear_masks(void) | |||
108 | static union topology_entry *next_tle(union topology_entry *tle) | 126 | static union topology_entry *next_tle(union topology_entry *tle) |
109 | { | 127 | { |
110 | if (!tle->nl) | 128 | if (!tle->nl) |
111 | return (union topology_entry *)((struct topology_cpu *)tle + 1); | 129 | return (union topology_entry *)((struct topology_core *)tle + 1); |
112 | return (union topology_entry *)((struct topology_container *)tle + 1); | 130 | return (union topology_entry *)((struct topology_container *)tle + 1); |
113 | } | 131 | } |
114 | 132 | ||
@@ -231,9 +249,11 @@ static void update_cpu_masks(void) | |||
231 | 249 | ||
232 | spin_lock_irqsave(&topology_lock, flags); | 250 | spin_lock_irqsave(&topology_lock, flags); |
233 | for_each_possible_cpu(cpu) { | 251 | for_each_possible_cpu(cpu) { |
252 | cpu_topology[cpu].thread_mask = cpu_thread_map(cpu); | ||
234 | cpu_topology[cpu].core_mask = cpu_group_map(&socket_info, cpu); | 253 | cpu_topology[cpu].core_mask = cpu_group_map(&socket_info, cpu); |
235 | cpu_topology[cpu].book_mask = cpu_group_map(&book_info, cpu); | 254 | cpu_topology[cpu].book_mask = cpu_group_map(&book_info, cpu); |
236 | if (!MACHINE_HAS_TOPOLOGY) { | 255 | if (!MACHINE_HAS_TOPOLOGY) { |
256 | cpu_topology[cpu].thread_id = cpu; | ||
237 | cpu_topology[cpu].core_id = cpu; | 257 | cpu_topology[cpu].core_id = cpu; |
238 | cpu_topology[cpu].socket_id = cpu; | 258 | cpu_topology[cpu].socket_id = cpu; |
239 | cpu_topology[cpu].book_id = cpu; | 259 | cpu_topology[cpu].book_id = cpu; |
@@ -445,6 +465,12 @@ int topology_cpu_init(struct cpu *cpu) | |||
445 | return sysfs_create_group(&cpu->dev.kobj, &topology_cpu_attr_group); | 465 | return sysfs_create_group(&cpu->dev.kobj, &topology_cpu_attr_group); |
446 | } | 466 | } |
447 | 467 | ||
468 | const struct cpumask *cpu_thread_mask(int cpu) | ||
469 | { | ||
470 | return &cpu_topology[cpu].thread_mask; | ||
471 | } | ||
472 | |||
473 | |||
448 | const struct cpumask *cpu_coregroup_mask(int cpu) | 474 | const struct cpumask *cpu_coregroup_mask(int cpu) |
449 | { | 475 | { |
450 | return &cpu_topology[cpu].core_mask; | 476 | return &cpu_topology[cpu].core_mask; |
@@ -456,6 +482,7 @@ static const struct cpumask *cpu_book_mask(int cpu) | |||
456 | } | 482 | } |
457 | 483 | ||
458 | static struct sched_domain_topology_level s390_topology[] = { | 484 | static struct sched_domain_topology_level s390_topology[] = { |
485 | { cpu_thread_mask, cpu_smt_flags, SD_INIT_NAME(SMT) }, | ||
459 | { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) }, | 486 | { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) }, |
460 | { cpu_book_mask, SD_INIT_NAME(BOOK) }, | 487 | { cpu_book_mask, SD_INIT_NAME(BOOK) }, |
461 | { cpu_cpu_mask, SD_INIT_NAME(DIE) }, | 488 | { cpu_cpu_mask, SD_INIT_NAME(DIE) }, |
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index e34122e539a1..e53d3595a7c8 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <asm/cputime.h> | 15 | #include <asm/cputime.h> |
16 | #include <asm/vtimer.h> | 16 | #include <asm/vtimer.h> |
17 | #include <asm/vtime.h> | 17 | #include <asm/vtime.h> |
18 | #include <asm/cpu_mf.h> | ||
19 | #include <asm/smp.h> | ||
18 | 20 | ||
19 | static void virt_timer_expire(void); | 21 | static void virt_timer_expire(void); |
20 | 22 | ||
@@ -23,6 +25,10 @@ static DEFINE_SPINLOCK(virt_timer_lock); | |||
23 | static atomic64_t virt_timer_current; | 25 | static atomic64_t virt_timer_current; |
24 | static atomic64_t virt_timer_elapsed; | 26 | static atomic64_t virt_timer_elapsed; |
25 | 27 | ||
28 | static DEFINE_PER_CPU(u64, mt_cycles[32]); | ||
29 | static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 }; | ||
30 | static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 }; | ||
31 | |||
26 | static inline u64 get_vtimer(void) | 32 | static inline u64 get_vtimer(void) |
27 | { | 33 | { |
28 | u64 timer; | 34 | u64 timer; |
@@ -61,6 +67,8 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset) | |||
61 | { | 67 | { |
62 | struct thread_info *ti = task_thread_info(tsk); | 68 | struct thread_info *ti = task_thread_info(tsk); |
63 | u64 timer, clock, user, system, steal; | 69 | u64 timer, clock, user, system, steal; |
70 | u64 user_scaled, system_scaled; | ||
71 | int i; | ||
64 | 72 | ||
65 | timer = S390_lowcore.last_update_timer; | 73 | timer = S390_lowcore.last_update_timer; |
66 | clock = S390_lowcore.last_update_clock; | 74 | clock = S390_lowcore.last_update_clock; |
@@ -76,15 +84,49 @@ static int do_account_vtime(struct task_struct *tsk, int hardirq_offset) | |||
76 | S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; | 84 | S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; |
77 | S390_lowcore.steal_timer += S390_lowcore.last_update_clock - clock; | 85 | S390_lowcore.steal_timer += S390_lowcore.last_update_clock - clock; |
78 | 86 | ||
87 | /* Do MT utilization calculation */ | ||
88 | if (smp_cpu_mtid) { | ||
89 | u64 cycles_new[32], *cycles_old; | ||
90 | u64 delta, mult, div; | ||
91 | |||
92 | cycles_old = this_cpu_ptr(mt_cycles); | ||
93 | if (stcctm5(smp_cpu_mtid + 1, cycles_new) < 2) { | ||
94 | mult = div = 0; | ||
95 | for (i = 0; i <= smp_cpu_mtid; i++) { | ||
96 | delta = cycles_new[i] - cycles_old[i]; | ||
97 | mult += delta; | ||
98 | div += (i + 1) * delta; | ||
99 | } | ||
100 | if (mult > 0) { | ||
101 | /* Update scaling factor */ | ||
102 | __this_cpu_write(mt_scaling_mult, mult); | ||
103 | __this_cpu_write(mt_scaling_div, div); | ||
104 | memcpy(cycles_old, cycles_new, | ||
105 | sizeof(u64) * (smp_cpu_mtid + 1)); | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | |||
79 | user = S390_lowcore.user_timer - ti->user_timer; | 110 | user = S390_lowcore.user_timer - ti->user_timer; |
80 | S390_lowcore.steal_timer -= user; | 111 | S390_lowcore.steal_timer -= user; |
81 | ti->user_timer = S390_lowcore.user_timer; | 112 | ti->user_timer = S390_lowcore.user_timer; |
82 | account_user_time(tsk, user, user); | ||
83 | 113 | ||
84 | system = S390_lowcore.system_timer - ti->system_timer; | 114 | system = S390_lowcore.system_timer - ti->system_timer; |
85 | S390_lowcore.steal_timer -= system; | 115 | S390_lowcore.steal_timer -= system; |
86 | ti->system_timer = S390_lowcore.system_timer; | 116 | ti->system_timer = S390_lowcore.system_timer; |
87 | account_system_time(tsk, hardirq_offset, system, system); | 117 | |
118 | user_scaled = user; | ||
119 | system_scaled = system; | ||
120 | /* Do MT utilization scaling */ | ||
121 | if (smp_cpu_mtid) { | ||
122 | u64 mult = __this_cpu_read(mt_scaling_mult); | ||
123 | u64 div = __this_cpu_read(mt_scaling_div); | ||
124 | |||
125 | user_scaled = (user_scaled * mult) / div; | ||
126 | system_scaled = (system_scaled * mult) / div; | ||
127 | } | ||
128 | account_user_time(tsk, user, user_scaled); | ||
129 | account_system_time(tsk, hardirq_offset, system, system_scaled); | ||
88 | 130 | ||
89 | steal = S390_lowcore.steal_timer; | 131 | steal = S390_lowcore.steal_timer; |
90 | if ((s64) steal > 0) { | 132 | if ((s64) steal > 0) { |
@@ -126,7 +168,7 @@ void vtime_account_user(struct task_struct *tsk) | |||
126 | void vtime_account_irq_enter(struct task_struct *tsk) | 168 | void vtime_account_irq_enter(struct task_struct *tsk) |
127 | { | 169 | { |
128 | struct thread_info *ti = task_thread_info(tsk); | 170 | struct thread_info *ti = task_thread_info(tsk); |
129 | u64 timer, system; | 171 | u64 timer, system, system_scaled; |
130 | 172 | ||
131 | timer = S390_lowcore.last_update_timer; | 173 | timer = S390_lowcore.last_update_timer; |
132 | S390_lowcore.last_update_timer = get_vtimer(); | 174 | S390_lowcore.last_update_timer = get_vtimer(); |
@@ -135,7 +177,15 @@ void vtime_account_irq_enter(struct task_struct *tsk) | |||
135 | system = S390_lowcore.system_timer - ti->system_timer; | 177 | system = S390_lowcore.system_timer - ti->system_timer; |
136 | S390_lowcore.steal_timer -= system; | 178 | S390_lowcore.steal_timer -= system; |
137 | ti->system_timer = S390_lowcore.system_timer; | 179 | ti->system_timer = S390_lowcore.system_timer; |
138 | account_system_time(tsk, 0, system, system); | 180 | system_scaled = system; |
181 | /* Do MT utilization scaling */ | ||
182 | if (smp_cpu_mtid) { | ||
183 | u64 mult = __this_cpu_read(mt_scaling_mult); | ||
184 | u64 div = __this_cpu_read(mt_scaling_div); | ||
185 | |||
186 | system_scaled = (system_scaled * mult) / div; | ||
187 | } | ||
188 | account_system_time(tsk, 0, system, system_scaled); | ||
139 | 189 | ||
140 | virt_timer_forward(system); | 190 | virt_timer_forward(system); |
141 | } | 191 | } |
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 034a35a3e9c1..d6c9991f7797 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c | |||
@@ -12,7 +12,15 @@ | |||
12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
14 | 14 | ||
15 | int spin_retry = 1000; | 15 | int spin_retry = -1; |
16 | |||
17 | static int __init spin_retry_init(void) | ||
18 | { | ||
19 | if (spin_retry < 0) | ||
20 | spin_retry = MACHINE_HAS_CAD ? 10 : 1000; | ||
21 | return 0; | ||
22 | } | ||
23 | early_initcall(spin_retry_init); | ||
16 | 24 | ||
17 | /** | 25 | /** |
18 | * spin_retry= parameter | 26 | * spin_retry= parameter |
@@ -24,6 +32,11 @@ static int __init spin_retry_setup(char *str) | |||
24 | } | 32 | } |
25 | __setup("spin_retry=", spin_retry_setup); | 33 | __setup("spin_retry=", spin_retry_setup); |
26 | 34 | ||
35 | static inline void _raw_compare_and_delay(unsigned int *lock, unsigned int old) | ||
36 | { | ||
37 | asm(".insn rsy,0xeb0000000022,%0,0,%1" : : "d" (old), "Q" (*lock)); | ||
38 | } | ||
39 | |||
27 | void arch_spin_lock_wait(arch_spinlock_t *lp) | 40 | void arch_spin_lock_wait(arch_spinlock_t *lp) |
28 | { | 41 | { |
29 | unsigned int cpu = SPINLOCK_LOCKVAL; | 42 | unsigned int cpu = SPINLOCK_LOCKVAL; |
@@ -46,6 +59,8 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) | |||
46 | /* Loop for a while on the lock value. */ | 59 | /* Loop for a while on the lock value. */ |
47 | count = spin_retry; | 60 | count = spin_retry; |
48 | do { | 61 | do { |
62 | if (MACHINE_HAS_CAD) | ||
63 | _raw_compare_and_delay(&lp->lock, owner); | ||
49 | owner = ACCESS_ONCE(lp->lock); | 64 | owner = ACCESS_ONCE(lp->lock); |
50 | } while (owner && count-- > 0); | 65 | } while (owner && count-- > 0); |
51 | if (!owner) | 66 | if (!owner) |
@@ -84,6 +99,8 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) | |||
84 | /* Loop for a while on the lock value. */ | 99 | /* Loop for a while on the lock value. */ |
85 | count = spin_retry; | 100 | count = spin_retry; |
86 | do { | 101 | do { |
102 | if (MACHINE_HAS_CAD) | ||
103 | _raw_compare_and_delay(&lp->lock, owner); | ||
87 | owner = ACCESS_ONCE(lp->lock); | 104 | owner = ACCESS_ONCE(lp->lock); |
88 | } while (owner && count-- > 0); | 105 | } while (owner && count-- > 0); |
89 | if (!owner) | 106 | if (!owner) |
@@ -100,11 +117,19 @@ EXPORT_SYMBOL(arch_spin_lock_wait_flags); | |||
100 | 117 | ||
101 | int arch_spin_trylock_retry(arch_spinlock_t *lp) | 118 | int arch_spin_trylock_retry(arch_spinlock_t *lp) |
102 | { | 119 | { |
120 | unsigned int cpu = SPINLOCK_LOCKVAL; | ||
121 | unsigned int owner; | ||
103 | int count; | 122 | int count; |
104 | 123 | ||
105 | for (count = spin_retry; count > 0; count--) | 124 | for (count = spin_retry; count > 0; count--) { |
106 | if (arch_spin_trylock_once(lp)) | 125 | owner = ACCESS_ONCE(lp->lock); |
107 | return 1; | 126 | /* Try to get the lock if it is free. */ |
127 | if (!owner) { | ||
128 | if (_raw_compare_and_swap(&lp->lock, 0, cpu)) | ||
129 | return 1; | ||
130 | } else if (MACHINE_HAS_CAD) | ||
131 | _raw_compare_and_delay(&lp->lock, owner); | ||
132 | } | ||
108 | return 0; | 133 | return 0; |
109 | } | 134 | } |
110 | EXPORT_SYMBOL(arch_spin_trylock_retry); | 135 | EXPORT_SYMBOL(arch_spin_trylock_retry); |
@@ -126,8 +151,11 @@ void _raw_read_lock_wait(arch_rwlock_t *rw) | |||
126 | } | 151 | } |
127 | old = ACCESS_ONCE(rw->lock); | 152 | old = ACCESS_ONCE(rw->lock); |
128 | owner = ACCESS_ONCE(rw->owner); | 153 | owner = ACCESS_ONCE(rw->owner); |
129 | if ((int) old < 0) | 154 | if ((int) old < 0) { |
155 | if (MACHINE_HAS_CAD) | ||
156 | _raw_compare_and_delay(&rw->lock, old); | ||
130 | continue; | 157 | continue; |
158 | } | ||
131 | if (_raw_compare_and_swap(&rw->lock, old, old + 1)) | 159 | if (_raw_compare_and_swap(&rw->lock, old, old + 1)) |
132 | return; | 160 | return; |
133 | } | 161 | } |
@@ -141,8 +169,11 @@ int _raw_read_trylock_retry(arch_rwlock_t *rw) | |||
141 | 169 | ||
142 | while (count-- > 0) { | 170 | while (count-- > 0) { |
143 | old = ACCESS_ONCE(rw->lock); | 171 | old = ACCESS_ONCE(rw->lock); |
144 | if ((int) old < 0) | 172 | if ((int) old < 0) { |
173 | if (MACHINE_HAS_CAD) | ||
174 | _raw_compare_and_delay(&rw->lock, old); | ||
145 | continue; | 175 | continue; |
176 | } | ||
146 | if (_raw_compare_and_swap(&rw->lock, old, old + 1)) | 177 | if (_raw_compare_and_swap(&rw->lock, old, old + 1)) |
147 | return 1; | 178 | return 1; |
148 | } | 179 | } |
@@ -173,6 +204,8 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, unsigned int prev) | |||
173 | } | 204 | } |
174 | if ((old & 0x7fffffff) == 0 && (int) prev >= 0) | 205 | if ((old & 0x7fffffff) == 0 && (int) prev >= 0) |
175 | break; | 206 | break; |
207 | if (MACHINE_HAS_CAD) | ||
208 | _raw_compare_and_delay(&rw->lock, old); | ||
176 | } | 209 | } |
177 | } | 210 | } |
178 | EXPORT_SYMBOL(_raw_write_lock_wait); | 211 | EXPORT_SYMBOL(_raw_write_lock_wait); |
@@ -201,6 +234,8 @@ void _raw_write_lock_wait(arch_rwlock_t *rw) | |||
201 | smp_rmb(); | 234 | smp_rmb(); |
202 | if ((old & 0x7fffffff) == 0 && (int) prev >= 0) | 235 | if ((old & 0x7fffffff) == 0 && (int) prev >= 0) |
203 | break; | 236 | break; |
237 | if (MACHINE_HAS_CAD) | ||
238 | _raw_compare_and_delay(&rw->lock, old); | ||
204 | } | 239 | } |
205 | } | 240 | } |
206 | EXPORT_SYMBOL(_raw_write_lock_wait); | 241 | EXPORT_SYMBOL(_raw_write_lock_wait); |
@@ -214,8 +249,11 @@ int _raw_write_trylock_retry(arch_rwlock_t *rw) | |||
214 | 249 | ||
215 | while (count-- > 0) { | 250 | while (count-- > 0) { |
216 | old = ACCESS_ONCE(rw->lock); | 251 | old = ACCESS_ONCE(rw->lock); |
217 | if (old) | 252 | if (old) { |
253 | if (MACHINE_HAS_CAD) | ||
254 | _raw_compare_and_delay(&rw->lock, old); | ||
218 | continue; | 255 | continue; |
256 | } | ||
219 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000)) | 257 | if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000)) |
220 | return 1; | 258 | return 1; |
221 | } | 259 | } |
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 9065d5aa3932..3ff86533f7db 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -171,7 +171,7 @@ static void dump_pagetable(unsigned long asce, unsigned long address) | |||
171 | table = table + ((address >> 20) & 0x7ff); | 171 | table = table + ((address >> 20) & 0x7ff); |
172 | if (bad_address(table)) | 172 | if (bad_address(table)) |
173 | goto bad; | 173 | goto bad; |
174 | pr_cont(KERN_CONT "S:%016lx ", *table); | 174 | pr_cont("S:%016lx ", *table); |
175 | if (*table & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE)) | 175 | if (*table & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE)) |
176 | goto out; | 176 | goto out; |
177 | table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); | 177 | table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); |
@@ -261,7 +261,7 @@ static inline void report_user_fault(struct pt_regs *regs, long signr) | |||
261 | return; | 261 | return; |
262 | if (!printk_ratelimit()) | 262 | if (!printk_ratelimit()) |
263 | return; | 263 | return; |
264 | printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d", | 264 | printk(KERN_ALERT "User process fault: interruption code %04x ilc:%d ", |
265 | regs->int_code & 0xffff, regs->int_code >> 17); | 265 | regs->int_code & 0xffff, regs->int_code >> 17); |
266 | print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); | 266 | print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); |
267 | printk(KERN_CONT "\n"); | 267 | printk(KERN_CONT "\n"); |
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index c7235e01fd67..d35b15113b17 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
@@ -71,13 +71,16 @@ static void __init setup_zero_pages(void) | |||
71 | break; | 71 | break; |
72 | case 0x2827: /* zEC12 */ | 72 | case 0x2827: /* zEC12 */ |
73 | case 0x2828: /* zEC12 */ | 73 | case 0x2828: /* zEC12 */ |
74 | default: | ||
75 | order = 5; | 74 | order = 5; |
76 | break; | 75 | break; |
76 | case 0x2964: /* z13 */ | ||
77 | default: | ||
78 | order = 7; | ||
79 | break; | ||
77 | } | 80 | } |
78 | /* Limit number of empty zero pages for small memory sizes */ | 81 | /* Limit number of empty zero pages for small memory sizes */ |
79 | if (order > 2 && totalram_pages <= 16384) | 82 | while (order > 2 && (totalram_pages >> 10) < (1UL << order)) |
80 | order = 2; | 83 | order--; |
81 | 84 | ||
82 | empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); | 85 | empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); |
83 | if (!empty_zero_page) | 86 | if (!empty_zero_page) |
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 9b436c21195e..d008f638b2cd 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c | |||
@@ -28,8 +28,12 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/random.h> | 29 | #include <linux/random.h> |
30 | #include <linux/compat.h> | 30 | #include <linux/compat.h> |
31 | #include <linux/security.h> | ||
31 | #include <asm/pgalloc.h> | 32 | #include <asm/pgalloc.h> |
32 | 33 | ||
34 | unsigned long mmap_rnd_mask; | ||
35 | unsigned long mmap_align_mask; | ||
36 | |||
33 | static unsigned long stack_maxrandom_size(void) | 37 | static unsigned long stack_maxrandom_size(void) |
34 | { | 38 | { |
35 | if (!(current->flags & PF_RANDOMIZE)) | 39 | if (!(current->flags & PF_RANDOMIZE)) |
@@ -60,8 +64,10 @@ static unsigned long mmap_rnd(void) | |||
60 | { | 64 | { |
61 | if (!(current->flags & PF_RANDOMIZE)) | 65 | if (!(current->flags & PF_RANDOMIZE)) |
62 | return 0; | 66 | return 0; |
63 | /* 8MB randomization for mmap_base */ | 67 | if (is_32bit_task()) |
64 | return (get_random_int() & 0x7ffUL) << PAGE_SHIFT; | 68 | return (get_random_int() & 0x7ff) << PAGE_SHIFT; |
69 | else | ||
70 | return (get_random_int() & mmap_rnd_mask) << PAGE_SHIFT; | ||
65 | } | 71 | } |
66 | 72 | ||
67 | static unsigned long mmap_base_legacy(void) | 73 | static unsigned long mmap_base_legacy(void) |
@@ -81,6 +87,106 @@ static inline unsigned long mmap_base(void) | |||
81 | return STACK_TOP - stack_maxrandom_size() - mmap_rnd() - gap; | 87 | return STACK_TOP - stack_maxrandom_size() - mmap_rnd() - gap; |
82 | } | 88 | } |
83 | 89 | ||
90 | unsigned long | ||
91 | arch_get_unmapped_area(struct file *filp, unsigned long addr, | ||
92 | unsigned long len, unsigned long pgoff, unsigned long flags) | ||
93 | { | ||
94 | struct mm_struct *mm = current->mm; | ||
95 | struct vm_area_struct *vma; | ||
96 | struct vm_unmapped_area_info info; | ||
97 | int do_color_align; | ||
98 | |||
99 | if (len > TASK_SIZE - mmap_min_addr) | ||
100 | return -ENOMEM; | ||
101 | |||
102 | if (flags & MAP_FIXED) | ||
103 | return addr; | ||
104 | |||
105 | if (addr) { | ||
106 | addr = PAGE_ALIGN(addr); | ||
107 | vma = find_vma(mm, addr); | ||
108 | if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && | ||
109 | (!vma || addr + len <= vma->vm_start)) | ||
110 | return addr; | ||
111 | } | ||
112 | |||
113 | do_color_align = 0; | ||
114 | if (filp || (flags & MAP_SHARED)) | ||
115 | do_color_align = !is_32bit_task(); | ||
116 | |||
117 | info.flags = 0; | ||
118 | info.length = len; | ||
119 | info.low_limit = mm->mmap_base; | ||
120 | info.high_limit = TASK_SIZE; | ||
121 | info.align_mask = do_color_align ? (mmap_align_mask << PAGE_SHIFT) : 0; | ||
122 | info.align_offset = pgoff << PAGE_SHIFT; | ||
123 | return vm_unmapped_area(&info); | ||
124 | } | ||
125 | |||
126 | unsigned long | ||
127 | arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | ||
128 | const unsigned long len, const unsigned long pgoff, | ||
129 | const unsigned long flags) | ||
130 | { | ||
131 | struct vm_area_struct *vma; | ||
132 | struct mm_struct *mm = current->mm; | ||
133 | unsigned long addr = addr0; | ||
134 | struct vm_unmapped_area_info info; | ||
135 | int do_color_align; | ||
136 | |||
137 | /* requested length too big for entire address space */ | ||
138 | if (len > TASK_SIZE - mmap_min_addr) | ||
139 | return -ENOMEM; | ||
140 | |||
141 | if (flags & MAP_FIXED) | ||
142 | return addr; | ||
143 | |||
144 | /* requesting a specific address */ | ||
145 | if (addr) { | ||
146 | addr = PAGE_ALIGN(addr); | ||
147 | vma = find_vma(mm, addr); | ||
148 | if (TASK_SIZE - len >= addr && addr >= mmap_min_addr && | ||
149 | (!vma || addr + len <= vma->vm_start)) | ||
150 | return addr; | ||
151 | } | ||
152 | |||
153 | do_color_align = 0; | ||
154 | if (filp || (flags & MAP_SHARED)) | ||
155 | do_color_align = !is_32bit_task(); | ||
156 | |||
157 | info.flags = VM_UNMAPPED_AREA_TOPDOWN; | ||
158 | info.length = len; | ||
159 | info.low_limit = max(PAGE_SIZE, mmap_min_addr); | ||
160 | info.high_limit = mm->mmap_base; | ||
161 | info.align_mask = do_color_align ? (mmap_align_mask << PAGE_SHIFT) : 0; | ||
162 | info.align_offset = pgoff << PAGE_SHIFT; | ||
163 | addr = vm_unmapped_area(&info); | ||
164 | |||
165 | /* | ||
166 | * A failed mmap() very likely causes application failure, | ||
167 | * so fall back to the bottom-up function here. This scenario | ||
168 | * can happen with large stack limits and large mmap() | ||
169 | * allocations. | ||
170 | */ | ||
171 | if (addr & ~PAGE_MASK) { | ||
172 | VM_BUG_ON(addr != -ENOMEM); | ||
173 | info.flags = 0; | ||
174 | info.low_limit = TASK_UNMAPPED_BASE; | ||
175 | info.high_limit = TASK_SIZE; | ||
176 | addr = vm_unmapped_area(&info); | ||
177 | } | ||
178 | |||
179 | return addr; | ||
180 | } | ||
181 | |||
182 | unsigned long randomize_et_dyn(void) | ||
183 | { | ||
184 | unsigned long base; | ||
185 | |||
186 | base = (STACK_TOP / 3 * 2) & (~mmap_align_mask << PAGE_SHIFT); | ||
187 | return base + mmap_rnd(); | ||
188 | } | ||
189 | |||
84 | #ifndef CONFIG_64BIT | 190 | #ifndef CONFIG_64BIT |
85 | 191 | ||
86 | /* | 192 | /* |
@@ -177,4 +283,36 @@ void arch_pick_mmap_layout(struct mm_struct *mm) | |||
177 | } | 283 | } |
178 | } | 284 | } |
179 | 285 | ||
286 | static int __init setup_mmap_rnd(void) | ||
287 | { | ||
288 | struct cpuid cpu_id; | ||
289 | |||
290 | get_cpu_id(&cpu_id); | ||
291 | switch (cpu_id.machine) { | ||
292 | case 0x9672: | ||
293 | case 0x2064: | ||
294 | case 0x2066: | ||
295 | case 0x2084: | ||
296 | case 0x2086: | ||
297 | case 0x2094: | ||
298 | case 0x2096: | ||
299 | case 0x2097: | ||
300 | case 0x2098: | ||
301 | case 0x2817: | ||
302 | case 0x2818: | ||
303 | case 0x2827: | ||
304 | case 0x2828: | ||
305 | mmap_rnd_mask = 0x7ffUL; | ||
306 | mmap_align_mask = 0UL; | ||
307 | break; | ||
308 | case 0x2964: /* z13 */ | ||
309 | default: | ||
310 | mmap_rnd_mask = 0x3ff80UL; | ||
311 | mmap_align_mask = 0x7fUL; | ||
312 | break; | ||
313 | } | ||
314 | return 0; | ||
315 | } | ||
316 | early_initcall(setup_mmap_rnd); | ||
317 | |||
180 | #endif | 318 | #endif |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 3cf8cc03fff6..b2c1542f2ba2 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -527,7 +527,7 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr) | |||
527 | table += (gaddr >> 53) & 0x7ff; | 527 | table += (gaddr >> 53) & 0x7ff; |
528 | if ((*table & _REGION_ENTRY_INVALID) && | 528 | if ((*table & _REGION_ENTRY_INVALID) && |
529 | gmap_alloc_table(gmap, table, _REGION2_ENTRY_EMPTY, | 529 | gmap_alloc_table(gmap, table, _REGION2_ENTRY_EMPTY, |
530 | gaddr & 0xffe0000000000000)) | 530 | gaddr & 0xffe0000000000000UL)) |
531 | return -ENOMEM; | 531 | return -ENOMEM; |
532 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 532 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
533 | } | 533 | } |
@@ -535,7 +535,7 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr) | |||
535 | table += (gaddr >> 42) & 0x7ff; | 535 | table += (gaddr >> 42) & 0x7ff; |
536 | if ((*table & _REGION_ENTRY_INVALID) && | 536 | if ((*table & _REGION_ENTRY_INVALID) && |
537 | gmap_alloc_table(gmap, table, _REGION3_ENTRY_EMPTY, | 537 | gmap_alloc_table(gmap, table, _REGION3_ENTRY_EMPTY, |
538 | gaddr & 0xfffffc0000000000)) | 538 | gaddr & 0xfffffc0000000000UL)) |
539 | return -ENOMEM; | 539 | return -ENOMEM; |
540 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 540 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
541 | } | 541 | } |
@@ -543,7 +543,7 @@ int __gmap_link(struct gmap *gmap, unsigned long gaddr, unsigned long vmaddr) | |||
543 | table += (gaddr >> 31) & 0x7ff; | 543 | table += (gaddr >> 31) & 0x7ff; |
544 | if ((*table & _REGION_ENTRY_INVALID) && | 544 | if ((*table & _REGION_ENTRY_INVALID) && |
545 | gmap_alloc_table(gmap, table, _SEGMENT_ENTRY_EMPTY, | 545 | gmap_alloc_table(gmap, table, _SEGMENT_ENTRY_EMPTY, |
546 | gaddr & 0xffffffff80000000)) | 546 | gaddr & 0xffffffff80000000UL)) |
547 | return -ENOMEM; | 547 | return -ENOMEM; |
548 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 548 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
549 | } | 549 | } |
diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c index 62c5ea6d8682..8aa271b3d1ad 100644 --- a/arch/s390/pci/pci_mmio.c +++ b/arch/s390/pci/pci_mmio.c | |||
@@ -55,7 +55,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr, | |||
55 | ret = get_pfn(mmio_addr, VM_WRITE, &pfn); | 55 | ret = get_pfn(mmio_addr, VM_WRITE, &pfn); |
56 | if (ret) | 56 | if (ret) |
57 | goto out; | 57 | goto out; |
58 | io_addr = (void *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK)); | 58 | io_addr = (void __iomem *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK)); |
59 | 59 | ||
60 | ret = -EFAULT; | 60 | ret = -EFAULT; |
61 | if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) | 61 | if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) |
@@ -96,7 +96,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr, | |||
96 | ret = get_pfn(mmio_addr, VM_READ, &pfn); | 96 | ret = get_pfn(mmio_addr, VM_READ, &pfn); |
97 | if (ret) | 97 | if (ret) |
98 | goto out; | 98 | goto out; |
99 | io_addr = (void *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK)); | 99 | io_addr = (void __iomem *)((pfn << PAGE_SHIFT) | (mmio_addr & ~PAGE_MASK)); |
100 | 100 | ||
101 | ret = -EFAULT; | 101 | ret = -EFAULT; |
102 | if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) | 102 | if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 4abf11965484..be34ef41b7c7 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -674,8 +674,9 @@ EXPORT_SYMBOL(dasd_enable_device); | |||
674 | unsigned int dasd_global_profile_level = DASD_PROFILE_OFF; | 674 | unsigned int dasd_global_profile_level = DASD_PROFILE_OFF; |
675 | 675 | ||
676 | #ifdef CONFIG_DASD_PROFILE | 676 | #ifdef CONFIG_DASD_PROFILE |
677 | struct dasd_profile_info dasd_global_profile_data; | 677 | struct dasd_profile dasd_global_profile = { |
678 | static struct dentry *dasd_global_profile_dentry; | 678 | .lock = __SPIN_LOCK_UNLOCKED(dasd_global_profile.lock), |
679 | }; | ||
679 | static struct dentry *dasd_debugfs_global_entry; | 680 | static struct dentry *dasd_debugfs_global_entry; |
680 | 681 | ||
681 | /* | 682 | /* |
@@ -696,11 +697,13 @@ static void dasd_profile_start(struct dasd_block *block, | |||
696 | if (++counter >= 31) | 697 | if (++counter >= 31) |
697 | break; | 698 | break; |
698 | 699 | ||
699 | if (dasd_global_profile_level) { | 700 | spin_lock(&dasd_global_profile.lock); |
700 | dasd_global_profile_data.dasd_io_nr_req[counter]++; | 701 | if (dasd_global_profile.data) { |
702 | dasd_global_profile.data->dasd_io_nr_req[counter]++; | ||
701 | if (rq_data_dir(req) == READ) | 703 | if (rq_data_dir(req) == READ) |
702 | dasd_global_profile_data.dasd_read_nr_req[counter]++; | 704 | dasd_global_profile.data->dasd_read_nr_req[counter]++; |
703 | } | 705 | } |
706 | spin_unlock(&dasd_global_profile.lock); | ||
704 | 707 | ||
705 | spin_lock(&block->profile.lock); | 708 | spin_lock(&block->profile.lock); |
706 | if (block->profile.data) { | 709 | if (block->profile.data) { |
@@ -825,8 +828,9 @@ static void dasd_profile_end(struct dasd_block *block, | |||
825 | dasd_profile_counter(irqtime / sectors, irqtimeps_ind); | 828 | dasd_profile_counter(irqtime / sectors, irqtimeps_ind); |
826 | dasd_profile_counter(endtime, endtime_ind); | 829 | dasd_profile_counter(endtime, endtime_ind); |
827 | 830 | ||
828 | if (dasd_global_profile_level) { | 831 | spin_lock(&dasd_global_profile.lock); |
829 | dasd_profile_end_add_data(&dasd_global_profile_data, | 832 | if (dasd_global_profile.data) { |
833 | dasd_profile_end_add_data(dasd_global_profile.data, | ||
830 | cqr->startdev != block->base, | 834 | cqr->startdev != block->base, |
831 | cqr->cpmode == 1, | 835 | cqr->cpmode == 1, |
832 | rq_data_dir(req) == READ, | 836 | rq_data_dir(req) == READ, |
@@ -835,6 +839,7 @@ static void dasd_profile_end(struct dasd_block *block, | |||
835 | irqtime_ind, irqtimeps_ind, | 839 | irqtime_ind, irqtimeps_ind, |
836 | endtime_ind); | 840 | endtime_ind); |
837 | } | 841 | } |
842 | spin_unlock(&dasd_global_profile.lock); | ||
838 | 843 | ||
839 | spin_lock(&block->profile.lock); | 844 | spin_lock(&block->profile.lock); |
840 | if (block->profile.data) | 845 | if (block->profile.data) |
@@ -876,12 +881,6 @@ void dasd_profile_reset(struct dasd_profile *profile) | |||
876 | spin_unlock_bh(&profile->lock); | 881 | spin_unlock_bh(&profile->lock); |
877 | } | 882 | } |
878 | 883 | ||
879 | void dasd_global_profile_reset(void) | ||
880 | { | ||
881 | memset(&dasd_global_profile_data, 0, sizeof(dasd_global_profile_data)); | ||
882 | getnstimeofday(&dasd_global_profile_data.starttod); | ||
883 | } | ||
884 | |||
885 | int dasd_profile_on(struct dasd_profile *profile) | 884 | int dasd_profile_on(struct dasd_profile *profile) |
886 | { | 885 | { |
887 | struct dasd_profile_info *data; | 886 | struct dasd_profile_info *data; |
@@ -949,12 +948,20 @@ static ssize_t dasd_stats_write(struct file *file, | |||
949 | dasd_profile_reset(prof); | 948 | dasd_profile_reset(prof); |
950 | } else if (strncmp(str, "on", 2) == 0) { | 949 | } else if (strncmp(str, "on", 2) == 0) { |
951 | rc = dasd_profile_on(prof); | 950 | rc = dasd_profile_on(prof); |
952 | if (!rc) | 951 | if (rc) |
953 | rc = user_len; | 952 | goto out; |
953 | rc = user_len; | ||
954 | if (prof == &dasd_global_profile) { | ||
955 | dasd_profile_reset(prof); | ||
956 | dasd_global_profile_level = DASD_PROFILE_GLOBAL_ONLY; | ||
957 | } | ||
954 | } else if (strncmp(str, "off", 3) == 0) { | 958 | } else if (strncmp(str, "off", 3) == 0) { |
959 | if (prof == &dasd_global_profile) | ||
960 | dasd_global_profile_level = DASD_PROFILE_OFF; | ||
955 | dasd_profile_off(prof); | 961 | dasd_profile_off(prof); |
956 | } else | 962 | } else |
957 | rc = -EINVAL; | 963 | rc = -EINVAL; |
964 | out: | ||
958 | vfree(buffer); | 965 | vfree(buffer); |
959 | return rc; | 966 | return rc; |
960 | } | 967 | } |
@@ -1044,57 +1051,6 @@ static const struct file_operations dasd_stats_raw_fops = { | |||
1044 | .write = dasd_stats_write, | 1051 | .write = dasd_stats_write, |
1045 | }; | 1052 | }; |
1046 | 1053 | ||
1047 | static ssize_t dasd_stats_global_write(struct file *file, | ||
1048 | const char __user *user_buf, | ||
1049 | size_t user_len, loff_t *pos) | ||
1050 | { | ||
1051 | char *buffer, *str; | ||
1052 | ssize_t rc; | ||
1053 | |||
1054 | if (user_len > 65536) | ||
1055 | user_len = 65536; | ||
1056 | buffer = dasd_get_user_string(user_buf, user_len); | ||
1057 | if (IS_ERR(buffer)) | ||
1058 | return PTR_ERR(buffer); | ||
1059 | str = skip_spaces(buffer); | ||
1060 | rc = user_len; | ||
1061 | if (strncmp(str, "reset", 5) == 0) { | ||
1062 | dasd_global_profile_reset(); | ||
1063 | } else if (strncmp(str, "on", 2) == 0) { | ||
1064 | dasd_global_profile_reset(); | ||
1065 | dasd_global_profile_level = DASD_PROFILE_GLOBAL_ONLY; | ||
1066 | } else if (strncmp(str, "off", 3) == 0) { | ||
1067 | dasd_global_profile_level = DASD_PROFILE_OFF; | ||
1068 | } else | ||
1069 | rc = -EINVAL; | ||
1070 | vfree(buffer); | ||
1071 | return rc; | ||
1072 | } | ||
1073 | |||
1074 | static int dasd_stats_global_show(struct seq_file *m, void *v) | ||
1075 | { | ||
1076 | if (!dasd_global_profile_level) { | ||
1077 | seq_puts(m, "disabled\n"); | ||
1078 | return 0; | ||
1079 | } | ||
1080 | dasd_stats_seq_print(m, &dasd_global_profile_data); | ||
1081 | return 0; | ||
1082 | } | ||
1083 | |||
1084 | static int dasd_stats_global_open(struct inode *inode, struct file *file) | ||
1085 | { | ||
1086 | return single_open(file, dasd_stats_global_show, NULL); | ||
1087 | } | ||
1088 | |||
1089 | static const struct file_operations dasd_stats_global_fops = { | ||
1090 | .owner = THIS_MODULE, | ||
1091 | .open = dasd_stats_global_open, | ||
1092 | .read = seq_read, | ||
1093 | .llseek = seq_lseek, | ||
1094 | .release = single_release, | ||
1095 | .write = dasd_stats_global_write, | ||
1096 | }; | ||
1097 | |||
1098 | static void dasd_profile_init(struct dasd_profile *profile, | 1054 | static void dasd_profile_init(struct dasd_profile *profile, |
1099 | struct dentry *base_dentry) | 1055 | struct dentry *base_dentry) |
1100 | { | 1056 | { |
@@ -1123,20 +1079,16 @@ static void dasd_profile_exit(struct dasd_profile *profile) | |||
1123 | static void dasd_statistics_removeroot(void) | 1079 | static void dasd_statistics_removeroot(void) |
1124 | { | 1080 | { |
1125 | dasd_global_profile_level = DASD_PROFILE_OFF; | 1081 | dasd_global_profile_level = DASD_PROFILE_OFF; |
1126 | debugfs_remove(dasd_global_profile_dentry); | 1082 | dasd_profile_exit(&dasd_global_profile); |
1127 | dasd_global_profile_dentry = NULL; | ||
1128 | debugfs_remove(dasd_debugfs_global_entry); | 1083 | debugfs_remove(dasd_debugfs_global_entry); |
1129 | debugfs_remove(dasd_debugfs_root_entry); | 1084 | debugfs_remove(dasd_debugfs_root_entry); |
1130 | } | 1085 | } |
1131 | 1086 | ||
1132 | static void dasd_statistics_createroot(void) | 1087 | static void dasd_statistics_createroot(void) |
1133 | { | 1088 | { |
1134 | umode_t mode; | ||
1135 | struct dentry *pde; | 1089 | struct dentry *pde; |
1136 | 1090 | ||
1137 | dasd_debugfs_root_entry = NULL; | 1091 | dasd_debugfs_root_entry = NULL; |
1138 | dasd_debugfs_global_entry = NULL; | ||
1139 | dasd_global_profile_dentry = NULL; | ||
1140 | pde = debugfs_create_dir("dasd", NULL); | 1092 | pde = debugfs_create_dir("dasd", NULL); |
1141 | if (!pde || IS_ERR(pde)) | 1093 | if (!pde || IS_ERR(pde)) |
1142 | goto error; | 1094 | goto error; |
@@ -1145,13 +1097,7 @@ static void dasd_statistics_createroot(void) | |||
1145 | if (!pde || IS_ERR(pde)) | 1097 | if (!pde || IS_ERR(pde)) |
1146 | goto error; | 1098 | goto error; |
1147 | dasd_debugfs_global_entry = pde; | 1099 | dasd_debugfs_global_entry = pde; |
1148 | 1100 | dasd_profile_init(&dasd_global_profile, dasd_debugfs_global_entry); | |
1149 | mode = (S_IRUSR | S_IWUSR | S_IFREG); | ||
1150 | pde = debugfs_create_file("statistics", mode, dasd_debugfs_global_entry, | ||
1151 | NULL, &dasd_stats_global_fops); | ||
1152 | if (!pde || IS_ERR(pde)) | ||
1153 | goto error; | ||
1154 | dasd_global_profile_dentry = pde; | ||
1155 | return; | 1101 | return; |
1156 | 1102 | ||
1157 | error: | 1103 | error: |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 8b5d4100abf7..227e3dea3155 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -651,7 +651,7 @@ dasd_check_blocksize(int bsize) | |||
651 | #define DASD_PROFILE_GLOBAL_ONLY 2 | 651 | #define DASD_PROFILE_GLOBAL_ONLY 2 |
652 | 652 | ||
653 | extern debug_info_t *dasd_debug_area; | 653 | extern debug_info_t *dasd_debug_area; |
654 | extern struct dasd_profile_info dasd_global_profile_data; | 654 | extern struct dasd_profile dasd_global_profile; |
655 | extern unsigned int dasd_global_profile_level; | 655 | extern unsigned int dasd_global_profile_level; |
656 | extern const struct block_device_operations dasd_device_operations; | 656 | extern const struct block_device_operations dasd_device_operations; |
657 | 657 | ||
@@ -728,7 +728,6 @@ int dasd_device_is_ro(struct dasd_device *); | |||
728 | void dasd_profile_reset(struct dasd_profile *); | 728 | void dasd_profile_reset(struct dasd_profile *); |
729 | int dasd_profile_on(struct dasd_profile *); | 729 | int dasd_profile_on(struct dasd_profile *); |
730 | void dasd_profile_off(struct dasd_profile *); | 730 | void dasd_profile_off(struct dasd_profile *); |
731 | void dasd_global_profile_reset(void); | ||
732 | char *dasd_get_user_string(const char __user *, size_t); | 731 | char *dasd_get_user_string(const char __user *, size_t); |
733 | 732 | ||
734 | /* externals in dasd_devmap.c */ | 733 | /* externals in dasd_devmap.c */ |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 78ac905a5b7f..aa7bb2d1da81 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -212,14 +212,15 @@ static int dasd_stats_proc_show(struct seq_file *m, void *v) | |||
212 | struct dasd_profile_info *prof; | 212 | struct dasd_profile_info *prof; |
213 | int factor; | 213 | int factor; |
214 | 214 | ||
215 | /* check for active profiling */ | 215 | spin_lock_bh(&dasd_global_profile.lock); |
216 | if (!dasd_global_profile_level) { | 216 | prof = dasd_global_profile.data; |
217 | if (!prof) { | ||
218 | spin_unlock_bh(&dasd_global_profile.lock); | ||
217 | seq_printf(m, "Statistics are off - they might be " | 219 | seq_printf(m, "Statistics are off - they might be " |
218 | "switched on using 'echo set on > " | 220 | "switched on using 'echo set on > " |
219 | "/proc/dasd/statistics'\n"); | 221 | "/proc/dasd/statistics'\n"); |
220 | return 0; | 222 | return 0; |
221 | } | 223 | } |
222 | prof = &dasd_global_profile_data; | ||
223 | 224 | ||
224 | /* prevent counter 'overflow' on output */ | 225 | /* prevent counter 'overflow' on output */ |
225 | for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999; | 226 | for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999; |
@@ -255,6 +256,7 @@ static int dasd_stats_proc_show(struct seq_file *m, void *v) | |||
255 | dasd_statistics_array(m, prof->dasd_io_time3, factor); | 256 | dasd_statistics_array(m, prof->dasd_io_time3, factor); |
256 | seq_printf(m, "# of req in chanq at enqueuing (1..32) \n"); | 257 | seq_printf(m, "# of req in chanq at enqueuing (1..32) \n"); |
257 | dasd_statistics_array(m, prof->dasd_io_nr_req, factor); | 258 | dasd_statistics_array(m, prof->dasd_io_nr_req, factor); |
259 | spin_unlock_bh(&dasd_global_profile.lock); | ||
258 | #else | 260 | #else |
259 | seq_printf(m, "Statistics are not activated in this kernel\n"); | 261 | seq_printf(m, "Statistics are not activated in this kernel\n"); |
260 | #endif | 262 | #endif |
@@ -291,14 +293,19 @@ static ssize_t dasd_stats_proc_write(struct file *file, | |||
291 | dasd_stats_all_block_off(); | 293 | dasd_stats_all_block_off(); |
292 | goto out_error; | 294 | goto out_error; |
293 | } | 295 | } |
294 | dasd_global_profile_reset(); | 296 | rc = dasd_profile_on(&dasd_global_profile); |
297 | if (rc) { | ||
298 | dasd_stats_all_block_off(); | ||
299 | goto out_error; | ||
300 | } | ||
301 | dasd_profile_reset(&dasd_global_profile); | ||
295 | dasd_global_profile_level = DASD_PROFILE_ON; | 302 | dasd_global_profile_level = DASD_PROFILE_ON; |
296 | pr_info("The statistics feature has been switched " | 303 | pr_info("The statistics feature has been switched " |
297 | "on\n"); | 304 | "on\n"); |
298 | } else if (strcmp(str, "off") == 0) { | 305 | } else if (strcmp(str, "off") == 0) { |
299 | /* switch off and reset statistics profiling */ | 306 | /* switch off statistics profiling */ |
300 | dasd_global_profile_level = DASD_PROFILE_OFF; | 307 | dasd_global_profile_level = DASD_PROFILE_OFF; |
301 | dasd_global_profile_reset(); | 308 | dasd_profile_off(&dasd_global_profile); |
302 | dasd_stats_all_block_off(); | 309 | dasd_stats_all_block_off(); |
303 | pr_info("The statistics feature has been switched " | 310 | pr_info("The statistics feature has been switched " |
304 | "off\n"); | 311 | "off\n"); |
@@ -306,7 +313,7 @@ static ssize_t dasd_stats_proc_write(struct file *file, | |||
306 | goto out_parse_error; | 313 | goto out_parse_error; |
307 | } else if (strncmp(str, "reset", 5) == 0) { | 314 | } else if (strncmp(str, "reset", 5) == 0) { |
308 | /* reset the statistics */ | 315 | /* reset the statistics */ |
309 | dasd_global_profile_reset(); | 316 | dasd_profile_reset(&dasd_global_profile); |
310 | dasd_stats_all_block_reset(); | 317 | dasd_stats_all_block_reset(); |
311 | pr_info("The statistics have been reset\n"); | 318 | pr_info("The statistics have been reset\n"); |
312 | } else | 319 | } else |
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index b550c8c8d010..7f900229404d 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -438,7 +438,13 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char | |||
438 | pr_info("All DCSSs that map to device %s are " | 438 | pr_info("All DCSSs that map to device %s are " |
439 | "saved\n", dev_info->segment_name); | 439 | "saved\n", dev_info->segment_name); |
440 | list_for_each_entry(entry, &dev_info->seg_list, lh) { | 440 | list_for_each_entry(entry, &dev_info->seg_list, lh) { |
441 | segment_save(entry->segment_name); | 441 | if (entry->segment_type == SEG_TYPE_EN || |
442 | entry->segment_type == SEG_TYPE_SN) | ||
443 | pr_warn("DCSS %s is of type SN or EN" | ||
444 | " and cannot be saved\n", | ||
445 | entry->segment_name); | ||
446 | else | ||
447 | segment_save(entry->segment_name); | ||
442 | } | 448 | } |
443 | } else { | 449 | } else { |
444 | // device is busy => we save it when it becomes | 450 | // device is busy => we save it when it becomes |
@@ -797,7 +803,12 @@ dcssblk_release(struct gendisk *disk, fmode_t mode) | |||
797 | pr_info("Device %s has become idle and is being saved " | 803 | pr_info("Device %s has become idle and is being saved " |
798 | "now\n", dev_info->segment_name); | 804 | "now\n", dev_info->segment_name); |
799 | list_for_each_entry(entry, &dev_info->seg_list, lh) { | 805 | list_for_each_entry(entry, &dev_info->seg_list, lh) { |
800 | segment_save(entry->segment_name); | 806 | if (entry->segment_type == SEG_TYPE_EN || |
807 | entry->segment_type == SEG_TYPE_SN) | ||
808 | pr_warn("DCSS %s is of type SN or EN and cannot" | ||
809 | " be saved\n", entry->segment_name); | ||
810 | else | ||
811 | segment_save(entry->segment_name); | ||
801 | } | 812 | } |
802 | dev_info->save_pending = 0; | 813 | dev_info->save_pending = 0; |
803 | } | 814 | } |
diff --git a/drivers/s390/char/hmcdrv_ftp.c b/drivers/s390/char/hmcdrv_ftp.c index 4bd63322fc29..d4b61d9088fb 100644 --- a/drivers/s390/char/hmcdrv_ftp.c +++ b/drivers/s390/char/hmcdrv_ftp.c | |||
@@ -200,10 +200,9 @@ int hmcdrv_ftp_probe(void) | |||
200 | rc = hmcdrv_ftp_startup(); | 200 | rc = hmcdrv_ftp_startup(); |
201 | 201 | ||
202 | if (rc) | 202 | if (rc) |
203 | return rc; | 203 | goto out; |
204 | 204 | ||
205 | rc = hmcdrv_ftp_do(&ftp); | 205 | rc = hmcdrv_ftp_do(&ftp); |
206 | free_page((unsigned long) ftp.buf); | ||
207 | hmcdrv_ftp_shutdown(); | 206 | hmcdrv_ftp_shutdown(); |
208 | 207 | ||
209 | switch (rc) { | 208 | switch (rc) { |
@@ -216,7 +215,8 @@ int hmcdrv_ftp_probe(void) | |||
216 | rc = 0; /* clear length (success) */ | 215 | rc = 0; /* clear length (success) */ |
217 | break; | 216 | break; |
218 | } /* switch */ | 217 | } /* switch */ |
219 | 218 | out: | |
219 | free_page((unsigned long) ftp.buf); | ||
220 | return rc; | 220 | return rc; |
221 | } | 221 | } |
222 | EXPORT_SYMBOL(hmcdrv_ftp_probe); | 222 | EXPORT_SYMBOL(hmcdrv_ftp_probe); |
diff --git a/drivers/s390/char/hmcdrv_mod.c b/drivers/s390/char/hmcdrv_mod.c index 505c6a78ee1a..251a318a9b75 100644 --- a/drivers/s390/char/hmcdrv_mod.c +++ b/drivers/s390/char/hmcdrv_mod.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/moduleparam.h> | 13 | #include <linux/moduleparam.h> |
14 | #include <linux/version.h> | ||
15 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
16 | 15 | ||
17 | #include "hmcdrv_ftp.h" | 16 | #include "hmcdrv_ftp.h" |
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index 5bd6cb145a87..daf6cd5079ec 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c | |||
@@ -20,26 +20,31 @@ struct read_info_sccb { | |||
20 | struct sccb_header header; /* 0-7 */ | 20 | struct sccb_header header; /* 0-7 */ |
21 | u16 rnmax; /* 8-9 */ | 21 | u16 rnmax; /* 8-9 */ |
22 | u8 rnsize; /* 10 */ | 22 | u8 rnsize; /* 10 */ |
23 | u8 _reserved0[16 - 11]; /* 11-15 */ | 23 | u8 _pad_11[16 - 11]; /* 11-15 */ |
24 | u16 ncpurl; /* 16-17 */ | 24 | u16 ncpurl; /* 16-17 */ |
25 | u16 cpuoff; /* 18-19 */ | 25 | u16 cpuoff; /* 18-19 */ |
26 | u8 _reserved7[24 - 20]; /* 20-23 */ | 26 | u8 _pad_20[24 - 20]; /* 20-23 */ |
27 | u8 loadparm[8]; /* 24-31 */ | 27 | u8 loadparm[8]; /* 24-31 */ |
28 | u8 _reserved1[48 - 32]; /* 32-47 */ | 28 | u8 _pad_32[42 - 32]; /* 32-41 */ |
29 | u8 fac42; /* 42 */ | ||
30 | u8 fac43; /* 43 */ | ||
31 | u8 _pad_44[48 - 44]; /* 44-47 */ | ||
29 | u64 facilities; /* 48-55 */ | 32 | u64 facilities; /* 48-55 */ |
30 | u8 _reserved2a[76 - 56]; /* 56-75 */ | 33 | u8 _pad_56[66 - 56]; /* 56-65 */ |
34 | u8 fac66; /* 66 */ | ||
35 | u8 _pad_67[76 - 67]; /* 67-83 */ | ||
31 | u32 ibc; /* 76-79 */ | 36 | u32 ibc; /* 76-79 */ |
32 | u8 _reserved2b[84 - 80]; /* 80-83 */ | 37 | u8 _pad80[84 - 80]; /* 80-83 */ |
33 | u8 fac84; /* 84 */ | 38 | u8 fac84; /* 84 */ |
34 | u8 fac85; /* 85 */ | 39 | u8 fac85; /* 85 */ |
35 | u8 _reserved3[91 - 86]; /* 86-90 */ | 40 | u8 _pad_86[91 - 86]; /* 86-90 */ |
36 | u8 flags; /* 91 */ | 41 | u8 flags; /* 91 */ |
37 | u8 _reserved4[100 - 92]; /* 92-99 */ | 42 | u8 _pad_92[100 - 92]; /* 92-99 */ |
38 | u32 rnsize2; /* 100-103 */ | 43 | u32 rnsize2; /* 100-103 */ |
39 | u64 rnmax2; /* 104-111 */ | 44 | u64 rnmax2; /* 104-111 */ |
40 | u8 _reserved5[120 - 112]; /* 112-119 */ | 45 | u8 _pad_112[120 - 112]; /* 112-119 */ |
41 | u16 hcpua; /* 120-121 */ | 46 | u16 hcpua; /* 120-121 */ |
42 | u8 _reserved6[4096 - 122]; /* 122-4095 */ | 47 | u8 _pad_122[4096 - 122]; /* 122-4095 */ |
43 | } __packed __aligned(PAGE_SIZE); | 48 | } __packed __aligned(PAGE_SIZE); |
44 | 49 | ||
45 | static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata; | 50 | static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata; |
@@ -50,6 +55,10 @@ static unsigned int sclp_max_cpu; | |||
50 | static struct sclp_ipl_info sclp_ipl_info; | 55 | static struct sclp_ipl_info sclp_ipl_info; |
51 | static unsigned char sclp_siif; | 56 | static unsigned char sclp_siif; |
52 | static u32 sclp_ibc; | 57 | static u32 sclp_ibc; |
58 | static unsigned int sclp_mtid; | ||
59 | static unsigned int sclp_mtid_cp; | ||
60 | static unsigned int sclp_mtid_max; | ||
61 | static unsigned int sclp_mtid_prev; | ||
53 | 62 | ||
54 | u64 sclp_facilities; | 63 | u64 sclp_facilities; |
55 | u8 sclp_fac84; | 64 | u8 sclp_fac84; |
@@ -128,7 +137,7 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb) | |||
128 | boot_cpu_address = stap(); | 137 | boot_cpu_address = stap(); |
129 | cpue = (void *)sccb + sccb->cpuoff; | 138 | cpue = (void *)sccb + sccb->cpuoff; |
130 | for (cpu = 0; cpu < sccb->ncpurl; cpue++, cpu++) { | 139 | for (cpu = 0; cpu < sccb->ncpurl; cpue++, cpu++) { |
131 | if (boot_cpu_address != cpue->address) | 140 | if (boot_cpu_address != cpue->core_id) |
132 | continue; | 141 | continue; |
133 | sclp_siif = cpue->siif; | 142 | sclp_siif = cpue->siif; |
134 | break; | 143 | break; |
@@ -139,6 +148,11 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb) | |||
139 | if (sccb->flags & 0x2) | 148 | if (sccb->flags & 0x2) |
140 | sclp_ipl_info.has_dump = 1; | 149 | sclp_ipl_info.has_dump = 1; |
141 | memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN); | 150 | memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN); |
151 | |||
152 | sclp_mtid = (sccb->fac42 & 0x80) ? (sccb->fac42 & 31) : 0; | ||
153 | sclp_mtid_cp = (sccb->fac42 & 0x80) ? (sccb->fac43 & 31) : 0; | ||
154 | sclp_mtid_max = max(sclp_mtid, sclp_mtid_cp); | ||
155 | sclp_mtid_prev = (sccb->fac42 & 0x80) ? (sccb->fac66 & 31) : 0; | ||
142 | } | 156 | } |
143 | 157 | ||
144 | bool __init sclp_has_linemode(void) | 158 | bool __init sclp_has_linemode(void) |
@@ -178,6 +192,21 @@ unsigned int sclp_get_ibc(void) | |||
178 | } | 192 | } |
179 | EXPORT_SYMBOL(sclp_get_ibc); | 193 | EXPORT_SYMBOL(sclp_get_ibc); |
180 | 194 | ||
195 | unsigned int sclp_get_mtid(u8 cpu_type) | ||
196 | { | ||
197 | return cpu_type ? sclp_mtid : sclp_mtid_cp; | ||
198 | } | ||
199 | |||
200 | unsigned int sclp_get_mtid_max(void) | ||
201 | { | ||
202 | return sclp_mtid_max; | ||
203 | } | ||
204 | |||
205 | unsigned int sclp_get_mtid_prev(void) | ||
206 | { | ||
207 | return sclp_mtid_prev; | ||
208 | } | ||
209 | |||
181 | /* | 210 | /* |
182 | * This function will be called after sclp_facilities_detect(), which gets | 211 | * This function will be called after sclp_facilities_detect(), which gets |
183 | * called from early.c code. The sclp_facilities_detect() function retrieves | 212 | * called from early.c code. The sclp_facilities_detect() function retrieves |
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 9aa79702b370..de69f0ddc321 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c | |||
@@ -773,13 +773,11 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request, | |||
773 | "occurred\n"); | 773 | "occurred\n"); |
774 | return tape_34xx_erp_failed(request, -EIO); | 774 | return tape_34xx_erp_failed(request, -EIO); |
775 | case 0x57: | 775 | case 0x57: |
776 | if (device->cdev->id.driver_info == tape_3480) { | 776 | /* |
777 | /* Attention intercept. */ | 777 | * 3480: Attention intercept. |
778 | return tape_34xx_erp_retry(request); | 778 | * 3490: Global status intercept. |
779 | } else { | 779 | */ |
780 | /* Global status intercept. */ | 780 | return tape_34xx_erp_retry(request); |
781 | return tape_34xx_erp_retry(request); | ||
782 | } | ||
783 | case 0x5a: | 781 | case 0x5a: |
784 | /* | 782 | /* |
785 | * Tape length incompatible. The tape inserted is too long, | 783 | * Tape length incompatible. The tape inserted is too long, |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 10eb738fc81a..3578105989a0 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -938,7 +938,7 @@ void reipl_ccw_dev(struct ccw_dev_id *devid) | |||
938 | { | 938 | { |
939 | struct subchannel_id uninitialized_var(schid); | 939 | struct subchannel_id uninitialized_var(schid); |
940 | 940 | ||
941 | s390_reset_system(NULL, NULL); | 941 | s390_reset_system(NULL, NULL, NULL); |
942 | if (reipl_find_schid(devid, &schid) != 0) | 942 | if (reipl_find_schid(devid, &schid) != 0) |
943 | panic("IPL Device not found\n"); | 943 | panic("IPL Device not found\n"); |
944 | do_reipl_asm(*((__u32*)&schid)); | 944 | do_reipl_asm(*((__u32*)&schid)); |
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c index 5a999084a229..b3e06a7b9480 100644 --- a/drivers/s390/cio/idset.c +++ b/drivers/s390/cio/idset.c | |||
@@ -38,11 +38,6 @@ void idset_free(struct idset *set) | |||
38 | vfree(set); | 38 | vfree(set); |
39 | } | 39 | } |
40 | 40 | ||
41 | void idset_clear(struct idset *set) | ||
42 | { | ||
43 | memset(set->bitmap, 0, bitmap_size(set->num_ssid, set->num_id)); | ||
44 | } | ||
45 | |||
46 | void idset_fill(struct idset *set) | 41 | void idset_fill(struct idset *set) |
47 | { | 42 | { |
48 | memset(set->bitmap, 0xff, bitmap_size(set->num_ssid, set->num_id)); | 43 | memset(set->bitmap, 0xff, bitmap_size(set->num_ssid, set->num_id)); |
@@ -103,21 +98,6 @@ int idset_sch_contains(struct idset *set, struct subchannel_id schid) | |||
103 | return idset_contains(set, schid.ssid, schid.sch_no); | 98 | return idset_contains(set, schid.ssid, schid.sch_no); |
104 | } | 99 | } |
105 | 100 | ||
106 | int idset_sch_get_first(struct idset *set, struct subchannel_id *schid) | ||
107 | { | ||
108 | int ssid = 0; | ||
109 | int id = 0; | ||
110 | int rc; | ||
111 | |||
112 | rc = idset_get_first(set, &ssid, &id); | ||
113 | if (rc) { | ||
114 | init_subchannel_id(schid); | ||
115 | schid->ssid = ssid; | ||
116 | schid->sch_no = id; | ||
117 | } | ||
118 | return rc; | ||
119 | } | ||
120 | |||
121 | int idset_is_empty(struct idset *set) | 101 | int idset_is_empty(struct idset *set) |
122 | { | 102 | { |
123 | return bitmap_empty(set->bitmap, set->num_ssid * set->num_id); | 103 | return bitmap_empty(set->bitmap, set->num_ssid * set->num_id); |
diff --git a/drivers/s390/cio/idset.h b/drivers/s390/cio/idset.h index 06d3bc01bb09..22b58104683b 100644 --- a/drivers/s390/cio/idset.h +++ b/drivers/s390/cio/idset.h | |||
@@ -11,7 +11,6 @@ | |||
11 | struct idset; | 11 | struct idset; |
12 | 12 | ||
13 | void idset_free(struct idset *set); | 13 | void idset_free(struct idset *set); |
14 | void idset_clear(struct idset *set); | ||
15 | void idset_fill(struct idset *set); | 14 | void idset_fill(struct idset *set); |
16 | 15 | ||
17 | struct idset *idset_sch_new(void); | 16 | struct idset *idset_sch_new(void); |
@@ -19,7 +18,6 @@ void idset_sch_add(struct idset *set, struct subchannel_id id); | |||
19 | void idset_sch_del(struct idset *set, struct subchannel_id id); | 18 | void idset_sch_del(struct idset *set, struct subchannel_id id); |
20 | void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid); | 19 | void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid); |
21 | int idset_sch_contains(struct idset *set, struct subchannel_id id); | 20 | int idset_sch_contains(struct idset *set, struct subchannel_id id); |
22 | int idset_sch_get_first(struct idset *set, struct subchannel_id *id); | ||
23 | int idset_is_empty(struct idset *set); | 21 | int idset_is_empty(struct idset *set); |
24 | void idset_add_set(struct idset *to, struct idset *from); | 22 | void idset_add_set(struct idset *to, struct idset *from); |
25 | 23 | ||
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 4d41bf75c233..3d7f19fb9a4e 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -204,6 +204,24 @@ ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type) | |||
204 | } | 204 | } |
205 | 205 | ||
206 | /** | 206 | /** |
207 | * ap_query_facilities(): PQAP(TAPQ) query facilities. | ||
208 | * @qid: The AP queue number | ||
209 | * | ||
210 | * Returns content of general register 2 after the PQAP(TAPQ) | ||
211 | * instruction was called. | ||
212 | */ | ||
213 | static inline unsigned long ap_query_facilities(ap_qid_t qid) | ||
214 | { | ||
215 | register unsigned long reg0 asm ("0") = qid | 0x00800000UL; | ||
216 | register unsigned long reg1 asm ("1"); | ||
217 | register unsigned long reg2 asm ("2") = 0UL; | ||
218 | |||
219 | asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */ | ||
220 | : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc"); | ||
221 | return reg2; | ||
222 | } | ||
223 | |||
224 | /** | ||
207 | * ap_reset_queue(): Reset adjunct processor queue. | 225 | * ap_reset_queue(): Reset adjunct processor queue. |
208 | * @qid: The AP queue number | 226 | * @qid: The AP queue number |
209 | * | 227 | * |
@@ -1007,6 +1025,51 @@ void ap_bus_force_rescan(void) | |||
1007 | EXPORT_SYMBOL(ap_bus_force_rescan); | 1025 | EXPORT_SYMBOL(ap_bus_force_rescan); |
1008 | 1026 | ||
1009 | /* | 1027 | /* |
1028 | * ap_test_config(): helper function to extract the nrth bit | ||
1029 | * within the unsigned int array field. | ||
1030 | */ | ||
1031 | static inline int ap_test_config(unsigned int *field, unsigned int nr) | ||
1032 | { | ||
1033 | if (nr > 0xFFu) | ||
1034 | return 0; | ||
1035 | return ap_test_bit((field + (nr >> 5)), (nr & 0x1f)); | ||
1036 | } | ||
1037 | |||
1038 | /* | ||
1039 | * ap_test_config_card_id(): Test, whether an AP card ID is configured. | ||
1040 | * @id AP card ID | ||
1041 | * | ||
1042 | * Returns 0 if the card is not configured | ||
1043 | * 1 if the card is configured or | ||
1044 | * if the configuration information is not available | ||
1045 | */ | ||
1046 | static inline int ap_test_config_card_id(unsigned int id) | ||
1047 | { | ||
1048 | if (!ap_configuration) | ||
1049 | return 1; | ||
1050 | return ap_test_config(ap_configuration->apm, id); | ||
1051 | } | ||
1052 | |||
1053 | /* | ||
1054 | * ap_test_config_domain(): Test, whether an AP usage domain is configured. | ||
1055 | * @domain AP usage domain ID | ||
1056 | * | ||
1057 | * Returns 0 if the usage domain is not configured | ||
1058 | * 1 if the usage domain is configured or | ||
1059 | * if the configuration information is not available | ||
1060 | */ | ||
1061 | static inline int ap_test_config_domain(unsigned int domain) | ||
1062 | { | ||
1063 | if (!ap_configuration) /* QCI not supported */ | ||
1064 | if (domain < 16) | ||
1065 | return 1; /* then domains 0...15 are configured */ | ||
1066 | else | ||
1067 | return 0; | ||
1068 | else | ||
1069 | return ap_test_config(ap_configuration->aqm, domain); | ||
1070 | } | ||
1071 | |||
1072 | /* | ||
1010 | * AP bus attributes. | 1073 | * AP bus attributes. |
1011 | */ | 1074 | */ |
1012 | static ssize_t ap_domain_show(struct bus_type *bus, char *buf) | 1075 | static ssize_t ap_domain_show(struct bus_type *bus, char *buf) |
@@ -1121,6 +1184,42 @@ static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf, | |||
1121 | 1184 | ||
1122 | static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store); | 1185 | static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store); |
1123 | 1186 | ||
1187 | static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf) | ||
1188 | { | ||
1189 | ap_qid_t qid; | ||
1190 | int i, nd, max_domain_id = -1; | ||
1191 | unsigned long fbits; | ||
1192 | |||
1193 | if (ap_configuration) { | ||
1194 | if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS) { | ||
1195 | for (i = 0; i < AP_DEVICES; i++) { | ||
1196 | if (!ap_test_config_card_id(i)) | ||
1197 | continue; | ||
1198 | qid = AP_MKQID(i, ap_domain_index); | ||
1199 | fbits = ap_query_facilities(qid); | ||
1200 | if (fbits & (1UL << 57)) { | ||
1201 | /* the N bit is 0, Nd field is filled */ | ||
1202 | nd = (int)((fbits & 0x00FF0000UL)>>16); | ||
1203 | if (nd > 0) | ||
1204 | max_domain_id = nd; | ||
1205 | else | ||
1206 | max_domain_id = 15; | ||
1207 | } else { | ||
1208 | /* N bit is 1, max 16 domains */ | ||
1209 | max_domain_id = 15; | ||
1210 | } | ||
1211 | break; | ||
1212 | } | ||
1213 | } | ||
1214 | } else { | ||
1215 | /* no APXA support, older machines with max 16 domains */ | ||
1216 | max_domain_id = 15; | ||
1217 | } | ||
1218 | return snprintf(buf, PAGE_SIZE, "%d\n", max_domain_id); | ||
1219 | } | ||
1220 | |||
1221 | static BUS_ATTR(ap_max_domain_id, 0444, ap_max_domain_id_show, NULL); | ||
1222 | |||
1124 | static struct bus_attribute *const ap_bus_attrs[] = { | 1223 | static struct bus_attribute *const ap_bus_attrs[] = { |
1125 | &bus_attr_ap_domain, | 1224 | &bus_attr_ap_domain, |
1126 | &bus_attr_ap_control_domain_mask, | 1225 | &bus_attr_ap_control_domain_mask, |
@@ -1128,50 +1227,10 @@ static struct bus_attribute *const ap_bus_attrs[] = { | |||
1128 | &bus_attr_poll_thread, | 1227 | &bus_attr_poll_thread, |
1129 | &bus_attr_ap_interrupts, | 1228 | &bus_attr_ap_interrupts, |
1130 | &bus_attr_poll_timeout, | 1229 | &bus_attr_poll_timeout, |
1230 | &bus_attr_ap_max_domain_id, | ||
1131 | NULL, | 1231 | NULL, |
1132 | }; | 1232 | }; |
1133 | 1233 | ||
1134 | static inline int ap_test_config(unsigned int *field, unsigned int nr) | ||
1135 | { | ||
1136 | if (nr > 0xFFu) | ||
1137 | return 0; | ||
1138 | return ap_test_bit((field + (nr >> 5)), (nr & 0x1f)); | ||
1139 | } | ||
1140 | |||
1141 | /* | ||
1142 | * ap_test_config_card_id(): Test, whether an AP card ID is configured. | ||
1143 | * @id AP card ID | ||
1144 | * | ||
1145 | * Returns 0 if the card is not configured | ||
1146 | * 1 if the card is configured or | ||
1147 | * if the configuration information is not available | ||
1148 | */ | ||
1149 | static inline int ap_test_config_card_id(unsigned int id) | ||
1150 | { | ||
1151 | if (!ap_configuration) | ||
1152 | return 1; | ||
1153 | return ap_test_config(ap_configuration->apm, id); | ||
1154 | } | ||
1155 | |||
1156 | /* | ||
1157 | * ap_test_config_domain(): Test, whether an AP usage domain is configured. | ||
1158 | * @domain AP usage domain ID | ||
1159 | * | ||
1160 | * Returns 0 if the usage domain is not configured | ||
1161 | * 1 if the usage domain is configured or | ||
1162 | * if the configuration information is not available | ||
1163 | */ | ||
1164 | static inline int ap_test_config_domain(unsigned int domain) | ||
1165 | { | ||
1166 | if (!ap_configuration) /* QCI not supported */ | ||
1167 | if (domain < 16) | ||
1168 | return 1; /* then domains 0...15 are configured */ | ||
1169 | else | ||
1170 | return 0; | ||
1171 | else | ||
1172 | return ap_test_config(ap_configuration->aqm, domain); | ||
1173 | } | ||
1174 | |||
1175 | /** | 1234 | /** |
1176 | * ap_query_configuration(): Query AP configuration information. | 1235 | * ap_query_configuration(): Query AP configuration information. |
1177 | * | 1236 | * |
@@ -1434,9 +1493,6 @@ static void ap_scan_bus(struct work_struct *unused) | |||
1434 | continue; | 1493 | continue; |
1435 | } | 1494 | } |
1436 | break; | 1495 | break; |
1437 | case 11: | ||
1438 | ap_dev->device_type = 10; | ||
1439 | break; | ||
1440 | default: | 1496 | default: |
1441 | ap_dev->device_type = device_type; | 1497 | ap_dev->device_type = device_type; |
1442 | } | 1498 | } |
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 055a0f956d17..2737d261a324 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h | |||
@@ -117,6 +117,7 @@ static inline int ap_test_bit(unsigned int *ptr, unsigned int nr) | |||
117 | #define AP_DEVICE_TYPE_CEX3A 8 | 117 | #define AP_DEVICE_TYPE_CEX3A 8 |
118 | #define AP_DEVICE_TYPE_CEX3C 9 | 118 | #define AP_DEVICE_TYPE_CEX3C 9 |
119 | #define AP_DEVICE_TYPE_CEX4 10 | 119 | #define AP_DEVICE_TYPE_CEX4 10 |
120 | #define AP_DEVICE_TYPE_CEX5 11 | ||
120 | 121 | ||
121 | /* | 122 | /* |
122 | * Known function facilities | 123 | * Known function facilities |
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h index b3d496bfaa7e..750876891931 100644 --- a/drivers/s390/crypto/zcrypt_api.h +++ b/drivers/s390/crypto/zcrypt_api.h | |||
@@ -75,6 +75,7 @@ struct ica_z90_status { | |||
75 | #define ZCRYPT_CEX3C 7 | 75 | #define ZCRYPT_CEX3C 7 |
76 | #define ZCRYPT_CEX3A 8 | 76 | #define ZCRYPT_CEX3A 8 |
77 | #define ZCRYPT_CEX4 10 | 77 | #define ZCRYPT_CEX4 10 |
78 | #define ZCRYPT_CEX5 11 | ||
78 | 79 | ||
79 | /** | 80 | /** |
80 | * Large random numbers are pulled in 4096 byte chunks from the crypto cards | 81 | * Large random numbers are pulled in 4096 byte chunks from the crypto cards |
diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c index 569f8b1d86c0..71e698b85772 100644 --- a/drivers/s390/crypto/zcrypt_cex4.c +++ b/drivers/s390/crypto/zcrypt_cex4.c | |||
@@ -26,6 +26,10 @@ | |||
26 | 26 | ||
27 | #define CEX4A_SPEED_RATING 900 /* TODO new card, new speed rating */ | 27 | #define CEX4A_SPEED_RATING 900 /* TODO new card, new speed rating */ |
28 | #define CEX4C_SPEED_RATING 6500 /* TODO new card, new speed rating */ | 28 | #define CEX4C_SPEED_RATING 6500 /* TODO new card, new speed rating */ |
29 | #define CEX4P_SPEED_RATING 7000 /* TODO new card, new speed rating */ | ||
30 | #define CEX5A_SPEED_RATING 450 /* TODO new card, new speed rating */ | ||
31 | #define CEX5C_SPEED_RATING 3250 /* TODO new card, new speed rating */ | ||
32 | #define CEX5P_SPEED_RATING 3500 /* TODO new card, new speed rating */ | ||
29 | 33 | ||
30 | #define CEX4A_MAX_MESSAGE_SIZE MSGTYPE50_CRB3_MAX_MSG_SIZE | 34 | #define CEX4A_MAX_MESSAGE_SIZE MSGTYPE50_CRB3_MAX_MSG_SIZE |
31 | #define CEX4C_MAX_MESSAGE_SIZE MSGTYPE06_MAX_MSG_SIZE | 35 | #define CEX4C_MAX_MESSAGE_SIZE MSGTYPE06_MAX_MSG_SIZE |
@@ -39,6 +43,7 @@ | |||
39 | 43 | ||
40 | static struct ap_device_id zcrypt_cex4_ids[] = { | 44 | static struct ap_device_id zcrypt_cex4_ids[] = { |
41 | { AP_DEVICE(AP_DEVICE_TYPE_CEX4) }, | 45 | { AP_DEVICE(AP_DEVICE_TYPE_CEX4) }, |
46 | { AP_DEVICE(AP_DEVICE_TYPE_CEX5) }, | ||
42 | { /* end of list */ }, | 47 | { /* end of list */ }, |
43 | }; | 48 | }; |
44 | 49 | ||
@@ -70,11 +75,18 @@ static int zcrypt_cex4_probe(struct ap_device *ap_dev) | |||
70 | 75 | ||
71 | switch (ap_dev->device_type) { | 76 | switch (ap_dev->device_type) { |
72 | case AP_DEVICE_TYPE_CEX4: | 77 | case AP_DEVICE_TYPE_CEX4: |
78 | case AP_DEVICE_TYPE_CEX5: | ||
73 | if (ap_test_bit(&ap_dev->functions, AP_FUNC_ACCEL)) { | 79 | if (ap_test_bit(&ap_dev->functions, AP_FUNC_ACCEL)) { |
74 | zdev = zcrypt_device_alloc(CEX4A_MAX_MESSAGE_SIZE); | 80 | zdev = zcrypt_device_alloc(CEX4A_MAX_MESSAGE_SIZE); |
75 | if (!zdev) | 81 | if (!zdev) |
76 | return -ENOMEM; | 82 | return -ENOMEM; |
77 | zdev->type_string = "CEX4A"; | 83 | if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) { |
84 | zdev->type_string = "CEX4A"; | ||
85 | zdev->speed_rating = CEX4A_SPEED_RATING; | ||
86 | } else { | ||
87 | zdev->type_string = "CEX5A"; | ||
88 | zdev->speed_rating = CEX5A_SPEED_RATING; | ||
89 | } | ||
78 | zdev->user_space_type = ZCRYPT_CEX3A; | 90 | zdev->user_space_type = ZCRYPT_CEX3A; |
79 | zdev->min_mod_size = CEX4A_MIN_MOD_SIZE; | 91 | zdev->min_mod_size = CEX4A_MIN_MOD_SIZE; |
80 | if (ap_test_bit(&ap_dev->functions, AP_FUNC_MEX4K) && | 92 | if (ap_test_bit(&ap_dev->functions, AP_FUNC_MEX4K) && |
@@ -90,33 +102,42 @@ static int zcrypt_cex4_probe(struct ap_device *ap_dev) | |||
90 | CEX4A_MAX_MOD_SIZE_2K; | 102 | CEX4A_MAX_MOD_SIZE_2K; |
91 | } | 103 | } |
92 | zdev->short_crt = 1; | 104 | zdev->short_crt = 1; |
93 | zdev->speed_rating = CEX4A_SPEED_RATING; | ||
94 | zdev->ops = zcrypt_msgtype_request(MSGTYPE50_NAME, | 105 | zdev->ops = zcrypt_msgtype_request(MSGTYPE50_NAME, |
95 | MSGTYPE50_VARIANT_DEFAULT); | 106 | MSGTYPE50_VARIANT_DEFAULT); |
96 | } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_COPRO)) { | 107 | } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_COPRO)) { |
97 | zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE); | 108 | zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE); |
98 | if (!zdev) | 109 | if (!zdev) |
99 | return -ENOMEM; | 110 | return -ENOMEM; |
100 | zdev->type_string = "CEX4C"; | 111 | if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) { |
112 | zdev->type_string = "CEX4C"; | ||
113 | zdev->speed_rating = CEX4C_SPEED_RATING; | ||
114 | } else { | ||
115 | zdev->type_string = "CEX5C"; | ||
116 | zdev->speed_rating = CEX5C_SPEED_RATING; | ||
117 | } | ||
101 | zdev->user_space_type = ZCRYPT_CEX3C; | 118 | zdev->user_space_type = ZCRYPT_CEX3C; |
102 | zdev->min_mod_size = CEX4C_MIN_MOD_SIZE; | 119 | zdev->min_mod_size = CEX4C_MIN_MOD_SIZE; |
103 | zdev->max_mod_size = CEX4C_MAX_MOD_SIZE; | 120 | zdev->max_mod_size = CEX4C_MAX_MOD_SIZE; |
104 | zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE; | 121 | zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE; |
105 | zdev->short_crt = 0; | 122 | zdev->short_crt = 0; |
106 | zdev->speed_rating = CEX4C_SPEED_RATING; | ||
107 | zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME, | 123 | zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME, |
108 | MSGTYPE06_VARIANT_DEFAULT); | 124 | MSGTYPE06_VARIANT_DEFAULT); |
109 | } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_EP11)) { | 125 | } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_EP11)) { |
110 | zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE); | 126 | zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE); |
111 | if (!zdev) | 127 | if (!zdev) |
112 | return -ENOMEM; | 128 | return -ENOMEM; |
113 | zdev->type_string = "CEX4P"; | 129 | if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) { |
130 | zdev->type_string = "CEX4P"; | ||
131 | zdev->speed_rating = CEX4P_SPEED_RATING; | ||
132 | } else { | ||
133 | zdev->type_string = "CEX5P"; | ||
134 | zdev->speed_rating = CEX5P_SPEED_RATING; | ||
135 | } | ||
114 | zdev->user_space_type = ZCRYPT_CEX4; | 136 | zdev->user_space_type = ZCRYPT_CEX4; |
115 | zdev->min_mod_size = CEX4C_MIN_MOD_SIZE; | 137 | zdev->min_mod_size = CEX4C_MIN_MOD_SIZE; |
116 | zdev->max_mod_size = CEX4C_MAX_MOD_SIZE; | 138 | zdev->max_mod_size = CEX4C_MAX_MOD_SIZE; |
117 | zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE; | 139 | zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE; |
118 | zdev->short_crt = 0; | 140 | zdev->short_crt = 0; |
119 | zdev->speed_rating = CEX4C_SPEED_RATING; | ||
120 | zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME, | 141 | zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME, |
121 | MSGTYPE06_VARIANT_EP11); | 142 | MSGTYPE06_VARIANT_EP11); |
122 | } | 143 | } |
diff --git a/drivers/tty/hvc/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c index ea74460f3638..f78a87b07872 100644 --- a/drivers/tty/hvc/hvc_iucv.c +++ b/drivers/tty/hvc/hvc_iucv.c | |||
@@ -1,10 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * hvc_iucv.c - z/VM IUCV hypervisor console (HVC) device driver | 2 | * z/VM IUCV hypervisor console (HVC) device driver |
3 | * | 3 | * |
4 | * This HVC device driver provides terminal access using | 4 | * This HVC device driver provides terminal access using |
5 | * z/VM IUCV communication paths. | 5 | * z/VM IUCV communication paths. |
6 | * | 6 | * |
7 | * Copyright IBM Corp. 2008, 2009 | 7 | * Copyright IBM Corp. 2008, 2013 |
8 | * | 8 | * |
9 | * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 9 | * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> |
10 | */ | 10 | */ |
@@ -102,6 +102,7 @@ static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES]; | |||
102 | #define IUCV_HVC_CON_IDX (0) | 102 | #define IUCV_HVC_CON_IDX (0) |
103 | /* List of z/VM user ID filter entries (struct iucv_vmid_filter) */ | 103 | /* List of z/VM user ID filter entries (struct iucv_vmid_filter) */ |
104 | #define MAX_VMID_FILTER (500) | 104 | #define MAX_VMID_FILTER (500) |
105 | #define FILTER_WILDCARD_CHAR '*' | ||
105 | static size_t hvc_iucv_filter_size; | 106 | static size_t hvc_iucv_filter_size; |
106 | static void *hvc_iucv_filter; | 107 | static void *hvc_iucv_filter; |
107 | static const char *hvc_iucv_filter_string; | 108 | static const char *hvc_iucv_filter_string; |
@@ -734,20 +735,31 @@ static void hvc_iucv_notifier_del(struct hvc_struct *hp, int id) | |||
734 | * hvc_iucv_filter_connreq() - Filter connection request based on z/VM user ID | 735 | * hvc_iucv_filter_connreq() - Filter connection request based on z/VM user ID |
735 | * @ipvmid: Originating z/VM user ID (right padded with blanks) | 736 | * @ipvmid: Originating z/VM user ID (right padded with blanks) |
736 | * | 737 | * |
737 | * Returns 0 if the z/VM user ID @ipvmid is allowed to connection, otherwise | 738 | * Returns 0 if the z/VM user ID that is specified with @ipvmid is permitted to |
738 | * non-zero. | 739 | * connect, otherwise non-zero. |
739 | */ | 740 | */ |
740 | static int hvc_iucv_filter_connreq(u8 ipvmid[8]) | 741 | static int hvc_iucv_filter_connreq(u8 ipvmid[8]) |
741 | { | 742 | { |
742 | size_t i; | 743 | const char *wildcard, *filter_entry; |
744 | size_t i, len; | ||
743 | 745 | ||
744 | /* Note: default policy is ACCEPT if no filter is set */ | 746 | /* Note: default policy is ACCEPT if no filter is set */ |
745 | if (!hvc_iucv_filter_size) | 747 | if (!hvc_iucv_filter_size) |
746 | return 0; | 748 | return 0; |
747 | 749 | ||
748 | for (i = 0; i < hvc_iucv_filter_size; i++) | 750 | for (i = 0; i < hvc_iucv_filter_size; i++) { |
749 | if (0 == memcmp(ipvmid, hvc_iucv_filter + (8 * i), 8)) | 751 | filter_entry = hvc_iucv_filter + (8 * i); |
752 | |||
753 | /* If a filter entry contains the filter wildcard character, | ||
754 | * reduce the length to match the leading portion of the user | ||
755 | * ID only (wildcard match). Characters following the wildcard | ||
756 | * are ignored. | ||
757 | */ | ||
758 | wildcard = strnchr(filter_entry, 8, FILTER_WILDCARD_CHAR); | ||
759 | len = (wildcard) ? wildcard - filter_entry : 8; | ||
760 | if (0 == memcmp(ipvmid, filter_entry, len)) | ||
750 | return 0; | 761 | return 0; |
762 | } | ||
751 | return 1; | 763 | return 1; |
752 | } | 764 | } |
753 | 765 | ||
@@ -1166,6 +1178,7 @@ static void __init hvc_iucv_destroy(struct hvc_iucv_private *priv) | |||
1166 | /** | 1178 | /** |
1167 | * hvc_iucv_parse_filter() - Parse filter for a single z/VM user ID | 1179 | * hvc_iucv_parse_filter() - Parse filter for a single z/VM user ID |
1168 | * @filter: String containing a comma-separated list of z/VM user IDs | 1180 | * @filter: String containing a comma-separated list of z/VM user IDs |
1181 | * @dest: Location where to store the parsed z/VM user ID | ||
1169 | */ | 1182 | */ |
1170 | static const char *hvc_iucv_parse_filter(const char *filter, char *dest) | 1183 | static const char *hvc_iucv_parse_filter(const char *filter, char *dest) |
1171 | { | 1184 | { |
@@ -1188,6 +1201,10 @@ static const char *hvc_iucv_parse_filter(const char *filter, char *dest) | |||
1188 | if (filter[len - 1] == '\n') | 1201 | if (filter[len - 1] == '\n') |
1189 | len--; | 1202 | len--; |
1190 | 1203 | ||
1204 | /* prohibit filter entries containing the wildcard character only */ | ||
1205 | if (len == 1 && *filter == FILTER_WILDCARD_CHAR) | ||
1206 | return ERR_PTR(-EINVAL); | ||
1207 | |||
1191 | if (len > 8) | 1208 | if (len > 8) |
1192 | return ERR_PTR(-EINVAL); | 1209 | return ERR_PTR(-EINVAL); |
1193 | 1210 | ||
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 176bf816875e..17f624cdf53c 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -54,7 +54,11 @@ extern void __chk_io_ptr(const volatile void __iomem *); | |||
54 | #include <linux/compiler-gcc.h> | 54 | #include <linux/compiler-gcc.h> |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | #ifdef CC_USING_HOTPATCH | ||
58 | #define notrace __attribute__((hotpatch(0,0))) | ||
59 | #else | ||
57 | #define notrace __attribute__((no_instrument_function)) | 60 | #define notrace __attribute__((no_instrument_function)) |
61 | #endif | ||
58 | 62 | ||
59 | /* Intel compiler defines __GNUC__. So we will overwrite implementations | 63 | /* Intel compiler defines __GNUC__. So we will overwrite implementations |
60 | * coming from above header files here | 64 | * coming from above header files here |
diff --git a/kernel/Makefile b/kernel/Makefile index 616994f0a76f..07737e50fe6e 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -13,8 +13,8 @@ obj-y = fork.o exec_domain.o panic.o \ | |||
13 | 13 | ||
14 | ifdef CONFIG_FUNCTION_TRACER | 14 | ifdef CONFIG_FUNCTION_TRACER |
15 | # Do not trace debug files and internal ftrace files | 15 | # Do not trace debug files and internal ftrace files |
16 | CFLAGS_REMOVE_cgroup-debug.o = -pg | 16 | CFLAGS_REMOVE_cgroup-debug.o = $(CC_FLAGS_FTRACE) |
17 | CFLAGS_REMOVE_irq_work.o = -pg | 17 | CFLAGS_REMOVE_irq_work.o = $(CC_FLAGS_FTRACE) |
18 | endif | 18 | endif |
19 | 19 | ||
20 | # cond_syscall is currently not LTO compatible | 20 | # cond_syscall is currently not LTO compatible |
diff --git a/kernel/events/Makefile b/kernel/events/Makefile index 103f5d147b2f..2925188f50ea 100644 --- a/kernel/events/Makefile +++ b/kernel/events/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | ifdef CONFIG_FUNCTION_TRACER | 1 | ifdef CONFIG_FUNCTION_TRACER |
2 | CFLAGS_REMOVE_core.o = -pg | 2 | CFLAGS_REMOVE_core.o = $(CC_FLAGS_FTRACE) |
3 | endif | 3 | endif |
4 | 4 | ||
5 | obj-y := core.o ring_buffer.o callchain.o | 5 | obj-y := core.o ring_buffer.o callchain.o |
diff --git a/kernel/locking/Makefile b/kernel/locking/Makefile index 4ca8eb151975..de7a416cca2a 100644 --- a/kernel/locking/Makefile +++ b/kernel/locking/Makefile | |||
@@ -2,10 +2,10 @@ | |||
2 | obj-y += mutex.o semaphore.o rwsem.o | 2 | obj-y += mutex.o semaphore.o rwsem.o |
3 | 3 | ||
4 | ifdef CONFIG_FUNCTION_TRACER | 4 | ifdef CONFIG_FUNCTION_TRACER |
5 | CFLAGS_REMOVE_lockdep.o = -pg | 5 | CFLAGS_REMOVE_lockdep.o = $(CC_FLAGS_FTRACE) |
6 | CFLAGS_REMOVE_lockdep_proc.o = -pg | 6 | CFLAGS_REMOVE_lockdep_proc.o = $(CC_FLAGS_FTRACE) |
7 | CFLAGS_REMOVE_mutex-debug.o = -pg | 7 | CFLAGS_REMOVE_mutex-debug.o = $(CC_FLAGS_FTRACE) |
8 | CFLAGS_REMOVE_rtmutex-debug.o = -pg | 8 | CFLAGS_REMOVE_rtmutex-debug.o = $(CC_FLAGS_FTRACE) |
9 | endif | 9 | endif |
10 | 10 | ||
11 | obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o | 11 | obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o |
diff --git a/kernel/sched/Makefile b/kernel/sched/Makefile index ab32b7b0db5c..46be87024875 100644 --- a/kernel/sched/Makefile +++ b/kernel/sched/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | ifdef CONFIG_FUNCTION_TRACER | 1 | ifdef CONFIG_FUNCTION_TRACER |
2 | CFLAGS_REMOVE_clock.o = -pg | 2 | CFLAGS_REMOVE_clock.o = $(CC_FLAGS_FTRACE) |
3 | endif | 3 | endif |
4 | 4 | ||
5 | ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) | 5 | ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) |
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index 979ccde26720..98f26588255e 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile | |||
@@ -3,11 +3,11 @@ | |||
3 | 3 | ||
4 | ifdef CONFIG_FUNCTION_TRACER | 4 | ifdef CONFIG_FUNCTION_TRACER |
5 | ORIG_CFLAGS := $(KBUILD_CFLAGS) | 5 | ORIG_CFLAGS := $(KBUILD_CFLAGS) |
6 | KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) | 6 | KBUILD_CFLAGS = $(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS)) |
7 | 7 | ||
8 | ifdef CONFIG_FTRACE_SELFTEST | 8 | ifdef CONFIG_FTRACE_SELFTEST |
9 | # selftest needs instrumentation | 9 | # selftest needs instrumentation |
10 | CFLAGS_trace_selftest_dynamic.o = -pg | 10 | CFLAGS_trace_selftest_dynamic.o = $(CC_FLAGS_FTRACE) |
11 | obj-y += trace_selftest_dynamic.o | 11 | obj-y += trace_selftest_dynamic.o |
12 | endif | 12 | endif |
13 | endif | 13 | endif |
diff --git a/lib/Makefile b/lib/Makefile index 7db78934ec07..25c061f77df7 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | ifdef CONFIG_FUNCTION_TRACER | 5 | ifdef CONFIG_FUNCTION_TRACER |
6 | ORIG_CFLAGS := $(KBUILD_CFLAGS) | 6 | ORIG_CFLAGS := $(KBUILD_CFLAGS) |
7 | KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) | 7 | KBUILD_CFLAGS = $(subst $(CC_FLAGS_FTRACE),,$(ORIG_CFLAGS)) |
8 | endif | 8 | endif |
9 | 9 | ||
10 | lib-y := ctype.o string.o vsprintf.o cmdline.o \ | 10 | lib-y := ctype.o string.o vsprintf.o cmdline.o \ |
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 649ce6844033..01df30af4d4a 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build | |||
@@ -234,8 +234,9 @@ sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH | |||
234 | "$(if $(part-of-module),1,0)" "$(@)"; | 234 | "$(if $(part-of-module),1,0)" "$(@)"; |
235 | recordmcount_source := $(srctree)/scripts/recordmcount.pl | 235 | recordmcount_source := $(srctree)/scripts/recordmcount.pl |
236 | endif | 236 | endif |
237 | cmd_record_mcount = \ | 237 | cmd_record_mcount = \ |
238 | if [ "$(findstring -pg,$(_c_flags))" = "-pg" ]; then \ | 238 | if [ "$(findstring $(CC_FLAGS_FTRACE),$(_c_flags))" = \ |
239 | "$(CC_FLAGS_FTRACE)" ]; then \ | ||
239 | $(sub_cmd_record_mcount) \ | 240 | $(sub_cmd_record_mcount) \ |
240 | fi; | 241 | fi; |
241 | endif | 242 | endif |
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index 537c38ca2e1c..826470d7f000 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl | |||
@@ -242,8 +242,13 @@ if ($arch eq "x86_64") { | |||
242 | $cc .= " -m32"; | 242 | $cc .= " -m32"; |
243 | 243 | ||
244 | } elsif ($arch eq "s390" && $bits == 64) { | 244 | } elsif ($arch eq "s390" && $bits == 64) { |
245 | $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_(PC|PLT)32DBL\\s+_mcount\\+0x2\$"; | 245 | if ($cc =~ /-DCC_USING_HOTPATCH/) { |
246 | $mcount_adjust = -14; | 246 | $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*c0 04 00 00 00 00\\s*brcl\\s*0,[0-9a-f]+ <([^\+]*)>\$"; |
247 | $mcount_adjust = 0; | ||
248 | } else { | ||
249 | $mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_(PC|PLT)32DBL\\s+_mcount\\+0x2\$"; | ||
250 | $mcount_adjust = -14; | ||
251 | } | ||
247 | $alignment = 8; | 252 | $alignment = 8; |
248 | $type = ".quad"; | 253 | $type = ".quad"; |
249 | $ld .= " -m elf64_s390"; | 254 | $ld .= " -m elf64_s390"; |