diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2013-09-30 08:47:46 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-10-24 11:16:59 -0400 |
commit | 12325f097898c120c6cd89797aae97836783b5ef (patch) | |
tree | eba83582d25ce2356e6bcffcbbce9235d955f044 | |
parent | 6aa2677a57fdd8964ccd44766cdc06cdd9c5db5b (diff) |
s390: cleanup and add sanity checks to control register macros
- turn some macros into functions
- merge two almost identical versions for 32/64 bit
- add BUILD_BUG_ON() check to make sure the passed in array is large enough
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/include/asm/ctl_reg.h | 112 |
1 files changed, 51 insertions, 61 deletions
diff --git a/arch/s390/include/asm/ctl_reg.h b/arch/s390/include/asm/ctl_reg.h index debfda33d1f8..9b69c0befdca 100644 --- a/arch/s390/include/asm/ctl_reg.h +++ b/arch/s390/include/asm/ctl_reg.h | |||
@@ -8,69 +8,59 @@ | |||
8 | #define __ASM_CTL_REG_H | 8 | #define __ASM_CTL_REG_H |
9 | 9 | ||
10 | #ifdef CONFIG_64BIT | 10 | #ifdef CONFIG_64BIT |
11 | 11 | # define __CTL_LOAD "lctlg" | |
12 | #define __ctl_load(array, low, high) ({ \ | 12 | # define __CTL_STORE "stctg" |
13 | typedef struct { char _[sizeof(array)]; } addrtype; \ | 13 | #else |
14 | asm volatile( \ | 14 | # define __CTL_LOAD "lctl" |
15 | " lctlg %1,%2,%0\n" \ | 15 | # define __CTL_STORE "stctl" |
16 | : : "Q" (*(addrtype *)(&array)), \ | 16 | #endif |
17 | "i" (low), "i" (high)); \ | 17 | |
18 | }) | 18 | #define __ctl_load(array, low, high) { \ |
19 | 19 | typedef struct { char _[sizeof(array)]; } addrtype; \ | |
20 | #define __ctl_store(array, low, high) ({ \ | 20 | \ |
21 | typedef struct { char _[sizeof(array)]; } addrtype; \ | 21 | BUILD_BUG_ON(sizeof(addrtype) != (high - low + 1) * sizeof(long));\ |
22 | asm volatile( \ | 22 | asm volatile( \ |
23 | " stctg %1,%2,%0\n" \ | 23 | __CTL_LOAD " %1,%2,%0\n" \ |
24 | : "=Q" (*(addrtype *)(&array)) \ | 24 | : : "Q" (*(addrtype *)(&array)), "i" (low), "i" (high));\ |
25 | : "i" (low), "i" (high)); \ | 25 | } |
26 | }) | 26 | |
27 | 27 | #define __ctl_store(array, low, high) { \ | |
28 | #else /* CONFIG_64BIT */ | 28 | typedef struct { char _[sizeof(array)]; } addrtype; \ |
29 | 29 | \ | |
30 | #define __ctl_load(array, low, high) ({ \ | 30 | BUILD_BUG_ON(sizeof(addrtype) != (high - low + 1) * sizeof(long));\ |
31 | typedef struct { char _[sizeof(array)]; } addrtype; \ | 31 | asm volatile( \ |
32 | asm volatile( \ | 32 | __CTL_STORE " %1,%2,%0\n" \ |
33 | " lctl %1,%2,%0\n" \ | 33 | : "=Q" (*(addrtype *)(&array)) \ |
34 | : : "Q" (*(addrtype *)(&array)), \ | 34 | : "i" (low), "i" (high)); \ |
35 | "i" (low), "i" (high)); \ | 35 | } |
36 | }) | 36 | |
37 | 37 | static inline void __ctl_set_bit(unsigned int cr, unsigned int bit) | |
38 | #define __ctl_store(array, low, high) ({ \ | 38 | { |
39 | typedef struct { char _[sizeof(array)]; } addrtype; \ | 39 | unsigned long reg; |
40 | asm volatile( \ | 40 | |
41 | " stctl %1,%2,%0\n" \ | 41 | __ctl_store(reg, cr, cr); |
42 | : "=Q" (*(addrtype *)(&array)) \ | 42 | reg |= 1UL << bit; |
43 | : "i" (low), "i" (high)); \ | 43 | __ctl_load(reg, cr, cr); |
44 | }) | 44 | } |
45 | 45 | ||
46 | #endif /* CONFIG_64BIT */ | 46 | static inline void __ctl_clear_bit(unsigned int cr, unsigned int bit) |
47 | 47 | { | |
48 | #define __ctl_set_bit(cr, bit) ({ \ | 48 | unsigned long reg; |
49 | unsigned long __dummy; \ | 49 | |
50 | __ctl_store(__dummy, cr, cr); \ | 50 | __ctl_store(reg, cr, cr); |
51 | __dummy |= 1UL << (bit); \ | 51 | reg &= ~(1UL << bit); |
52 | __ctl_load(__dummy, cr, cr); \ | 52 | __ctl_load(reg, cr, cr); |
53 | }) | 53 | } |
54 | 54 | ||
55 | #define __ctl_clear_bit(cr, bit) ({ \ | 55 | void smp_ctl_set_bit(int cr, int bit); |
56 | unsigned long __dummy; \ | 56 | void smp_ctl_clear_bit(int cr, int bit); |
57 | __ctl_store(__dummy, cr, cr); \ | ||
58 | __dummy &= ~(1UL << (bit)); \ | ||
59 | __ctl_load(__dummy, cr, cr); \ | ||
60 | }) | ||
61 | 57 | ||
62 | #ifdef CONFIG_SMP | 58 | #ifdef CONFIG_SMP |
63 | 59 | # define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit) | |
64 | extern void smp_ctl_set_bit(int cr, int bit); | 60 | # define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit) |
65 | extern void smp_ctl_clear_bit(int cr, int bit); | ||
66 | #define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit) | ||
67 | #define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit) | ||
68 | |||
69 | #else | 61 | #else |
70 | 62 | # define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit) | |
71 | #define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit) | 63 | # define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit) |
72 | #define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit) | 64 | #endif |
73 | |||
74 | #endif /* CONFIG_SMP */ | ||
75 | 65 | ||
76 | #endif /* __ASM_CTL_REG_H */ | 66 | #endif /* __ASM_CTL_REG_H */ |