s390 fixes for 5.8-rc2

- Few ptrace fixes mostly for strace and seccomp_bpf kernel tests
   findings.
 
 - Cleanup unused pm callbacks in virtio ccw.
 
 - Replace kmalloc + memset with kzalloc in crypto.
 
 - Use $(LD) for vDSO linkage to make clang happy.
 
 - Fix vDSO clock_getres() to preserve the same behaviour as
   posix_get_hrtimer_res().
 
 - Fix workqueue cpumask warning when NUMA=n and nr_node_ids=2.
 
 - Reduce SLSB writes during input processing, improve warnings and
   cleanup qdio_data usage in qdio.
 
 - Few fixes to use scnprintf() instead of snprintf().
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCAAdFiEE3QHqV+H2a8xAv27vjYWKoQLXFBgFAl7uJy8ACgkQjYWKoQLX
 FBitMwgAovHP6O19ZS2RE2Ps20CjM+z0sLLGHF6aMrV7OqmOWrNnFzN4jT2j42Ck
 idSZ6sehVd3Uj6K8NnzrlSS3sjGRhVaQJEjjN+rLyw0HBwxspJJfW5HgcoMtqNH1
 oo+nt+zw5jk+6MqHx4QEwTxN5rgGs6UMhiLIAIlkDu4bivgohvGUxe4RUrN/mINx
 cdYqomCkvovLT5sBTaWyXKNCDAdAWgNpOfdqc9MjOUXSbUg3lrUol0gUULzenPo7
 wUN+sZ0di0Ox0+2+4m8LU1av/kMTLSSvnR9DW5KdpGTon1nwpZcdJnhI5o1v7uaU
 pIaMOYNieEHJ2DnieR9iBBSbGoNCmw==
 =gkgN
 -----END PGP SIGNATURE-----

Merge tag 's390-5.8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 fixes from Vasily Gorbik:

 - a few ptrace fixes mostly for strace and seccomp_bpf kernel tests
   findings

 - cleanup unused pm callbacks in virtio ccw

 - replace kmalloc + memset with kzalloc in crypto

 - use $(LD) for vDSO linkage to make clang happy

 - fix vDSO clock_getres() to preserve the same behaviour as
   posix_get_hrtimer_res()

 - fix workqueue cpumask warning when NUMA=n and nr_node_ids=2

 - reduce SLSB writes during input processing, improve warnings and
   cleanup qdio_data usage in qdio

 - a few fixes to use scnprintf() instead of snprintf()

* tag 's390-5.8-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390: fix syscall_get_error for compat processes
  s390/qdio: warn about unexpected SLSB states
  s390/qdio: clean up usage of qdio_data
  s390/numa: let NODES_SHIFT depend on NEED_MULTIPLE_NODES
  s390/vdso: fix vDSO clock_getres()
  s390/vdso: Use $(LD) instead of $(CC) to link vDSO
  s390/protvirt: use scnprintf() instead of snprintf()
  s390: use scnprintf() in sys_##_prefix##_##_name##_show
  s390/crypto: use scnprintf() instead of snprintf()
  s390/zcrypt: use kzalloc
  s390/virtio: remove unused pm callbacks
  s390/qdio: reduce SLSB writes during Input Queue processing
  selftests/seccomp: s390 shares the syscall and return value register
  s390/ptrace: fix setting syscall number
  s390/ptrace: pass invalid syscall numbers to tracing
  s390/ptrace: return -ENOSYS when invalid syscall is supplied
  s390/seccomp: pass syscall arguments via seccomp_data
  s390/qdio: fine-tune SLSB update
This commit is contained in:
Linus Torvalds 2020-06-20 12:31:08 -07:00
commit 1566feea45
18 changed files with 154 additions and 134 deletions

View File

@ -462,6 +462,7 @@ config NUMA
config NODES_SHIFT
int
depends on NEED_MULTIPLE_NODES
default "1"
config SCHED_SMT

View File

