- int descriptor = S390_lowcore.trans_exc_code & 3;
- if (unlikely(descriptor == 1))
- return __check_access_register(regs, error_code);
- if (descriptor == 2)
- return current->thread.mm_segment.ar4;
- return ((descriptor != 0) ^ (switch_amode)) << s390_noexec;
+ int desc = S390_lowcore.trans_exc_code & 3;
+
+ if (desc == 3) /* Home Segment Table Descriptor */
+ return switch_amode == 0;
+ if (desc == 2) /* Secondary Segment Table Descriptor */
+ return tsk->thread.mm_segment.ar4;
+#ifdef CONFIG_S390_SWITCH_AMODE
+ if (unlikely(desc == 1)) { /* STD determined via access register */
+ /* %a0 always indicates primary space. */
+ if (S390_lowcore.exc_access_id != 0) {
+ save_access_regs(tsk->thread.acrs);
+ /*
+ * An alet of 0 indicates primary space.
+ * An alet of 1 indicates secondary space.
+ * Any other alet values generate an
+ * alen-translation exception.
+ */
+ if (tsk->thread.acrs[S390_lowcore.exc_access_id])
+ return tsk->thread.mm_segment.ar4;
+ }
+ }
+#endif
+ /* Primary Segment Table Descriptor */
+ return switch_amode << s390_noexec;