@@ -109,6 +109,7 @@ struct io_tlb_mem {
} *slots;
};
extern struct io_tlb_mem io_tlb_default_mem;
+extern struct io_tlb_mem io_tlb_high_mem;
static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr)
{
@@ -164,6 +165,7 @@ static inline void swiotlb_adjust_size(unsigned long size)
}
#endif /* CONFIG_SWIOTLB */
+extern bool swiotlb_high_active(void);
extern void swiotlb_print_info(void);
#ifdef CONFIG_DMA_RESTRICTED_POOL
@@ -66,10 +66,12 @@ static bool swiotlb_force_bounce;
static bool swiotlb_force_disable;
struct io_tlb_mem io_tlb_default_mem;
+struct io_tlb_mem io_tlb_high_mem;
phys_addr_t swiotlb_unencrypted_base;
static unsigned long default_nslabs = IO_TLB_DEFAULT_SIZE >> IO_TLB_SHIFT;
+static unsigned long high_nslabs;
static int __init
setup_io_tlb_npages(char *str)
@@ -81,6 +83,15 @@ setup_io_tlb_npages(char *str)
}
if (*str == ',')
++str;
+
+ if (isdigit(*str)) {
+ /* avoid tail segment of size < IO_TLB_SEGSIZE */
+ high_nslabs =
+ ALIGN(simple_strtoul(str, &str, 0), IO_TLB_SEGSIZE);
+ }
+ if (*str == ',')
+ ++str;
+
if (!strcmp(str, "force"))
swiotlb_force_bounce = true;
else if (!strcmp(str, "noforce"))
@@ -90,6 +101,11 @@ setup_io_tlb_npages(char *str)
}
early_param("swiotlb", setup_io_tlb_npages);
+bool swiotlb_high_active(void)
+{
+ return high_nslabs && io_tlb_high_mem.nslabs;
+}
+
unsigned int swiotlb_max_segment(void)
{
if (!io_tlb_default_mem.nslabs)
Currently, the virtio driver is not able to use 4+ GB memory when the swiotlb is enforced, e.g., when amd sev is involved. Fortunately, the SWIOTLB_ANY flag has been introduced since commit 8ba2ed1be90f ("swiotlb: add a SWIOTLB_ANY flag to lift the low memory restriction") to allocate swiotlb buffer from high memory. While the default swiotlb is 'io_tlb_default_mem', the extra 'io_tlb_high_mem' is introduced to allocate with SWIOTLB_ANY flag in the future patches. E.g., the user may configure the extra highmem swiotlb buffer via "swiotlb=327680,4194304" to allocate 8GB memory. In the future, the driver will be able to decide to use whether 'io_tlb_default_mem' or 'io_tlb_high_mem'. The highmem swiotlb is enabled by user if io_tlb_high_mem is set. It can be actively used if swiotlb_high_active() returns true. The kernel command line "swiotlb=32768,3145728,force" is to allocate 64MB for default swiotlb, and 6GB for the extra highmem swiotlb. Cc: Konrad Wilk <konrad.wilk@oracle.com> Cc: Joe Jin <joe.jin@oracle.com> Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com> --- include/linux/swiotlb.h | 2 ++ kernel/dma/swiotlb.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+)