@ -693,7 +693,7 @@ static ssize_t prng_chunksize_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%u\n", prng_chunk_size);
return scnprintf(buf, PAGE_SIZE, "%u\n", prng_chunk_size);
}
static DEVICE_ATTR(chunksize, 0444, prng_chunksize_show, NULL);
@ -712,7 +712,7 @@ static ssize_t prng_counter_show(struct device *dev,
counter = prng_data->prngws.byte_counter;
mutex_unlock(&prng_data->mutex);
return snprintf(buf, PAGE_SIZE, "%llu\n", counter);
return scnprintf(buf, PAGE_SIZE, "%llu\n", counter);
}
static DEVICE_ATTR(byte_counter, 0444, prng_counter_show, NULL);
@ -721,7 +721,7 @@ static ssize_t prng_errorflag_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", prng_errorflag);
return scnprintf(buf, PAGE_SIZE, "%d\n", prng_errorflag);
}
static DEVICE_ATTR(errorflag, 0444, prng_errorflag_show, NULL);
@ -731,9 +731,9 @@ static ssize_t prng_mode_show(struct device *dev,
char *buf)
{
if (prng_mode == PRNG_MODE_TDES)
return snprintf(buf, PAGE_SIZE, "TDES\n");
return scnprintf(buf, PAGE_SIZE, "TDES\n");
else
return snprintf(buf, PAGE_SIZE, "SHA512\n");
return scnprintf(buf, PAGE_SIZE, "SHA512\n");
}
static DEVICE_ATTR(mode, 0444, prng_mode_show, NULL);
@ -756,7 +756,7 @@ static ssize_t prng_reseed_limit_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%u\n", prng_reseed_limit);
return scnprintf(buf, PAGE_SIZE, "%u\n", prng_reseed_limit);
}
static ssize_t prng_reseed_limit_store(struct device *dev,
struct device_attribute *attr,
@ -787,7 +787,7 @@ static ssize_t prng_strength_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "256\n");
return scnprintf(buf, PAGE_SIZE, "256\n");
}
static DEVICE_ATTR(strength, 0444, prng_strength_show, NULL);

View File

