* refs/heads/tmp-c97d2b5:
Linux 4.19.26
net: phylink: avoid resolving link state too early
pinctrl: max77620: Use define directive for max77620_pinconf_param values
udlfb: handle unplug properly
netfilter: ipt_CLUSTERIP: fix sleep-in-atomic bug in clusterip_config_entry_put()
netfilter: nfnetlink_osf: add missing fmatch check
netfilter: ipv6: Don't preserve original oif for loopback address
netfilter: nft_compat: use-after-free when deleting targets
netfilter: nf_tables: fix flush after rule deletion in the same batch
Revert "bridge: do not add port to router list when receives query with source 0.0.0.0"
staging: erofs: unzip_vle_lz4.c,utils.c: rectify BUG_ONs
staging: erofs: unzip_{pagevec.h,vle.c}: rectify BUG_ONs
staging: erofs: {dir,inode,super}.c: rectify BUG_ONs
staging: erofs: add a full barrier in erofs_workgroup_unfreeze
staging: erofs: fix `erofs_workgroup_{try_to_freeze, unfreeze}'
staging: erofs: atomic_cond_read_relaxed on ref-locked workgroup
staging: erofs: remove the redundant d_rehash() for the root dentry
staging: erofs: drop multiref support temporarily
staging: erofs: replace BUG_ON with DBG_BUGON in data.c
staging: erofs: complete error handing of z_erofs_do_read_page
staging: erofs: fix a bug when appling cache strategy
net: avoid false positives in untrusted gso validation
net: validate untrusted gso packets without csum offload
kvm: x86: Return LA57 feature based on hardware capability
mac80211: allocate tailroom for forwarded mesh packets
drm/amd/display: Fix MST reboot/poweroff sequence
drm/i915/fbdev: Actually configure untiled displays
gpu: drm: radeon: Set DPM_FLAG_NEVER_SKIP when enabling PM-runtime
drm/amdgpu: Set DPM_FLAG_NEVER_SKIP when enabling PM-runtime
ARC: define ARCH_SLAB_MINALIGN = 8
ARC: U-boot: check arguments paranoidly
ARCv2: Enable unaligned access in early ASM code
parisc: Fix ptrace syscall number modification
KEYS: always initialize keyring_index_key::desc_len
KEYS: user: Align the payload buffer
RDMA/srp: Rework SCSI device reset handling
net/mlx5e: XDP, fix redirect resources availability check
net_sched: fix two more memory leaks in cls_tcindex
net_sched: fix a memory leak in cls_tcindex
net_sched: fix a race condition in tcindex_destroy()
sit: check if IPv6 enabled before calling ip6_err_gen_icmpv6_unreach()
geneve: should not call rt6_lookup() when ipv6 was disabled
net: socket: make bond ioctls go through compat_ifreq_ioctl()
net: socket: fix SIOCGIFNAME in compat
Revert "kill dev_ifsioc()"
Revert "socket: fix struct ifreq size in compat ioctl"
team: avoid complex list operations in team_nl_cmd_options_set()
sctp: set stream ext to NULL after freeing it in sctp_stream_outq_migrate
sctp: call gso_reset_checksum when computing checksum in sctp_gso_segment
net: sfp: do not probe SFP module before we're attached
net/packet: fix 4gb buffer limit due to overflow check
net/mlx5e: Don't overwrite pedit action when multiple pedit used
net/mlx4_en: Force CHECKSUM_NONE for short ethernet frames
net: ena: fix race between link up and device initalization
ipv6: propagate genlmsg_reply return code
inet_diag: fix reporting cgroup classid and fallback to priority
batman-adv: fix uninit-value in batadv_interface_tx()
isdn: avm: Fix string plus integer warning from Clang
net/mlx5e: Fix wrong (zero) TX drop counter indication for representor
selftests: forwarding: Add a test case for externally learned FDB entries
mlxsw: spectrum_switchdev: Do not treat static FDB entries as sticky
net: bridge: Mark FDB entries that were added by user as such
mlxsw: pci: Return error on PCI reset timeout
dpaa_eth: NETIF_F_LLTX requires to do our own update of trans_start
bpf: bpf_setsockopt: reset sock dst on SO_MARK changes
leds: lp5523: fix a missing check of return value of lp55xx_read
hwmon: (tmp421) Correct the misspelling of the tmp442 compatible attribute in OF device ID table
atm: he: fix sign-extension overflow on large shift
selftests/bpf: retry tests that expect build-id
bpf: zero out build_id for BPF_STACK_BUILD_ID_IP
bpf: don't assume build-id length is always 20 bytes
afs: Fix key refcounting in file locking code
afs: Don't set vnode->cb_s_break in afs_validate()
selftests: tc-testing: fix parsing of ife type
selftests: tc-testing: fix tunnel_key failure if dst_port is unspecified
selftests: tc-testing: drop test on missing tunnel key id
pvcalls-front: fix potential null dereference
drm/sun4i: backend: add missing of_node_puts
vhost: return EINVAL if iovecs size does not match the message size
drm/amd/display: fix PME notification not working in RV desktop
drm/amdkfd: Don't assign dGPUs to APU topology devices
drm/meson: add missing of_node_put
always clear the X2APIC_ENABLE bit for PV guest
netfilter: nft_flow_offload: fix checking method of conntrack helper
scsi: cxgb4i: add wait_for_completion()
scsi: ufs: Fix geometry descriptor size
scsi: qedi: Add ep_state for login completion on un-reachable targets
scsi: ufs: Fix system suspend status
scsi: tcmu: avoid cmd/qfull timers updated whenever a new cmd comes
isdn: i4l: isdn_tty: Fix some concurrency double-free bugs
net: stmmac: Prevent RX starvation in stmmac_napi_poll()
net: stmmac: Fix the logic of checking if RX Watchdog must be enabled
net: stmmac: Check if CBS is supported before configuring
net: stmmac: dwxgmac2: Only clear interrupts that are active
net: stmmac: Fix PCI module removal leak
acpi/nfit: Fix race accessing memdev in nfit_get_smbios_id()
powerpc/8xx: fix setting of pagetable for Abatron BDI debug tool.
RDMA/mthca: Clear QP objects during their allocation
netfilter: nft_flow_offload: fix interaction with vrf slave device
bpf: fix panic in stack_map_get_build_id() on i386 and arm32
pvcalls-front: Avoid get_free_pages(GFP_KERNEL) under spinlock
bpf: correctly set initial window on active Fast Open sender
netfilter: nft_flow_offload: Fix reverse route lookup
MIPS: jazz: fix 64bit build
include/linux/compiler*.h: fix OPTIMIZER_HIDE_VAR
scsi: isci: initialize shost fully before calling scsi_add_host()
scsi: qla4xxx: check return code of qla4xxx_copy_from_fwddb_param
netfilter: nf_tables: fix leaking object reference count
selftests: forwarding: Add a test for VLAN deletion
mlxsw: spectrum_acl: Add cleanup after C-TCAM update error condition
xprtrdma: Double free in rpcrdma_sendctxs_create()
MIPS: ath79: Enable OF serial ports in the default config
net/mlx4: Get rid of page operation after dma_alloc_coherent
watchdog: mt7621_wdt/rt2880_wdt: Fix compilation problem
selftests/bpf: Test [::] -> [::1] rewrite in sys_sendmsg in test_sock_addr
bpf: Fix [::] -> [::1] rewrite in sys_sendmsg
net: hns: Fix use after free identified by SLUB debug
qed: Fix qed_ll2_post_rx_buffer_notify_fw() by adding a write memory barrier
qed: Fix qed_chain_set_prod() for PBL chains with non power of 2 page count
xen/pvcalls: remove set but not used variable 'intf'
mfd: mc13xxx: Fix a missing check of a register-read failure
mfd: tps65218: Use devm_regmap_add_irq_chip and clean up error path in probe()
mfd: cros_ec_dev: Add missing mfd_remove_devices() call in remove
mfd: axp20x: Add supported cells for AXP803
mfd: axp20x: Re-align MFD cell entries
mfd: axp20x: Add AC power supply cell for AXP813
mfd: wm5110: Add missing ASRC rate register
mfd: qcom_rpm: write fw_version to CTRL_REG
mfd: bd9571mwv: Add volatile register to make DVFS work
mfd: ab8500-core: Return zero in get_register_interruptible()
mfd: mt6397: Do not call irq_domain_remove if PMIC unsupported
mfd: db8500-prcmu: Fix some section annotations
mfd: twl-core: Fix section annotations on {,un}protect_pm_master
pvcalls-back: set -ENOTCONN in pvcalls_conn_back_read
pvcalls-front: properly allocate sk
pvcalls-front: don't try to free unallocated rings
pvcalls-front: read all data before closing the connection
mfd: ti_am335x_tscadc: Use PLATFORM_DEVID_AUTO while registering mfd cells
backlight: pwm_bl: Fix devicetree parsing with auto-generated brightness tables
KEYS: allow reaching the keys quotas exactly
ALSA: hda/realtek: Disable PC beep in passthrough on alc285
ALSA: hda/realtek - Headset microphone and internal speaker support for System76 oryp5
proc, oom: do not report alien mms when setting oom_score_adj
numa: change get_mempolicy() to use nr_node_ids instead of MAX_NUMNODES
ceph: avoid repeatedly adding inode to mdsc->snap_flush_list
libceph: handle an empty authorize reply
mac80211: Free mpath object when rhashtable insertion fails
mac80211: Use linked list instead of rhashtable walk for mesh tables
mac80211: Restore vif beacon interval if start ap fails
gpio: pxa: avoid attempting to set pin direction via pinctrl on MMP2
gpio: MT7621: use a per instance irq_chip structure
MIPS: eBPF: Always return sign extended 32b values
tracing: Fix number of entries in trace header
ARM: 8834/1: Fix: kprobes: optimized kprobes illegal instruction
Change-Id: Ie585d8274f881ac87155e9deda341c43cd8923b4
Signed-off-by: Ivaylo Georgiev <irgeorgiev@codeaurora.org>
352 lines
11 KiB
C
352 lines
11 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef __LINUX_COMPILER_H
|
|
#define __LINUX_COMPILER_H
|
|
|
|
#include <linux/compiler_types.h>
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
/*
|
|
* Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code
|
|
* to disable branch tracing on a per file basis.
|
|
*/
|
|
#if defined(CONFIG_TRACE_BRANCH_PROFILING) \
|
|
&& !defined(DISABLE_BRANCH_PROFILING) && !defined(__CHECKER__)
|
|
void ftrace_likely_update(struct ftrace_likely_data *f, int val,
|
|
int expect, int is_constant);
|
|
|
|
#define likely_notrace(x) __builtin_expect(!!(x), 1)
|
|
#define unlikely_notrace(x) __builtin_expect(!!(x), 0)
|
|
|
|
#define __branch_check__(x, expect, is_constant) ({ \
|
|
long ______r; \
|
|
static struct ftrace_likely_data \
|
|
__attribute__((__aligned__(4))) \
|
|
__attribute__((section("_ftrace_annotated_branch"))) \
|
|
______f = { \
|
|
.data.func = __func__, \
|
|
.data.file = __FILE__, \
|
|
.data.line = __LINE__, \
|
|
}; \
|
|
______r = __builtin_expect(!!(x), expect); \
|
|
ftrace_likely_update(&______f, ______r, \
|
|
expect, is_constant); \
|
|
______r; \
|
|
})
|
|
|
|
/*
|
|
* Using __builtin_constant_p(x) to ignore cases where the return
|
|
* value is always the same. This idea is taken from a similar patch
|
|
* written by Daniel Walker.
|
|
*/
|
|
# ifndef likely
|
|
# define likely(x) (__branch_check__(x, 1, __builtin_constant_p(x)))
|
|
# endif
|
|
# ifndef unlikely
|
|
# define unlikely(x) (__branch_check__(x, 0, __builtin_constant_p(x)))
|
|
# endif
|
|
|
|
#ifdef CONFIG_PROFILE_ALL_BRANCHES
|
|
/*
|
|
* "Define 'is'", Bill Clinton
|
|
* "Define 'if'", Steven Rostedt
|
|
*/
|
|
#define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
|
|
#define __trace_if(cond) \
|
|
if (__builtin_constant_p(!!(cond)) ? !!(cond) : \
|
|
({ \
|
|
int ______r; \
|
|
static struct ftrace_branch_data \
|
|
__attribute__((__aligned__(4))) \
|
|
__attribute__((section("_ftrace_branch"))) \
|
|
______f = { \
|
|
.func = __func__, \
|
|
.file = __FILE__, \
|
|
.line = __LINE__, \
|
|
}; \
|
|
______r = !!(cond); \
|
|
______f.miss_hit[______r]++; \
|
|
______r; \
|
|
}))
|
|
#endif /* CONFIG_PROFILE_ALL_BRANCHES */
|
|
|
|
#else
|
|
# define likely(x) __builtin_expect(!!(x), 1)
|
|
# define unlikely(x) __builtin_expect(!!(x), 0)
|
|
#endif
|
|
|
|
/* Optimization barrier */
|
|
#ifndef barrier
|
|
# define barrier() __memory_barrier()
|
|
#endif
|
|
|
|
#ifndef barrier_data
|
|
# define barrier_data(ptr) barrier()
|
|
#endif
|
|
|
|
/* workaround for GCC PR82365 if needed */
|
|
#ifndef barrier_before_unreachable
|
|
# define barrier_before_unreachable() do { } while (0)
|
|
#endif
|
|
|
|
/* Unreachable code */
|
|
#ifdef CONFIG_STACK_VALIDATION
|
|
/*
|
|
* These macros help objtool understand GCC code flow for unreachable code.
|
|
* The __COUNTER__ based labels are a hack to make each instance of the macros
|
|
* unique, to convince GCC not to merge duplicate inline asm statements.
|
|
*/
|
|
#define annotate_reachable() ({ \
|
|
asm volatile("%c0:\n\t" \
|
|
".pushsection .discard.reachable\n\t" \
|
|
".long %c0b - .\n\t" \
|
|
".popsection\n\t" : : "i" (__COUNTER__)); \
|
|
})
|
|
#define annotate_unreachable() ({ \
|
|
asm volatile("%c0:\n\t" \
|
|
".pushsection .discard.unreachable\n\t" \
|
|
".long %c0b - .\n\t" \
|
|
".popsection\n\t" : : "i" (__COUNTER__)); \
|
|
})
|
|
#define ASM_UNREACHABLE \
|
|
"999:\n\t" \
|
|
".pushsection .discard.unreachable\n\t" \
|
|
".long 999b - .\n\t" \
|
|
".popsection\n\t"
|
|
#else
|
|
#define annotate_reachable()
|
|
#define annotate_unreachable()
|
|
#endif
|
|
|
|
#ifndef ASM_UNREACHABLE
|
|
# define ASM_UNREACHABLE
|
|
#endif
|
|
#ifndef unreachable
|
|
# define unreachable() do { annotate_reachable(); do { } while (1); } while (0)
|
|
#endif
|
|
|
|
/*
|
|
* KENTRY - kernel entry point
|
|
* This can be used to annotate symbols (functions or data) that are used
|
|
* without their linker symbol being referenced explicitly. For example,
|
|
* interrupt vector handlers, or functions in the kernel image that are found
|
|
* programatically.
|
|
*
|
|
* Not required for symbols exported with EXPORT_SYMBOL, or initcalls. Those
|
|
* are handled in their own way (with KEEP() in linker scripts).
|
|
*
|
|
* KENTRY can be avoided if the symbols in question are marked as KEEP() in the
|
|
* linker script. For example an architecture could KEEP() its entire
|
|
* boot/exception vector code rather than annotate each function and data.
|
|
*/
|
|
#ifndef KENTRY
|
|
# define KENTRY(sym) \
|
|
extern typeof(sym) sym; \
|
|
static const unsigned long __kentry_##sym \
|
|
__used \
|
|
__attribute__((section("___kentry" "+" #sym ), used)) \
|
|
= (unsigned long)&sym;
|
|
#endif
|
|
|
|
#ifndef RELOC_HIDE
|
|
# define RELOC_HIDE(ptr, off) \
|
|
({ unsigned long __ptr; \
|
|
__ptr = (unsigned long) (ptr); \
|
|
(typeof(ptr)) (__ptr + (off)); })
|
|
#endif
|
|
|
|
#ifndef OPTIMIZER_HIDE_VAR
|
|
/* Make the optimizer believe the variable can be manipulated arbitrarily. */
|
|
#define OPTIMIZER_HIDE_VAR(var) \
|
|
__asm__ ("" : "=r" (var) : "0" (var))
|
|
#endif
|
|
|
|
/* Not-quite-unique ID. */
|
|
#ifndef __UNIQUE_ID
|
|
# define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__)
|
|
#endif
|
|
|
|
#include <uapi/linux/types.h>
|
|
|
|
#define __READ_ONCE_SIZE \
|
|
({ \
|
|
switch (size) { \
|
|
case 1: *(__u8 *)res = *(volatile __u8 *)p; break; \
|
|
case 2: *(__u16 *)res = *(volatile __u16 *)p; break; \
|
|
case 4: *(__u32 *)res = *(volatile __u32 *)p; break; \
|
|
case 8: *(__u64 *)res = *(volatile __u64 *)p; break; \
|
|
default: \
|
|
barrier(); \
|
|
__builtin_memcpy((void *)res, (const void *)p, size); \
|
|
barrier(); \
|
|
} \
|
|
})
|
|
|
|
static __always_inline
|
|
void __read_once_size(const volatile void *p, void *res, int size)
|
|
{
|
|
__READ_ONCE_SIZE;
|
|
}
|
|
|
|
#ifdef CONFIG_KASAN
|
|
/*
|
|
* We can't declare function 'inline' because __no_sanitize_address confilcts
|
|
* with inlining. Attempt to inline it may cause a build failure.
|
|
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
|
|
* '__maybe_unused' allows us to avoid defined-but-not-used warnings.
|
|
*/
|
|
# define __no_kasan_or_inline __no_sanitize_address __maybe_unused
|
|
#else
|
|
# define __no_kasan_or_inline __always_inline
|
|
#endif
|
|
|
|
static __no_kasan_or_inline
|
|
void __read_once_size_nocheck(const volatile void *p, void *res, int size)
|
|
{
|
|
__READ_ONCE_SIZE;
|
|
}
|
|
|
|
static __always_inline void __write_once_size(volatile void *p, void *res, int size)
|
|
{
|
|
switch (size) {
|
|
case 1: *(volatile __u8 *)p = *(__u8 *)res; break;
|
|
case 2: *(volatile __u16 *)p = *(__u16 *)res; break;
|
|
case 4: *(volatile __u32 *)p = *(__u32 *)res; break;
|
|
case 8: *(volatile __u64 *)p = *(__u64 *)res; break;
|
|
default:
|
|
barrier();
|
|
__builtin_memcpy((void *)p, (const void *)res, size);
|
|
barrier();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Prevent the compiler from merging or refetching reads or writes. The
|
|
* compiler is also forbidden from reordering successive instances of
|
|
* READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some
|
|
* particular ordering. One way to make the compiler aware of ordering is to
|
|
* put the two invocations of READ_ONCE or WRITE_ONCE in different C
|
|
* statements.
|
|
*
|
|
* These two macros will also work on aggregate data types like structs or
|
|
* unions. If the size of the accessed data type exceeds the word size of
|
|
* the machine (e.g., 32 bits or 64 bits) READ_ONCE() and WRITE_ONCE() will
|
|
* fall back to memcpy(). There's at least two memcpy()s: one for the
|
|
* __builtin_memcpy() and then one for the macro doing the copy of variable
|
|
* - '__u' allocated on the stack.
|
|
*
|
|
* Their two major use cases are: (1) Mediating communication between
|
|
* process-level code and irq/NMI handlers, all running on the same CPU,
|
|
* and (2) Ensuring that the compiler does not fold, spindle, or otherwise
|
|
* mutilate accesses that either do not require ordering or that interact
|
|
* with an explicit memory barrier or atomic instruction that provides the
|
|
* required ordering.
|
|
*/
|
|
#include <asm/barrier.h>
|
|
#include <linux/kasan-checks.h>
|
|
|
|
#define __READ_ONCE(x, check) \
|
|
({ \
|
|
union { typeof(x) __val; char __c[1]; } __u; \
|
|
if (check) \
|
|
__read_once_size(&(x), __u.__c, sizeof(x)); \
|
|
else \
|
|
__read_once_size_nocheck(&(x), __u.__c, sizeof(x)); \
|
|
smp_read_barrier_depends(); /* Enforce dependency ordering from x */ \
|
|
__u.__val; \
|
|
})
|
|
#define READ_ONCE(x) __READ_ONCE(x, 1)
|
|
|
|
/*
|
|
* Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need
|
|
* to hide memory access from KASAN.
|
|
*/
|
|
#define READ_ONCE_NOCHECK(x) __READ_ONCE(x, 0)
|
|
|
|
static __no_kasan_or_inline
|
|
unsigned long read_word_at_a_time(const void *addr)
|
|
{
|
|
kasan_check_read(addr, 1);
|
|
return *(unsigned long *)addr;
|
|
}
|
|
|
|
#define WRITE_ONCE(x, val) \
|
|
({ \
|
|
union { typeof(x) __val; char __c[1]; } __u = \
|
|
{ .__val = (__force typeof(x)) (val) }; \
|
|
__write_once_size(&(x), __u.__c, sizeof(x)); \
|
|
__u.__val; \
|
|
})
|
|
|
|
#endif /* __KERNEL__ */
|
|
|
|
/*
|
|
* Force the compiler to emit 'sym' as a symbol, so that we can reference
|
|
* it from inline assembler. Necessary in case 'sym' could be inlined
|
|
* otherwise, or eliminated entirely due to lack of references that are
|
|
* visible to the compiler.
|
|
*/
|
|
#define __ADDRESSABLE(sym) \
|
|
static void * __attribute__((section(".discard.addressable"), used)) \
|
|
__PASTE(__addressable_##sym, __LINE__) = (void *)&sym;
|
|
|
|
/**
|
|
* offset_to_ptr - convert a relative memory offset to an absolute pointer
|
|
* @off: the address of the 32-bit offset value
|
|
*/
|
|
static inline void *offset_to_ptr(const int *off)
|
|
{
|
|
return (void *)((unsigned long)off + *off);
|
|
}
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#ifndef __optimize
|
|
# define __optimize(level)
|
|
#endif
|
|
|
|
/* Compile time object size, -1 for unknown */
|
|
#ifndef __compiletime_object_size
|
|
# define __compiletime_object_size(obj) -1
|
|
#endif
|
|
#ifndef __compiletime_warning
|
|
# define __compiletime_warning(message)
|
|
#endif
|
|
#ifndef __compiletime_error
|
|
# define __compiletime_error(message)
|
|
#endif
|
|
|
|
#ifdef __OPTIMIZE__
|
|
# define __compiletime_assert(condition, msg, prefix, suffix) \
|
|
do { \
|
|
extern void prefix ## suffix(void) __compiletime_error(msg); \
|
|
if (!(condition)) \
|
|
prefix ## suffix(); \
|
|
} while (0)
|
|
#else
|
|
# define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0)
|
|
#endif
|
|
|
|
#define _compiletime_assert(condition, msg, prefix, suffix) \
|
|
__compiletime_assert(condition, msg, prefix, suffix)
|
|
|
|
/**
|
|
* compiletime_assert - break build and emit msg if condition is false
|
|
* @condition: a compile-time constant condition to check
|
|
* @msg: a message to emit if condition is false
|
|
*
|
|
* In tradition of POSIX assert, this macro will break the build if the
|
|
* supplied condition is *false*, emitting the supplied error message if the
|
|
* compiler has support to do so.
|
|
*/
|
|
#define compiletime_assert(condition, msg) \
|
|
_compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
|
|
|
|
#define compiletime_assert_atomic_type(t) \
|
|
compiletime_assert(__native_word(t), \
|
|
"Need native word sized stores/loads for atomicity.")
|
|
|
|
#endif /* __LINUX_COMPILER_H */
|