[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH] Make AMD GART work as a mini IOMMU [4/4]



>The fourth patch modifies pci-gart-xen.c and 
>aperture-xen.c to work with Xen.  It adds a
>hypervisor call to clear the aperture address
>range from the hypervisor's memory tables,
>which is necessary to avoid a cache coherency
>issue, and ups the range of contiguous memory
>that Xen provides, which is necessary since
>the aperture must be at least 32 MB.

>--- a/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c   Thu Mar 01 15:04:47 
>2007 -0600
>+++ b/linux-2.6-xen-sparse/arch/i386/mm/hypervisor.c   Mon Mar 05 16:01:11 
>2007 -0600
>@@ -252,7 +252,7 @@ static void contiguous_bitmap_clear(
> }
> 
> /* Protected by balloon_lock. */
>-#define MAX_CONTIG_ORDER 9 /* 2MB */
>+#define MAX_CONTIG_ORDER 16 /* 256MB */
> static unsigned long discontig_frames[1<<MAX_CONTIG_ORDER];
> static multicall_entry_t cr_mcl[1<<MAX_CONTIG_ORDER];
 
Keir had asked you to not statically bump MAX_CONTIG_ORDER here as a
minimal acceptance criteria. 

>--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/aperture-xen.c   Thu Mar 01 
>15:04:47 2007 -0600
>+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/aperture-xen.c   Mon Mar 05 
>16:01:11 2007 -0600
>@@ -53,7 +53,7 @@ static u32 __init allocate_aperture(void
>        * IOMMU useless.
>        */
>       p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); 
>-      if (!p || __pa(p)+aper_size > 0xffffffff) {
>+      if (!p || (xen_create_contiguous_region((unsigned long) p, 
>get_order(aper_size), 31) != 0) ||
virt_to_bus(p)+aper_size >
>0xffffffff) {
>               printk("Cannot allocate aperture memory hole (%p,%uK)\n",
>                      p, aper_size>>10);
>               if (p)

Why 31 when native code uses a check for 32 bits?
Also, I don't think the range check is necessary after the call to
xen_create_contiguous_region() - if at all you should BUG() if the
call was successful but the resulting address isn't fitting.

>--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c       Thu Mar 01 
>15:04:47 2007 -0600
>+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c       Mon Mar 05 
>16:01:11 2007 -0600
>@@ -97,7 +97,6 @@ static inline int bad_addr(unsigned long
>       return 0;
> } 
> 
>-#ifndef CONFIG_XEN
> /*
>  * This function checks if any part of the range <start,end> is mapped
>  * with type.
>@@ -116,7 +115,6 @@ e820_any_mapped(unsigned long start, uns
>       } 
>       return 0;
> }
>-#endif
> 
> /*
>  * This function checks if the entire range <start,end> is mapped with type.

Simply enabling this function is insufficient: It must check against 
machine_e820
for Xen (see e820_all_mapped), which is populated only under
is_initial_xen_domain() (though that's not a problem, as domU-s shouldn't find
any AGP bridge in the first place).

>--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/pci-gart-xen.c   Thu Mar 01 
>15:04:47 2007 -0600
>+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/pci-gart-xen.c   Mon Mar 05 
>16:01:11 2007 -0600
>...
>@@ -523,6 +523,9 @@ static __init int init_k8_gatt(struct ag
>       gatt = (void *)__get_free_pages(GFP_KERNEL, get_order(gatt_size)); 
>       if (!gatt) 
>               panic("Cannot allocate GATT table"); 
>+      if (xen_create_contiguous_region((unsigned long) gatt, 
>get_order(gatt_size), 31))
>+              panic("Cannot create a contiguous memory region below 4GB for 
>the GATT table");
>+
>       memset(gatt, 0, gatt_size); 
>       agp_gatt_table = gatt;
> 

Why 31, and more importantly, why a restriction at all? Native uses GFP_KERNEL
(not GFP_DMA32), so why is there a restriction here under Xen?

>@@ -531,7 +534,7 @@ static __init int init_k8_gatt(struct ag
>               u32 gatt_reg; 
> 
>               dev = k8_northbridges[i];
>-              gatt_reg = __pa(gatt) >> 12; 
>+              gatt_reg = phys_to_machine(__pa(gatt)) >> 12; 
>               gatt_reg <<= 4; 
>               pci_write_config_dword(dev, 0x98, gatt_reg);
>               pci_read_config_dword(dev, 0x90, &ctl); 

Wouldn't virt_to_bus() be more appropriate/consistent here?

>--- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c   Thu Mar 01 15:04:47 
>2007 -0600
>+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c   Mon Mar 05 16:01:11 
>2007 -0600
>...
>@@ -855,13 +856,10 @@ void __init clear_kernel_mapping(unsigne
>               pmd = pmd_offset(pud, address);
>               if (!pmd || pmd_none(*pmd))
>                       continue; 
>-              if (0 == (pmd_val(*pmd) & _PAGE_PSE)) { 
>-                      /* Could handle this, but it should not happen 
>currently. */
>-                      printk(KERN_ERR 
>-             "clear_kernel_mapping: mapping has been split. will leak 
>memory\n"); 
>-                      pmd_ERROR(*pmd); 
>-              }
>-              set_pmd(pmd, __pmd(0));                 
>+              pte = pte_offset_map(pmd, address);
>+              if (!pte || pte_none(*pte))                                     
>+                      continue;
>+              pte_clear(&init_mm,address,pte);

I'd prefer keeping the original code by means of a #ifndef CONFIG_XEN
construct.

>--- a/xen/arch/x86/mm.c        Thu Mar 01 15:04:47 2007 -0600
>+++ b/xen/arch/x86/mm.c        Mon Mar 05 16:01:11 2007 -0600
>@@ -2098,6 +2098,13 @@ int do_mmuext_op(
>                 }
>             }
>             break;
>+
>+      case MMUEXT_UNMAP_REGION:
>+              map_pages_to_xen(
>+                      PAGE_OFFSET + (op.arg1.mfn << PAGE_SHIFT),
>+                      op.arg1.mfn, op.arg2.nr_ents, PAGE_HYPERVISOR &
>+                      ~_PAGE_PRESENT);
>+          break;
> #endif
>         
>         case MMUEXT_TLB_FLUSH_LOCAL:

This must be refused for non-privileged domains. I would also think that it
should be verified that the pages are not in use elsewhere.
Finally, hypervisor sources use 4-space indentation, not tabs.

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.