Skip to content

Commit 320437a

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Martin Schwidefsky: "Several last minute bug fixes. Two of them are on the larger side for rc7, the dasd format patch for older storage devices and the store-clock-fast patch where we have been to optimistic with an optimization" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/time: correct use of store clock fast s390/vmlogrdr: fix array access in vmlogrdr_open() s390/compat,signal: fix return value of copy_siginfo_(to|from)_user32() s390/dasd: check for availability of prefix command during format s390/mm,kvm: fix software dirty bits vs. kvm for old machines
2 parents 9033832 + 8c071b0 commit 320437a

File tree

11 files changed

+111
-65
lines changed

11 files changed

+111
-65
lines changed

arch/s390/include/asm/pgtable.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,9 @@ static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry)
748748

749749
static inline void pgste_set_pte(pte_t *ptep, pte_t entry)
750750
{
751-
if (!MACHINE_HAS_ESOP && (pte_val(entry) & _PAGE_WRITE)) {
751+
if (!MACHINE_HAS_ESOP &&
752+
(pte_val(entry) & _PAGE_PRESENT) &&
753+
(pte_val(entry) & _PAGE_WRITE)) {
752754
/*
753755
* Without enhanced suppression-on-protection force
754756
* the dirty bit on for all writable ptes.

arch/s390/include/asm/timex.h

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,30 +71,30 @@ static inline void local_tick_enable(unsigned long long comp)
7171

7272
typedef unsigned long long cycles_t;
7373

74-
static inline unsigned long long get_tod_clock(void)
75-
{
76-
unsigned long long clk;
77-
78-
#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
79-
asm volatile(".insn s,0xb27c0000,%0" : "=Q" (clk) : : "cc");
80-
#else
81-
asm volatile("stck %0" : "=Q" (clk) : : "cc");
82-
#endif
83-
return clk;
84-
}
85-
8674
static inline void get_tod_clock_ext(char *clk)
8775
{
8876
asm volatile("stcke %0" : "=Q" (*clk) : : "cc");
8977
}
9078

91-
static inline unsigned long long get_tod_clock_xt(void)
79+
static inline unsigned long long get_tod_clock(void)
9280
{
9381
unsigned char clk[16];
9482
get_tod_clock_ext(clk);
9583
return *((unsigned long long *)&clk[1]);
9684
}
9785

86+
static inline unsigned long long get_tod_clock_fast(void)
87+
{
88+
#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
89+
unsigned long long clk;
90+
91+
asm volatile("stckf %0" : "=Q" (clk) : : "cc");
92+
return clk;
93+
#else
94+
return get_tod_clock();
95+
#endif
96+
}
97+
9898
static inline cycles_t get_cycles(void)
9999
{
100100
return (cycles_t) get_tod_clock() >> 2;
@@ -125,7 +125,7 @@ extern u64 sched_clock_base_cc;
125125
*/
126126
static inline unsigned long long get_tod_clock_monotonic(void)
127127
{
128-
return get_tod_clock_xt() - sched_clock_base_cc;
128+
return get_tod_clock() - sched_clock_base_cc;
129129
}
130130

131131
/**

arch/s390/kernel/compat_signal.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
9999
break;
100100
}
101101
}
102-
return err;
102+
return err ? -EFAULT : 0;
103103
}
104104

105105
int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
@@ -148,7 +148,7 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
148148
break;
149149
}
150150
}
151-
return err;
151+
return err ? -EFAULT : 0;
152152
}
153153

154154
static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)

arch/s390/kernel/debug.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ static inline void
867867
debug_finish_entry(debug_info_t * id, debug_entry_t* active, int level,
868868
int exception)
869869
{
870-
active->id.stck = get_tod_clock();
870+
active->id.stck = get_tod_clock_fast();
871871
active->id.fields.cpuid = smp_processor_id();
872872
active->caller = __builtin_return_address(0);
873873
active->id.fields.exception = exception;

arch/s390/kvm/interrupt.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ static int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu)
385385
}
386386

387387
if ((!rc) && (vcpu->arch.sie_block->ckc <
388-
get_tod_clock() + vcpu->arch.sie_block->epoch)) {
388+
get_tod_clock_fast() + vcpu->arch.sie_block->epoch)) {
389389
if ((!psw_extint_disabled(vcpu)) &&
390390
(vcpu->arch.sie_block->gcr[0] & 0x800ul))
391391
rc = 1;
@@ -425,7 +425,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
425425
goto no_timer;
426426
}
427427

428-
now = get_tod_clock() + vcpu->arch.sie_block->epoch;
428+
now = get_tod_clock_fast() + vcpu->arch.sie_block->epoch;
429429
if (vcpu->arch.sie_block->ckc < now) {
430430
__unset_cpu_idle(vcpu);
431431
return 0;
@@ -515,7 +515,7 @@ void kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
515515
}
516516

517517
if ((vcpu->arch.sie_block->ckc <
518-
get_tod_clock() + vcpu->arch.sie_block->epoch))
518+
get_tod_clock_fast() + vcpu->arch.sie_block->epoch))
519519
__try_deliver_ckc_interrupt(vcpu);
520520

521521
if (atomic_read(&fi->active)) {

arch/s390/lib/delay.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ static void __udelay_disabled(unsigned long long usecs)
4444
do {
4545
set_clock_comparator(end);
4646
vtime_stop_cpu();
47-
} while (get_tod_clock() < end);
47+
} while (get_tod_clock_fast() < end);
4848
lockdep_on();
4949
__ctl_load(cr0, 0, 0);
5050
__ctl_load(cr6, 6, 6);
@@ -55,7 +55,7 @@ static void __udelay_enabled(unsigned long long usecs)
5555
{
5656
u64 clock_saved, end;
5757

58-
end = get_tod_clock() + (usecs << 12);
58+
end = get_tod_clock_fast() + (usecs << 12);
5959
do {
6060
clock_saved = 0;
6161
if (end < S390_lowcore.clock_comparator) {
@@ -65,7 +65,7 @@ static void __udelay_enabled(unsigned long long usecs)
6565
vtime_stop_cpu();
6666
if (clock_saved)
6767
local_tick_enable(clock_saved);
68-
} while (get_tod_clock() < end);
68+
} while (get_tod_clock_fast() < end);
6969
}
7070

7171
/*
@@ -109,8 +109,8 @@ void udelay_simple(unsigned long long usecs)
109109
{
110110
u64 end;
111111

112-
end = get_tod_clock() + (usecs << 12);
113-
while (get_tod_clock() < end)
112+
end = get_tod_clock_fast() + (usecs << 12);
113+
while (get_tod_clock_fast() < end)
114114
cpu_relax();
115115
}
116116

@@ -120,10 +120,10 @@ void __ndelay(unsigned long long nsecs)
120120

121121
nsecs <<= 9;
122122
do_div(nsecs, 125);
123-
end = get_tod_clock() + nsecs;
123+
end = get_tod_clock_fast() + nsecs;
124124
if (nsecs & ~0xfffUL)
125125
__udelay(nsecs >> 12);
126-
while (get_tod_clock() < end)
126+
while (get_tod_clock_fast() < end)
127127
barrier();
128128
}
129129
EXPORT_SYMBOL(__ndelay);

drivers/s390/block/dasd_eckd.c

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2077,6 +2077,7 @@ dasd_eckd_build_format(struct dasd_device *base,
20772077
int intensity = 0;
20782078
int r0_perm;
20792079
int nr_tracks;
2080+
int use_prefix;
20802081

20812082
startdev = dasd_alias_get_start_dev(base);
20822083
if (!startdev)
@@ -2106,28 +2107,46 @@ dasd_eckd_build_format(struct dasd_device *base,
21062107
intensity = fdata->intensity;
21072108
}
21082109

2110+
use_prefix = base_priv->features.feature[8] & 0x01;
2111+
21092112
switch (intensity) {
21102113
case 0x00: /* Normal format */
21112114
case 0x08: /* Normal format, use cdl. */
21122115
cplength = 2 + (rpt*nr_tracks);
2113-
datasize = sizeof(struct PFX_eckd_data) +
2114-
sizeof(struct LO_eckd_data) +
2115-
rpt * nr_tracks * sizeof(struct eckd_count);
2116+
if (use_prefix)
2117+
datasize = sizeof(struct PFX_eckd_data) +
2118+
sizeof(struct LO_eckd_data) +
2119+
rpt * nr_tracks * sizeof(struct eckd_count);
2120+
else
2121+
datasize = sizeof(struct DE_eckd_data) +
2122+
sizeof(struct LO_eckd_data) +
2123+
rpt * nr_tracks * sizeof(struct eckd_count);
21162124
break;
21172125
case 0x01: /* Write record zero and format track. */
21182126
case 0x09: /* Write record zero and format track, use cdl. */
21192127
cplength = 2 + rpt * nr_tracks;
2120-
datasize = sizeof(struct PFX_eckd_data) +
2121-
sizeof(struct LO_eckd_data) +
2122-
sizeof(struct eckd_count) +
2123-
rpt * nr_tracks * sizeof(struct eckd_count);
2128+
if (use_prefix)
2129+
datasize = sizeof(struct PFX_eckd_data) +
2130+
sizeof(struct LO_eckd_data) +
2131+
sizeof(struct eckd_count) +
2132+
rpt * nr_tracks * sizeof(struct eckd_count);
2133+
else
2134+
datasize = sizeof(struct DE_eckd_data) +
2135+
sizeof(struct LO_eckd_data) +
2136+
sizeof(struct eckd_count) +
2137+
rpt * nr_tracks * sizeof(struct eckd_count);
21242138
break;
21252139
case 0x04: /* Invalidate track. */
21262140
case 0x0c: /* Invalidate track, use cdl. */
21272141
cplength = 3;
2128-
datasize = sizeof(struct PFX_eckd_data) +
2129-
sizeof(struct LO_eckd_data) +
2130-
sizeof(struct eckd_count);
2142+
if (use_prefix)
2143+
datasize = sizeof(struct PFX_eckd_data) +
2144+
sizeof(struct LO_eckd_data) +
2145+
sizeof(struct eckd_count);
2146+
else
2147+
datasize = sizeof(struct DE_eckd_data) +
2148+
sizeof(struct LO_eckd_data) +
2149+
sizeof(struct eckd_count);
21312150
break;
21322151
default:
21332152
dev_warn(&startdev->cdev->dev,
@@ -2147,14 +2166,25 @@ dasd_eckd_build_format(struct dasd_device *base,
21472166

21482167
switch (intensity & ~0x08) {
21492168
case 0x00: /* Normal format. */
2150-
prefix(ccw++, (struct PFX_eckd_data *) data,
2151-
fdata->start_unit, fdata->stop_unit,
2152-
DASD_ECKD_CCW_WRITE_CKD, base, startdev);
2153-
/* grant subsystem permission to format R0 */
2154-
if (r0_perm)
2155-
((struct PFX_eckd_data *)data)
2156-
->define_extent.ga_extended |= 0x04;
2157-
data += sizeof(struct PFX_eckd_data);
2169+
if (use_prefix) {
2170+
prefix(ccw++, (struct PFX_eckd_data *) data,
2171+
fdata->start_unit, fdata->stop_unit,
2172+
DASD_ECKD_CCW_WRITE_CKD, base, startdev);
2173+
/* grant subsystem permission to format R0 */
2174+
if (r0_perm)
2175+
((struct PFX_eckd_data *)data)
2176+
->define_extent.ga_extended |= 0x04;
2177+
data += sizeof(struct PFX_eckd_data);
2178+
} else {
2179+
define_extent(ccw++, (struct DE_eckd_data *) data,
2180+
fdata->start_unit, fdata->stop_unit,
2181+
DASD_ECKD_CCW_WRITE_CKD, startdev);
2182+
/* grant subsystem permission to format R0 */
2183+
if (r0_perm)
2184+
((struct DE_eckd_data *) data)
2185+
->ga_extended |= 0x04;
2186+
data += sizeof(struct DE_eckd_data);
2187+
}
21582188
ccw[-1].flags |= CCW_FLAG_CC;
21592189
locate_record(ccw++, (struct LO_eckd_data *) data,
21602190
fdata->start_unit, 0, rpt*nr_tracks,
@@ -2163,11 +2193,18 @@ dasd_eckd_build_format(struct dasd_device *base,
21632193
data += sizeof(struct LO_eckd_data);
21642194
break;
21652195
case 0x01: /* Write record zero + format track. */
2166-
prefix(ccw++, (struct PFX_eckd_data *) data,
2167-
fdata->start_unit, fdata->stop_unit,
2168-
DASD_ECKD_CCW_WRITE_RECORD_ZERO,
2169-
base, startdev);
2170-
data += sizeof(struct PFX_eckd_data);
2196+
if (use_prefix) {
2197+
prefix(ccw++, (struct PFX_eckd_data *) data,
2198+
fdata->start_unit, fdata->stop_unit,
2199+
DASD_ECKD_CCW_WRITE_RECORD_ZERO,
2200+
base, startdev);
2201+
data += sizeof(struct PFX_eckd_data);
2202+
} else {
2203+
define_extent(ccw++, (struct DE_eckd_data *) data,
2204+
fdata->start_unit, fdata->stop_unit,
2205+
DASD_ECKD_CCW_WRITE_RECORD_ZERO, startdev);
2206+
data += sizeof(struct DE_eckd_data);
2207+
}
21712208
ccw[-1].flags |= CCW_FLAG_CC;
21722209
locate_record(ccw++, (struct LO_eckd_data *) data,
21732210
fdata->start_unit, 0, rpt * nr_tracks + 1,
@@ -2176,10 +2213,17 @@ dasd_eckd_build_format(struct dasd_device *base,
21762213
data += sizeof(struct LO_eckd_data);
21772214
break;
21782215
case 0x04: /* Invalidate track. */
2179-
prefix(ccw++, (struct PFX_eckd_data *) data,
2180-
fdata->start_unit, fdata->stop_unit,
2181-
DASD_ECKD_CCW_WRITE_CKD, base, startdev);
2182-
data += sizeof(struct PFX_eckd_data);
2216+
if (use_prefix) {
2217+
prefix(ccw++, (struct PFX_eckd_data *) data,
2218+
fdata->start_unit, fdata->stop_unit,
2219+
DASD_ECKD_CCW_WRITE_CKD, base, startdev);
2220+
data += sizeof(struct PFX_eckd_data);
2221+
} else {
2222+
define_extent(ccw++, (struct DE_eckd_data *) data,
2223+
fdata->start_unit, fdata->stop_unit,
2224+
DASD_ECKD_CCW_WRITE_CKD, startdev);
2225+
data += sizeof(struct DE_eckd_data);
2226+
}
21832227
ccw[-1].flags |= CCW_FLAG_CC;
21842228
locate_record(ccw++, (struct LO_eckd_data *) data,
21852229
fdata->start_unit, 0, 1,

drivers/s390/char/sclp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ sclp_sync_wait(void)
486486
timeout = 0;
487487
if (timer_pending(&sclp_request_timer)) {
488488
/* Get timeout TOD value */
489-
timeout = get_tod_clock() +
489+
timeout = get_tod_clock_fast() +
490490
sclp_tod_from_jiffies(sclp_request_timer.expires -
491491
jiffies);
492492
}
@@ -508,7 +508,7 @@ sclp_sync_wait(void)
508508
while (sclp_running_state != sclp_running_state_idle) {
509509
/* Check for expired request timer */
510510
if (timer_pending(&sclp_request_timer) &&
511-
get_tod_clock() > timeout &&
511+
get_tod_clock_fast() > timeout &&
512512
del_timer(&sclp_request_timer))
513513
sclp_request_timer.function(sclp_request_timer.data);
514514
cpu_relax();

drivers/s390/char/vmlogrdr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ static int vmlogrdr_open (struct inode *inode, struct file *filp)
313313
int ret;
314314

315315
dev_num = iminor(inode);
316-
if (dev_num > MAXMINOR)
316+
if (dev_num >= MAXMINOR)
317317
return -ENODEV;
318318
logptr = &sys_ser[dev_num];
319319

drivers/s390/cio/cio.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,9 +878,9 @@ static void css_reset(void)
878878
atomic_inc(&chpid_reset_count);
879879
}
880880
/* Wait for machine check for all channel paths. */
881-
timeout = get_tod_clock() + (RCHP_TIMEOUT << 12);
881+
timeout = get_tod_clock_fast() + (RCHP_TIMEOUT << 12);
882882
while (atomic_read(&chpid_reset_count) != 0) {
883-
if (get_tod_clock() > timeout)
883+
if (get_tod_clock_fast() > timeout)
884884
break;
885885
cpu_relax();
886886
}

drivers/s390/cio/qdio_main.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,10 +338,10 @@ static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit,
338338
retries++;
339339

340340
if (!start_time) {
341-
start_time = get_tod_clock();
341+
start_time = get_tod_clock_fast();
342342
goto again;
343343
}
344-
if ((get_tod_clock() - start_time) < QDIO_BUSY_BIT_PATIENCE)
344+
if (get_tod_clock_fast() - start_time < QDIO_BUSY_BIT_PATIENCE)
345345
goto again;
346346
}
347347
if (retries) {
@@ -504,7 +504,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
504504
int count, stop;
505505
unsigned char state = 0;
506506

507-
q->timestamp = get_tod_clock();
507+
q->timestamp = get_tod_clock_fast();
508508

509509
/*
510510
* Don't check 128 buffers, as otherwise qdio_inbound_q_moved
@@ -595,7 +595,7 @@ static inline int qdio_inbound_q_done(struct qdio_q *q)
595595
* At this point we know, that inbound first_to_check
596596
* has (probably) not moved (see qdio_inbound_processing).
597597
*/
598-
if (get_tod_clock() > q->u.in.timestamp + QDIO_INPUT_THRESHOLD) {
598+
if (get_tod_clock_fast() > q->u.in.timestamp + QDIO_INPUT_THRESHOLD) {
599599
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in done:%02x",
600600
q->first_to_check);
601601
return 1;
@@ -728,7 +728,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
728728
int count, stop;
729729
unsigned char state = 0;
730730

731-
q->timestamp = get_tod_clock();
731+
q->timestamp = get_tod_clock_fast();
732732

733733
if (need_siga_sync(q))
734734
if (((queue_type(q) != QDIO_IQDIO_QFMT) &&

0 commit comments

Comments
 (0)