Hi,
This is another work in progress patch. The previous swiotlb &
sba_iommu paravirtualization seems to work pretty well on dom0, but not
so much for domU. domUs will naturally start up using the DIG machine
vector, which means they try to allocate an swiotlb buffer. This fails.
The x86 code we were borrowing handled this via some ugly branches in
the PCI DMA mapping services. I think we can do this more cleanly on
ia64 by creating a Xen machine vector. This replaces the DMA mapping
services with very basic services. The idea is that the Xen machine
vector is only for domU guests. I need to add some error catching,
copyrights, and actually get it working reliably (it seem to be getting
upcalls while unmapping DMA and ending up in bad page faults in dom0),
but I thought I'd run this idea by the group before doing all the
polishing.
This patch applies on top of the previous swiotlb/sba_iommu/generic
patch and you'll need to add the following files to the sparse tree
before applying:
linux-2.6-xen-sparse/include/asm-ia64/machvec.h
linux-2.6-xen-sparse/arch/ia64/kernel/acpi.c
Is this the way to go? I think it might add some interesting
flexibility. The -xenU kernel config should probably switch to a
CONFIG_IA64_XEN flavor with this. Thanks,
Alex
Signed-off-by: Alex Williamson <alex.williamson@xxxxxx>
---
diff -r 6e86c16c2db2 linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig Thu May 03 15:45:52 2007 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig Thu May 03 17:32:27 2007 -0600
@@ -160,6 +160,10 @@ config IA64_SGI_SN2
config IA64_HP_SIM
bool "Ski-simulator"
+
+config IA64_XEN
+ bool "Xen guest"
+ depends on XEN
endchoice
diff -r 6e86c16c2db2 linux-2.6-xen-sparse/arch/ia64/xen/machvec.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/machvec.c Thu May 03 16:56:28
2007 -0600
@@ -0,0 +1,4 @@
+#define MACHVEC_PLATFORM_NAME xen
+#define MACHVEC_PLATFORM_HEADER <asm/machvec_xen.h>
+#include <asm/machvec_init.h>
+
diff -r 6e86c16c2db2 linux-2.6-xen-sparse/arch/ia64/xen/xen_pci_dma.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/xen_pci_dma.c Thu May 03 17:47:12
2007 -0600
@@ -0,0 +1,94 @@
+#include <linux/dma-mapping.h>
+#include <linux/mm.h>
+#include <asm/scatterlist.h>
+
+int
+xen_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
+{
+ int i;
+
+ for (i = 0 ; i < nents ; i++) {
+ sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset;
+ sg[i].dma_length = sg[i].length;
+ }
+
+ return nents;
+}
+EXPORT_SYMBOL(xen_map_sg);
+
+void
+xen_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
+{
+}
+EXPORT_SYMBOL(xen_unmap_sg);
+
+int
+xen_dma_mapping_error(dma_addr_t dma_addr)
+{
+ return 0;
+}
+EXPORT_SYMBOL(xen_dma_mapping_error);
+
+int
+xen_dma_supported(struct device *dev, u64 mask)
+{
+ return 1;
+}
+EXPORT_SYMBOL(xen_dma_supported);
+
+void *
+xen_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ unsigned long vaddr;
+ unsigned int order = get_order(size);
+
+ vaddr = __get_free_pages(gfp, order);
+
+ if (!vaddr)
+ return NULL;
+
+ if (xen_create_contiguous_region(vaddr, order,
+ dev->coherent_dma_mask)) {
+ free_pages(vaddr, order);
+ return NULL;
+ }
+
+ memset((void *)vaddr, 0, size);
+ *dma_handle = virt_to_bus((void *)vaddr);
+
+ return (void *)vaddr;
+}
+EXPORT_SYMBOL(xen_alloc_coherent);
+
+void
+xen_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ unsigned int order = get_order(size);
+
+ xen_destroy_contiguous_region((unsigned long)vaddr, order);
+ free_pages((unsigned long)vaddr, order);
+}
+EXPORT_SYMBOL(xen_free_coherent);
+
+dma_addr_t
+xen_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction)
+{
+ return virt_to_bus(ptr);
+}
+EXPORT_SYMBOL(xen_map_single);
+
+void
+xen_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction)
+{
+}
+EXPORT_SYMBOL(xen_unmap_single);
+
+
+
+
diff -r 6e86c16c2db2 linux-2.6-xen-sparse/include/asm-ia64/machvec_xen.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/linux-2.6-xen-sparse/include/asm-ia64/machvec_xen.h Thu May 03
17:33:48 2007 -0600
@@ -0,0 +1,37 @@
+#ifndef _ASM_IA64_MACHVEC_XEN_h
+#define _ASM_IA64_MACHVEC_XEN_h
+
+extern ia64_mv_setup_t dig_setup;
+extern ia64_mv_dma_alloc_coherent xen_alloc_coherent;
+extern ia64_mv_dma_free_coherent xen_free_coherent;
+extern ia64_mv_dma_map_single xen_map_single;
+extern ia64_mv_dma_unmap_single xen_unmap_single;
+extern ia64_mv_dma_map_sg xen_map_sg;
+extern ia64_mv_dma_unmap_sg xen_unmap_sg;
+extern ia64_mv_dma_supported xen_dma_supported;
+extern ia64_mv_dma_mapping_error xen_dma_mapping_error;
+
+/*
+ * This stuff has dual use!
+ *
+ * For a generic kernel, the macros are used to initialize the
+ * platform's machvec structure. When compiling a non-generic kernel,
+ * the macros are used directly.
+ */
+#define platform_name "xen"
+#define platform_setup dig_setup
+#define platform_dma_init machvec_noop
+#define platform_dma_alloc_coherent xen_alloc_coherent
+#define platform_dma_free_coherent xen_free_coherent
+#define platform_dma_map_single xen_map_single
+#define platform_dma_unmap_single xen_unmap_single
+#define platform_dma_map_sg xen_map_sg
+#define platform_dma_unmap_sg xen_unmap_sg
+#define platform_dma_sync_single_for_cpu machvec_dma_sync_single
+#define platform_dma_sync_sg_for_cpu machvec_dma_sync_sg
+#define platform_dma_sync_single_for_device machvec_dma_sync_single
+#define platform_dma_sync_sg_for_device machvec_dma_sync_sg
+#define platform_dma_supported xen_dma_supported
+#define platform_dma_mapping_error xen_dma_mapping_error
+
+#endif /* _ASM_IA64_MACHVEC_XEN_h */
--- a/linux-2.6-xen-sparse/include/asm-ia64/machvec.h 2006-09-19
21:42:06.000000000 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/machvec.h 2007-05-03
17:26:02.000000000 -0600
@@ -108,6 +108,8 @@
# include <asm/machvec_hpzx1_swiotlb.h>
# elif defined (CONFIG_IA64_SGI_SN2)
# include <asm/machvec_sn2.h>
+# elif defined (CONFIG_IA64_XEN)
+# include <asm/machvec_xen.h>
# elif defined (CONFIG_IA64_GENERIC)
# ifdef MACHVEC_PLATFORM_HEADER
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/acpi.c 2006-09-19
21:42:06.000000000 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/acpi.c 2007-05-03
17:52:43.000000000 -0600
@@ -109,6 +109,10 @@
return "hpzx1";
} else if (!strcmp(hdr->oem_id, "SGI")) {
return "sn2";
+#ifdef CONFIG_XEN
+ } else if (!strcmp(hdr->oem_id, "XEN")) {
+ return "xen";
+#endif
}
return "dig";
@@ -123,6 +127,8 @@
return "sn2";
# elif defined (CONFIG_IA64_DIG)
return "dig";
+# elif defined (CONFIG_IA64_XEN)
+ return "xen";
# else
# error Unknown platform. Fix acpi.c.
# endif
--- a/linux-2.6-xen-sparse/arch/ia64/xen/Makefile 2007-05-02
22:52:34.000000000 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/Makefile 2007-05-03
17:35:31.000000000 -0600
@@ -4,4 +4,6 @@
obj-y := hypercall.o xenivt.o xenentry.o xensetup.o xenpal.o xenhpski.o \
hypervisor.o util.o xencomm.o xcom_hcall.o xcom_mini.o \
- xcom_privcmd.o mem.o
+ xcom_privcmd.o mem.o xen_pci_dma.o
+
+obj-$(CONFIG_IA64_GENERIC) += machvec.o
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
|