From 2e1e5016036993e83c91416478860e6b5cc40771 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Sun, 13 Apr 2003 21:25:08 -0700 Subject: [PATCH] [PATCH] s390: base s390 fixes. s390 fixes: - Initialize timing related variables first and then enable the timer interrupt. - Normalize nano seconds to micro seconds in do_gettimeofday. - Add types for __kernel_timer_t and __kernel_clockid_t. - Fix ugly bug in switch_to: set prev to the return value of resume, otherwise prev still contains the previous process at the time resume was called and not the previous process at the time resume returned. They differ... - Add missing include to get the kernel compiled. - Get a closer match with the i386 termios.h file. - Cope with INITIAL_JIFFIES. - Define cpu_relax to do a cpu yield on VM and LPAR. - Don't reenable interrupts in program check handler. - Add pte_file definitions. - Fix PT_IEEE_IP special case in ptrace. - Use compare and swap to release the lock in _raw_spin_unlock. - Introduce invoke_softirq to switch to async. interrupt stack. --- arch/s390/defconfig | 81 +++++++++++++++++++++------------- arch/s390/kernel/entry.S | 4 +- arch/s390/kernel/ptrace.c | 21 +++++---- arch/s390/kernel/time.c | 16 ++++--- arch/s390/mm/fault.c | 1 - arch/s390/mm/ioremap.c | 2 +- include/asm-s390/hardirq.h | 2 + include/asm-s390/pgtable.h | 69 ++++++++++++++++++++--------- include/asm-s390/posix_types.h | 2 + include/asm-s390/processor.h | 5 ++- include/asm-s390/signal.h | 1 + include/asm-s390/spinlock.h | 8 ++-- include/asm-s390/system.h | 2 +- include/asm-s390/termios.h | 25 +++++------ include/linux/interrupt.h | 3 ++ kernel/softirq.c | 2 +- 16 files changed, 153 insertions(+), 91 deletions(-) diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 9e884d67895bd..2a3523904701d 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -2,7 +2,6 @@ # Automatically generated make config: don't edit # CONFIG_MMU=y -CONFIG_SWAP=y CONFIG_UID16=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_ARCH_S390=y @@ -15,6 +14,7 @@ CONFIG_EXPERIMENTAL=y # # General setup # +CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y @@ -141,7 +141,6 @@ CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set # CONFIG_NETLINK_DEV is not set # CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -156,8 +155,12 @@ CONFIG_IP_MULTICAST=y # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set -# CONFIG_XFRM_USER is not set +# CONFIG_INET_IPCOMP is not set CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_XFRM_USER is not set # # SCTP Configuration (EXPERIMENTAL) @@ -252,48 +255,63 @@ CONFIG_CCWGROUP=m # # File systems # +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set # CONFIG_QUOTA is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_TMPFS is not set -CONFIG_RAMFS=y -# CONFIG_ISO9660_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_MINIX_FS is not set # CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set # CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -CONFIG_DEVPTS_FS=y # CONFIG_QNX4FS_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set # CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_XFS_FS is not set # # Network File Systems # -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V4 is not set @@ -301,16 +319,17 @@ CONFIG_NFSD=y CONFIG_NFSD_V3=y # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set -CONFIG_SUNRPC=y -# CONFIG_SUNRPC_GSS is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y -# CONFIG_CIFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set # CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set # CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set # CONFIG_AFS_FS is not set -CONFIG_FS_MBCACHE=y # # Partition Types @@ -324,6 +343,7 @@ CONFIG_IBM_PARTITION=y # CONFIG_MAC_PARTITION is not set # CONFIG_MSDOS_PARTITION is not set # CONFIG_LDM_PARTITION is not set +# CONFIG_NEC98_PARTITION is not set # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set @@ -359,6 +379,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set # CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_TEST is not set # diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 254f7790a8be8..a73db90ffd5e6 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -644,13 +644,12 @@ pgm_check_handler: tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception bnz BASED(pgm_per) # got per exception -> special case SAVE_ALL __LC_PGM_OLD_PSW,1 - la %r8,0x7f l %r3,__LC_PGM_ILC # load program interruption code + la %r8,0x7f l %r7,BASED(.Ljump_table) nr %r8,%r3 sll %r8,2 GET_THREAD_INFO - stosm 24(%r15),0x03 # reenable interrupts l %r7,0(%r8,%r7) # load address of handler routine la %r2,SP_PTREGS(%r15) # address of register-save area la %r14,BASED(sysc_return) @@ -677,7 +676,6 @@ pgm_per_std: GET_THREAD_INFO la %r4,0x7f l %r3,__LC_PGM_ILC # load program interruption code - stosm 24(%r15),0x03 # reenable interrupts nr %r4,%r3 # clear per-event-bit and ilc be BASED(pgm_per_only) # only per or per+check ? l %r1,BASED(.Ljump_table) diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 37e1c031891e0..342032b6b315f 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -207,21 +207,24 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) return ptrace_attach(child); /* - * I added child != current line so we can get the - * ieee_instruction_pointer from the user structure DJB + * Special cases to get/store the ieee instructions pointer. */ - if (child != current) { - ret = ptrace_check_attach(child, request == PTRACE_KILL); - if (ret < 0) - return ret; + if (child == current) { + if (request == PTRACE_PEEKUSR && addr == PT_IEEE_IP) + return peek_user(child, addr, data); + if (request == PTRACE_POKEUSR && addr == PT_IEEE_IP) + return poke_user(child, addr, data); } - /* Remove high order bit from address. */ - addr &= PSW_ADDR_INSN; + ret = ptrace_check_attach(child, request == PTRACE_KILL); + if (ret < 0) + return ret; switch (request) { case PTRACE_PEEKTEXT: case PTRACE_PEEKDATA: + /* Remove high order bit from address. */ + addr &= PSW_ADDR_INSN; /* read word at location addr. */ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); if (copied != sizeof(tmp)) @@ -234,6 +237,8 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_POKETEXT: case PTRACE_POKEDATA: + /* Remove high order bit from address. */ + addr &= PSW_ADDR_INSN; /* write the word at location addr. */ copied = access_process_vm(child, addr, &data, sizeof(data),1); if (copied != sizeof(data)) diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 60f8059c5afac..821f10d94d0b9 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -49,8 +49,9 @@ u64 jiffies_64 = INITIAL_JIFFIES; static ext_int_info_t ext_int_info_timer; -static uint64_t xtime_cc; -static uint64_t init_timer_cc; +static u64 init_timer_cc; +static u64 jiffies_timer_cc; +static u64 xtime_cc; extern unsigned long wall_jiffies; @@ -70,7 +71,7 @@ static inline unsigned long do_gettimeoffset(void) __u64 now; asm volatile ("STCK 0(%0)" : : "a" (&now) : "memory", "cc"); - now = (now - init_timer_cc) >> 12; + now = (now - jiffies_timer_cc) >> 12; /* We require the offset from the latest update of xtime */ now -= (__u64) wall_jiffies*USECS_PER_JIFFY; return (unsigned long) now; @@ -202,14 +203,14 @@ void init_cpu_timer(void) unsigned long cr0; __u64 timer; + timer = jiffies_timer_cc + jiffies_64 * CLK_TICKS_PER_JIFFY; + S390_lowcore.jiffy_timer = timer; + timer += CLK_TICKS_PER_JIFFY + CPU_DEVIATION; + asm volatile ("SCKC %0" : : "m" (timer)); /* allow clock comparator timer interrupt */ asm volatile ("STCTL 0,0,%0" : "=m" (cr0) : : "memory"); cr0 |= 0x800; asm volatile ("LCTL 0,0,%0" : : "m" (cr0) : "memory"); - timer = init_timer_cc + jiffies_64 * CLK_TICKS_PER_JIFFY; - S390_lowcore.jiffy_timer = timer; - timer += CLK_TICKS_PER_JIFFY + CPU_DEVIATION; - asm volatile ("SCKC %0" : : "m" (timer)); } /* @@ -239,6 +240,7 @@ void __init time_init(void) printk("time_init: TOD clock stopped/non-operational\n"); break; } + jiffies_timer_cc = init_timer_cc - jiffies_64 * CLK_TICKS_PER_JIFFY; /* set xtime */ xtime_cc = init_timer_cc; diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index e4ba1408f6807..e501df33df74f 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/s390/mm/ioremap.c b/arch/s390/mm/ioremap.c index 234940a558c8e..6f2db6e299997 100644 --- a/arch/s390/mm/ioremap.c +++ b/arch/s390/mm/ioremap.c @@ -38,7 +38,7 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned l printk("remap_area_pte: page already exists\n"); BUG(); } - set_pte(pte, pfn_pte(pfn, __pgprot(_PAGE_PRESENT | flags))); + set_pte(pte, pfn_pte(pfn, __pgprot(flags))); address += PAGE_SIZE; pfn++; pte++; diff --git a/include/asm-s390/hardirq.h b/include/asm-s390/hardirq.h index 7f38c6f01e05c..49218029d753f 100644 --- a/include/asm-s390/hardirq.h +++ b/include/asm-s390/hardirq.h @@ -80,6 +80,8 @@ typedef struct { extern void do_call_softirq(void); +#define invoke_softirq() do_call_softirq() + #if CONFIG_PREEMPT # define in_atomic() (in_interrupt() || preempt_count() == PREEMPT_ACTIVE) # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h index ea9d8c7365863..60b364260a37f 100644 --- a/include/asm-s390/pgtable.h +++ b/include/asm-s390/pgtable.h @@ -143,13 +143,21 @@ extern char empty_zero_page[PAGE_SIZE]; * C : changed bit */ -/* Bits in the page table entry */ -#define _PAGE_PRESENT 0x001 /* Software */ -#define _PAGE_MKCLEAN 0x002 /* Software */ -#define _PAGE_ISCLEAN 0x004 /* Software */ +/* Hardware bits in the page table entry */ #define _PAGE_RO 0x200 /* HW read-only */ #define _PAGE_INVALID 0x400 /* HW invalid */ +/* Software bits in the page table entry */ +#define _PAGE_MKCLEAN 0x002 +#define _PAGE_ISCLEAN 0x004 + +/* Mask and four different kinds of invalid pages. */ +#define _PAGE_INVALID_MASK 0x601 +#define _PAGE_INVALID_EMPTY 0x400 +#define _PAGE_INVALID_NONE 0x001 +#define _PAGE_INVALID_SWAP 0x200 +#define _PAGE_INVALID_FILE 0x201 + /* Bits in the segment table entry */ #define _PAGE_TABLE_LEN 0xf /* only full page-tables */ #define _PAGE_TABLE_COM 0x10 /* common page-table */ @@ -166,29 +174,28 @@ extern char empty_zero_page[PAGE_SIZE]; /* * User and Kernel pagetables are identical */ -#define _PAGE_TABLE (_PAGE_TABLE_LEN ) -#define _KERNPG_TABLE (_PAGE_TABLE_LEN ) +#define _PAGE_TABLE _PAGE_TABLE_LEN +#define _KERNPG_TABLE _PAGE_TABLE_LEN /* * The Kernel segment-tables includes the User segment-table */ -#define _SEGMENT_TABLE (_USER_SEG_TABLE_LEN|0x80000000|0x100) -#define _KERNSEG_TABLE (_KERNEL_SEG_TABLE_LEN) +#define _SEGMENT_TABLE (_USER_SEG_TABLE_LEN|0x80000000|0x100) +#define _KERNSEG_TABLE _KERNEL_SEG_TABLE_LEN -#define USER_STD_MASK 0x00000080UL +#define USER_STD_MASK 0x00000080UL /* * No mapping available */ -#define PAGE_INVALID __pgprot(_PAGE_INVALID) -#define PAGE_NONE_SHARED __pgprot(_PAGE_PRESENT|_PAGE_INVALID) -#define PAGE_NONE_PRIVATE __pgprot(_PAGE_PRESENT|_PAGE_INVALID|_PAGE_ISCLEAN) -#define PAGE_RO_SHARED __pgprot(_PAGE_PRESENT|_PAGE_RO) -#define PAGE_RO_PRIVATE __pgprot(_PAGE_PRESENT|_PAGE_RO|_PAGE_ISCLEAN) -#define PAGE_COPY __pgprot(_PAGE_PRESENT|_PAGE_RO|_PAGE_ISCLEAN) -#define PAGE_SHARED __pgprot(_PAGE_PRESENT) -#define PAGE_KERNEL __pgprot(_PAGE_PRESENT) +#define PAGE_NONE_SHARED __pgprot(_PAGE_INVALID_NONE) +#define PAGE_NONE_PRIVATE __pgprot(_PAGE_INVALID_NONE|_PAGE_ISCLEAN) +#define PAGE_RO_SHARED __pgprot(_PAGE_RO) +#define PAGE_RO_PRIVATE __pgprot(_PAGE_RO|_PAGE_ISCLEAN) +#define PAGE_COPY __pgprot(_PAGE_RO|_PAGE_ISCLEAN) +#define PAGE_SHARED __pgprot(0) +#define PAGE_KERNEL __pgprot(0) /* * The S390 can't do page protection for execute, and considers that the @@ -247,11 +254,20 @@ extern inline int pmd_bad(pmd_t pmd) return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE; } -extern inline int pte_present(pte_t pte) { return pte_val(pte) & _PAGE_PRESENT; } extern inline int pte_none(pte_t pte) { - return ((pte_val(pte) & - (_PAGE_INVALID | _PAGE_RO | _PAGE_PRESENT)) == _PAGE_INVALID); + return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_EMPTY; +} + +extern inline int pte_present(pte_t pte) +{ + return !(pte_val(pte) & _PAGE_INVALID) || + (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_NONE; +} + +extern inline int pte_file(pte_t pte) +{ + return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_FILE; } #define pte_same(a,b) (pte_val(a) == pte_val(b)) @@ -298,7 +314,7 @@ extern inline void pmd_clear(pmd_t * pmdp) extern inline void pte_clear(pte_t *ptep) { - pte_val(*ptep) = _PAGE_INVALID; + pte_val(*ptep) = _PAGE_INVALID_EMPTY; } /* @@ -495,7 +511,7 @@ extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) { pte_t pte; - pte_val(pte) = (type << 1) | (offset << 12) | _PAGE_INVALID | _PAGE_RO; + pte_val(pte) = (type << 1) | (offset << 12) | _PAGE_INVALID_SWAP; pte_val(pte) &= 0x7ffff6fe; /* better to be paranoid */ return pte; } @@ -509,6 +525,15 @@ extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) typedef pte_t *pte_addr_t; +#define PTE_FILE_MAX_BITS 26 + +#define pte_to_pgoff(__pte) \ + ((((__pte).pte >> 12) << 7) + (((__pte).pte >> 1) & 0x7f)) + +#define pgoff_to_pte(__off) \ + ((pte_t) { ((((__off) & 0x7f) << 1) + (((__off) >> 7) << 12)) \ + | _PAGE_INVALID_FILE }) + #endif /* !__ASSEMBLY__ */ #define kern_addr_valid(addr) (1) diff --git a/include/asm-s390/posix_types.h b/include/asm-s390/posix_types.h index 99e82ffa8c6fb..ebfa4b7a24006 100644 --- a/include/asm-s390/posix_types.h +++ b/include/asm-s390/posix_types.h @@ -30,6 +30,8 @@ typedef int __kernel_ptrdiff_t; typedef long __kernel_time_t; typedef long __kernel_suseconds_t; typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; typedef int __kernel_daddr_t; typedef char * __kernel_caddr_t; typedef unsigned short __kernel_uid16_t; diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index dcac9d8ad5b24..c03823e9a6fd2 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h @@ -133,7 +133,10 @@ unsigned long get_wchan(struct task_struct *p); #define KSTK_EIP(tsk) (__KSTK_PTREGS(tsk)->psw.addr) #define KSTK_ESP(tsk) (__KSTK_PTREGS(tsk)->gprs[15]) -#define cpu_relax() barrier() +/* + * Give up the time slice of the virtual PU. + */ +#define cpu_relax() asm volatile ("diag 0,0,68" : : : "memory") /* * Set PSW mask to specified value, while leaving the diff --git a/include/asm-s390/signal.h b/include/asm-s390/signal.h index 43e3f7d23220b..0186302515dcc 100644 --- a/include/asm-s390/signal.h +++ b/include/asm-s390/signal.h @@ -10,6 +10,7 @@ #define _ASMS390_SIGNAL_H #include +#include /* Avoid too many header ordering problems. */ struct siginfo; diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h index dcd5dbe7c0a9b..0b1a24611457e 100644 --- a/include/asm-s390/spinlock.h +++ b/include/asm-s390/spinlock.h @@ -52,9 +52,11 @@ extern inline int _raw_spin_trylock(spinlock_t *lp) extern inline void _raw_spin_unlock(spinlock_t *lp) { - __asm__ __volatile(" xc 0(4,%1),0(%1)\n" - " bcr 15,0" - : "+m" (lp->lock) : "a" (&lp->lock) : "cc" ); + unsigned int old; + + __asm__ __volatile("cs %0,%3,0(%4)" + : "=d" (old), "=m" (lp->lock) + : "0" (lp->lock), "d" (0), "a" (lp) : "cc" ); } /* diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index 34fb4ad45598c..0d19bdb36a432 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h @@ -82,7 +82,7 @@ static inline void restore_fp_regs(s390_fp_regs *fpregs) break; \ save_fp_regs(&prev->thread.fp_regs); \ restore_fp_regs(&next->thread.fp_regs); \ - resume(prev,next); \ + prev = resume(prev,next); \ } while (0) #define nop() __asm__ __volatile__ ("nop") diff --git a/include/asm-s390/termios.h b/include/asm-s390/termios.h index 5f51bcbf76ece..d1e29cca54c9d 100644 --- a/include/asm-s390/termios.h +++ b/include/asm-s390/termios.h @@ -12,7 +12,6 @@ #include #include - struct winsize { unsigned short ws_row; unsigned short ws_col; @@ -44,7 +43,7 @@ struct termio { #define TIOCM_RI TIOCM_RNG #define TIOCM_OUT1 0x2000 #define TIOCM_OUT2 0x4000 -#define TIOCM_LOOP 0x8000 +#define TIOCM_LOOP 0x8000 /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ @@ -62,7 +61,8 @@ struct termio { #define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ #define N_IRDA 11 /* Linux IR - http://irda.sourceforge.net/ */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ -#define N_HDLC 13 /* synchronous HDLC */ +#define N_HDLC 13 /* synchronous HDLC */ +#define N_SYNC_PPP 14 /* synchronous PPP */ #define N_HCI 15 /* Bluetooth HCI UART */ #ifdef __KERNEL__ @@ -78,19 +78,18 @@ struct termio { /* * Translate a "termio" structure into a "termios". Ugh. */ +#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ + unsigned short __tmp; \ + get_user(__tmp,&(termio)->x); \ + (termios)->x = (0xffff0000 & ((termios)->x)) | __tmp; \ +} #define user_termio_to_kernel_termios(termios, termio) \ ({ \ - unsigned short tmp; \ - get_user(tmp, &(termio)->c_iflag); \ - (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ - get_user(tmp, &(termio)->c_oflag); \ - (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ - get_user(tmp, &(termio)->c_cflag); \ - (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ - get_user(tmp, &(termio)->c_lflag); \ - (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ - get_user((termios)->c_line, &(termio)->c_line); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ + SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ }) diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 48ff2abe52a7c..78969bb605212 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -77,6 +77,9 @@ extern void softirq_init(void); extern void FASTCALL(cpu_raise_softirq(unsigned int cpu, unsigned int nr)); extern void FASTCALL(raise_softirq(unsigned int nr)); +#ifndef invoke_softirq +#define invoke_softirq() do_softirq() +#endif /* Tasklets --- multithreaded analogue of BHs. diff --git a/kernel/softirq.c b/kernel/softirq.c index 79ed6b9cbdee9..bce93b6118227 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -105,7 +105,7 @@ void local_bh_enable(void) BUG_ON(irqs_disabled()); if (unlikely(!in_interrupt() && local_softirq_pending())) - do_softirq(); + invoke_softirq(); preempt_check_resched(); } EXPORT_SYMBOL(local_bh_enable); -- 2.53.0