s390 patches for 4.5-rc2
Subsystems (9)
Hi Linus,
please pull from the 'for-linus' branch of
git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git for-linus
to receive the following updates:
An optimization for irq-restore, the SSM instruction is quite a bit slower than an if-statement and a STOSM.
The copy_file_range system all is added.
Cleanup for PCI and CIO.
And a couple of bug fixes.
Shortlog:
Christian Borntraeger (1):
s390/irqflags: optimize irq restore
Dominik Dingel (1):
s390/mm: use TASK_MAX_SIZE where applicable
Heiko Carstens (5):
s390/numa: allocate memory with correct alignment
s390: remove superfluous memblock_alloc() return value checks
s390: wire up copy_file_range syscall
s390: remove all usages of PSW_ADDR_AMODE
s390: remove all usages of PSW_ADDR_INSN
Ingo Tuchscherer (1):
s390/zcrypt: Fix cryptographic device id in kernel messages
Michael Holzheu (1):
s390/numa: move numa_init_late() from device to arch_initcall
Sebastian Ott (10):
s390/pci: adjust IOMAP_MAX_ENTRIES s390/pci: provide ZPCI_ADDR macro s390/pci: improve ZPCI_* macros s390/pci: resize iomap
s390/pci: fix bar check
s390/pci: set error state for unusable functions s390/pci: remove iomap sanity checks s390/cio: fix measurement characteristics memleak s390/cio: ensure consistent measurement state s390/cio: update measurement characteristics
arch/s390/include/asm/irqflags.h | 9 +++-- arch/s390/include/asm/pci_io.h | 14 +++++--- arch/s390/include/asm/processor.h | 4 +-- arch/s390/include/asm/ptrace.h | 6 ++-- arch/s390/include/uapi/asm/unistd.h | 3 +- arch/s390/kernel/compat_wrapper.c | 1 + arch/s390/kernel/crash_dump.c | 2 -- arch/s390/kernel/debug.c | 2 +- arch/s390/kernel/dumpstack.c | 9 +++-- arch/s390/kernel/early.c | 8 ++--- arch/s390/kernel/ftrace.c | 2 +- arch/s390/kernel/ipl.c | 4 +-- arch/s390/kernel/kprobes.c | 16 ++++----- arch/s390/kernel/perf_event.c | 12 +++---- arch/s390/kernel/process.c | 12 +++---- arch/s390/kernel/ptrace.c | 6 ++-- arch/s390/kernel/setup.c | 16 ++++----- arch/s390/kernel/signal.c | 13 ++++---- arch/s390/kernel/smp.c | 2 -- arch/s390/kernel/stacktrace.c | 11 +++--- arch/s390/kernel/syscalls.S | 1 + arch/s390/kernel/traps.c | 11 +++--- arch/s390/kvm/guestdbg.c | 4 +-- arch/s390/mm/fault.c | 6 ++-- arch/s390/mm/init.c | 2 +- arch/s390/mm/mmap.c | 12 +++---- arch/s390/mm/pgtable.c | 2 +- arch/s390/numa/numa.c | 6 ++-- arch/s390/oprofile/backtrace.c | 9 +++-- arch/s390/pci/pci.c | 61 +++++++++++++++++----------------- arch/s390/pci/pci_event.c | 5 +++ drivers/s390/cio/chp.c | 21 +++++------- drivers/s390/cio/chp.h | 2 +- drivers/s390/cio/chsc.c | 43 +++++++++++++----------- drivers/s390/crypto/zcrypt_error.h | 15 +++++---- drivers/s390/crypto/zcrypt_msgtype50.c | 9 ++--- drivers/s390/crypto/zcrypt_msgtype6.c | 20 +++++------ 37 files changed, 192 insertions(+), 189 deletions(-)
arch/s390/include/asm/irqflags.h +7 -2
@@ -8,6 +8,8 @@#include <linux/types.h> +#define ARCH_IRQ_ENABLED (3UL << (BITS_PER_LONG - 8)) +/* store then OR system mask. */ #define __arch_local_irq_stosm (__or) \ ({ \
@@ -54,14 +56,17 @@ static inline notrace void arch_local_irq_enable(void)__arch_local_irq_stosm (0x03 ); } +/* This only restores external and I/O interrupt state */ static inline notrace void arch_local_irq_restore(unsigned long flags) { -__arch_local_irq_ssm (flags); +/* only disabled->disabled and disabled->enabled is valid */ +if (flags &ARCH_IRQ_ENABLED ) +arch_local_irq_enable (); } static inline notrace bool arch_irqs_disabled_flags(unsigned long flags) { -return !(flags & (3UL << (BITS_PER_LONG -8 ))); +return !(flags &ARCH_IRQ_ENABLED ); } static inline notrace bool arch_irqs_disabled(void)
arch/s390/include/asm/pci_io.h +9 -5
@@ -8,10 +8,13 @@#include <asm/pci_insn.h> /* I/O Map */ -#define ZPCI_IOMAP_MAX_ENTRIES 0x7fff -#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000ULL -#define ZPCI_IOMAP_ADDR_IDX_MASK 0x7fff000000000000ULL -#define ZPCI_IOMAP_ADDR_OFF_MASK 0x0000ffffffffffffULL +#define ZPCI_IOMAP_SHIFT 48 +#define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000UL +#define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1) +#define ZPCI_IOMAP_MAX_ENTRIES \ + ((ULONG_MAX - ZPCI_IOMAP_ADDR_BASE + 1) / (1UL << ZPCI_IOMAP_SHIFT)) +#define ZPCI_IOMAP_ADDR_IDX_MASK \ + (~ZPCI_IOMAP_ADDR_OFF_MASK - ZPCI_IOMAP_ADDR_BASE)struct zpci_iomap_entry {u32 fh;
@@ -21,8 +24,9 @@ struct zpci_iomap_entry {extern struct zpci_iomap_entry *zpci_iomap_start; +#define ZPCI_ADDR (idx) (ZPCI_IOMAP_ADDR_BASE | ((u64) idx << ZPCI_IOMAP_SHIFT))#define ZPCI_IDX (addr) \ - (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> 48) + (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> ZPCI_IOMAP_SHIFT)#define ZPCI_OFFSET (addr) \ ((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK)
arch/s390/include/asm/processor.h +2 -2
@@ -166,14 +166,14 @@ extern __vector128 init_task_fpu_regs[__NUM_VXRS];*/ #define start_thread (regs, new_psw, new_stackp) do { \ regs->psw.mask = PSW_USER_BITS | PSW_MASK_EA | PSW_MASK_BA; \ - regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ + regs->psw.addr = new_psw; \ regs->gprs[15] = new_stackp; \ execve_tail(); \ } while (0)#define start_thread31 (regs, new_psw, new_stackp) do { \ regs->psw.mask = PSW_USER_BITS | PSW_MASK_BA; \ - regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ + regs->psw.addr = new_psw; \ regs->gprs[15] = new_stackp; \ crst_table_downgrade(current->mm, 1UL << 31); \ execve_tail(); \
arch/s390/include/asm/ptrace.h +3 -3
@@ -149,7 +149,7 @@ static inline int test_pt_regs_flag(struct pt_regs *regs, int flag)#define arch_has_block_step () (1)#define user_mode (regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) -#define instruction_pointer (regs) ((regs)->psw.addr & PSW_ADDR_INSN) +#define instruction_pointer (regs) ((regs)->psw.addr)#define user_stack_pointer (regs)((regs)->gprs[15])#define profile_pc (regs) instruction_pointer(regs)
@@ -161,7 +161,7 @@ static inline long regs_return_value(struct pt_regs *regs)static inline void instruction_pointer_set (struct pt_regs *regs,unsigned long val) { - regs->psw.addr = val |PSW_ADDR_AMODE ; + regs->psw.addr = val; }int regs_query_register_offset (const char *name);
@@ -171,7 +171,7 @@ unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n);static inline unsigned long kernel_stack_pointer (struct pt_regs *regs) { -return regs->gprs[15 ] &PSW_ADDR_INSN ; +return regs->gprs[15 ]; }#endif /* __ASSEMBLY__ */
arch/s390/include/uapi/asm/unistd.h +2 -1
@@ -310,7 +310,8 @@#define __NR_recvmsg 372#define __NR_shutdown 373#define __NR_mlock2 374 -#define NR_syscalls 375 +#define __NR_copy_file_range 375 +#define NR_syscalls 376/* * There are some system calls that are not present on 64 bit, some
arch/s390/kernel/compat_wrapper.c +1 -0
@@ -177,3 +177,4 @@ COMPAT_SYSCALL_WRAP3(getsockname, int, fd, struct sockaddr __user *, usockaddr, COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len); COMPAT_SYSCALL_WRAP6(sendto, int, fd, void __user *, buff, size_t, len, unsigned int, flags, struct sockaddr __user *, addr, int, addr_len); COMPAT_SYSCALL_WRAP3(mlock2, unsigned long, start, size_t, len, int, flags); +COMPAT_SYSCALL_WRAP6(copy_file_range, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags);
arch/s390/kernel/crash_dump.c +0 -2
@@ -59,8 +59,6 @@ struct save_area * __init save_area_alloc(bool is_boot_cpu)struct save_area *sa; sa = (void *)memblock_alloc (sizeof (*sa),8 ); -if (!sa) -return NULL ;if (is_boot_cpu)list_add (&sa->list, &dump_save_areas);else
arch/s390/kernel/debug.c +1 -1
@@ -1470,7 +1470,7 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view, except_str ="*" ; else except_str ="-" ; - caller = ((unsigned long ) entry->caller) &PSW_ADDR_INSN ; + caller = (unsigned long ) entry->caller; rc += sprintf(out_buf, "%02i %011lld:%06lu %1u %1s %02i %p ", area, (long long)time_spec.tv_sec, time_spec.tv_nsec / 1000, level, except_str,
arch/s390/kernel/dumpstack.c +4 -5
@@ -34,22 +34,21 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high)unsigned long addr;while (1 ) { - sp = sp &PSW_ADDR_INSN ;if (sp < low || sp > high -sizeof (*sf))return sp; sf = (struct stack_frame *) sp; - addr = sf->gprs[8 ] &PSW_ADDR_INSN ; + addr = sf->gprs[8 ];printk ("([<%016lx>] %pSR)\n" , addr, (void *)addr);/* Follow the backchain. */ while (1 ) { low = sp; - sp = sf->back_chain &PSW_ADDR_INSN ; + sp = sf->back_chain;if (!sp)break ;if (sp <= low || sp > high -sizeof (*sf))return sp; sf = (struct stack_frame *) sp; - addr = sf->gprs[8 ] &PSW_ADDR_INSN ; + addr = sf->gprs[8 ];printk (" [<%016lx>] %pSR\n" , addr, (void *)addr); }/* Zero backchain detected, check for interrupt frame. */
@@ -57,7 +56,7 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high)if (sp <= low || sp > high -sizeof (*regs))return sp; regs = (struct pt_regs *) sp; - addr = regs->psw.addr &PSW_ADDR_INSN ; + addr = regs->psw.addr;printk (" [<%016lx>] %pSR\n" , addr, (void *)addr); low = sp; sp = regs->gprs[15 ];
arch/s390/kernel/early.c +4 -4
@@ -252,14 +252,14 @@ static void early_pgm_check_handler(void)unsigned long addr; addr = S390_lowcore.program_old_psw.addr; - fixup =search_exception_tables (addr &PSW_ADDR_INSN ); + fixup =search_exception_tables (addr);if (!fixup)disabled_wait (0 );/* Disable low address protection before storing into lowcore. */ __ctl_store (cr0,0 ,0 ); cr0_new = cr0 & ~(1UL <<28 );__ctl_load (cr0_new,0 ,0 ); - S390_lowcore.program_old_psw.addr =extable_fixup (fixup)|PSW_ADDR_AMODE ; + S390_lowcore.program_old_psw.addr =extable_fixup (fixup);__ctl_load (cr0,0 ,0 ); }
@@ -268,9 +268,9 @@ static noinline __init void setup_lowcore_early(void)psw_t psw; psw.mask =PSW_MASK_BASE |PSW_DEFAULT_KEY |PSW_MASK_EA |PSW_MASK_BA ; - psw.addr =PSW_ADDR_AMODE | (unsigned long ) s390_base_ext_handler; + psw.addr = (unsigned long ) s390_base_ext_handler; S390_lowcore.external_new_psw = psw; - psw.addr =PSW_ADDR_AMODE | (unsigned long ) s390_base_pgm_handler; + psw.addr = (unsigned long ) s390_base_pgm_handler; S390_lowcore.program_new_psw = psw; s390_base_pgm_handler_fn = early_pgm_check_handler; }
arch/s390/kernel/ftrace.c +1 -1
@@ -203,7 +203,7 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip) goto out;if (unlikely (atomic_read (¤t->tracing_graph_pause))) goto out; - ip = (ip &PSW_ADDR_INSN ) -MCOUNT_INSN_SIZE ; + ip -=MCOUNT_INSN_SIZE ; trace.func = ip; trace.depth = current->curr_ret_stack +1 ;/* Only trace if the calling function expects to. */
arch/s390/kernel/ipl.c +2 -2
@@ -2057,12 +2057,12 @@ void s390_reset_system(void)/* Set new machine check handler */ S390_lowcore.mcck_new_psw.mask =PSW_KERNEL_BITS |PSW_MASK_DAT ; S390_lowcore.mcck_new_psw.addr = -PSW_ADDR_AMODE | (unsigned long ) s390_base_mcck_handler; + (unsigned long ) s390_base_mcck_handler;/* Set new program check handler */ S390_lowcore.program_new_psw.mask =PSW_KERNEL_BITS |PSW_MASK_DAT ; S390_lowcore.program_new_psw.addr = -PSW_ADDR_AMODE | (unsigned long ) s390_base_pgm_handler; + (unsigned long ) s390_base_pgm_handler;/* * Clear subchannel ID and number to signal new kernel that no CCW or
arch/s390/kernel/kprobes.c +8 -8
@@ -226,7 +226,7 @@ static void enable_singlestep(struct kprobe_ctlblk *kcb,__ctl_load (per_kprobe,9 ,11 ); regs->psw.mask |=PSW_MASK_PER ; regs->psw.mask &= ~(PSW_MASK_IO |PSW_MASK_EXT ); - regs->psw.addr = ip |PSW_ADDR_AMODE ; + regs->psw.addr = ip; }NOKPROBE_SYMBOL (enable_singlestep);
@@ -238,7 +238,7 @@ static void disable_singlestep(struct kprobe_ctlblk *kcb,__ctl_load (kcb->kprobe_saved_ctl,9 ,11 ); regs->psw.mask &= ~PSW_MASK_PER ; regs->psw.mask |= kcb->kprobe_saved_imask; - regs->psw.addr = ip |PSW_ADDR_AMODE ; + regs->psw.addr = ip; }NOKPROBE_SYMBOL (disable_singlestep);
@@ -310,7 +310,7 @@ static int kprobe_handler(struct pt_regs *regs)*/ preempt_disable (); kcb =get_kprobe_ctlblk (); - p =get_kprobe ((void *)((regs->psw.addr &PSW_ADDR_INSN ) -2 )); + p =get_kprobe ((void *)(regs->psw.addr -2 ));if (p) {if (kprobe_running ()) {
@@ -460,7 +460,7 @@ static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)break ; } - regs->psw.addr = orig_ret_address |PSW_ADDR_AMODE ; + regs->psw.addr = orig_ret_address;pop_kprobe (get_kprobe_ctlblk ());kretprobe_hash_unlock (current, &flags);
@@ -490,7 +490,7 @@ NOKPROBE_SYMBOL(trampoline_probe_handler);static void resume_execution (struct kprobe *p,struct pt_regs *regs) {struct kprobe_ctlblk *kcb =get_kprobe_ctlblk (); -unsigned long ip = regs->psw.addr &PSW_ADDR_INSN ; +unsigned long ip = regs->psw.addr;int fixup =probe_get_fixup_type (p->ainsn.insn);/* Check if the kprobes location is an enabled ftrace caller */
@@ -605,9 +605,9 @@ static int kprobe_trap_handler(struct pt_regs *regs, int trapnr)* In case the user-specified fault handler returned * zero, try to fix up. */ - entry =search_exception_tables (regs->psw.addr &PSW_ADDR_INSN ); + entry =search_exception_tables (regs->psw.addr);if (entry) { - regs->psw.addr =extable_fixup (entry) |PSW_ADDR_AMODE ; + regs->psw.addr =extable_fixup (entry);return 1 ; }
@@ -683,7 +683,7 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)memcpy (&kcb->jprobe_saved_regs, regs,sizeof (struct pt_regs ));/* setup return addr to the jprobe handler routine */ - regs->psw.addr = (unsigned long ) jp->entry |PSW_ADDR_AMODE ; + regs->psw.addr = (unsigned long ) jp->entry; regs->psw.mask &= ~(PSW_MASK_IO |PSW_MASK_EXT );/* r15 is the stack pointer */
arch/s390/kernel/perf_event.c +5 -7
@@ -74,7 +74,7 @@ static unsigned long guest_is_user_mode(struct pt_regs *regs)static unsigned long instruction_pointer_guest (struct pt_regs *regs) { -return sie_block (regs)->gpsw.addr &PSW_ADDR_INSN ; +return sie_block (regs)->gpsw.addr; }unsigned long perf_instruction_pointer (struct pt_regs *regs)
@@ -231,29 +231,27 @@ static unsigned long __store_trace(struct perf_callchain_entry *entry,struct pt_regs *regs;while (1 ) { - sp = sp &PSW_ADDR_INSN ;if (sp < low || sp > high -sizeof (*sf))return sp; sf = (struct stack_frame *) sp; -perf_callchain_store (entry, sf->gprs[8 ] &PSW_ADDR_INSN ); +perf_callchain_store (entry, sf->gprs[8 ]);/* Follow the backchain. */ while (1 ) { low = sp; - sp = sf->back_chain &PSW_ADDR_INSN ; + sp = sf->back_chain;if (!sp)break ;if (sp <= low || sp > high -sizeof (*sf))return sp; sf = (struct stack_frame *) sp; -perf_callchain_store (entry, - sf->gprs[8 ] &PSW_ADDR_INSN ); +perf_callchain_store (entry, sf->gprs[8 ]); }/* Zero backchain detected, check for interrupt frame. */ sp = (unsigned long ) (sf +1 );if (sp <= low || sp > high -sizeof (*regs))return sp; regs = (struct pt_regs *) sp; -perf_callchain_store (entry, sf->gprs[8 ] &PSW_ADDR_INSN ); +perf_callchain_store (entry, sf->gprs[8 ]); low = sp; sp = regs->gprs[15 ]; }
arch/s390/kernel/process.c +6 -6
@@ -56,10 +56,10 @@ unsigned long thread_saved_pc(struct task_struct *tsk)return 0 ; low =task_stack_page (tsk); high = (struct stack_frame *)task_pt_regs (tsk); - sf = (struct stack_frame *) (tsk->thread.ksp &PSW_ADDR_INSN ); + sf = (struct stack_frame *) tsk->thread.ksp;if (sf <= low || sf > high)return 0 ; - sf = (struct stack_frame *) (sf->back_chain &PSW_ADDR_INSN ); + sf = (struct stack_frame *) sf->back_chain;if (sf <= low || sf > high)return 0 ;return sf->gprs[8 ];
@@ -154,7 +154,7 @@ int copy_thread(unsigned long clone_flags, unsigned long new_stackp,memset (&frame->childregs,0 ,sizeof (struct pt_regs )); frame->childregs.psw.mask =PSW_KERNEL_BITS |PSW_MASK_DAT |PSW_MASK_IO |PSW_MASK_EXT |PSW_MASK_MCHECK ; - frame->childregs.psw.addr =PSW_ADDR_AMODE | + frame->childregs.psw.addr = (unsigned long ) kernel_thread_starter; frame->childregs.gprs[9 ] = new_stackp;/* function */ frame->childregs.gprs[10 ] = arg;
@@ -220,14 +220,14 @@ unsigned long get_wchan(struct task_struct *p)return 0 ; low =task_stack_page (p); high = (struct stack_frame *)task_pt_regs (p); - sf = (struct stack_frame *) (p->thread.ksp &PSW_ADDR_INSN ); + sf = (struct stack_frame *) p->thread.ksp;if (sf <= low || sf > high)return 0 ;for (count =0 ; count <16 ; count++) { - sf = (struct stack_frame *) (sf->back_chain &PSW_ADDR_INSN ); + sf = (struct stack_frame *) sf->back_chain;if (sf <= low || sf > high)return 0 ; - return_address = sf->gprs[8 ] &PSW_ADDR_INSN ; + return_address = sf->gprs[8 ];if (!in_sched_functions (return_address))return return_address; }
arch/s390/kernel/ptrace.c +2 -4
@@ -84,7 +84,7 @@ void update_cr_regs(struct task_struct *task)if (test_tsk_thread_flag (task,TIF_UPROBE_SINGLESTEP )) new.control |=PER_EVENT_IFETCH ; new.start =0 ; - new.end =PSW_ADDR_INSN ; + new.end =-1UL ; }/* Take care of the PER enablement bit in the PSW. */
@@ -148,7 +148,7 @@ static inline unsigned long __peek_user_per(struct task_struct *child,else if (addr == (addr_t) &dummy->cr11)/* End address of the active per set. */ return test_thread_flag (TIF_SINGLE_STEP ) ? -PSW_ADDR_INSN : child->thread.per_user.end; +-1UL : child->thread.per_user.end;else if (addr == (addr_t) &dummy->bits)/* Single-step bit. */ return test_thread_flag(TIF_SINGLE_STEP) ?
@@ -495,8 +495,6 @@ long arch_ptrace(struct task_struct *child, long request, }return 0 ;default : -/* Removing high order bit from addr (only for 31 bit). */ - addr &=PSW_ADDR_INSN ;return ptrace_request (child, request, addr, data); } }
arch/s390/kernel/setup.c +6 -10
@@ -301,25 +301,21 @@ static void __init setup_lowcore(void)BUILD_BUG_ON (sizeof (struct lowcore ) !=LC_PAGES *4096 ); lc =__alloc_bootmem_low (LC_PAGES *PAGE_SIZE ,LC_PAGES *PAGE_SIZE ,0 ); lc->restart_psw.mask =PSW_KERNEL_BITS ; - lc->restart_psw.addr = -PSW_ADDR_AMODE | (unsigned long ) restart_int_handler; + lc->restart_psw.addr = (unsigned long ) restart_int_handler; lc->external_new_psw.mask =PSW_KERNEL_BITS |PSW_MASK_DAT |PSW_MASK_MCHECK ; - lc->external_new_psw.addr = -PSW_ADDR_AMODE | (unsigned long ) ext_int_handler; + lc->external_new_psw.addr = (unsigned long ) ext_int_handler; lc->svc_new_psw.mask =PSW_KERNEL_BITS |PSW_MASK_DAT |PSW_MASK_IO |PSW_MASK_EXT |PSW_MASK_MCHECK ; - lc->svc_new_psw.addr =PSW_ADDR_AMODE | (unsigned long ) system_call; + lc->svc_new_psw.addr = (unsigned long ) system_call; lc->program_new_psw.mask =PSW_KERNEL_BITS |PSW_MASK_DAT |PSW_MASK_MCHECK ; - lc->program_new_psw.addr = -PSW_ADDR_AMODE | (unsigned long ) pgm_check_handler; + lc->program_new_psw.addr = (unsigned long ) pgm_check_handler; lc->mcck_new_psw.mask =PSW_KERNEL_BITS ; - lc->mcck_new_psw.addr = -PSW_ADDR_AMODE | (unsigned long ) mcck_int_handler; + lc->mcck_new_psw.addr = (unsigned long ) mcck_int_handler; lc->io_new_psw.mask =PSW_KERNEL_BITS |PSW_MASK_DAT |PSW_MASK_MCHECK ; - lc->io_new_psw.addr =PSW_ADDR_AMODE | (unsigned long ) io_int_handler; + lc->io_new_psw.addr = (unsigned long ) io_int_handler; lc->clock_comparator =-1ULL ; lc->kernel_stack = ((unsigned long ) &init_thread_union) +THREAD_SIZE -STACK_FRAME_OVERHEAD -sizeof (struct pt_regs );
arch/s390/kernel/signal.c +6 -7
@@ -331,13 +331,13 @@ static int setup_frame(int sig, struct k_sigaction *ka,/* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags &SA_RESTORER ) { - restorer = (unsigned long ) ka->sa.sa_restorer |PSW_ADDR_AMODE ; + restorer = (unsigned long ) ka->sa.sa_restorer; }else {/* Signal frame without vector registers are short ! */ __u16 __user *svc = (void __user *) frame + frame_size -2 ;if (__put_user (S390_SYSCALL_OPCODE | __NR_sigreturn, svc))return -EFAULT ; - restorer = (unsigned long ) svc |PSW_ADDR_AMODE ; + restorer = (unsigned long ) svc; }/* Set up registers for signal handler */
@@ -347,7 +347,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, regs->psw.mask =PSW_MASK_EA |PSW_MASK_BA | (PSW_USER_BITS &PSW_MASK_ASC ) | (regs->psw.mask & ~PSW_MASK_ASC ); - regs->psw.addr = (unsigned long ) ka->sa.sa_handler |PSW_ADDR_AMODE ; + regs->psw.addr = (unsigned long ) ka->sa.sa_handler; regs->gprs[2 ] = sig; regs->gprs[3 ] = (unsigned long ) &frame->sc;
@@ -394,13 +394,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,/* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ksig->ka.sa.sa_flags &SA_RESTORER ) { - restorer = (unsigned long ) - ksig->ka.sa.sa_restorer |PSW_ADDR_AMODE ; + restorer = (unsigned long ) ksig->ka.sa.sa_restorer; }else {__u16 __user *svc = &frame->svc_insn;if (__put_user (S390_SYSCALL_OPCODE | __NR_rt_sigreturn, svc))return -EFAULT ; - restorer = (unsigned long ) svc |PSW_ADDR_AMODE ; + restorer = (unsigned long ) svc; }/* Create siginfo on the signal stack */
@@ -426,7 +425,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, regs->psw.mask =PSW_MASK_EA |PSW_MASK_BA | (PSW_USER_BITS &PSW_MASK_ASC ) | (regs->psw.mask & ~PSW_MASK_ASC ); - regs->psw.addr = (unsigned long ) ksig->ka.sa.sa_handler |PSW_ADDR_AMODE ; + regs->psw.addr = (unsigned long ) ksig->ka.sa.sa_handler; regs->gprs[2 ] = ksig->sig; regs->gprs[3 ] = (unsigned long ) &frame->info;
arch/s390/kernel/smp.c +0 -2
@@ -623,8 +623,6 @@ void __init smp_save_dump_cpus(void)return ;/* Allocate a page as dumping area for the store status sigps */ page =memblock_alloc_base (PAGE_SIZE ,PAGE_SIZE ,1UL <<31 ); -if (!page) -panic ("could not allocate memory for save area\n" );/* Set multi-threading state to the previous system. */ pcpu_set_smt (sclp.mtid_prev); boot_cpu_addr =stap ();
arch/s390/kernel/stacktrace.c +5 -6
@@ -21,12 +21,11 @@ static unsigned long save_context_stack(struct stack_trace *trace,unsigned long addr;while (1 ) { - sp &=PSW_ADDR_INSN ;if (sp < low || sp > high)return sp; sf = (struct stack_frame *)sp;while (1 ) { - addr = sf->gprs[8 ] &PSW_ADDR_INSN ; + addr = sf->gprs[8 ];if (!trace->skip) trace->entries[trace->nr_entries++] = addr;else
@@ -34,7 +33,7 @@ static unsigned long save_context_stack(struct stack_trace *trace,if (trace->nr_entries >= trace->max_entries)return sp; low = sp; - sp = sf->back_chain &PSW_ADDR_INSN ; + sp = sf->back_chain;if (!sp)break ;if (sp <= low || sp > high -sizeof (*sf))
@@ -46,7 +45,7 @@ static unsigned long save_context_stack(struct stack_trace *trace,if (sp <= low || sp > high -sizeof (*regs))return sp; regs = (struct pt_regs *)sp; - addr = regs->psw.addr &PSW_ADDR_INSN ; + addr = regs->psw.addr;if (savesched || !in_sched_functions (addr)) {if (!trace->skip) trace->entries[trace->nr_entries++] = addr;
@@ -65,7 +64,7 @@ void save_stack_trace(struct stack_trace *trace) registerunsigned long sp asm ("15" );unsigned long orig_sp, new_sp; - orig_sp = sp &PSW_ADDR_INSN ; + orig_sp = sp; new_sp =save_context_stack (trace, orig_sp, S390_lowcore.panic_stack -PAGE_SIZE , S390_lowcore.panic_stack,1 );
@@ -86,7 +85,7 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) {unsigned long sp, low, high; - sp = tsk->thread.ksp &PSW_ADDR_INSN ; + sp = tsk->thread.ksp; low = (unsigned long )task_stack_page (tsk); high = (unsigned long )task_pt_regs (tsk);save_context_stack (trace, sp, low, high,0 );
arch/s390/kernel/syscalls.S +1 -0
@@ -383,3 +383,4 @@ SYSCALL(sys_recvfrom,compat_sys_recvfrom) SYSCALL(sys_recvmsg,compat_sys_recvmsg) SYSCALL(sys_shutdown,sys_shutdown) SYSCALL(sys_mlock2,compat_sys_mlock2) +SYSCALL(sys_copy_file_range,compat_sys_copy_file_range) /* 375 */
arch/s390/kernel/traps.c +5 -6
@@ -32,8 +32,7 @@ static inline void __user *get_trap_ip(struct pt_regs *regs) address = *(unsigned long *)(current->thread.trap_tdb +24 ); else address = regs->psw.addr; -return (void __user *) - ((address - (regs->int_code >>16 )) &PSW_ADDR_INSN ); +return (void __user *) (address - (regs->int_code >>16 )); }static inline void report_user_fault (struct pt_regs *regs,int signr)
@@ -46,7 +45,7 @@ static inline void report_user_fault(struct pt_regs *regs, int signr)return ;printk ("User process fault: interruption code %04x ilc:%d " , regs->int_code &0xffff , regs->int_code >>17 ); -print_vma_addr ("in " , regs->psw.addr &PSW_ADDR_INSN ); +print_vma_addr ("in " , regs->psw.addr);printk ("\n" );show_regs (regs); }
@@ -69,13 +68,13 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)report_user_fault (regs, si_signo); }else {const struct exception_table_entry *fixup; - fixup =search_exception_tables (regs->psw.addr &PSW_ADDR_INSN ); + fixup =search_exception_tables (regs->psw.addr);if (fixup) - regs->psw.addr =extable_fixup (fixup) |PSW_ADDR_AMODE ; + regs->psw.addr =extable_fixup (fixup);else {enum bug_trap_type btt; - btt =report_bug (regs->psw.addr &PSW_ADDR_INSN , regs); + btt =report_bug (regs->psw.addr, regs);if (btt ==BUG_TRAP_TYPE_WARN )return ;die (regs, str);
arch/s390/kvm/guestdbg.c +2 -2
@@ -116,7 +116,7 @@ static void enable_all_hw_wp(struct kvm_vcpu *vcpu)if (*cr9 &PER_EVENT_STORE && *cr9 &PER_CONTROL_ALTERATION ) { *cr9 &= ~PER_CONTROL_ALTERATION ; *cr10 =0 ; - *cr11 =PSW_ADDR_INSN ; + *cr11 =-1UL ; }else { *cr9 &= ~PER_CONTROL_ALTERATION ; *cr9 |=PER_EVENT_STORE ;
@@ -159,7 +159,7 @@ void kvm_s390_patch_guest_per_regs(struct kvm_vcpu *vcpu) vcpu->arch.sie_block->gcr[0 ] &= ~0x800ul ; vcpu->arch.sie_block->gcr[9 ] |=PER_EVENT_IFETCH ; vcpu->arch.sie_block->gcr[10 ] =0 ; - vcpu->arch.sie_block->gcr[11 ] =PSW_ADDR_INSN ; + vcpu->arch.sie_block->gcr[11 ] =-1UL ; }if (guestdbg_hw_bp_enabled (vcpu)) {
arch/s390/mm/fault.c +3 -3
@@ -228,7 +228,7 @@ static inline void report_user_fault(struct pt_regs *regs, long signr)return ;printk (KERN_ALERT "User process fault: interruption code %04x ilc:%d " , regs->int_code &0xffff , regs->int_code >>17 ); -print_vma_addr (KERN_CONT "in " , regs->psw.addr &PSW_ADDR_INSN ); +print_vma_addr (KERN_CONT "in " , regs->psw.addr);printk (KERN_CONT "\n" );printk (KERN_ALERT "failing address: %016lx TEID: %016lx\n" , regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
@@ -256,9 +256,9 @@ static noinline void do_no_context(struct pt_regs *regs)const struct exception_table_entry *fixup;/* Are we prepared to handle this kernel fault? */ - fixup =search_exception_tables (regs->psw.addr &PSW_ADDR_INSN ); + fixup =search_exception_tables (regs->psw.addr);if (fixup) { - regs->psw.addr =extable_fixup (fixup) |PSW_ADDR_AMODE ; + regs->psw.addr =extable_fixup (fixup);return ; }
arch/s390/mm/init.c +1 -1
@@ -98,7 +98,7 @@ void __init paging_init(void)__ctl_load (S390_lowcore.kernel_asce,1 ,1 );__ctl_load (S390_lowcore.kernel_asce,7 ,7 );__ctl_load (S390_lowcore.kernel_asce,13 ,13 ); -arch_local_irq_restore (4UL << (BITS_PER_LONG -8 )); +__arch_local_irq_stosm (0x04 );sparse_memory_present_with_active_regions (MAX_NUMNODES );sparse_init ();
arch/s390/mm/mmap.c +6 -6
@@ -169,12 +169,12 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,int s390_mmap_check (unsigned long addr,unsigned long len,unsigned long flags) { -if (is_compat_task () || (TASK_SIZE >= (1UL <<53 ))) +if (is_compat_task () ||TASK_SIZE >=TASK_MAX_SIZE )return 0 ;if (!(flags &MAP_FIXED )) addr =0 ;if ((addr + len) >=TASK_SIZE ) -return crst_table_upgrade (current->mm,1UL <<53 ); +return crst_table_upgrade (current->mm,TASK_MAX_SIZE );return 0 ; }
@@ -189,9 +189,9 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr, area =arch_get_unmapped_area (filp, addr, len, pgoff, flags);if (!(area & ~PAGE_MASK ))return area; -if (area == -ENOMEM && !is_compat_task () &&TASK_SIZE < (1UL <<53 )) { +if (area == -ENOMEM && !is_compat_task () &&TASK_SIZE <TASK_MAX_SIZE ) {/* Upgrade the page table to 4 levels and retry. */ - rc =crst_table_upgrade (mm,1UL <<53 ); + rc =crst_table_upgrade (mm,TASK_MAX_SIZE );if (rc)return (unsigned long ) rc; area =arch_get_unmapped_area (filp, addr, len, pgoff, flags);
@@ -211,9 +211,9 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, area =arch_get_unmapped_area_topdown (filp, addr, len, pgoff, flags);if (!(area & ~PAGE_MASK ))return area; -if (area == -ENOMEM && !is_compat_task () &&TASK_SIZE < (1UL <<53 )) { +if (area == -ENOMEM && !is_compat_task () &&TASK_SIZE <TASK_MAX_SIZE ) {/* Upgrade the page table to 4 levels and retry. */ - rc =crst_table_upgrade (mm,1UL <<53 ); + rc =crst_table_upgrade (mm,TASK_MAX_SIZE );if (rc)return (unsigned long ) rc; area = arch_get_unmapped_area_topdown(filp, addr, len,
arch/s390/mm/pgtable.c +1 -1
@@ -55,7 +55,7 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long limit)unsigned long entry;int flush; -BUG_ON (limit > (1UL <<53 )); +BUG_ON (limit >TASK_MAX_SIZE ); flush =0 ; repeat: table =crst_table_alloc (mm);
arch/s390/numa/numa.c +2 -4
@@ -57,9 +57,7 @@ static __init pg_data_t *alloc_node_data(void) {pg_data_t *res; - res = (pg_data_t *)memblock_alloc (sizeof (pg_data_t),1 ); -if (!res) -panic ("Could not allocate memory for node data!\n" ); + res = (pg_data_t *)memblock_alloc (sizeof (pg_data_t),8 );memset (res,0 ,sizeof (pg_data_t));return res; }
@@ -162,7 +160,7 @@ static int __init numa_init_late(void)register_one_node (nid);return 0 ; } -device_initcall (numa_init_late); +arch_initcall (numa_init_late);static int __init parse_debug (char *parm) {
arch/s390/oprofile/backtrace.c +4 -5
@@ -16,24 +16,23 @@ __show_trace(unsigned int *depth, unsigned long sp,struct pt_regs *regs;while (*depth) { - sp = sp &PSW_ADDR_INSN ;if (sp < low || sp > high -sizeof (*sf))return sp; sf = (struct stack_frame *) sp; (*depth)--; -oprofile_add_trace (sf->gprs[8 ] &PSW_ADDR_INSN ); +oprofile_add_trace (sf->gprs[8 ]);/* Follow the backchain. */ while (*depth) { low = sp; - sp = sf->back_chain &PSW_ADDR_INSN ; + sp = sf->back_chain;if (!sp)break ;if (sp <= low || sp > high -sizeof (*sf))return sp; sf = (struct stack_frame *) sp; (*depth)--; -oprofile_add_trace (sf->gprs[8 ] &PSW_ADDR_INSN ); +oprofile_add_trace (sf->gprs[8 ]); }
@@ -46,7 +45,7 @@ __show_trace(unsigned int *depth, unsigned long sp,return sp; regs = (struct pt_regs *) sp; (*depth)--; -oprofile_add_trace (sf->gprs[8 ] &PSW_ADDR_INSN ); +oprofile_add_trace (sf->gprs[8 ]); low = sp; sp = regs->gprs[15 ]; }
arch/s390/pci/pci.c +31 -30
132 lines not on this page · raw message
arch/s390/pci/pci_event.c +5 -0
@@ -53,6 +53,11 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)pr_err ("%s: Event 0x%x reports an error for PCI function 0x%x\n" , pdev ?pci_name (pdev) :"n/a" , ccdf->pec, ccdf->fid); + +if (!pdev) +return ; + + pdev->error_state = pci_channel_io_perm_failure; }void zpci_event_error (void *data)
drivers/s390/cio/chp.c +8 -13
@@ -139,11 +139,11 @@ static ssize_t chp_measurement_chars_read(struct file *filp, device = container_of(kobj, struct device, kobj); chp =to_channelpath (device); -if (!chp->cmg_chars) +if (chp->cmg ==-1 )return 0 ; -return memory_read_from_buffer (buf, count, &off, - chp->cmg_chars,sizeof (struct cmg_chars )); +return memory_read_from_buffer (buf, count, &off, &chp->cmg_chars, +sizeof (chp->cmg_chars)); }static struct bin_attribute chp_measurement_chars_attr = {
@@ -416,7 +416,8 @@ static void chp_release(struct device *dev)* chp_update_desc - update channel-path description * @chp - channel-path * -* Update the channel-path description of the specified channel-path. +* Update the channel-path description of the specified channel-path +* including channel measurement related information. * Return zero on success, non-zero otherwise. */ int chp_update_desc (struct channel_path *chp)
@@ -428,8 +429,10 @@ int chp_update_desc(struct channel_path *chp)return rc; rc =chsc_determine_fmt1_channel_path_desc (chp->chpid, &chp->desc_fmt1); +if (rc) +return rc; -return rc; +return chsc_get_channel_measurement_chars (chp); }/**
@@ -466,14 +469,6 @@ int chp_new(struct chp_id chpid) ret = -ENODEV ; goto out_free; } -/* Get channel-measurement characteristics. */ -if (css_chsc_characteristics.scmc && css_chsc_characteristics.secm) { - ret =chsc_get_channel_measurement_chars (chp); -if (ret) - goto out_free; - }else { - chp->cmg =-1 ; - }dev_set_name (&chp->dev,"chp%x.%02x" , chpid.cssid, chpid.id);/* make it known to the system */
drivers/s390/cio/chp.h +1 -1
@@ -48,7 +48,7 @@ struct channel_path {/* Channel-measurement related stuff: */ int cmg;int shared; -void *cmg_chars; +struct cmg_chars cmg_chars; };/* Return channel_path struct for given chpid. */
drivers/s390/cio/chsc.c +24 -19
115 lines not on this page · raw message
drivers/s390/crypto/zcrypt_error.h +9 -6
@@ -112,9 +112,10 @@ static inline int convert_error(struct zcrypt_device *zdev,atomic_set (&zcrypt_rescan_req,1 ); zdev->online =0 ;pr_err ("Cryptographic device %x failed and was set offline\n" , - zdev->ap_dev->qid); +AP_QID_DEVICE (zdev->ap_dev->qid));ZCRYPT_DBF_DEV (DBF_ERR , zdev,"dev%04xo%drc%d" , - zdev->ap_dev->qid, zdev->online, ehdr->reply_code); +AP_QID_DEVICE (zdev->ap_dev->qid), zdev->online, + ehdr->reply_code);return -EAGAIN ;case REP82_ERROR_TRANSPORT_FAIL :case REP82_ERROR_MACHINE_FAILURE :
@@ -123,16 +124,18 @@ static inline int convert_error(struct zcrypt_device *zdev,atomic_set (&zcrypt_rescan_req,1 ); zdev->online =0 ;pr_err ("Cryptographic device %x failed and was set offline\n" , - zdev->ap_dev->qid); +AP_QID_DEVICE (zdev->ap_dev->qid));ZCRYPT_DBF_DEV (DBF_ERR , zdev,"dev%04xo%drc%d" , - zdev->ap_dev->qid, zdev->online, ehdr->reply_code); +AP_QID_DEVICE (zdev->ap_dev->qid), zdev->online, + ehdr->reply_code);return -EAGAIN ;default : zdev->online =0 ;pr_err ("Cryptographic device %x failed and was set offline\n" , - zdev->ap_dev->qid); +AP_QID_DEVICE (zdev->ap_dev->qid));ZCRYPT_DBF_DEV (DBF_ERR , zdev,"dev%04xo%drc%d" , - zdev->ap_dev->qid, zdev->online, ehdr->reply_code); +AP_QID_DEVICE (zdev->ap_dev->qid), zdev->online, + ehdr->reply_code);return -EAGAIN ;/* repeat the request on a different device. */ } }
drivers/s390/crypto/zcrypt_msgtype50.c +5 -4
@@ -336,9 +336,10 @@ static int convert_type80(struct zcrypt_device *zdev,/* The result is too short, the CEX2A card may not do that.. */ zdev->online =0 ;pr_err ("Cryptographic device %x failed and was set offline\n" , - zdev->ap_dev->qid); +AP_QID_DEVICE (zdev->ap_dev->qid));ZCRYPT_DBF_DEV (DBF_ERR , zdev,"dev%04xo%drc%d" , - zdev->ap_dev->qid, zdev->online, t80h->code); +AP_QID_DEVICE (zdev->ap_dev->qid), + zdev->online, t80h->code);return -EAGAIN ;/* repeat the request on a different device. */ }
@@ -368,9 +369,9 @@ static int convert_response(struct zcrypt_device *zdev,default :/* Unknown response type, this should NEVER EVER happen */ zdev->online =0 ;pr_err ("Cryptographic device %x failed and was set offline\n" , - zdev->ap_dev->qid); +AP_QID_DEVICE (zdev->ap_dev->qid));ZCRYPT_DBF_DEV (DBF_ERR , zdev,"dev%04xo%dfail" , - zdev->ap_dev->qid, zdev->online); +AP_QID_DEVICE (zdev->ap_dev->qid), zdev->online);return -EAGAIN ;/* repeat the request on a different device. */ } }
drivers/s390/crypto/zcrypt_msgtype6.c +10 -10
@@ -572,9 +572,9 @@ static int convert_type86_ica(struct zcrypt_device *zdev,return -EINVAL ; zdev->online =0 ;pr_err ("Cryptographic device %x failed and was set offline\n" , - zdev->ap_dev->qid); +AP_QID_DEVICE (zdev->ap_dev->qid));ZCRYPT_DBF_DEV (DBF_ERR , zdev,"dev%04xo%drc%d" , - zdev->ap_dev->qid, zdev->online, +AP_QID_DEVICE (zdev->ap_dev->qid), zdev->online, msg->hdr.reply_code);return -EAGAIN ;/* repeat the request on a different device. */ }
@@ -715,9 +715,9 @@ static int convert_response_ica(struct zcrypt_device *zdev,default :/* Unknown response type, this should NEVER EVER happen */ zdev->online =0 ;pr_err ("Cryptographic device %x failed and was set offline\n" , - zdev->ap_dev->qid); +AP_QID_DEVICE (zdev->ap_dev->qid));ZCRYPT_DBF_DEV (DBF_ERR , zdev,"dev%04xo%dfail" , - zdev->ap_dev->qid, zdev->online); +AP_QID_DEVICE (zdev->ap_dev->qid), zdev->online);return -EAGAIN ;/* repeat the request on a different device. */ } }
@@ -747,9 +747,9 @@ static int convert_response_xcrb(struct zcrypt_device *zdev, xcRB->status =0x0008044DL ;/* HDD_InvalidParm */ zdev->online =0 ;pr_err ("Cryptographic device %x failed and was set offline\n" , - zdev->ap_dev->qid); +AP_QID_DEVICE (zdev->ap_dev->qid));ZCRYPT_DBF_DEV (DBF_ERR , zdev,"dev%04xo%dfail" , - zdev->ap_dev->qid, zdev->online); +AP_QID_DEVICE (zdev->ap_dev->qid), zdev->online);return -EAGAIN ;/* repeat the request on a different device. */ } }
@@ -773,9 +773,9 @@ static int convert_response_ep11_xcrb(struct zcrypt_device *zdev,default :/* Unknown response type, this should NEVER EVER happen */ zdev->online =0 ;pr_err ("Cryptographic device %x failed and was set offline\n" , - zdev->ap_dev->qid); +AP_QID_DEVICE (zdev->ap_dev->qid));ZCRYPT_DBF_DEV (DBF_ERR , zdev,"dev%04xo%dfail" , - zdev->ap_dev->qid, zdev->online); +AP_QID_DEVICE (zdev->ap_dev->qid), zdev->online);return -EAGAIN ;/* repeat the request on a different device. */ } }
@@ -800,9 +800,9 @@ static int convert_response_rng(struct zcrypt_device *zdev,default :/* Unknown response type, this should NEVER EVER happen */ zdev->online =0 ;pr_err ("Cryptographic device %x failed and was set offline\n" , - zdev->ap_dev->qid); +AP_QID_DEVICE (zdev->ap_dev->qid));ZCRYPT_DBF_DEV (DBF_ERR , zdev,"dev%04xo%dfail" , - zdev->ap_dev->qid, zdev->online); +AP_QID_DEVICE (zdev->ap_dev->qid), zdev->online);return -EAGAIN ;/* repeat the request on a different device. */ } }