mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Allow DMA address width to be overridden with boot parameters:
In Xen: dma_bits=28 (for example) In Linux: swiotlb_bits=28 (for example) Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
f8cd45575d
commit
b2cb3ada56
7 files changed
+60
-26
No files matched your search
@@ -48,7 +48,7 @@ EXPORT_SYMBOL(swiotlb);
|
||||
#define IO_TLB_SHIFT 11
|
||||
|
||||
/* Width of DMA addresses in the IO TLB. 30 bits is a b44 limitation. */
|
||||
#define IO_TLB_DMA_BITS 30
|
||||
#define DEFAULT_IO_TLB_DMA_BITS 30
|
||||
|
||||
static int swiotlb_force;
|
||||
static char *iotlb_virt_start;
|
||||
@@ -98,6 +98,15 @@ static struct phys_addr {
|
||||
*/
|
||||
static DEFINE_SPINLOCK(io_tlb_lock);
|
||||
|
||||
static unsigned int io_tlb_dma_bits = DEFAULT_IO_TLB_DMA_BITS;
|
||||
static int __init
|
||||
setup_io_tlb_bits(char *str)
|
||||
{
|
||||
io_tlb_dma_bits = simple_strtoul(str, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
__setup("swiotlb_bits=", setup_io_tlb_bits);
|
||||
|
||||
static int __init
|
||||
setup_io_tlb_npages(char *str)
|
||||
{
|
||||
@@ -158,7 +167,7 @@ swiotlb_init_with_default_size (size_t default_size)
|
||||
int rc = xen_create_contiguous_region(
|
||||
(unsigned long)iotlb_virt_start + (i << IO_TLB_SHIFT),
|
||||
get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT),
|
||||
IO_TLB_DMA_BITS);
|
||||
io_tlb_dma_bits);
|
||||
BUG_ON(rc);
|
||||
}
|
||||
|
||||
@@ -183,10 +192,12 @@ swiotlb_init_with_default_size (size_t default_size)
|
||||
|
||||
printk(KERN_INFO "Software IO TLB enabled: \n"
|
||||
" Aperture: %lu megabytes\n"
|
||||
" Kernel range: 0x%016lx - 0x%016lx\n",
|
||||
" Kernel range: 0x%016lx - 0x%016lx\n"
|
||||
" Address size: %u bits\n",
|
||||
bytes >> 20,
|
||||
(unsigned long)iotlb_virt_start,
|
||||
(unsigned long)iotlb_virt_start + bytes);
|
||||
(unsigned long)iotlb_virt_start + bytes,
|
||||
io_tlb_dma_bits);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -654,7 +665,7 @@ swiotlb_dma_mapping_error(dma_addr_t dma_addr)
|
||||
int
|
||||
swiotlb_dma_supported (struct device *hwdev, u64 mask)
|
||||
{
|
||||
return (mask >= ((1UL << IO_TLB_DMA_BITS) - 1));
|
||||
return (mask >= ((1UL << io_tlb_dma_bits) - 1));
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(swiotlb_init);
|
||||
|
||||
+2
-2
@@ -328,7 +328,7 @@ static long memory_exchange(XEN_GUEST_HANDLE(xen_memory_exchange_t) arg)
|
||||
(exch.out.address_bits <
|
||||
(get_order_from_pages(max_page) + PAGE_SHIFT)) )
|
||||
{
|
||||
if ( exch.out.address_bits < MAX_DMADOM_BITS )
|
||||
if ( exch.out.address_bits < dma_bitsize )
|
||||
{
|
||||
rc = -ENOMEM;
|
||||
goto fail_early;
|
||||
@@ -541,7 +541,7 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
(reservation.address_bits <
|
||||
(get_order_from_pages(max_page) + PAGE_SHIFT)) )
|
||||
{
|
||||
if ( reservation.address_bits < MAX_DMADOM_BITS )
|
||||
if ( reservation.address_bits < dma_bitsize )
|
||||
return start_extent;
|
||||
args.memflags = MEMF_dma;
|
||||
}
|
||||
|
||||
+35
-12
@@ -45,19 +45,40 @@
|
||||
static char opt_badpage[100] = "";
|
||||
string_param("badpage", opt_badpage);
|
||||
|
||||
/*
|
||||
* Bit width of the DMA heap.
|
||||
*/
|
||||
unsigned int dma_bitsize = CONFIG_DMA_BITSIZE;
|
||||
unsigned long max_dma_mfn = (1UL << (CONFIG_DMA_BITSIZE - PAGE_SHIFT)) - 1;
|
||||
static void parse_dma_bits(char *s)
|
||||
{
|
||||
unsigned int v = simple_strtol(s, NULL, 0);
|
||||
if ( v >= (sizeof(long)*8 + PAGE_SHIFT) )
|
||||
{
|
||||
dma_bitsize = sizeof(long)*8 + PAGE_SHIFT;
|
||||
max_dma_mfn = ~0UL;
|
||||
}
|
||||
else
|
||||
{
|
||||
dma_bitsize = v;
|
||||
max_dma_mfn = (1UL << (dma_bitsize - PAGE_SHIFT)) - 1;
|
||||
}
|
||||
}
|
||||
custom_param("dma_bits", parse_dma_bits);
|
||||
|
||||
/*
|
||||
* Amount of memory to reserve in a low-memory (<4GB) pool for specific
|
||||
* allocation requests. Ordinary requests will not fall back to the
|
||||
* lowmem emergency pool.
|
||||
*/
|
||||
static unsigned long lowmem_emergency_pool_pages;
|
||||
static void parse_lowmem_emergency_pool(char *s)
|
||||
static unsigned long dma_emergency_pool_pages;
|
||||
static void parse_dma_emergency_pool(char *s)
|
||||
{
|
||||
unsigned long long bytes;
|
||||
bytes = parse_size_and_unit(s, NULL);
|
||||
lowmem_emergency_pool_pages = bytes >> PAGE_SHIFT;
|
||||
dma_emergency_pool_pages = bytes >> PAGE_SHIFT;
|
||||
}
|
||||
custom_param("lowmem_emergency_pool", parse_lowmem_emergency_pool);
|
||||
custom_param("dma_emergency_pool", parse_dma_emergency_pool);
|
||||
|
||||
#define round_pgdown(_p) ((_p)&PAGE_MASK)
|
||||
#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
|
||||
@@ -248,7 +269,7 @@ unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align)
|
||||
#define NR_ZONES 3
|
||||
|
||||
#define pfn_dom_zone_type(_pfn) \
|
||||
(((_pfn) <= MAX_DMADOM_PFN) ? MEMZONE_DMADOM : MEMZONE_DOM)
|
||||
(((_pfn) <= max_dma_mfn) ? MEMZONE_DMADOM : MEMZONE_DOM)
|
||||
|
||||
static struct list_head heap[NR_ZONES][MAX_NUMNODES][MAX_ORDER+1];
|
||||
|
||||
@@ -278,6 +299,8 @@ void end_boot_allocator(void)
|
||||
if ( curr_free )
|
||||
init_heap_pages(pfn_dom_zone_type(i), mfn_to_page(i), 1);
|
||||
}
|
||||
|
||||
printk("Domain heap initialised: DMA width %u bits\n", dma_bitsize);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -575,13 +598,13 @@ void init_domheap_pages(paddr_t ps, paddr_t pe)
|
||||
s_tot = round_pgup(ps) >> PAGE_SHIFT;
|
||||
e_tot = round_pgdown(pe) >> PAGE_SHIFT;
|
||||
|
||||
s_dma = min(s_tot, MAX_DMADOM_PFN + 1);
|
||||
e_dma = min(e_tot, MAX_DMADOM_PFN + 1);
|
||||
s_dma = min(s_tot, max_dma_mfn + 1);
|
||||
e_dma = min(e_tot, max_dma_mfn + 1);
|
||||
if ( s_dma < e_dma )
|
||||
init_heap_pages(MEMZONE_DMADOM, mfn_to_page(s_dma), e_dma - s_dma);
|
||||
|
||||
s_nrm = max(s_tot, MAX_DMADOM_PFN + 1);
|
||||
e_nrm = max(e_tot, MAX_DMADOM_PFN + 1);
|
||||
s_nrm = max(s_tot, max_dma_mfn + 1);
|
||||
e_nrm = max(e_tot, max_dma_mfn + 1);
|
||||
if ( s_nrm < e_nrm )
|
||||
init_heap_pages(MEMZONE_DOM, mfn_to_page(s_nrm), e_nrm - s_nrm);
|
||||
}
|
||||
@@ -655,7 +678,7 @@ struct page_info *__alloc_domheap_pages(
|
||||
if ( unlikely(pg == NULL) &&
|
||||
((order > MAX_ORDER) ||
|
||||
(avail_heap_pages(MEMZONE_DMADOM,-1) <
|
||||
(lowmem_emergency_pool_pages + (1UL << order)))) )
|
||||
(dma_emergency_pool_pages + (1UL << order)))) )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -799,8 +822,8 @@ unsigned long avail_domheap_pages(void)
|
||||
avail_nrm = avail_heap_pages(MEMZONE_DOM,-1);
|
||||
|
||||
avail_dma = avail_heap_pages(MEMZONE_DMADOM,-1);
|
||||
if ( avail_dma > lowmem_emergency_pool_pages )
|
||||
avail_dma -= lowmem_emergency_pool_pages;
|
||||
if ( avail_dma > dma_emergency_pool_pages )
|
||||
avail_dma -= dma_emergency_pool_pages;
|
||||
else
|
||||
avail_dma = 0;
|
||||
|
||||
|
||||
@@ -41,9 +41,7 @@
|
||||
#define CONFIG_IOSAPIC
|
||||
#define supervisor_mode_kernel (0)
|
||||
|
||||
#define MAX_DMADOM_BITS 30
|
||||
#define MAX_DMADOM_MASK ((1UL << MAX_DMADOM_BITS) - 1)
|
||||
#define MAX_DMADOM_PFN (MAX_DMADOM_MASK >> PAGE_SHIFT)
|
||||
#define CONFIG_DMA_BITSIZE 30
|
||||
|
||||
/* If PERFC is used, include privop maps. */
|
||||
#ifdef PERF_COUNTERS
|
||||
|
||||
@@ -70,7 +70,7 @@ extern char __bss_start[];
|
||||
|
||||
#define supervisor_mode_kernel (0)
|
||||
|
||||
#define MAX_DMADOM_PFN (~0UL)
|
||||
#define CONFIG_DMA_BITSIZE 64
|
||||
|
||||
#include <asm/powerpc64/config.h>
|
||||
|
||||
|
||||
@@ -82,9 +82,7 @@
|
||||
/* Debug stack is restricted to 8kB by guard pages. */
|
||||
#define DEBUG_STACK_SIZE 8192
|
||||
|
||||
#define MAX_DMADOM_BITS 30
|
||||
#define MAX_DMADOM_MASK ((1UL << MAX_DMADOM_BITS) - 1)
|
||||
#define MAX_DMADOM_PFN (MAX_DMADOM_MASK >> PAGE_SHIFT)
|
||||
#define CONFIG_DMA_BITSIZE 30
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern unsigned long _end; /* standard ELF symbol */
|
||||
|
||||
@@ -89,6 +89,10 @@ int assign_pages(
|
||||
#define MAX_ORDER 20 /* 2^20 contiguous pages */
|
||||
#endif
|
||||
|
||||
/* DMA heap parameters. */
|
||||
extern unsigned int dma_bitsize;
|
||||
extern unsigned long max_dma_mfn;
|
||||
|
||||
/* Automatic page scrubbing for dead domains. */
|
||||
extern struct list_head page_scrub_list;
|
||||
#define page_scrub_schedule_work() \
|
||||
|
||||