diff options
| -rw-r--r-- | arch/s390/Makefile | 4 | ||||
| -rw-r--r-- | arch/s390/include/asm/pgtable.h | 5 | ||||
| -rw-r--r-- | arch/s390/include/asm/timex.h | 28 | ||||
| -rw-r--r-- | arch/s390/kernel/time.c | 2 | ||||
| -rw-r--r-- | arch/s390/kvm/interrupt.c | 2 | ||||
| -rw-r--r-- | drivers/s390/cio/chsc.c | 31 |
6 files changed, 45 insertions, 27 deletions
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 4b8e08b56f49..7e3ce78d4290 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
| @@ -24,8 +24,8 @@ CHECKFLAGS += -D__s390__ -msize-long | |||
| 24 | else | 24 | else |
| 25 | LD_BFD := elf64-s390 | 25 | LD_BFD := elf64-s390 |
| 26 | LDFLAGS := -m elf64_s390 | 26 | LDFLAGS := -m elf64_s390 |
| 27 | KBUILD_AFLAGS_MODULE += -fpic -D__PIC__ | 27 | KBUILD_AFLAGS_MODULE += -fPIC |
| 28 | KBUILD_CFLAGS_MODULE += -fpic -D__PIC__ | 28 | KBUILD_CFLAGS_MODULE += -fPIC |
| 29 | KBUILD_CFLAGS += -m64 | 29 | KBUILD_CFLAGS += -m64 |
| 30 | KBUILD_AFLAGS += -m64 | 30 | KBUILD_AFLAGS += -m64 |
| 31 | UTS_MACHINE := s390x | 31 | UTS_MACHINE := s390x |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index c928dc1938f2..c1d7930a82f4 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
| @@ -1387,10 +1387,7 @@ static inline int has_transparent_hugepage(void) | |||
| 1387 | 1387 | ||
| 1388 | static inline unsigned long pmd_pfn(pmd_t pmd) | 1388 | static inline unsigned long pmd_pfn(pmd_t pmd) |
| 1389 | { | 1389 | { |
| 1390 | if (pmd_trans_huge(pmd)) | 1390 | return pmd_val(pmd) >> PAGE_SHIFT; |
| 1391 | return pmd_val(pmd) >> HPAGE_SHIFT; | ||
| 1392 | else | ||
| 1393 | return pmd_val(pmd) >> PAGE_SHIFT; | ||
| 1394 | } | 1391 | } |
| 1395 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 1392 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
| 1396 | 1393 | ||
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index fba4d66788a2..4c060bb5b8ea 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h | |||
| @@ -128,4 +128,32 @@ static inline unsigned long long get_clock_monotonic(void) | |||
| 128 | return get_clock_xt() - sched_clock_base_cc; | 128 | return get_clock_xt() - sched_clock_base_cc; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | /** | ||
| 132 | * tod_to_ns - convert a TOD format value to nanoseconds | ||
| 133 | * @todval: to be converted TOD format value | ||
| 134 | * Returns: number of nanoseconds that correspond to the TOD format value | ||
| 135 | * | ||
| 136 | * Converting a 64 Bit TOD format value to nanoseconds means that the value | ||
| 137 | * must be divided by 4.096. In order to achieve that we multiply with 125 | ||
| 138 | * and divide by 512: | ||
| 139 | * | ||
| 140 | * ns = (todval * 125) >> 9; | ||
| 141 | * | ||
| 142 | * In order to avoid an overflow with the multiplication we can rewrite this. | ||
| 143 | * With a split todval == 2^32 * th + tl (th upper 32 bits, tl lower 32 bits) | ||
| 144 | * we end up with | ||
| 145 | * | ||
| 146 | * ns = ((2^32 * th + tl) * 125 ) >> 9; | ||
| 147 | * -> ns = (2^23 * th * 125) + ((tl * 125) >> 9); | ||
| 148 | * | ||
| 149 | */ | ||
| 150 | static inline unsigned long long tod_to_ns(unsigned long long todval) | ||
| 151 | { | ||
| 152 | unsigned long long ns; | ||
| 153 | |||
| 154 | ns = ((todval >> 32) << 23) * 125; | ||
| 155 | ns += ((todval & 0xffffffff) * 125) >> 9; | ||
| 156 | return ns; | ||
| 157 | } | ||
| 158 | |||
| 131 | #endif | 159 | #endif |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index aff0e350d776..a5f4f5a1d24b 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
| @@ -63,7 +63,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators); | |||
| 63 | */ | 63 | */ |
| 64 | unsigned long long notrace __kprobes sched_clock(void) | 64 | unsigned long long notrace __kprobes sched_clock(void) |
| 65 | { | 65 | { |
| 66 | return (get_clock_monotonic() * 125) >> 9; | 66 | return tod_to_ns(get_clock_monotonic()); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | /* | 69 | /* |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index c30615e605ac..82c481ddef76 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
| @@ -408,7 +408,7 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) | |||
| 408 | return 0; | 408 | return 0; |
| 409 | } | 409 | } |
| 410 | 410 | ||
| 411 | sltime = ((vcpu->arch.sie_block->ckc - now)*125)>>9; | 411 | sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now); |
| 412 | 412 | ||
| 413 | hrtimer_start(&vcpu->arch.ckc_timer, ktime_set (0, sltime) , HRTIMER_MODE_REL); | 413 | hrtimer_start(&vcpu->arch.ckc_timer, ktime_set (0, sltime) , HRTIMER_MODE_REL); |
| 414 | VCPU_EVENT(vcpu, 5, "enabled wait via clock comparator: %llx ns", sltime); | 414 | VCPU_EVENT(vcpu, 5, "enabled wait via clock comparator: %llx ns", sltime); |
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 68e80e2734a4..10729bbceced 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
| @@ -283,7 +283,7 @@ struct chsc_sei_nt2_area { | |||
| 283 | u8 ccdf[PAGE_SIZE - 24 - 56]; /* content-code dependent field */ | 283 | u8 ccdf[PAGE_SIZE - 24 - 56]; /* content-code dependent field */ |
| 284 | } __packed; | 284 | } __packed; |
| 285 | 285 | ||
| 286 | #define CHSC_SEI_NT0 0ULL | 286 | #define CHSC_SEI_NT0 (1ULL << 63) |
| 287 | #define CHSC_SEI_NT2 (1ULL << 61) | 287 | #define CHSC_SEI_NT2 (1ULL << 61) |
| 288 | 288 | ||
| 289 | struct chsc_sei { | 289 | struct chsc_sei { |
| @@ -291,7 +291,8 @@ struct chsc_sei { | |||
| 291 | u32 reserved1; | 291 | u32 reserved1; |
| 292 | u64 ntsm; /* notification type mask */ | 292 | u64 ntsm; /* notification type mask */ |
| 293 | struct chsc_header response; | 293 | struct chsc_header response; |
| 294 | u32 reserved2; | 294 | u32 :24; |
| 295 | u8 nt; | ||
| 295 | union { | 296 | union { |
| 296 | struct chsc_sei_nt0_area nt0_area; | 297 | struct chsc_sei_nt0_area nt0_area; |
| 297 | struct chsc_sei_nt2_area nt2_area; | 298 | struct chsc_sei_nt2_area nt2_area; |
| @@ -496,17 +497,17 @@ static int __chsc_process_crw(struct chsc_sei *sei, u64 ntsm) | |||
| 496 | css_schedule_eval_all(); | 497 | css_schedule_eval_all(); |
| 497 | } | 498 | } |
| 498 | 499 | ||
| 499 | switch (sei->ntsm) { | 500 | switch (sei->nt) { |
| 500 | case CHSC_SEI_NT0: | 501 | case 0: |
| 501 | chsc_process_sei_nt0(&sei->u.nt0_area); | 502 | chsc_process_sei_nt0(&sei->u.nt0_area); |
| 502 | return 1; | 503 | break; |
| 503 | case CHSC_SEI_NT2: | 504 | case 2: |
| 504 | chsc_process_sei_nt2(&sei->u.nt2_area); | 505 | chsc_process_sei_nt2(&sei->u.nt2_area); |
| 505 | return 1; | 506 | break; |
| 506 | default: | 507 | default: |
| 507 | CIO_CRW_EVENT(2, "chsc: unhandled nt (nt=%08Lx)\n", | 508 | CIO_CRW_EVENT(2, "chsc: unhandled nt=%d\n", |
| 508 | sei->ntsm); | 509 | sei->nt); |
| 509 | return 0; | 510 | break; |
| 510 | } | 511 | } |
| 511 | } else { | 512 | } else { |
| 512 | CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n", | 513 | CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n", |
| @@ -537,15 +538,7 @@ static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow) | |||
| 537 | sei = sei_page; | 538 | sei = sei_page; |
| 538 | 539 | ||
| 539 | CIO_TRACE_EVENT(2, "prcss"); | 540 | CIO_TRACE_EVENT(2, "prcss"); |
| 540 | 541 | __chsc_process_crw(sei, CHSC_SEI_NT0 | CHSC_SEI_NT2); | |
| 541 | /* | ||
| 542 | * The ntsm does not allow to select NT0 and NT2 together. We need to | ||
| 543 | * first check for NT2, than additionally for NT0... | ||
| 544 | */ | ||
| 545 | #ifdef CONFIG_PCI | ||
| 546 | if (!__chsc_process_crw(sei, CHSC_SEI_NT2)) | ||
| 547 | #endif | ||
| 548 | __chsc_process_crw(sei, CHSC_SEI_NT0); | ||
| 549 | } | 542 | } |
| 550 | 543 | ||
| 551 | void chsc_chp_online(struct chp_id chpid) | 544 | void chsc_chp_online(struct chp_id chpid) |
