[PATCH] mm: Remove double faults once write a device pfn

Zhou, Xianrong Xianrong.Zhou at amd.com
Fri Jan 26 05:10:12 UTC 2024


[AMD Official Use Only - General]

> >>>>>>>> The vmf_insert_pfn_prot could cause unnecessary double faults
> >>>>>>>> on a device pfn. Because currently the vmf_insert_pfn_prot does
> >>>>>>>> not make the pfn writable so the pte entry is normally
> >>>>>>>> read-only or dirty catching.
> >>>>>>> What? How do you got to this conclusion?
> >>>>>> Sorry. I did not mention that this problem only exists on arm64
> platform.
> >>>>> Ok, that makes at least a little bit more sense.
> >>>>>
> >>>>>> Because on arm64 platform the PTE_RDONLY is automatically
> >>>>>> attached to the userspace pte entries even through VM_WRITE +
> VM_SHARE.
> >>>>>> The  PTE_RDONLY needs to be cleared in vmf_insert_pfn_prot.
> >>>>>> However vmf_insert_pfn_prot do not make the pte writable passing
> >>>>>> false @mkwrite to insert_pfn.
> >>>>> Question is why is arm64 doing this? As far as I can see they must
> >>>>> have some hardware reason for that.
> >>>>>
> >>>>> The mkwrite parameter to insert_pfn() was added by commit
> >>>>> b2770da642540 to make insert_pfn() look more like insert_pfn_pmd()
> >>>>> so that the DAX code can insert PTEs which are writable and dirty
> >>>>> at the same
> >>> time.
> >>>> This is one scenario to do so. In fact on arm64 there are many
> >>>> scenarios could be to do so. So we can let vmf_insert_pfn_prot
> >>>> supporting @mkwrite for drivers at core layer and let drivers to
> >>>> decide whether or not to make writable and dirty at one time. The
> >>>> patch did this. Otherwise double faults on arm64 when call
> >>> vmf_insert_pfn_prot.
> >>>
> >>> Well, that doesn't answer my question why arm64 is double faulting
> >>> in the first place,.
> >>>
> >>
> >> Eh.
> >>
> >> On arm64 When userspace mmap() with PROT_WRITE and MAP_SHARED
> the
> >> vma->vm_page_prot has the PTE_RDONLY and PTE_WRITE within
> >> PAGE_SHARED_EXEC. (seeing arm64 protection_map)
>
> Well that's your observation, but not the explanation why arm64 is doing this.
>
> See this would have quite some negative impact on performance, not only for
> gfx drivers but in general.
>
> So either the observation is incorrect or there is a *really* good reason why
> arm64 is taking this performance penalty.
>
> >> When write the userspace virtual address the first fault happen and
> >> call into driver's .fault->ttm_bo_vm_fault_reserved->vmf_insert_pfn_prot-
> >insert_pfn.
> >> The insert_pfn will establish the pte entry. However the
> >> vmf_insert_pfn_prot pass false @mkwrite to insert_pfn by default and
> >> so insert_pfn could not make the pfn writable and it do not call
> >> maybe_mkwrite(pte_mkdirty(entry), vma) to clear the PTE_RDONLY bit. So
> the pte entry is actually write protection for mmu.
> >> So when the first fault return and re-execute the store instruction
> >> the second fault happen again. And in second fault it just only do
> >> pte_mkdirty(entry) which clear the PTE_RDONLY.
> > It depends if the ARM64 CPU in question supports hardware dirty bit
> > management (DBM). If that is the case and PTE_DBM (ie. PTE_WRITE) is
> > set HW will automatically clear PTE_RDONLY bit to mark the entry dirty
> > instead of raising a write fault. So you shouldn't see a double fault
> > if PTE_DBM/WRITE is set.

Thanks. This is reasonable. But I still really had the double faults in my project
platform.

> >
> > On ARM64 you can kind of think of PTE_RDONLY as the HW dirty bit and
> > PTE_DBM as the read/write permission bit with SW being responsible for
> > updating PTE_RDONLY via the fault handler if DBM is not supported by HW.
> >
> > At least that's my understanding from having hacked on this in the
> > past. You can see all this weirdness happening in the definitions of
> > pte_dirty() and pte_write() for ARM64.
>
> +1
>
> Thanks a lot for that, this was exactly the information I was looking for.
>
> In this light it makes this patch here look unnecessary and questionable at
> best.
>
> Xianrong if you have an arm64 platform which really double faults (confirmed
> through a debugger for example) then you have to ask why this platform
> shows this behavior and not try to work around it.
>
> Behaviors like those usually have a very very good reason and without a
> confirmed explanation I'm not allowing any patch in which would disable stuff
> like that.

Thanks. You are very right. I found CONFIG_ARM64_HW_AFDBM is not enabled
in my project. So actually PTE_DBM is not hardware bit. It is software bit.
Now i understand why arm64 to do this attaching PTE_RDONLY automatically.
It is compatible for PTE_DBM hardware or not. This answers your question.

So I met double faults in my project when CONFIG_ARM64_HW_AFDBM is false.
However these double faults can be eliminated when i replace the vmf_insert_mixed
to vmf_insert_mixed_mkwrite in drivers under CONFIG_ARM64_HW_AFDBM = false.
The vmf_insert_pfn_prot is similar with vmf_insert_mixed. It should supply @mkwrite
parameter rather than false mkwrite by default.

So i think if you forgot to enable CONFIG_ARM64_HW_AFDBM or before Armv8 hardware
which might not support PTE_DBM this modification is meaningful.

>
> Regards,
> Christian.
>
> >
> >> I think so and hope no wrong.
> >>
> >>> So as long as this isn't sorted out I'm going to reject this patch.
> >>>
> >>> Regards,
> >>> Christian.
> >>>
> >>>>> This is a completely different use case to what you try to use it
> >>>>> here for and that looks extremely fishy to me.
> >>>>>
> >>>>> Regards,
> >>>>> Christian.
> >>>>>
> >>>>>>>> The first fault only sets up the pte entry which actually is
> >>>>>>>> dirty catching. And the second immediate fault to the pfn due
> >>>>>>>> to first dirty catching when the cpu re-execute the store instruction.
> >>>>>>> It could be that this is done to work around some hw behavior,
> >>>>>>> but not because of dirty catching.
> >>>>>>>
> >>>>>>>> Normally if the drivers call vmf_insert_pfn_prot and also
> >>>>>>>> supply 'pfn_mkwrite' callback within vm_operations_struct which
> >>>>>>>> requires the pte to be dirty catching then the
> >>>>>>>> vmf_insert_pfn_prot and the double fault are reasonable. It is not a
> problem.
> >>>>>>> Well, as far as I can see that behavior absolutely doesn't make sense.
> >>>>>>>
> >>>>>>> When pfn_mkwrite is requested then the driver should use
> >>>>>>> PAGE_COPY, which is exactly what VMWGFX (the only driver using
> >>>>>>> dirty tracking) is
> >>>>> doing.
> >>>>>>> Everybody else uses PAGE_SHARED which should make the pte
> >>>>>>> writeable immediately.
> >>>>>>>
> >>>>>>> Regards,
> >>>>>>> Christian.
> >>>>>>>
> >>>>>>>> However the most of drivers calling vmf_insert_pfn_prot do not
> >>>>>>>> supply the 'pfn_mkwrite' callback so that the second fault is
> >>> unnecessary.
> >>>>>>>> So just like vmf_insert_mixed and vmf_insert_mixed_mkwrite
> >>>>>>>> pair, we should also supply vmf_insert_pfn_mkwrite for drivers as
> well.
> >>>>>>>>
> >>>>>>>> Signed-off-by: Xianrong Zhou <Xianrong.Zhou at amd.com>
> >>>>>>>> ---
> >>>>>>>>      arch/x86/entry/vdso/vma.c                  |  3 ++-
> >>>>>>>>      drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c    |  2 +-
> >>>>>>>>      drivers/gpu/drm/i915/gem/i915_gem_ttm.c    |  2 +-
> >>>>>>>>      drivers/gpu/drm/nouveau/nouveau_gem.c      |  2 +-
> >>>>>>>>      drivers/gpu/drm/radeon/radeon_gem.c        |  2 +-
> >>>>>>>>      drivers/gpu/drm/ttm/ttm_bo_vm.c            |  8 +++++---
> >>>>>>>>      drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c |  8 +++++---
> >>>>>>>>      include/drm/ttm/ttm_bo.h                   |  3 ++-
> >>>>>>>>      include/linux/mm.h                         |  2 +-
> >>>>>>>>      mm/memory.c                                | 14 +++++++++++---
> >>>>>>>>      10 files changed, 30 insertions(+), 16 deletions(-)
> >>>>>>>>
> >>>>>>>> diff --git a/arch/x86/entry/vdso/vma.c
> >>>>>>>> b/arch/x86/entry/vdso/vma.c index
> 7645730dc228..dd2431c2975f
> >>>>>>>> 100644
> >>>>>>>> --- a/arch/x86/entry/vdso/vma.c
> >>>>>>>> +++ b/arch/x86/entry/vdso/vma.c
> >>>>>>>> @@ -185,7 +185,8 @@ static vm_fault_t vvar_fault(const struct
> >>>>>>> vm_special_mapping *sm,
> >>>>>>>>                if (pvti &&
> >>>>>>>> vclock_was_used(VDSO_CLOCKMODE_PVCLOCK))
> >>>>>>> {
> >>>>>>>>                        return vmf_insert_pfn_prot(vma, vmf->address,
> >>>>>>>>                                        __pa(pvti) >> PAGE_SHIFT,
> >>>>>>>> -                                   pgprot_decrypted(vma-
> >>>>>>>> vm_page_prot));
> >>>>>>>> +                                   pgprot_decrypted(vma-
> >>>>>>>> vm_page_prot),
> >>>>>>>> +                                   true);
> >>>>>>>>                }
> >>>>>>>>        } else if (sym_offset == image->sym_hvclock_page) {
> >>>>>>>>                pfn = hv_get_tsc_pfn(); diff --git
> >>>>>>>> a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> >>>>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> >>>>>>>> index 49a5f1c73b3e..adcb20d9e624 100644
> >>>>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> >>>>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
> >>>>>>>> @@ -64,7 +64,7 @@ static vm_fault_t amdgpu_gem_fault(struct
> >>>>> vm_fault
> >>>>>>> *vmf)
> >>>>>>>>                }
> >>>>>>>>
> >>>>>>>>                ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma-
> >>>>>>>> vm_page_prot,
> >>>>>>>> -                                          TTM_BO_VM_NUM_PREFAULT);
> >>>>>>>> +
> >>>>>>>> + TTM_BO_VM_NUM_PREFAULT,
> >>>>>>> true);
> >>>>>>>>                drm_dev_exit(idx);
> >>>>>>>>        } else {
> >>>>>>>> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> >>>>>>>> b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> >>>>>>>> index 9227f8146a58..c6f13ae6c308 100644
> >>>>>>>> --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> >>>>>>>> +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> >>>>>>>> @@ -1114,7 +1114,7 @@ static vm_fault_t vm_fault_ttm(struct
> >>>>>>>> vm_fault
> >>>>>>>> *vmf)
> >>>>>>>>
> >>>>>>>>        if (drm_dev_enter(dev, &idx)) {
> >>>>>>>>                ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma-
> >>>>>>>> vm_page_prot,
> >>>>>>>> -                                          TTM_BO_VM_NUM_PREFAULT);
> >>>>>>>> +
> >>>>>>>> + TTM_BO_VM_NUM_PREFAULT,
> >>>>>>> true);
> >>>>>>>>                drm_dev_exit(idx);
> >>>>>>>>        } else {
> >>>>>>>>                ret = ttm_bo_vm_dummy_page(vmf, vmf->vma-
> >>>>>>>> vm_page_prot); diff --git
> >>>>>>>> a/drivers/gpu/drm/nouveau/nouveau_gem.c
> >>>>>>>> b/drivers/gpu/drm/nouveau/nouveau_gem.c
> >>>>>>>> index 49c2bcbef129..7e1453762ec9 100644
> >>>>>>>> --- a/drivers/gpu/drm/nouveau/nouveau_gem.c
> >>>>>>>> +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
> >>>>>>>> @@ -56,7 +56,7 @@ static vm_fault_t nouveau_ttm_fault(struct
> >>>>>>>> vm_fault
> >>>>>>>> *vmf)
> >>>>>>>>
> >>>>>>>>        nouveau_bo_del_io_reserve_lru(bo);
> >>>>>>>>        prot = vm_get_page_prot(vma->vm_flags);
> >>>>>>>> -   ret = ttm_bo_vm_fault_reserved(vmf, prot,
> >>>>>>> TTM_BO_VM_NUM_PREFAULT);
> >>>>>>>> +   ret = ttm_bo_vm_fault_reserved(vmf, prot,
> >>>>>>> TTM_BO_VM_NUM_PREFAULT,
> >>>>>>>> +true);
> >>>>>>>>        nouveau_bo_add_io_reserve_lru(bo);
> >>>>>>>>        if (ret == VM_FAULT_RETRY && !(vmf->flags &
> >>>>>>> FAULT_FLAG_RETRY_NOWAIT))
> >>>>>>>>                return ret;
> >>>>>>>> diff --git a/drivers/gpu/drm/radeon/radeon_gem.c
> >>>>>>>> b/drivers/gpu/drm/radeon/radeon_gem.c
> >>>>>>>> index 3fec3acdaf28..b21cf00ae162 100644
> >>>>>>>> --- a/drivers/gpu/drm/radeon/radeon_gem.c
> >>>>>>>> +++ b/drivers/gpu/drm/radeon/radeon_gem.c
> >>>>>>>> @@ -62,7 +62,7 @@ static vm_fault_t radeon_gem_fault(struct
> >>>>>>>> vm_fault
> >>>>>>> *vmf)
> >>>>>>>>                goto unlock_resv;
> >>>>>>>>
> >>>>>>>>        ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma-
> >vm_page_prot,
> >>>>>>>> -                                  TTM_BO_VM_NUM_PREFAULT);
> >>>>>>>> +                                  TTM_BO_VM_NUM_PREFAULT,
> >>>>>>>> + true);
> >>>>>>>>        if (ret == VM_FAULT_RETRY && !(vmf->flags &
> >>>>>>> FAULT_FLAG_RETRY_NOWAIT))
> >>>>>>>>                goto unlock_mclk;
> >>>>>>>>
> >>>>>>>> diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c
> >>>>>>>> b/drivers/gpu/drm/ttm/ttm_bo_vm.c index
> >>>>>>> 4212b8c91dd4..7d14a7d267aa
> >>>>>>>> 100644
> >>>>>>>> --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
> >>>>>>>> +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
> >>>>>>>> @@ -167,6 +167,7 @@ EXPORT_SYMBOL(ttm_bo_vm_reserve);
> >>>>>>>>       * @num_prefault: Maximum number of prefault pages. The
> >>>>>>>> caller may
> >>>>>>> want to
> >>>>>>>>       * specify this based on madvice settings and the size of
> >>>>>>>> the GPU
> >>> object
> >>>>>>>>       * backed by the memory.
> >>>>>>>> + * @mkwrite: make the pfn or page writable
> >>>>>>>>       *
> >>>>>>>>       * This function inserts one or more page table entries pointing to
> the
> >>>>>>>>       * memory backing the buffer object, and then returns a
> >>>>>>>> return code @@ -180,7 +181,8 @@
> EXPORT_SYMBOL(ttm_bo_vm_reserve);
> >>>>>>>>       */
> >>>>>>>>      vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
> >>>>>>>>                                    pgprot_t prot,
> >>>>>>>> -                               pgoff_t num_prefault)
> >>>>>>>> +                               pgoff_t num_prefault,
> >>>>>>>> +                               bool mkwrite)
> >>>>>>>>      {
> >>>>>>>>        struct vm_area_struct *vma = vmf->vma;
> >>>>>>>>        struct ttm_buffer_object *bo = vma->vm_private_data; @@
> >>>>>>>> -263,7
> >>>>>>>> +265,7 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault
> >>>>>>>> +*vmf,
> >>>>>>>>                 * at arbitrary times while the data is mmap'ed.
> >>>>>>>>                 * See vmf_insert_pfn_prot() for a discussion.
> >>>>>>>>                 */
> >>>>>>>> -           ret = vmf_insert_pfn_prot(vma, address, pfn, prot);
> >>>>>>>> +           ret = vmf_insert_pfn_prot(vma, address, pfn, prot,
> >>>>>>>> + mkwrite);
> >>>>>>>>
> >>>>>>>>                /* Never error on prefaulted PTEs */
> >>>>>>>>                if (unlikely((ret & VM_FAULT_ERROR))) { @@
> >>>>>>>> -312,7
> >>>>>>>> +314,7
> >>>>>>> @@
> >>>>>>>> vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf,
> pgprot_t
> >>>>> prot)
> >>>>>>>>        /* Prefault the entire VMA range right away to avoid further
> faults */
> >>>>>>>>        for (address = vma->vm_start; address < vma->vm_end;
> >>>>>>>>             address += PAGE_SIZE)
> >>>>>>>> -           ret = vmf_insert_pfn_prot(vma, address, pfn, prot);
> >>>>>>>> +           ret = vmf_insert_pfn_prot(vma, address, pfn, prot,
> >>>>>>>> + true);
> >>>>>>>>
> >>>>>>>>        return ret;
> >>>>>>>>      }
> >>>>>>>> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
> >>>>>>>> b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
> >>>>>>>> index 74ff2812d66a..bb8e4b641681 100644
> >>>>>>>> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
> >>>>>>>> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c
> >>>>>>>> @@ -452,12 +452,14 @@ vm_fault_t vmw_bo_vm_fault(struct
> >>> vm_fault
> >>>>>>> *vmf)
> >>>>>>>>         * sure the page protection is write-enabled so we don't get
> >>>>>>>>         * a lot of unnecessary write faults.
> >>>>>>>>         */
> >>>>>>>> -   if (vbo->dirty && vbo->dirty->method ==
> >>> VMW_BO_DIRTY_MKWRITE)
> >>>>>>>> +   if (vbo->dirty && vbo->dirty->method ==
> >>> VMW_BO_DIRTY_MKWRITE)
> >>>>>>> {
> >>>>>>>>                prot = vm_get_page_prot(vma->vm_flags & ~VM_SHARED);
> >>>>>>>> -   else
> >>>>>>>> +           ret = ttm_bo_vm_fault_reserved(vmf, prot,
> >>>>>>>> + num_prefault,
> >>>>>>> false);
> >>>>>>>> +   } else {
> >>>>>>>>                prot = vm_get_page_prot(vma->vm_flags);
> >>>>>>>> +           ret = ttm_bo_vm_fault_reserved(vmf, prot,
> >>>>>>>> + num_prefault,
> >>>>>>> true);
> >>>>>>>> +   }
> >>>>>>>>
> >>>>>>>> -   ret = ttm_bo_vm_fault_reserved(vmf, prot, num_prefault);
> >>>>>>>>        if (ret == VM_FAULT_RETRY && !(vmf->flags &
> >>>>>>> FAULT_FLAG_RETRY_NOWAIT))
> >>>>>>>>                return ret;
> >>>>>>>>
> >>>>>>>> diff --git a/include/drm/ttm/ttm_bo.h
> >>>>>>>> b/include/drm/ttm/ttm_bo.h index
> 0223a41a64b2..66e293db69ee
> >>>>>>>> 100644
> >>>>>>>> --- a/include/drm/ttm/ttm_bo.h
> >>>>>>>> +++ b/include/drm/ttm/ttm_bo.h
> >>>>>>>> @@ -386,7 +386,8 @@ vm_fault_t ttm_bo_vm_reserve(struct
> >>>>>>> ttm_buffer_object *bo,
> >>>>>>>>                             struct vm_fault *vmf);
> >>>>>>>>      vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
> >>>>>>>>                                    pgprot_t prot,
> >>>>>>>> -                               pgoff_t num_prefault);
> >>>>>>>> +                               pgoff_t num_prefault,
> >>>>>>>> +                               bool mkwrite);
> >>>>>>>>      vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf);
> >>>>>>>>      void ttm_bo_vm_open(struct vm_area_struct *vma);
> >>>>>>>>      void ttm_bo_vm_close(struct vm_area_struct *vma); diff
> >>>>>>>> --git a/include/linux/mm.h b/include/linux/mm.h index
> >>>>>>>> f5a97dec5169..f8868e28ea04 100644
> >>>>>>>> --- a/include/linux/mm.h
> >>>>>>>> +++ b/include/linux/mm.h
> >>>>>>>> @@ -3553,7 +3553,7 @@ int vm_map_pages_zero(struct
> >>>>> vm_area_struct
> >>>>>>> *vma, struct page **pages,
> >>>>>>>>      vm_fault_t vmf_insert_pfn(struct vm_area_struct *vma,
> >>>>>>>> unsigned long
> >>>>>>> addr,
> >>>>>>>>                        unsigned long pfn);
> >>>>>>>>      vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma,
> >>>>>>>> unsigned
> >>>>>>> long addr,
> >>>>>>>> -                   unsigned long pfn, pgprot_t pgprot);
> >>>>>>>> +                   unsigned long pfn, pgprot_t pgprot, bool
> >>>>>>>> + mkwrite);
> >>>>>>>>      vm_fault_t vmf_insert_mixed(struct vm_area_struct *vma,
> >>>>>>>> unsigned long
> >>>>>>> addr,
> >>>>>>>>                        pfn_t pfn);
> >>>>>>>>      vm_fault_t vmf_insert_mixed_mkwrite(struct vm_area_struct
> >>>>>>>> *vma, diff --git a/mm/memory.c b/mm/memory.c index
> >>>>>>>> 7e1f4849463a..2c28f1a349ff
> >>>>>>>> 100644
> >>>>>>>> --- a/mm/memory.c
> >>>>>>>> +++ b/mm/memory.c
> >>>>>>>> @@ -2195,6 +2195,7 @@ static vm_fault_t insert_pfn(struct
> >>>>>>> vm_area_struct *vma, unsigned long addr,
> >>>>>>>>       * @addr: target user address of this page
> >>>>>>>>       * @pfn: source kernel pfn
> >>>>>>>>       * @pgprot: pgprot flags for the inserted page
> >>>>>>>> + * @mkwrite: make the pfn writable
> >>>>>>>>       *
> >>>>>>>>       * This is exactly like vmf_insert_pfn(), except that it allows drivers
> >>>>>>>>       * to override pgprot on a per-page basis.
> >>>>>>>> @@ -2223,7 +2224,7 @@ static vm_fault_t insert_pfn(struct
> >>>>>>> vm_area_struct *vma, unsigned long addr,
> >>>>>>>>       * Return: vm_fault_t value.
> >>>>>>>>       */
> >>>>>>>>      vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma,
> >>>>>>>> unsigned
> >>>>>>> long addr,
> >>>>>>>> -                   unsigned long pfn, pgprot_t pgprot)
> >>>>>>>> +                   unsigned long pfn, pgprot_t pgprot, bool
> >>>>>>>> + mkwrite)
> >>>>>>>>      {
> >>>>>>>>        /*
> >>>>>>>>         * Technically, architectures with pte_special can avoid
> >>>>>>>> all these @@ -2246,7 +2247,7 @@ vm_fault_t
> >>> vmf_insert_pfn_prot(struct
> >>>>>>> vm_area_struct *vma, unsigned long addr,
> >>>>>>>>        track_pfn_insert(vma, &pgprot, __pfn_to_pfn_t(pfn,
> >>>>>>>> PFN_DEV));
> >>>>>>>>
> >>>>>>>>        return insert_pfn(vma, addr, __pfn_to_pfn_t(pfn,
> >>>>>>>> PFN_DEV),
> >>> pgprot,
> >>>>>>>> -                   false);
> >>>>>>>> +                   mkwrite);
> >>>>>>>>      }
> >>>>>>>>      EXPORT_SYMBOL(vmf_insert_pfn_prot);
> >>>>>>>>
> >>>>>>>> @@ -2273,10 +2274,17 @@
> EXPORT_SYMBOL(vmf_insert_pfn_prot);
> >>>>>>>>      vm_fault_t vmf_insert_pfn(struct vm_area_struct *vma,
> >>>>>>>> unsigned long
> >>>>>>> addr,
> >>>>>>>>                        unsigned long pfn)
> >>>>>>>>      {
> >>>>>>>> -   return vmf_insert_pfn_prot(vma, addr, pfn, vma-
> >vm_page_prot);
> >>>>>>>> +   return vmf_insert_pfn_prot(vma, addr, pfn,
> >>>>>>>> +vma->vm_page_prot, false);
> >>>>>>>>      }
> >>>>>>>>      EXPORT_SYMBOL(vmf_insert_pfn);
> >>>>>>>>
> >>>>>>>> +vm_fault_t vmf_insert_pfn_mkwrite(struct vm_area_struct *vma,
> >>>>>>>> +unsigned
> >>>>>>> long addr,
> >>>>>>>> +                   unsigned long pfn) {
> >>>>>>>> +   return vmf_insert_pfn_prot(vma, addr, pfn,
> >>>>>>>> + vma->vm_page_prot,
> >>>>>>> true);
> >>>>>>>> +} EXPORT_SYMBOL(vmf_insert_pfn_mkwrite);
> >>>>>>>> +
> >>>>>>>>      static bool vm_mixed_ok(struct vm_area_struct *vma, pfn_t pfn)
> >>>>>>>>      {
> >>>>>>>>        /* these checks mirror the abort conditions in
> >>>>>>>> vm_normal_page */



More information about the amd-gfx mailing list