^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*---------------------------------------------------------------------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) | fpu_system.h |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) | Copyright (C) 1992,1994,1997 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) | W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) | Australia. E-mail billm@suburbia.net |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) +---------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #ifndef _FPU_SYSTEM_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define _FPU_SYSTEM_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /* system dependent definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/desc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) static inline struct desc_struct FPU_get_ldt_descriptor(unsigned seg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static struct desc_struct zero_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct desc_struct ret = zero_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #ifdef CONFIG_MODIFY_LDT_SYSCALL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) seg >>= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) mutex_lock(¤t->mm->context.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (current->mm->context.ldt && seg < current->mm->context.ldt->nr_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ret = current->mm->context.ldt->entries[seg];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) mutex_unlock(¤t->mm->context.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define SEG_TYPE_WRITABLE (1U << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define SEG_TYPE_EXPANDS_DOWN (1U << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define SEG_TYPE_EXECUTE (1U << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define SEG_TYPE_EXPAND_MASK (SEG_TYPE_EXPANDS_DOWN | SEG_TYPE_EXECUTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define SEG_TYPE_EXECUTE_MASK (SEG_TYPE_WRITABLE | SEG_TYPE_EXECUTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static inline unsigned long seg_get_base(struct desc_struct *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned long base = (unsigned long)d->base2 << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return base | ((unsigned long)d->base1 << 16) | d->base0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static inline unsigned long seg_get_limit(struct desc_struct *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return ((unsigned long)d->limit1 << 16) | d->limit0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static inline unsigned long seg_get_granularity(struct desc_struct *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return d->g ? 4096 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static inline bool seg_expands_down(struct desc_struct *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return (d->type & SEG_TYPE_EXPAND_MASK) == SEG_TYPE_EXPANDS_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static inline bool seg_execute_only(struct desc_struct *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return (d->type & SEG_TYPE_EXECUTE_MASK) == SEG_TYPE_EXECUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static inline bool seg_writable(struct desc_struct *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return (d->type & SEG_TYPE_EXECUTE_MASK) == SEG_TYPE_WRITABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define I387 (¤t->thread.fpu.state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define FPU_info (I387->soft.info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define FPU_CS (*(unsigned short *) &(FPU_info->regs->cs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define FPU_SS (*(unsigned short *) &(FPU_info->regs->ss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define FPU_DS (*(unsigned short *) &(FPU_info->regs->ds))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define FPU_EAX (FPU_info->regs->ax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define FPU_EFLAGS (FPU_info->regs->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define FPU_EIP (FPU_info->regs->ip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define FPU_ORIG_EIP (FPU_info->___orig_eip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define FPU_lookahead (I387->soft.lookahead)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* nz if ip_offset and cs_selector are not to be set for the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) instruction. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define no_ip_update (*(u_char *)&(I387->soft.no_update))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define FPU_rm (*(u_char *)&(I387->soft.rm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* Number of bytes of data which can be legally accessed by the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) instruction. This only needs to hold a number <= 108, so a byte will do. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define access_limit (*(u_char *)&(I387->soft.alimit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define partial_status (I387->soft.swd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define control_word (I387->soft.cwd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define fpu_tag_word (I387->soft.twd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define registers (I387->soft.st_space)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define top (I387->soft.ftop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define instruction_address (*(struct address *)&I387->soft.fip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define operand_address (*(struct address *)&I387->soft.foo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define FPU_access_ok(y,z) if ( !access_ok(y,z) ) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) math_abort(FPU_info,SIGSEGV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define FPU_abort math_abort(FPU_info, SIGSEGV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define FPU_copy_from_user(to, from, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) do { if (copy_from_user(to, from, n)) FPU_abort; } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #undef FPU_IGNORE_CODE_SEGV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #ifdef FPU_IGNORE_CODE_SEGV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* access_ok() is very expensive, and causes the emulator to run
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) about 20% slower if applied to the code. Anyway, errors due to bad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) code addresses should be much rarer than errors due to bad data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) addresses. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define FPU_code_access_ok(z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* A simpler test than access_ok() can probably be done for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) FPU_code_access_ok() because the only possible error is to step
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) past the upper boundary of a legal code area. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define FPU_code_access_ok(z) FPU_access_ok((void __user *)FPU_EIP,z)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define FPU_get_user(x,y) do { if (get_user((x),(y))) FPU_abort; } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define FPU_put_user(x,y) do { if (put_user((x),(y))) FPU_abort; } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #endif