@ -33,7 +33,17 @@ static inline void syscall_rollback(struct task_struct *task,
static inline long syscall_get_error(struct task_struct *task,
struct pt_regs *regs)
{
return IS_ERR_VALUE(regs->gprs[2]) ? regs->gprs[2] : 0;
unsigned long error = regs->gprs[2];
#ifdef CONFIG_COMPAT
if (test_tsk_thread_flag(task, TIF_31BIT)) {
/*
* Sign-extend the value so (int)-EFOO becomes (long)-EFOO
* and will match correctly in comparisons.
*/
error = (long)(int)error;
}
#endif
return IS_ERR_VALUE(error) ? error : 0;
}
static inline long syscall_get_return_value(struct task_struct *task,

View File

@ -36,6 +36,7 @@ struct vdso_data {
__u32 tk_shift; /* Shift used for xtime_nsec 0x60 */
__u32 ts_dir; /* TOD steering direction 0x64 */
__u64 ts_end; /* TOD steering end 0x68 */
__u32 hrtimer_res; /* hrtimer resolution 0x70 */
};
struct vdso_per_cpu_data {

View File

@ -76,6 +76,7 @@ int main(void)
OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift);
OFFSET(__VDSO_TS_DIR, vdso_data, ts_dir);
OFFSET(__VDSO_TS_END, vdso_data, ts_end);
OFFSET(__VDSO_CLOCK_REALTIME_RES, vdso_data, hrtimer_res);
OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base);
OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time);
OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val);
@ -86,7 +87,6 @@ int main(void)
DEFINE(__CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
DEFINE(__CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
DEFINE(__CLOCK_THREAD_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID);
DEFINE(__CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
DEFINE(__CLOCK_COARSE_RES, LOW_RES_NSEC);
BLANK();
/* idle data offsets */

View File

@ -401,9 +401,9 @@ ENTRY(system_call)
jnz .Lsysc_nr_ok
# svc 0: system call number in %r1
llgfr %r1,%r1 # clear high word in r1
sth %r1,__PT_INT_CODE+2(%r11)
cghi %r1,NR_syscalls
jnl .Lsysc_nr_ok
sth %r1,__PT_INT_CODE+2(%r11)
slag %r8,%r1,3
.Lsysc_nr_ok:
xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)

View File

@ -181,7 +181,7 @@ static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj, \
struct kobj_attribute *attr, \
char *page) \
{ \
return snprintf(page, PAGE_SIZE, _format, ##args); \
return scnprintf(page, PAGE_SIZE, _format, ##args); \
}
#define IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk) \

View File

@ -323,6 +323,25 @@ static inline void __poke_user_per(struct task_struct *child,
child->thread.per_user.end = data;
}
static void fixup_int_code(struct task_struct *child, addr_t data)
{
struct pt_regs *regs = task_pt_regs(child);
int ilc = regs->int_code >> 16;
u16 insn;
if (ilc > 6)
return;
if (ptrace_access_vm(child, regs->psw.addr - (regs->int_code >> 16),
&insn, sizeof(insn), FOLL_FORCE) != sizeof(insn))
return;
/* double check that tracee stopped on svc instruction */
if ((insn >> 8) != 0xa)
return;
regs->int_code = 0x20000 | (data & 0xffff);
}
/*
* Write a word to the user area of a process at location addr. This
* operation does have an additional problem compared to peek_user.
@ -334,7 +353,9 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
struct user *dummy = NULL;
addr_t offset;
if (addr < (addr_t) &dummy->regs.acrs) {
struct pt_regs *regs = task_pt_regs(child);
/*
* psw and gprs are stored on the stack
*/
@ -352,7 +373,11 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
/* Invalid addressing mode bits */
return -EINVAL;
}
*(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
if (test_pt_regs_flag(regs, PIF_SYSCALL) &&
addr == offsetof(struct user, regs.gprs[2]))
fixup_int_code(child, data);
*(addr_t *)((addr_t) &regs->psw + addr) = data;
} else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
/*
@ -718,6 +743,10 @@ static int __poke_user_compat(struct task_struct *child,
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) |
(__u64)(tmp & PSW32_ADDR_AMODE);
} else {
if (test_pt_regs_flag(regs, PIF_SYSCALL) &&
addr == offsetof(struct compat_user, regs.gprs[2]))
fixup_int_code(child, data);
/* gpr 0-15 */
*(__u32*)((addr_t) &regs->psw + addr*2 + 4) = tmp;
}
@ -837,40 +866,66 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
{
unsigned long mask = -1UL;
long ret = -1;
if (is_compat_task())
mask = 0xffffffff;
/*
* The sysc_tracesys code in entry.S stored the system
* call number to gprs[2].
*/
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
(tracehook_report_syscall_entry(regs) ||
regs->gprs[2] >= NR_syscalls)) {
tracehook_report_syscall_entry(regs)) {
/*
* Tracing decided this syscall should not happen or the
* debugger stored an invalid system call number. Skip
* Tracing decided this syscall should not happen. Skip
* the system call and the system call restart handling.
*/
clear_pt_regs_flag(regs, PIF_SYSCALL);
return -1;
goto skip;
}
#ifdef CONFIG_SECCOMP
/* Do the secure computing check after ptrace. */
if (secure_computing()) {
/* seccomp failures shouldn't expose any additional code. */
return -1;
if (unlikely(test_thread_flag(TIF_SECCOMP))) {
struct seccomp_data sd;
if (is_compat_task()) {
sd.instruction_pointer = regs->psw.addr & 0x7fffffff;
sd.arch = AUDIT_ARCH_S390;
} else {
sd.instruction_pointer = regs->psw.addr;
sd.arch = AUDIT_ARCH_S390X;
}
sd.nr = regs->int_code & 0xffff;
sd.args[0] = regs->orig_gpr2 & mask;
sd.args[1] = regs->gprs[3] & mask;
sd.args[2] = regs->gprs[4] & mask;
sd.args[3] = regs->gprs[5] & mask;
sd.args[4] = regs->gprs[6] & mask;
sd.args[5] = regs->gprs[7] & mask;
if (__secure_computing(&sd) == -1)
goto skip;
}
#endif /* CONFIG_SECCOMP */
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
trace_sys_enter(regs, regs->gprs[2]);
trace_sys_enter(regs, regs->int_code & 0xffff);
if (is_compat_task())
mask = 0xffffffff;
audit_syscall_entry(regs->gprs[2], regs->orig_gpr2 & mask,
audit_syscall_entry(regs->int_code & 0xffff, regs->orig_gpr2 & mask,
regs->gprs[3] &mask, regs->gprs[4] &mask,
regs->gprs[5] &mask);
if ((signed long)regs->gprs[2] >= NR_syscalls) {
regs->gprs[2] = -ENOSYS;
ret = -ENOSYS;
}
return regs->gprs[2];
skip:
clear_pt_regs_flag(regs, PIF_SYSCALL);
return ret;
}
asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)

View File

@ -301,6 +301,7 @@ void update_vsyscall(struct timekeeper *tk)
vdso_data->tk_mult = tk->tkr_mono.mult;
vdso_data->tk_shift = tk->tkr_mono.shift;
vdso_data->hrtimer_res = hrtimer_resolution;
smp_wmb();
++vdso_data->tb_update_count;
}

