aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/include/asm/system.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/include/asm/system.h')
-rw-r--r--arch/s390/include/asm/system.h51
1 files changed, 22 insertions, 29 deletions
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h
index 1f2ebc4afd82..3ad16dbf622e 100644
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -85,14 +85,16 @@ static inline void restore_access_regs(unsigned int *acrs)
85 asm volatile("lam 0,15,%0" : : "Q" (*acrs)); 85 asm volatile("lam 0,15,%0" : : "Q" (*acrs));
86} 86}
87 87
88#define switch_to(prev,next,last) do { \ 88#define switch_to(prev,next,last) do { \
89 if (prev == next) \ 89 if (prev->mm) { \
90 break; \ 90 save_fp_regs(&prev->thread.fp_regs); \
91 save_fp_regs(&prev->thread.fp_regs); \ 91 save_access_regs(&prev->thread.acrs[0]); \
92 restore_fp_regs(&next->thread.fp_regs); \ 92 } \
93 save_access_regs(&prev->thread.acrs[0]); \ 93 if (next->mm) { \
94 restore_access_regs(&next->thread.acrs[0]); \ 94 restore_fp_regs(&next->thread.fp_regs); \
95 prev = __switch_to(prev,next); \ 95 restore_access_regs(&next->thread.acrs[0]); \
96 } \
97 prev = __switch_to(prev,next); \
96} while (0) 98} while (0)
97 99
98extern void account_vtime(struct task_struct *, struct task_struct *); 100extern void account_vtime(struct task_struct *, struct task_struct *);
@@ -418,30 +420,21 @@ extern void smp_ctl_clear_bit(int cr, int bit);
418 420
419#endif /* CONFIG_SMP */ 421#endif /* CONFIG_SMP */
420 422
421static inline unsigned int stfl(void) 423#define MAX_FACILITY_BIT (256*8) /* stfle_fac_list has 256 bytes */
422{
423 asm volatile(
424 " .insn s,0xb2b10000,0(0)\n" /* stfl */
425 "0:\n"
426 EX_TABLE(0b,0b));
427 return S390_lowcore.stfl_fac_list;
428}
429 424
430static inline int __stfle(unsigned long long *list, int doublewords) 425/*
426 * The test_facility function uses the bit odering where the MSB is bit 0.
427 * That makes it easier to query facility bits with the bit number as
428 * documented in the Principles of Operation.
429 */
430static inline int test_facility(unsigned long nr)
431{ 431{
432 typedef struct { unsigned long long _[doublewords]; } addrtype; 432 unsigned char *ptr;
433 register unsigned long __nr asm("0") = doublewords - 1;
434
435 asm volatile(".insn s,0xb2b00000,%0" /* stfle */
436 : "=m" (*(addrtype *) list), "+d" (__nr) : : "cc");
437 return __nr + 1;
438}
439 433
440static inline int stfle(unsigned long long *list, int doublewords) 434 if (nr >= MAX_FACILITY_BIT)
441{ 435 return 0;
442 if (!(stfl() & (1UL << 24))) 436 ptr = (unsigned char *) &S390_lowcore.stfle_fac_list + (nr >> 3);
443 return -EOPNOTSUPP; 437 return (*ptr & (0x80 >> (nr & 7))) != 0;
444 return __stfle(list, doublewords);
445} 438}
446 439
447static inline unsigned short stap(void) 440static inline unsigned short stap(void)