mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-20 00:26:39 +08:00
x86, CPA: Add set_pages_arrayuc and set_pages_array_wb
Add new interfaces: set_pages_array_uc() set_pages_array_wb() that can be used change the page attribute for a bunch of pages with flush etc done once at the end of all the changes. These interfaces are similar to existing set_memory_array_uc() and set_memory_array_wc(). Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Cc: arjan@infradead.org Cc: eric@anholt.net Cc: airlied@redhat.com LKML-Reference: <20090319215358.901545000@intel.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
9ae2847591
commit
0f3507555f
@ -90,6 +90,9 @@ int set_memory_4k(unsigned long addr, int numpages);
|
||||
int set_memory_array_uc(unsigned long *addr, int addrinarray);
|
||||
int set_memory_array_wb(unsigned long *addr, int addrinarray);
|
||||
|
||||
int set_pages_array_uc(struct page **pages, int addrinarray);
|
||||
int set_pages_array_wb(struct page **pages, int addrinarray);
|
||||
|
||||
/*
|
||||
* For legacy compatibility with the old APIs, a few functions
|
||||
* are provided that work on a "struct page".
|
||||
|
@ -920,6 +920,20 @@ static inline int change_page_attr_clear(unsigned long *addr, int numpages,
|
||||
(array ? CPA_ARRAY : 0), NULL);
|
||||
}
|
||||
|
||||
static inline int cpa_set_pages_array(struct page **pages, int numpages,
|
||||
pgprot_t mask)
|
||||
{
|
||||
return change_page_attr_set_clr(NULL, numpages, mask, __pgprot(0), 0,
|
||||
CPA_PAGES_ARRAY, pages);
|
||||
}
|
||||
|
||||
static inline int cpa_clear_pages_array(struct page **pages, int numpages,
|
||||
pgprot_t mask)
|
||||
{
|
||||
return change_page_attr_set_clr(NULL, numpages, __pgprot(0), mask, 0,
|
||||
CPA_PAGES_ARRAY, pages);
|
||||
}
|
||||
|
||||
int _set_memory_uc(unsigned long addr, int numpages)
|
||||
{
|
||||
/*
|
||||
@ -1076,6 +1090,35 @@ int set_pages_uc(struct page *page, int numpages)
|
||||
}
|
||||
EXPORT_SYMBOL(set_pages_uc);
|
||||
|
||||
int set_pages_array_uc(struct page **pages, int addrinarray)
|
||||
{
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
int i;
|
||||
int free_idx;
|
||||
|
||||
for (i = 0; i < addrinarray; i++) {
|
||||
start = (unsigned long)page_address(pages[i]);
|
||||
end = start + PAGE_SIZE;
|
||||
if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL))
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (cpa_set_pages_array(pages, addrinarray,
|
||||
__pgprot(_PAGE_CACHE_UC_MINUS)) == 0) {
|
||||
return 0; /* Success */
|
||||
}
|
||||
err_out:
|
||||
free_idx = i;
|
||||
for (i = 0; i < free_idx; i++) {
|
||||
start = (unsigned long)page_address(pages[i]);
|
||||
end = start + PAGE_SIZE;
|
||||
free_memtype(start, end);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL(set_pages_array_uc);
|
||||
|
||||
int set_pages_wb(struct page *page, int numpages)
|
||||
{
|
||||
unsigned long addr = (unsigned long)page_address(page);
|
||||
@ -1084,6 +1127,26 @@ int set_pages_wb(struct page *page, int numpages)
|
||||
}
|
||||
EXPORT_SYMBOL(set_pages_wb);
|
||||
|
||||
int set_pages_array_wb(struct page **pages, int addrinarray)
|
||||
{
|
||||
int retval;
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
int i;
|
||||
|
||||
retval = cpa_clear_pages_array(pages, addrinarray,
|
||||
__pgprot(_PAGE_CACHE_MASK));
|
||||
|
||||
for (i = 0; i < addrinarray; i++) {
|
||||
start = (unsigned long)page_address(pages[i]);
|
||||
end = start + PAGE_SIZE;
|
||||
free_memtype(start, end);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL(set_pages_array_wb);
|
||||
|
||||
int set_pages_x(struct page *page, int numpages)
|
||||
{
|
||||
unsigned long addr = (unsigned long)page_address(page);
|
||||
|
Loading…
Reference in New Issue
Block a user