View File

@ -331,7 +331,7 @@ EXPORT_SYMBOL_GPL(arch_make_page_accessible);
static ssize_t uv_query_facilities(struct kobject *kobj,
struct kobj_attribute *attr, char *page)
{
return snprintf(page, PAGE_SIZE, "%lx\n%lx\n%lx\n%lx\n",
return scnprintf(page, PAGE_SIZE, "%lx\n%lx\n%lx\n%lx\n",
uv_info.inst_calls_list[0],
uv_info.inst_calls_list[1],
uv_info.inst_calls_list[2],
@ -344,7 +344,7 @@ static struct kobj_attribute uv_query_facilities_attr =
static ssize_t uv_query_max_guest_cpus(struct kobject *kobj,
struct kobj_attribute *attr, char *page)
{
return snprintf(page, PAGE_SIZE, "%d\n",
return scnprintf(page, PAGE_SIZE, "%d\n",
uv_info.max_guest_cpus);
}
@ -354,7 +354,7 @@ static struct kobj_attribute uv_query_max_guest_cpus_attr =
static ssize_t uv_query_max_guest_vms(struct kobject *kobj,
struct kobj_attribute *attr, char *page)
{
return snprintf(page, PAGE_SIZE, "%d\n",
return scnprintf(page, PAGE_SIZE, "%d\n",
uv_info.max_num_sec_conf);
}
@ -364,7 +364,7 @@ static struct kobj_attribute uv_query_max_guest_vms_attr =
static ssize_t uv_query_max_guest_addr(struct kobject *kobj,
struct kobj_attribute *attr, char *page)
{
return snprintf(page, PAGE_SIZE, "%lx\n",
return scnprintf(page, PAGE_SIZE, "%lx\n",
uv_info.max_sec_stor_addr);
}

View File

@ -18,8 +18,8 @@ KBUILD_AFLAGS_64 += -m64 -s
KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS))
KBUILD_CFLAGS_64 += -m64 -fPIC -shared -fno-common -fno-builtin
KBUILD_CFLAGS_64 += -nostdlib -Wl,-soname=linux-vdso64.so.1 \
-Wl,--hash-style=both
ldflags-y := -fPIC -shared -nostdlib -soname=linux-vdso64.so.1 \
--hash-style=both --build-id -T
$(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64)
$(targets:%=$(obj)/%.dbg): KBUILD_AFLAGS = $(KBUILD_AFLAGS_64)
@ -37,8 +37,8 @@ KASAN_SANITIZE := n
$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so
# link rule for the .so file, .lds has to be first
$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) FORCE
$(call if_changed,vdso64ld)
$(obj)/vdso64.so.dbg: $(obj)/vdso64.lds $(obj-vdso64) FORCE
$(call if_changed,ld)
# strip rule for the .so file
$(obj)/%.so: OBJCOPYFLAGS := -S
@ -50,8 +50,6 @@ $(obj-vdso64): %.o: %.S FORCE
$(call if_changed_dep,vdso64as)
# actual build commands
quiet_cmd_vdso64ld = VDSO64L $@
cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $(filter %.lds %.o,$^) -o $@
quiet_cmd_vdso64as = VDSO64A $@
cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<

View File

@ -17,12 +17,14 @@
.type __kernel_clock_getres,@function
__kernel_clock_getres:
CFI_STARTPROC
larl %r1,4f
larl %r1,3f
lg %r0,0(%r1)
cghi %r2,__CLOCK_REALTIME_COARSE
je 0f
cghi %r2,__CLOCK_MONOTONIC_COARSE
je 0f
larl %r1,3f
larl %r1,_vdso_data
llgf %r0,__VDSO_CLOCK_REALTIME_RES(%r1)
cghi %r2,__CLOCK_REALTIME
je 0f
cghi %r2,__CLOCK_MONOTONIC
@ -36,7 +38,6 @@ __kernel_clock_getres:
jz 2f
0: ltgr %r3,%r3
jz 1f /* res == NULL */
lg %r0,0(%r1)
xc 0(8,%r3),0(%r3) /* set tp->tv_sec to zero */
stg %r0,8(%r3) /* store tp->tv_usec */
1: lghi %r2,0
@ -45,6 +46,5 @@ __kernel_clock_getres:
svc 0
br %r14
CFI_ENDPROC
3: .quad __CLOCK_REALTIME_RES
4: .quad __CLOCK_COARSE_RES
3: .quad __CLOCK_COARSE_RES
.size __kernel_clock_getres,.-__kernel_clock_getres

View File

@ -182,10 +182,9 @@ enum qdio_irq_poll_states {
};
struct qdio_input_q {
/* first ACK'ed buffer */
int ack_start;
/* how many SBALs are acknowledged */
int ack_count;
/* Batch of SBALs that we processed while polling the queue: */
unsigned int batch_start;
unsigned int batch_count;
/* last time of noticing incoming data */
u64 timestamp;
};

View File

@ -110,8 +110,8 @@ static int qstat_show(struct seq_file *m, void *v)
seq_printf(m, "nr_used: %d ftc: %d\n",
atomic_read(&q->nr_buf_used), q->first_to_check);
if (q->is_input_q) {
seq_printf(m, "ack start: %d ack count: %d\n",
q->u.in.ack_start, q->u.in.ack_count);
seq_printf(m, "batch start: %u batch count: %u\n",
q->u.in.batch_start, q->u.in.batch_count);
seq_printf(m, "DSCI: %x IRQs disabled: %u\n",
*(u8 *)q->irq_ptr->dsci,
test_bit(QDIO_IRQ_DISABLED,

View File

@ -254,10 +254,17 @@ static inline int set_buf_states(struct qdio_q *q, int bufnr,
if (is_qebsm(q))
return qdio_do_sqbs(q, state, bufnr, count);
/* Ensure that all preceding changes to the SBALs are visible: */
mb();
for (i = 0; i < count; i++) {
xchg(&q->slsb.val[bufnr], state);
WRITE_ONCE(q->slsb.val[bufnr], state);
bufnr = next_buf(bufnr);
}
/* Make our SLSB changes visible: */
mb();
return count;
}
@ -393,15 +400,15 @@ int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
static inline void qdio_stop_polling(struct qdio_q *q)
{
if (!q->u.in.ack_count)
if (!q->u.in.batch_count)
return;
qperf_inc(q, stop_polling);
/* show the card that we are not polling anymore */
set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
q->u.in.ack_count);
q->u.in.ack_count = 0;
set_buf_states(q, q->u.in.batch_start, SLSB_P_INPUT_NOT_INIT,
q->u.in.batch_count);
q->u.in.batch_count = 0;
}
static inline void account_sbals(struct qdio_q *q, unsigned int count)
@ -441,42 +448,13 @@ static void process_buffer_error(struct qdio_q *q, unsigned int start,
static inline void inbound_handle_work(struct qdio_q *q, unsigned int start,
int count, bool auto_ack)
{
int new;
/* ACK the newest SBAL: */
if (!auto_ack)
set_buf_state(q, add_buf(start, count - 1), SLSB_P_INPUT_ACK);
if (auto_ack) {
if (!q->u.in.ack_count) {
q->u.in.ack_count = count;
q->u.in.ack_start = start;
return;
}
/* delete the previous ACK's */
set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
q->u.in.ack_count);
q->u.in.ack_count = count;
q->u.in.ack_start = start;
return;
}
/*
* ACK the newest buffer. The ACK will be removed in qdio_stop_polling
* or by the next inbound run.
*/
new = add_buf(start, count - 1);
set_buf_state(q, new, SLSB_P_INPUT_ACK);
/* delete the previous ACKs */
if (q->u.in.ack_count)
set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
q->u.in.ack_count);
q->u.in.ack_count = 1;
q->u.in.ack_start = new;
count--;
if (!count)
return;
/* need to change ALL buffers to get more interrupts */
set_buf_states(q, start, SLSB_P_INPUT_NOT_INIT, count);
if (!q->u.in.batch_count)
q->u.in.batch_start = start;
q->u.in.batch_count += count;
}
static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start)
@ -525,15 +503,18 @@ static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start)
account_sbals_error(q, count);
return count;
case SLSB_CU_INPUT_EMPTY:
case SLSB_P_INPUT_NOT_INIT:
case SLSB_P_INPUT_ACK:
if (q->irq_ptr->perf_stat_enabled)
q->q_stats.nr_sbal_nop++;
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop:%1d %#02x",
q->nr, start);
return 0;
case SLSB_P_INPUT_NOT_INIT:
case SLSB_P_INPUT_ACK:
/* We should never see this state, throw a WARN: */
default:
WARN_ON_ONCE(1);
dev_WARN_ONCE(&q->irq_ptr->cdev->dev, 1,
"found state %#x at index %u on queue %u\n",
state, start, q->nr);
return 0;
}
}
@ -738,11 +719,14 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start)
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out primed:%1d",
q->nr);
return 0;
case SLSB_P_OUTPUT_NOT_INIT:
case SLSB_P_OUTPUT_HALTED:
return 0;
case SLSB_P_OUTPUT_NOT_INIT:
/* We should never see this state, throw a WARN: */
default:
WARN_ON_ONCE(1);
dev_WARN_ONCE(&q->irq_ptr->cdev->dev, 1,
"found state %#x at index %u on queue %u\n",
state, start, q->nr);
return 0;
}
}
@ -938,10 +922,10 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr)
}
}
static void qdio_handle_activate_check(struct ccw_device *cdev,
unsigned long intparm, int cstat, int dstat)
static void qdio_handle_activate_check(struct qdio_irq *irq_ptr,
unsigned long intparm, int cstat,
int dstat)
{
struct qdio_irq *irq_ptr = cdev->private->qdio_data;
struct qdio_q *q;
DBF_ERROR("%4x ACT CHECK", irq_ptr->schid.sch_no);
@ -968,11 +952,9 @@ no_handler:
lgr_info_log();
}
static void qdio_establish_handle_irq(struct ccw_device *cdev, int cstat,
static void qdio_establish_handle_irq(struct qdio_irq *irq_ptr, int cstat,
int dstat)
{
struct qdio_irq *irq_ptr = cdev->private->qdio_data;
DBF_DEV_EVENT(DBF_INFO, irq_ptr, "qest irq");
if (cstat)
@ -1019,7 +1001,7 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
switch (irq_ptr->state) {
case QDIO_IRQ_STATE_INACTIVE:
qdio_establish_handle_irq(cdev, cstat, dstat);
qdio_establish_handle_irq(irq_ptr, cstat, dstat);
break;
case QDIO_IRQ_STATE_CLEANUP:
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
@ -1031,7 +1013,7 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
return;
}
if (cstat || dstat)
qdio_handle_activate_check(cdev, intparm, cstat,
qdio_handle_activate_check(irq_ptr, intparm, cstat,
dstat);
break;
case QDIO_IRQ_STATE_STOPPED:
@ -1446,12 +1428,12 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags,
qperf_inc(q, inbound_call);
/* If any ACKed SBALs are returned to HW, adjust ACK tracking: */
overlap = min(count - sub_buf(q->u.in.ack_start, bufnr),
q->u.in.ack_count);
/* If any processed SBALs are returned to HW, adjust our tracking: */
overlap = min_t(int, count - sub_buf(q->u.in.batch_start, bufnr),
q->u.in.batch_count);
if (overlap > 0) {
q->u.in.ack_start = add_buf(q->u.in.ack_start, overlap);
q->u.in.ack_count -= overlap;
q->u.in.batch_start = add_buf(q->u.in.batch_start, overlap);
q->u.in.batch_count -= overlap;
}
count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count);
@ -1535,12 +1517,11 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
int q_nr, unsigned int bufnr, unsigned int count)
{
struct qdio_irq *irq_ptr;
struct qdio_irq *irq_ptr = cdev->private->qdio_data;
if (bufnr >= QDIO_MAX_BUFFERS_PER_Q || count > QDIO_MAX_BUFFERS_PER_Q)
return -EINVAL;
irq_ptr = cdev->private->qdio_data;
if (!irq_ptr)
return -ENODEV;

View File

@ -195,11 +195,10 @@ static inline struct ep11_cprb *alloc_cprb(size_t payload_len)
size_t len = sizeof(struct ep11_cprb) + payload_len;
struct ep11_cprb *cprb;
cprb = kmalloc(len, GFP_KERNEL);
cprb = kzalloc(len, GFP_KERNEL);
if (!cprb)
return NULL;
memset(cprb, 0, len);
cprb->cprb_len = sizeof(struct ep11_cprb);
cprb->cprb_ver_id = 0x04;
memcpy(cprb->func_id, "T4", 2);

View File

@ -1372,27 +1372,6 @@ static struct ccw_device_id virtio_ids[] = {
{},
};
#ifdef CONFIG_PM_SLEEP
static int virtio_ccw_freeze(struct ccw_device *cdev)
{
struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
return virtio_device_freeze(&vcdev->vdev);
}
static int virtio_ccw_restore(struct ccw_device *cdev)
{
struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev);
int ret;
ret = virtio_ccw_set_transport_rev(vcdev);
if (ret)
return ret;
return virtio_device_restore(&vcdev->vdev);
}
#endif
static struct ccw_driver virtio_ccw_driver = {
.driver = {
.owner = THIS_MODULE,
@ -1405,11 +1384,6 @@ static struct ccw_driver virtio_ccw_driver = {
.set_online = virtio_ccw_online,
.notify = virtio_ccw_cio_notify,
.int_class = IRQIO_VIR,
#ifdef CONFIG_PM_SLEEP
.freeze = virtio_ccw_freeze,
.thaw = virtio_ccw_restore,
.restore = virtio_ccw_restore,
#endif
};
static int __init pure_hex(char **cp, unsigned int *val, int min_digit,

View File

@ -1615,6 +1615,7 @@ TEST_F(TRACE_poke, getpid_runs_normally)
# define ARCH_REGS s390_regs
# define SYSCALL_NUM gprs[2]
# define SYSCALL_RET gprs[2]
# define SYSCALL_NUM_RET_SHARE_REG
#elif defined(__mips__)
# define ARCH_REGS struct pt_regs
# define SYSCALL_NUM regs[2]