From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org,
Christophe Leroy <christophe.leroy@c-s.fr>,
Nicholas Piggin <npiggin@gmail.com>,
Michael Ellerman <mpe@ellerman.id.au>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 4.14 05/50] powerpc/mm: Only read faulting instruction when necessary in do_page_fault()
Date: Mon, 24 Aug 2020 10:31:06 +0200 [thread overview]
Message-ID: <20200824082352.178041484@linuxfoundation.org> (raw)
In-Reply-To: <20200824082351.823243923@linuxfoundation.org>
From: Christophe Leroy <christophe.leroy@c-s.fr>
[ Upstream commit 0e36b0d12501e278686634712975b785bae11641 ]
Commit a7a9dcd882a67 ("powerpc: Avoid taking a data miss on every
userspace instruction miss") has shown that limiting the read of
faulting instruction to likely cases improves performance.
This patch goes further into this direction by limiting the read
of the faulting instruction to the only cases where it is likely
needed.
On an MPC885, with the same benchmark app as in the commit referred
above, we see a reduction of about 3900 dTLB misses (approx 3%):
Before the patch:
Performance counter stats for './fault 500' (10 runs):
683033312 cpu-cycles ( +- 0.03% )
134538 dTLB-load-misses ( +- 0.03% )
46099 iTLB-load-misses ( +- 0.02% )
19681 faults ( +- 0.02% )
5.389747878 seconds time elapsed ( +- 0.06% )
With the patch:
Performance counter stats for './fault 500' (10 runs):
682112862 cpu-cycles ( +- 0.03% )
130619 dTLB-load-misses ( +- 0.03% )
46073 iTLB-load-misses ( +- 0.05% )
19681 faults ( +- 0.01% )
5.381342641 seconds time elapsed ( +- 0.07% )
The proper work of the huge stack expansion was tested with the
following app:
int main(int argc, char **argv)
{
char buf[1024 * 1025];
sprintf(buf, "Hello world !\n");
printf(buf);
exit(0);
}
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
[mpe: Add include of pagemap.h to fix build errors]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/mm/fault.c | 50 ++++++++++++++++++++++++++++-------------
1 file changed, 34 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 5fc8a010fdf07..998c77e600a43 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -22,6 +22,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
+#include <linux/pagemap.h>
#include <linux/ptrace.h>
#include <linux/mman.h>
#include <linux/mm.h>
@@ -66,15 +67,11 @@ static inline bool notify_page_fault(struct pt_regs *regs)
}
/*
- * Check whether the instruction at regs->nip is a store using
+ * Check whether the instruction inst is a store using
* an update addressing form which will update r1.
*/
-static bool store_updates_sp(struct pt_regs *regs)
+static bool store_updates_sp(unsigned int inst)
{
- unsigned int inst;
-
- if (get_user(inst, (unsigned int __user *)regs->nip))
- return false;
/* check for 1 in the rA field */
if (((inst >> 16) & 0x1f) != 1)
return false;
@@ -228,8 +225,8 @@ static bool bad_kernel_fault(bool is_exec, unsigned long error_code,
}
static bool bad_stack_expansion(struct pt_regs *regs, unsigned long address,
- struct vm_area_struct *vma,
- bool store_update_sp)
+ struct vm_area_struct *vma, unsigned int flags,
+ bool *must_retry)
{
/*
* N.B. The POWER/Open ABI allows programs to access up to
@@ -241,6 +238,7 @@ static bool bad_stack_expansion(struct pt_regs *regs, unsigned long address,
* expand to 1MB without further checks.
*/
if (address + 0x100000 < vma->vm_end) {
+ unsigned int __user *nip = (unsigned int __user *)regs->nip;
/* get user regs even if this fault is in kernel mode */
struct pt_regs *uregs = current->thread.regs;
if (uregs == NULL)
@@ -258,8 +256,22 @@ static bool bad_stack_expansion(struct pt_regs *regs, unsigned long address,
* between the last mapped region and the stack will
* expand the stack rather than segfaulting.
*/
- if (address + 2048 < uregs->gpr[1] && !store_update_sp)
- return true;
+ if (address + 2048 >= uregs->gpr[1])
+ return false;
+
+ if ((flags & FAULT_FLAG_WRITE) && (flags & FAULT_FLAG_USER) &&
+ access_ok(VERIFY_READ, nip, sizeof(*nip))) {
+ unsigned int inst;
+ int res;
+
+ pagefault_disable();
+ res = __get_user_inatomic(inst, nip);
+ pagefault_enable();
+ if (!res)
+ return !store_updates_sp(inst);
+ *must_retry = true;
+ }
+ return true;
}
return false;
}
@@ -392,7 +404,7 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
int is_user = user_mode(regs);
int is_write = page_fault_is_write(error_code);
int fault, major = 0;
- bool store_update_sp = false;
+ bool must_retry = false;
if (notify_page_fault(regs))
return 0;
@@ -439,9 +451,6 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address,
* can result in fault, which will cause a deadlock when called with
* mmap_sem held
*/
- if (is_write && is_user)
- store_update_sp = store_updates_sp(regs);
-
if (is_user)
flags |= FAULT_FLAG_USER;
if (is_write)
@@ -488,8 +497,17 @@ retry:
return bad_area(regs, address);
/* The stack is being expanded, check if it's valid */
- if (unlikely(bad_stack_expansion(regs, address, vma, store_update_sp)))
- return bad_area(regs, address);
+ if (unlikely(bad_stack_expansion(regs, address, vma, flags,
+ &must_retry))) {
+ if (!must_retry)
+ return bad_area(regs, address);
+
+ up_read(&mm->mmap_sem);
+ if (fault_in_pages_readable((const char __user *)regs->nip,
+ sizeof(unsigned int)))
+ return bad_area_nosemaphore(regs, address);
+ goto retry;
+ }
/* Try to expand it */
if (unlikely(expand_stack(vma, address)))
--
2.25.1
next prev parent reply other threads:[~2020-08-24 9:26 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-24 8:31 [PATCH 4.14 00/50] 4.14.195-rc1 review Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 01/50] drm/vgem: Replace opencoded version of drm_gem_dumb_map_offset() Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 02/50] perf probe: Fix memory leakage when the probe point is not found Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 03/50] khugepaged: khugepaged_test_exit() check mmget_still_valid() Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 04/50] khugepaged: adjust VM_BUG_ON_MM() in __khugepaged_enter() Greg Kroah-Hartman
2020-08-24 8:31 ` Greg Kroah-Hartman [this message]
2020-08-24 8:31 ` [PATCH 4.14 06/50] powerpc: Allow 4224 bytes of stack expansion for the signal frame Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 07/50] btrfs: export helpers for subvolume name/id resolution Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 08/50] btrfs: dont show full path of bind mounts in subvol= Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 09/50] btrfs: Move free_pages_out label in inline extent handling branch in compress_file_range Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 10/50] btrfs: inode: fix NULL pointer dereference if inode doesnt need compression Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 11/50] btrfs: sysfs: use NOFS for device creation Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 12/50] romfs: fix uninitialized memory leak in romfs_dev_read() Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 13/50] kernel/relay.c: fix memleak on destroy relay channel Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 14/50] mm: include CMA pages in lowmem_reserve at boot Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 15/50] mm, page_alloc: fix core hung in free_pcppages_bulk() Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 16/50] ext4: fix checking of directory entry validity for inline directories Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 17/50] jbd2: add the missing unlock_buffer() in the error path of jbd2_write_superblock() Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 18/50] mm/memory.c: skip spurious TLB flush for retried page fault Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 19/50] spi: Prevent adding devices below an unregistering controller Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 20/50] scsi: ufs: Add DELAY_BEFORE_LPM quirk for Micron devices Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 21/50] media: budget-core: Improve exception handling in budget_register() Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 22/50] rtc: goldfish: Enable interrupt in set_alarm() when necessary Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 23/50] media: vpss: clean up resources in init Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 24/50] Input: psmouse - add a newline when printing proto by sysfs Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 25/50] m68knommu: fix overwriting of bits in ColdFire V3 cache control Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 26/50] xfs: fix inode quota reservation checks Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 27/50] jffs2: fix UAF problem Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 28/50] cpufreq: intel_pstate: Fix cpuinfo_max_freq when MSR_TURBO_RATIO_LIMIT is 0 Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 29/50] scsi: libfc: Free skb in fc_disc_gpn_id_resp() for valid cases Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 30/50] virtio_ring: Avoid loop when vq is broken in virtqueue_poll Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 31/50] xfs: Fix UBSAN null-ptr-deref in xfs_sysfs_init Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 32/50] alpha: fix annotation of io{read,write}{16,32}be() Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 33/50] ext4: fix potential negative array index in do_split() Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 34/50] i40e: Set RX_ONLY mode for unicast promiscuous on VLAN Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 35/50] i40e: Fix crash during removing i40e driver Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 36/50] net: fec: correct the error path for regulator disable in probe Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 37/50] bonding: show saner speed for broadcast mode Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 38/50] bonding: fix a potential double-unregister Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 39/50] ASoC: msm8916-wcd-analog: fix register Interrupt offset Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 40/50] ASoC: intel: Fix memleak in sst_media_open Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 41/50] vfio/type1: Add proper error unwind for vfio_iommu_replay() Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 42/50] bonding: fix active-backup failover for current ARP slave Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 43/50] hv_netvsc: Fix the queue_mapping in netvsc_vf_xmit() Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 44/50] net: dsa: b53: check for timeout Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 45/50] powerpc/pseries: Do not initiate shutdown when system is running on UPS Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 46/50] epoll: Keep a reference on files added to the check list Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 47/50] do_epoll_ctl(): clean the failure exits up a bit Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 48/50] mm/hugetlb: fix calculation of adjust_range_if_pmd_sharing_possible Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 49/50] xen: dont reschedule in preemption off sections Greg Kroah-Hartman
2020-08-24 8:31 ` [PATCH 4.14 50/50] clk: Evict unregistered clks from parent caches Greg Kroah-Hartman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200824082352.178041484@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=christophe.leroy@c-s.fr \
--cc=linux-kernel@vger.kernel.org \
--cc=mpe@ellerman.id.au \
--cc=npiggin@gmail.com \
--cc=sashal@kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox