Skip to content

Commit 8a295db

Browse files
Ralph Campbellakpm00
authored andcommitted
mm/hmm: fault non-owner device private entries
If hmm_range_fault() is called with the HMM_PFN_REQ_FAULT flag and a device private PTE is found, the hmm_range::dev_private_owner page is used to determine if the device private page should not be faulted in. However, if the device private page is not owned by the caller, hmm_range_fault() returns an error instead of calling migrate_to_ram() to fault in the page. For example, if a page is migrated to GPU private memory and a RDMA fault capable NIC tries to read the migrated page, without this patch it will get an error. With this patch, the page will be migrated back to system memory and the NIC will be able to read the data. Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Fixes: 08ddddd ("mm/hmm: check the device private page owner in hmm_range_fault()") Signed-off-by: Ralph Campbell <[email protected]> Reported-by: Felix Kuehling <[email protected]> Reviewed-by: Alistair Popple <[email protected]> Cc: Philip Yang <[email protected]> Cc: Jason Gunthorpe <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 9282012 commit 8a295db

File tree

1 file changed

+8
-11
lines changed

1 file changed

+8
-11
lines changed

mm/hmm.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,6 @@ int hmm_vma_handle_pmd(struct mm_walk *walk, unsigned long addr,
212212
unsigned long end, unsigned long hmm_pfns[], pmd_t pmd);
213213
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
214214

215-
static inline bool hmm_is_device_private_entry(struct hmm_range *range,
216-
swp_entry_t entry)
217-
{
218-
return is_device_private_entry(entry) &&
219-
pfn_swap_entry_to_page(entry)->pgmap->owner ==
220-
range->dev_private_owner;
221-
}
222-
223215
static inline unsigned long pte_to_hmm_pfn_flags(struct hmm_range *range,
224216
pte_t pte)
225217
{
@@ -252,10 +244,12 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
252244
swp_entry_t entry = pte_to_swp_entry(pte);
253245

254246
/*
255-
* Never fault in device private pages, but just report
256-
* the PFN even if not present.
247+
* Don't fault in device private pages owned by the caller,
248+
* just report the PFN.
257249
*/
258-
if (hmm_is_device_private_entry(range, entry)) {
250+
if (is_device_private_entry(entry) &&
251+
pfn_swap_entry_to_page(entry)->pgmap->owner ==
252+
range->dev_private_owner) {
259253
cpu_flags = HMM_PFN_VALID;
260254
if (is_writable_device_private_entry(entry))
261255
cpu_flags |= HMM_PFN_WRITE;
@@ -273,6 +267,9 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
273267
if (!non_swap_entry(entry))
274268
goto fault;
275269

270+
if (is_device_private_entry(entry))
271+
goto fault;
272+
276273
if (is_device_exclusive_entry(entry))
277274
goto fault;
278275

0 commit comments

Comments
 (0)