aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/pat.h5
-rw-r--r--arch/x86/mm/pat.c49
2 files changed, 54 insertions, 0 deletions
diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h
index 7af14e512f97..e2c1668dde7a 100644
--- a/arch/x86/include/asm/pat.h
+++ b/arch/x86/include/asm/pat.h
@@ -19,4 +19,9 @@ extern int free_memtype(u64 start, u64 end);
19extern int kernel_map_sync_memtype(u64 base, unsigned long size, 19extern int kernel_map_sync_memtype(u64 base, unsigned long size,
20 unsigned long flag); 20 unsigned long flag);
21 21
22int io_reserve_memtype(resource_size_t start, resource_size_t end,
23 unsigned long *type);
24
25void io_free_memtype(resource_size_t start, resource_size_t end);
26
22#endif /* _ASM_X86_PAT_H */ 27#endif /* _ASM_X86_PAT_H */
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index d5af2792d2fd..82d097ce3091 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -498,6 +498,55 @@ int free_memtype(u64 start, u64 end)
498} 498}
499 499
500 500
501/**
502 * io_reserve_memtype - Request a memory type mapping for a region of memory
503 * @start: start (physical address) of the region
504 * @end: end (physical address) of the region
505 * @type: A pointer to memtype, with requested type. On success, requested
506 * or any other compatible type that was available for the region is returned
507 *
508 * On success, returns 0
509 * On failure, returns non-zero
510 */
511int io_reserve_memtype(resource_size_t start, resource_size_t end,
512 unsigned long *type)
513{
514 unsigned long req_type = *type;
515 unsigned long new_type;
516 int ret;
517
518 WARN_ON_ONCE(iomem_map_sanity_check(start, end - start));
519
520 ret = reserve_memtype(start, end, req_type, &new_type);
521 if (ret)
522 goto out_err;
523
524 if (!is_new_memtype_allowed(req_type, new_type))
525 goto out_free;
526
527 if (kernel_map_sync_memtype(start, end - start, new_type) < 0)
528 goto out_free;
529
530 *type = new_type;
531 return 0;
532
533out_free:
534 free_memtype(start, end);
535 ret = -EBUSY;
536out_err:
537 return ret;
538}
539
540/**
541 * io_free_memtype - Release a memory type mapping for a region of memory
542 * @start: start (physical address) of the region
543 * @end: end (physical address) of the region
544 */
545void io_free_memtype(resource_size_t start, resource_size_t end)
546{
547 free_memtype(start, end);
548}
549
501pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, 550pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
502 unsigned long size, pgprot_t vma_prot) 551 unsigned long size, pgprot_t vma_prot)
503{ 552{