Skip to content

Commit

Permalink
x86, pat: New i/f for driver to request memtype for IO regions
Browse files Browse the repository at this point in the history
Add new routines to request memtype for IO regions. This will currently
be a backend for io_mapping_* routines. But, it can also be made available
to drivers directly in future, in case it is needed.

reserve interface reserves the memory, makes sure we have a compatible
memory type available and keeps the identity map in sync when needed.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
  • Loading branch information
Venkatesh Pallipadi authored and H. Peter Anvin committed Aug 26, 2009
1 parent 279e669 commit 9fd126b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
5 changes: 5 additions & 0 deletions arch/x86/include/asm/pat.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ extern int free_memtype(u64 start, u64 end);
extern int kernel_map_sync_memtype(u64 base, unsigned long size,
unsigned long flag);

int io_reserve_memtype(resource_size_t start, resource_size_t end,
unsigned long *type);

void io_free_memtype(resource_size_t start, resource_size_t end);

#endif /* _ASM_X86_PAT_H */
49 changes: 49 additions & 0 deletions arch/x86/mm/pat.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,55 @@ int free_memtype(u64 start, u64 end)
}


/**
* io_reserve_memtype - Request a memory type mapping for a region of memory
* @start: start (physical address) of the region
* @end: end (physical address) of the region
* @type: A pointer to memtype, with requested type. On success, requested
* or any other compatible type that was available for the region is returned
*
* On success, returns 0
* On failure, returns non-zero
*/
int io_reserve_memtype(resource_size_t start, resource_size_t end,
unsigned long *type)
{
unsigned long req_type = *type;
unsigned long new_type;
int ret;

WARN_ON_ONCE(iomem_map_sanity_check(start, end - start));

ret = reserve_memtype(start, end, req_type, &new_type);
if (ret)
goto out_err;

if (!is_new_memtype_allowed(req_type, new_type))
goto out_free;

if (kernel_map_sync_memtype(start, end - start, new_type) < 0)
goto out_free;

*type = new_type;
return 0;

out_free:
free_memtype(start, end);
ret = -EBUSY;
out_err:
return ret;
}

/**
* io_free_memtype - Release a memory type mapping for a region of memory
* @start: start (physical address) of the region
* @end: end (physical address) of the region
*/
void io_free_memtype(resource_size_t start, resource_size_t end)
{
free_memtype(start, end);
}

pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t vma_prot)
{
Expand Down

0 comments on commit 9fd126b

Please sign in to comment.