Commit ef3a1632 authored by ZhangPeng's avatar ZhangPeng Committed by Ma Wupeng
Browse files

userswap: introduce new flag to determine the first page fault

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I6CAIM



--------------------------------

Introduce new flag to determine the first page fault.

Signed-off-by: default avatarZhangPeng <zhangpeng362@huawei.com>
parent 010932f5
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -485,6 +485,10 @@ vm_fault_t handle_userfault(struct vm_fault *vmf, unsigned long reason)
	uwq.wq.private = current;
	uwq.msg = userfault_msg(vmf->address, vmf->flags, reason,
			ctx->features);
#ifdef CONFIG_USERSWAP
	if (reason & VM_USWAP && pte_none(vmf->orig_pte))
		uwq.msg.arg.pagefault.flags |= UFFD_PAGEFAULT_FLAG_FPF;
#endif
	uwq.ctx = ctx;
	uwq.waken = false;

+7 −0
Original line number Diff line number Diff line
@@ -59,6 +59,13 @@ static inline bool uswap_vm_flag_bug_on(unsigned long reason)
	return !(reason & VM_UFFD_MISSING) ^ !!(reason & VM_UFFD_WP);
}

static inline bool uswap_missing(struct vm_area_struct *vma)
{
	if (vma->vm_flags & VM_USWAP && vma->vm_flags & VM_UFFD_MISSING)
		return true;
	return false;
}

#endif /* CONFIG_USERSWAP */

#endif /* _LINUX_USERSWAP_H */
+1 −0
Original line number Diff line number Diff line
@@ -127,6 +127,7 @@ struct uffd_msg {
/* flags for UFFD_EVENT_PAGEFAULT */
#define UFFD_PAGEFAULT_FLAG_WRITE	(1<<0)	/* If this was a write fault */
#define UFFD_PAGEFAULT_FLAG_WP		(1<<1)	/* If reason is VM_UFFD_WP */
#define UFFD_PAGEFAULT_FLAG_FPF		(1<<10) /* If this was the first page fault */

struct uffdio_api {
	/* userland asks for an API number and the features to enable */
+14 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@
#include <linux/perf_event.h>
#include <linux/ptrace.h>
#include <linux/vmalloc.h>
#include <linux/userswap.h>

#include <trace/events/kmem.h>

@@ -3689,6 +3690,12 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
		if (ret)
			goto unlock;
		/* Deliver the page fault to userland, check inside PT lock */
#ifdef CONFIG_USERSWAP
		if (uswap_missing(vma)) {
			pte_unmap_unlock(vmf->pte, vmf->ptl);
			return handle_userfault(vmf, VM_UFFD_MISSING|VM_USWAP);
		}
#endif
		if (userfaultfd_missing(vma)) {
			pte_unmap_unlock(vmf->pte, vmf->ptl);
			return handle_userfault(vmf, VM_UFFD_MISSING);
@@ -3731,6 +3738,13 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf)
		goto release;

	/* Deliver the page fault to userland, check inside PT lock */
#ifdef CONFIG_USERSWAP
	if (uswap_missing(vma)) {
		pte_unmap_unlock(vmf->pte, vmf->ptl);
		put_page(page);
		return handle_userfault(vmf, VM_UFFD_MISSING | VM_USWAP);
	}
#endif
	if (userfaultfd_missing(vma)) {
		pte_unmap_unlock(vmf->pte, vmf->ptl);
		put_page(page);