aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-22 11:07:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-22 11:07:11 -0500
commit3bab0bf045e1cc4880e2cfc9351e52cf7ec8e35e (patch)
treedc7d43536c431608054a9988886e240fe253dfe2 /arch
parenta5d6e63323fe7799eb0e6fd0a41fbfad10fca258 (diff)
parentc13f20ac48328b05cd3b8c19e31ed6c132b44b42 (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
Pull third set of powerpc updates from Benjamin Herrenschmidt: "This is a small collection of random bug fixes and a few improvements of Oops output which I deemed valuable enough to include as well. The fixes are essentially recent build breakage and regressions, and a couple of older bugs such as the DTL log duplication, the EEH issue with PCI_COMMAND_MASTER and the problem with small contexts passed to get/set_context with VSX enabled" * 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: powerpc/signals: Mark VSX not saved with small contexts powerpc/pseries: Fix SMP=n build of rng.c powerpc: Make cpu_to_chip_id() available when SMP=n powerpc/vio: Fix a dma_mask issue of vio powerpc: booke: Fix build failures powerpc: ppc64 address space capped at 32TB, mmap randomisation disabled powerpc: Only print PACATMSCRATCH in oops when TM is active powerpc/pseries: Duplicate dtl entries sometimes sent to userspace powerpc: Remove a few lines of oops output powerpc: Print DAR and DSISR on machine check oopses powerpc: Fix __get_user_pages_fast() irq handling powerpc/eeh: More accurate log powerpc/eeh: Enable PCI_COMMAND_MASTER for PCI bridges
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/include/asm/smp.h2
-rw-r--r--arch/powerpc/kernel/eeh.c9
-rw-r--r--arch/powerpc/kernel/eeh_event.c9
-rw-r--r--arch/powerpc/kernel/process.c21
-rw-r--r--arch/powerpc/kernel/prom.c20
-rw-r--r--arch/powerpc/kernel/signal_32.c10
-rw-r--r--arch/powerpc/kernel/smp.c16
-rw-r--r--arch/powerpc/kernel/time.c4
-rw-r--r--arch/powerpc/kernel/vio.c2
-rw-r--r--arch/powerpc/mm/gup.c5
-rw-r--r--arch/powerpc/mm/slice.c2
-rw-r--r--arch/powerpc/platforms/powernv/rng.c1
-rw-r--r--arch/powerpc/platforms/pseries/rng.c1
-rw-r--r--arch/powerpc/platforms/wsp/chroma.c1
-rw-r--r--arch/powerpc/platforms/wsp/h8.c1
-rw-r--r--arch/powerpc/platforms/wsp/ics.c2
-rw-r--r--arch/powerpc/platforms/wsp/opb_pic.c2
-rw-r--r--arch/powerpc/platforms/wsp/psr2.c1
-rw-r--r--arch/powerpc/platforms/wsp/scom_wsp.c1
-rw-r--r--arch/powerpc/platforms/wsp/wsp.c1
20 files changed, 75 insertions, 36 deletions
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 98da78e0c2c0..084e0807db98 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -33,6 +33,7 @@ extern int boot_cpuid;
33extern int spinning_secondaries; 33extern int spinning_secondaries;
34 34
35extern void cpu_die(void); 35extern void cpu_die(void);
36extern int cpu_to_chip_id(int cpu);
36 37
37#ifdef CONFIG_SMP 38#ifdef CONFIG_SMP
38 39
@@ -112,7 +113,6 @@ static inline struct cpumask *cpu_core_mask(int cpu)
112} 113}
113 114
114extern int cpu_to_core_id(int cpu); 115extern int cpu_to_core_id(int cpu);
115extern int cpu_to_chip_id(int cpu);
116 116
117/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. 117/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
118 * 118 *
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 671302065347..4bd687d5e7aa 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -686,6 +686,15 @@ void eeh_save_bars(struct eeh_dev *edev)
686 686
687 for (i = 0; i < 16; i++) 687 for (i = 0; i < 16; i++)
688 eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]); 688 eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]);
689
690 /*
691 * For PCI bridges including root port, we need enable bus
692 * master explicitly. Otherwise, it can't fetch IODA table
693 * entries correctly. So we cache the bit in advance so that
694 * we can restore it after reset, either PHB range or PE range.
695 */
696 if (edev->mode & EEH_DEV_BRIDGE)
697 edev->config_space[1] |= PCI_COMMAND_MASTER;
689} 698}
690 699
691/** 700/**
diff --git a/arch/powerpc/kernel/eeh_event.c b/arch/powerpc/kernel/eeh_event.c
index d27c5afc90ae..72d748b56c86 100644
--- a/arch/powerpc/kernel/eeh_event.c
+++ b/arch/powerpc/kernel/eeh_event.c
@@ -74,8 +74,13 @@ static int eeh_event_handler(void * dummy)
74 pe = event->pe; 74 pe = event->pe;
75 if (pe) { 75 if (pe) {
76 eeh_pe_state_mark(pe, EEH_PE_RECOVERING); 76 eeh_pe_state_mark(pe, EEH_PE_RECOVERING);
77 pr_info("EEH: Detected PCI bus error on PHB#%d-PE#%x\n", 77 if (pe->type & EEH_PE_PHB)
78 pe->phb->global_number, pe->addr); 78 pr_info("EEH: Detected error on PHB#%d\n",
79 pe->phb->global_number);
80 else
81 pr_info("EEH: Detected PCI bus error on "
82 "PHB#%d-PE#%x\n",
83 pe->phb->global_number, pe->addr);
79 eeh_handle_event(pe); 84 eeh_handle_event(pe);
80 eeh_pe_state_clear(pe, EEH_PE_RECOVERING); 85 eeh_pe_state_clear(pe, EEH_PE_RECOVERING);
81 } else { 86 } else {
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 0650e18169f8..3386d8ab7eb0 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -858,17 +858,21 @@ void show_regs(struct pt_regs * regs)
858 printk("MSR: "REG" ", regs->msr); 858 printk("MSR: "REG" ", regs->msr);
859 printbits(regs->msr, msr_bits); 859 printbits(regs->msr, msr_bits);
860 printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); 860 printk(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
861#ifdef CONFIG_PPC64
862 printk("SOFTE: %ld\n", regs->softe);
863#endif
864 trap = TRAP(regs); 861 trap = TRAP(regs);
865 if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR)) 862 if ((regs->trap != 0xc00) && cpu_has_feature(CPU_FTR_CFAR))
866 printk("CFAR: "REG"\n", regs->orig_gpr3); 863 printk("CFAR: "REG" ", regs->orig_gpr3);
867 if (trap == 0x300 || trap == 0x600) 864 if (trap == 0x200 || trap == 0x300 || trap == 0x600)
868#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 865#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
869 printk("DEAR: "REG", ESR: "REG"\n", regs->dar, regs->dsisr); 866 printk("DEAR: "REG" ESR: "REG" ", regs->dar, regs->dsisr);
870#else 867#else
871 printk("DAR: "REG", DSISR: %08lx\n", regs->dar, regs->dsisr); 868 printk("DAR: "REG" DSISR: %08lx ", regs->dar, regs->dsisr);
869#endif
870#ifdef CONFIG_PPC64
871 printk("SOFTE: %ld ", regs->softe);
872#endif
873#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
874 if (MSR_TM_ACTIVE(regs->msr))
875 printk("\nPACATMSCRATCH: %016llx ", get_paca()->tm_scratch);
872#endif 876#endif
873 877
874 for (i = 0; i < 32; i++) { 878 for (i = 0; i < 32; i++) {
@@ -887,9 +891,6 @@ void show_regs(struct pt_regs * regs)
887 printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip); 891 printk("NIP ["REG"] %pS\n", regs->nip, (void *)regs->nip);
888 printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link); 892 printk("LR ["REG"] %pS\n", regs->link, (void *)regs->link);
889#endif 893#endif
890#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
891 printk("PACATMSCRATCH [%llx]\n", get_paca()->tm_scratch);
892#endif
893 show_stack(current, (unsigned long *) regs->gpr[1]); 894 show_stack(current, (unsigned long *) regs->gpr[1]);
894 if (!user_mode(regs)) 895 if (!user_mode(regs))
895 show_instructions(regs); 896 show_instructions(regs);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index f3a47098fb8e..fa0ad8aafbcc 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -777,6 +777,26 @@ int of_get_ibm_chip_id(struct device_node *np)
777 return -1; 777 return -1;
778} 778}
779 779
780/**
781 * cpu_to_chip_id - Return the cpus chip-id
782 * @cpu: The logical cpu number.
783 *
784 * Return the value of the ibm,chip-id property corresponding to the given
785 * logical cpu number. If the chip-id can not be found, returns -1.
786 */
787int cpu_to_chip_id(int cpu)
788{
789 struct device_node *np;
790
791 np = of_get_cpu_node(cpu, NULL);
792 if (!np)
793 return -1;
794
795 of_node_put(np);
796 return of_get_ibm_chip_id(np);
797}
798EXPORT_SYMBOL(cpu_to_chip_id);
799
780#ifdef CONFIG_PPC_PSERIES 800#ifdef CONFIG_PPC_PSERIES
781/* 801/*
782 * Fix up the uninitialized fields in a new device node: 802 * Fix up the uninitialized fields in a new device node:
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 749778e0a69d..1844298f5ea4 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -457,7 +457,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
457 if (copy_vsx_to_user(&frame->mc_vsregs, current)) 457 if (copy_vsx_to_user(&frame->mc_vsregs, current))
458 return 1; 458 return 1;
459 msr |= MSR_VSX; 459 msr |= MSR_VSX;
460 } 460 } else if (!ctx_has_vsx_region)
461 /*
462 * With a small context structure we can't hold the VSX
463 * registers, hence clear the MSR value to indicate the state
464 * was not saved.
465 */
466 msr &= ~MSR_VSX;
467
468
461#endif /* CONFIG_VSX */ 469#endif /* CONFIG_VSX */
462#ifdef CONFIG_SPE 470#ifdef CONFIG_SPE
463 /* save spe registers */ 471 /* save spe registers */
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 930cd8af3503..a3b64f3bf9a2 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -597,22 +597,6 @@ out:
597 return id; 597 return id;
598} 598}
599 599
600/* Return the value of the chip-id property corresponding
601 * to the given logical cpu.
602 */
603int cpu_to_chip_id(int cpu)
604{
605 struct device_node *np;
606
607 np = of_get_cpu_node(cpu, NULL);
608 if (!np)
609 return -1;
610
611 of_node_put(np);
612 return of_get_ibm_chip_id(np);
613}
614EXPORT_SYMBOL(cpu_to_chip_id);
615
616/* Helper routines for cpu to core mapping */ 600/* Helper routines for cpu to core mapping */
617int cpu_core_index_of_thread(int cpu) 601int cpu_core_index_of_thread(int cpu)
618{ 602{
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 192b051df97e..b3b144121cc9 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -213,8 +213,6 @@ static u64 scan_dispatch_log(u64 stop_tb)
213 if (i == be64_to_cpu(vpa->dtl_idx)) 213 if (i == be64_to_cpu(vpa->dtl_idx))
214 return 0; 214 return 0;
215 while (i < be64_to_cpu(vpa->dtl_idx)) { 215 while (i < be64_to_cpu(vpa->dtl_idx)) {
216 if (dtl_consumer)
217 dtl_consumer(dtl, i);
218 dtb = be64_to_cpu(dtl->timebase); 216 dtb = be64_to_cpu(dtl->timebase);
219 tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) + 217 tb_delta = be32_to_cpu(dtl->enqueue_to_dispatch_time) +
220 be32_to_cpu(dtl->ready_to_enqueue_time); 218 be32_to_cpu(dtl->ready_to_enqueue_time);
@@ -227,6 +225,8 @@ static u64 scan_dispatch_log(u64 stop_tb)
227 } 225 }
228 if (dtb > stop_tb) 226 if (dtb > stop_tb)
229 break; 227 break;
228 if (dtl_consumer)
229 dtl_consumer(dtl, i);
230 stolen += tb_delta; 230 stolen += tb_delta;
231 ++i; 231 ++i;
232 ++dtl; 232 ++dtl;
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index e7d0c88f621a..76a64821f4a2 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -1419,7 +1419,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node)
1419 1419
1420 /* needed to ensure proper operation of coherent allocations 1420 /* needed to ensure proper operation of coherent allocations
1421 * later, in case driver doesn't set it explicitly */ 1421 * later, in case driver doesn't set it explicitly */
1422 dma_set_mask_and_coherent(&viodev->dev, DMA_BIT_MASK(64)); 1422 dma_coerce_mask_and_coherent(&viodev->dev, DMA_BIT_MASK(64));
1423 } 1423 }
1424 1424
1425 /* register with generic device framework */ 1425 /* register with generic device framework */
diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c
index 6936547018b8..c5f734e20b0f 100644
--- a/arch/powerpc/mm/gup.c
+++ b/arch/powerpc/mm/gup.c
@@ -123,6 +123,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
123 struct mm_struct *mm = current->mm; 123 struct mm_struct *mm = current->mm;
124 unsigned long addr, len, end; 124 unsigned long addr, len, end;
125 unsigned long next; 125 unsigned long next;
126 unsigned long flags;
126 pgd_t *pgdp; 127 pgd_t *pgdp;
127 int nr = 0; 128 int nr = 0;
128 129
@@ -156,7 +157,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
156 * So long as we atomically load page table pointers versus teardown, 157 * So long as we atomically load page table pointers versus teardown,
157 * we can follow the address down to the the page and take a ref on it. 158 * we can follow the address down to the the page and take a ref on it.
158 */ 159 */
159 local_irq_disable(); 160 local_irq_save(flags);
160 161
161 pgdp = pgd_offset(mm, addr); 162 pgdp = pgd_offset(mm, addr);
162 do { 163 do {
@@ -179,7 +180,7 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
179 break; 180 break;
180 } while (pgdp++, addr = next, addr != end); 181 } while (pgdp++, addr = next, addr != end);
181 182
182 local_irq_enable(); 183 local_irq_restore(flags);
183 184
184 return nr; 185 return nr;
185} 186}
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 3e99c149271a..7ce9cf3b6988 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -258,7 +258,7 @@ static bool slice_scan_available(unsigned long addr,
258 slice = GET_HIGH_SLICE_INDEX(addr); 258 slice = GET_HIGH_SLICE_INDEX(addr);
259 *boundary_addr = (slice + end) ? 259 *boundary_addr = (slice + end) ?
260 ((slice + end) << SLICE_HIGH_SHIFT) : SLICE_LOW_TOP; 260 ((slice + end) << SLICE_HIGH_SHIFT) : SLICE_LOW_TOP;
261 return !!(available.high_slices & (1u << slice)); 261 return !!(available.high_slices & (1ul << slice));
262 } 262 }
263} 263}
264 264
diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c
index 8844628915dc..1cb160dc1609 100644
--- a/arch/powerpc/platforms/powernv/rng.c
+++ b/arch/powerpc/platforms/powernv/rng.c
@@ -19,6 +19,7 @@
19#include <asm/io.h> 19#include <asm/io.h>
20#include <asm/prom.h> 20#include <asm/prom.h>
21#include <asm/machdep.h> 21#include <asm/machdep.h>
22#include <asm/smp.h>
22 23
23 24
24struct powernv_rng { 25struct powernv_rng {
diff --git a/arch/powerpc/platforms/pseries/rng.c b/arch/powerpc/platforms/pseries/rng.c
index a702f1c08242..72a102758d4e 100644
--- a/arch/powerpc/platforms/pseries/rng.c
+++ b/arch/powerpc/platforms/pseries/rng.c
@@ -13,6 +13,7 @@
13#include <linux/of.h> 13#include <linux/of.h>
14#include <asm/archrandom.h> 14#include <asm/archrandom.h>
15#include <asm/machdep.h> 15#include <asm/machdep.h>
16#include <asm/plpar_wrappers.h>
16 17
17 18
18static int pseries_get_random_long(unsigned long *v) 19static int pseries_get_random_long(unsigned long *v)
diff --git a/arch/powerpc/platforms/wsp/chroma.c b/arch/powerpc/platforms/wsp/chroma.c
index 8ef53bc2e70e..aaa46b353715 100644
--- a/arch/powerpc/platforms/wsp/chroma.c
+++ b/arch/powerpc/platforms/wsp/chroma.c
@@ -15,6 +15,7 @@
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/smp.h> 16#include <linux/smp.h>
17#include <linux/time.h> 17#include <linux/time.h>
18#include <linux/of_fdt.h>
18 19
19#include <asm/machdep.h> 20#include <asm/machdep.h>
20#include <asm/udbg.h> 21#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/wsp/h8.c b/arch/powerpc/platforms/wsp/h8.c
index d18e6cc19df3..a3c87f395750 100644
--- a/arch/powerpc/platforms/wsp/h8.c
+++ b/arch/powerpc/platforms/wsp/h8.c
@@ -10,6 +10,7 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/of.h> 11#include <linux/of.h>
12#include <linux/io.h> 12#include <linux/io.h>
13#include <linux/of_address.h>
13 14
14#include "wsp.h" 15#include "wsp.h"
15 16
diff --git a/arch/powerpc/platforms/wsp/ics.c b/arch/powerpc/platforms/wsp/ics.c
index 2d3b1dd9571d..9cd92e645028 100644
--- a/arch/powerpc/platforms/wsp/ics.c
+++ b/arch/powerpc/platforms/wsp/ics.c
@@ -18,6 +18,8 @@
18#include <linux/smp.h> 18#include <linux/smp.h>
19#include <linux/spinlock.h> 19#include <linux/spinlock.h>
20#include <linux/types.h> 20#include <linux/types.h>
21#include <linux/of_address.h>
22#include <linux/of_irq.h>
21 23
22#include <asm/io.h> 24#include <asm/io.h>
23#include <asm/irq.h> 25#include <asm/irq.h>
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index cb565bf93650..3f6729807938 100644
--- a/arch/powerpc/platforms/wsp/opb_pic.c
+++ b/arch/powerpc/platforms/wsp/opb_pic.c
@@ -15,6 +15,8 @@
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/time.h> 17#include <linux/time.h>
18#include <linux/of_address.h>
19#include <linux/of_irq.h>
18 20
19#include <asm/reg_a2.h> 21#include <asm/reg_a2.h>
20#include <asm/irq.h> 22#include <asm/irq.h>
diff --git a/arch/powerpc/platforms/wsp/psr2.c b/arch/powerpc/platforms/wsp/psr2.c
index 508ec8282b96..a87b414c766a 100644
--- a/arch/powerpc/platforms/wsp/psr2.c
+++ b/arch/powerpc/platforms/wsp/psr2.c
@@ -15,6 +15,7 @@
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/smp.h> 16#include <linux/smp.h>
17#include <linux/time.h> 17#include <linux/time.h>
18#include <linux/of_fdt.h>
18 19
19#include <asm/machdep.h> 20#include <asm/machdep.h>
20#include <asm/udbg.h> 21#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/wsp/scom_wsp.c b/arch/powerpc/platforms/wsp/scom_wsp.c
index 8928507affea..6538b4de34fc 100644
--- a/arch/powerpc/platforms/wsp/scom_wsp.c
+++ b/arch/powerpc/platforms/wsp/scom_wsp.c
@@ -14,6 +14,7 @@
14#include <linux/of.h> 14#include <linux/of.h>
15#include <linux/spinlock.h> 15#include <linux/spinlock.h>
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/of_address.h>
17 18
18#include <asm/cputhreads.h> 19#include <asm/cputhreads.h>
19#include <asm/reg_a2.h> 20#include <asm/reg_a2.h>
diff --git a/arch/powerpc/platforms/wsp/wsp.c b/arch/powerpc/platforms/wsp/wsp.c
index ddb6efe88914..58cd1f00e1ef 100644
--- a/arch/powerpc/platforms/wsp/wsp.c
+++ b/arch/powerpc/platforms/wsp/wsp.c
@@ -13,6 +13,7 @@
13#include <linux/smp.h> 13#include <linux/smp.h>
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/time.h> 15#include <linux/time.h>
16#include <linux/of_address.h>
16 17
17#include <asm/scom.h> 18#include <asm/scom.h>
18 19