linuxkpi: Fix uses of pmap_change_attr()

[Why]
This function takes an offset and a length as argument, not a physical
address and a number of pages.

This misuse caused the `set_memory_*()` and
`arch_io_reserve_memtype_wc()` functions to return EINVAL.

Another problem was the fact that they returned errors as a positive
integer, whereas Linux uses negative integers.

[How]
Physical addresses and number of pages are converted to offset+length in
the `set_memory_*()` functions.

`arch_io_reserve_memtype_wc()` now calls `pmap_change_attr()` directly
instead of using `set_memory_wc()`.

Reviewed by:	manu
Approved by:	manu
Differential Revision:	https://reviews.freebsd.org/D42053

(cherry picked from commit 1e99b2ee90956f275c3668e92a408400f2dada1c)
This commit is contained in:
Jean-Sébastien Pédron 2023-08-16 22:32:42 +02:00 committed by Vladimir Kondratyev
parent adac86cd7b
commit bb01efa6f8
2 changed files with 34 additions and 5 deletions

View file

@ -34,14 +34,26 @@
static inline int
set_memory_uc(unsigned long addr, int numpages)
{
return (pmap_change_attr(addr, numpages, VM_MEMATTR_UNCACHEABLE));
vm_offset_t va;
vm_size_t len;
va = PHYS_TO_DMAP(addr);
len = numpages << PAGE_SHIFT;
return (-pmap_change_attr(va, len, VM_MEMATTR_UNCACHEABLE));
}
static inline int
set_memory_wc(unsigned long addr, int numpages)
{
#ifdef VM_MEMATTR_WRITE_COMBINING
return (pmap_change_attr(addr, numpages, VM_MEMATTR_WRITE_COMBINING));
vm_offset_t va;
vm_size_t len;
va = PHYS_TO_DMAP(addr);
len = numpages << PAGE_SHIFT;
return (-pmap_change_attr(va, len, VM_MEMATTR_WRITE_COMBINING));
#else
return (set_memory_uc(addr, numpages));
#endif
@ -50,7 +62,13 @@ set_memory_wc(unsigned long addr, int numpages)
static inline int
set_memory_wb(unsigned long addr, int numpages)
{
return (pmap_change_attr(addr, numpages, VM_MEMATTR_WRITE_BACK));
vm_offset_t va;
vm_size_t len;
va = PHYS_TO_DMAP(addr);
len = numpages << PAGE_SHIFT;
return (-pmap_change_attr(va, len, VM_MEMATTR_WRITE_BACK));
}
static inline int

View file

@ -532,14 +532,25 @@ void lkpi_arch_phys_wc_del(int);
static inline int
arch_io_reserve_memtype_wc(resource_size_t start, resource_size_t size)
{
vm_offset_t va;
return (set_memory_wc(start, size >> PAGE_SHIFT));
va = PHYS_TO_DMAP(start);
#ifdef VM_MEMATTR_WRITE_COMBINING
return (-pmap_change_attr(va, size, VM_MEMATTR_WRITE_COMBINING));
#else
return (-pmap_change_attr(va, size, VM_MEMATTR_UNCACHEABLE));
#endif
}
static inline void
arch_io_free_memtype_wc(resource_size_t start, resource_size_t size)
{
set_memory_wb(start, size >> PAGE_SHIFT);
vm_offset_t va;
va = PHYS_TO_DMAP(start);
pmap_change_attr(va, size, VM_MEMATTR_WRITE_BACK);
}
#endif