xref: /OK3568_Linux_fs/kernel/tools/testing/nvdimm/dax-dev.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2016, Intel Corporation.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun #include "test/nfit_test.h"
6*4882a593Smuzhiyun #include <linux/mm.h>
7*4882a593Smuzhiyun #include "../../../drivers/dax/dax-private.h"
8*4882a593Smuzhiyun 
dax_pgoff_to_phys(struct dev_dax * dev_dax,pgoff_t pgoff,unsigned long size)9*4882a593Smuzhiyun phys_addr_t dax_pgoff_to_phys(struct dev_dax *dev_dax, pgoff_t pgoff,
10*4882a593Smuzhiyun 		unsigned long size)
11*4882a593Smuzhiyun {
12*4882a593Smuzhiyun 	int i;
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun 	for (i = 0; i < dev_dax->nr_range; i++) {
15*4882a593Smuzhiyun 		struct dev_dax_range *dax_range = &dev_dax->ranges[i];
16*4882a593Smuzhiyun 		struct range *range = &dax_range->range;
17*4882a593Smuzhiyun 		unsigned long long pgoff_end;
18*4882a593Smuzhiyun 		phys_addr_t addr;
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun 		pgoff_end = dax_range->pgoff + PHYS_PFN(range_len(range)) - 1;
21*4882a593Smuzhiyun 		if (pgoff < dax_range->pgoff || pgoff > pgoff_end)
22*4882a593Smuzhiyun 			continue;
23*4882a593Smuzhiyun 		addr = PFN_PHYS(pgoff - dax_range->pgoff) + range->start;
24*4882a593Smuzhiyun 		if (addr + size - 1 <= range->end) {
25*4882a593Smuzhiyun 			if (get_nfit_res(addr)) {
26*4882a593Smuzhiyun 				struct page *page;
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 				if (dev_dax->region->align > PAGE_SIZE)
29*4882a593Smuzhiyun 					return -1;
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun 				page = vmalloc_to_page((void *)addr);
32*4882a593Smuzhiyun 				return PFN_PHYS(page_to_pfn(page));
33*4882a593Smuzhiyun 			}
34*4882a593Smuzhiyun 			return addr;
35*4882a593Smuzhiyun 		}
36*4882a593Smuzhiyun 		break;
37*4882a593Smuzhiyun 	}
38*4882a593Smuzhiyun 	return -1;
39*4882a593Smuzhiyun }
40