sync with upstream.
Committer: Ross Philipson <rossp@latara.uk.xensource.com>
Changes to be committed:
modified: xen/arch/ia64/xen/mm.c
modified: xen/arch/x86/mm.c
modified: xen/drivers/passthrough/vtd/dmar.c
modified: xen/drivers/passthrough/vtd/iommu.c
modified: xen/include/xen/mm.h
return 1;
}
-int page_is_ram_type(unsigned long mfn, unsigned long type) /* CS 19085 mem to page */
-{
- /**
- * N.B. This function should really be enhanced to return what is more in line with the e820
- * semantics for usable and reservered RAM. For example type RAM_TYPE_CONVENTIONAL can
- * include the areas freed after OS loader calls ExitBootServices:
- * EFI_LOADER_CODE, EFI_LOADER_DATA, EFI_BOOT_SERVICES_CODE, EFI_BOOT_SERVICES_DATA, and EFI_CONVENTIONAL_MEMORY
- * The reserved regions would include:
- * EFI_RUNTIME_SERVICES_CODE, EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_MAPPED_IO, EFI_MEMORY_MAPPED_IO_PORT_SPACE and EFI_PAL_CODE
- */
- return (efi_mem_type(pfn_to_paddr(mfn)) == EFI_CONVENTIONAL_MEMORY);
+int page_is_ram_type(unsigned long mfn, unsigned long type)
+{
+ /* N.B. I believe the implementation below is correct for determing EFI memory types.
+ It needs testing but it is only used once in vga.c right now for conventional ram
+ (and xc not really interested in IA64). */
+ u32 mem_type = efi_mem_type(pfn_to_paddr(mfn));
+
+ if (type & RAM_TYPE_CONVENTIONAL)
+ {
+ switch (mem_type)
+ {
+ case EFI_BOOT_SERVICES_CODE:
+ case EFI_BOOT_SERVICES_DATA:
+ case EFI_LOADER_CODE:
+ case EFI_LOADER_DATA:
+ case EFI_CONVENTIONAL_MEMORY:
+ return 1;
+ default:
+ break;
+ }
+ }
+ if (type & RAM_TYPE_RESERVED)
+ {
+ switch (mem_type)
+ {
+ case EFI_RUNTIME_SERVICES_CODE:
+ case EFI_RUNTIME_SERVICES_DATA:
+ case EFI_RESERVED_TYPE:
+ case EFI_MEMORY_MAPPED_IO:
+ case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
+ case EFI_PAL_CODE:
+ return 1;
+ default:
+ break;
+ }
+ }
+ if (type & RAM_TYPE_ACPI)
+ {
+ switch (mem_type)
+ {
+ case EFI_ACPI_RECLAIM_MEMORY:
+ case EFI_ACPI_MEMORY_NVS:
+ return 1;
+ default:
+ break;
+ }
+ }
+ else if (type & RAM_TYPE_UNUSABLE)
+ {
+ return (mem_type == EFI_UNUSABLE_MEMORY);
+ }
+ return 0;
}
long
if (mem_type & RAM_TYPE_RESERVED)
break;
continue;
+ case E820_UNUSABLE:
+ if (mem_type & RAM_TYPE_UNUSABLE)
+ break;
+ continue;
+ case E820_ACPI:
+ case E820_NVS:
+ if (mem_type & RAM_TYPE_ACPI)
+ break;
+ continue;
default:
/* unknown */
continue;
{
dprintk(XENLOG_WARNING VTDPREFIX,
"RMRR address range not in reserved memory base = %"PRIx64" end = %"PRIx64"; " \
- "iommu_include_reserved parameter may be needed\n",
+ "iommu_inclusive_mapping=1 parameter may be needed\n",
rmrr->base_address, rmrr->end_address);
}
#endif
#include "extern.h"
#include "vtd.h"
+/* iommu_inclusive_mapping: when set, all memory below 4GB is included in dom0 1-1 iommu mappings except xen and unusable regions */
+static int iommu_inclusive_mapping = 0;
+boolean_param("iommu_inclusive_mapping", iommu_inclusive_mapping);
+
#define domain_iommu_domid(d) ((d)->arch.hvm_domain.hvm_iommu.iommu_domid)
static spinlock_t domid_bitmap_lock; /* protect domain id bitmap */
static int domid_bitmap_size; /* domain id bitmap size in bits */
static unsigned long *domid_bitmap; /* iommu domain id bitmap */
-/* iommu_include_reserved: include reserved memory ranges in dom0 1-1 iommu mappings if set */
-static int iommu_include_reserved = 0;
-boolean_param("iommu_include_reserved", iommu_include_reserved);
-
static void setup_dom0_devices(struct domain *d);
static void setup_dom0_rmrr(struct domain *d);
struct iommu *iommu = NULL;
struct acpi_drhd_unit *drhd;
u64 i;
- u32 mem_type;
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
iommu = drhd->iommu;
{
extern int xen_in_range(paddr_t start, paddr_t end);
- /* input param overrides default memory mapping */
- mem_type = RAM_TYPE_CONVENTIONAL;
- if (iommu_include_reserved)
- mem_type |= RAM_TYPE_RESERVED;
-
/*
* Set up 1:1 page table for dom0 except the critical segments
* like Xen and tboot.
*/
for ( i = 0; i < max_page; i++ )
{
- /* CS 19084 remove tboot_in_range, CS 19085 use page_is_conventional_ram */
- /* Modified to include reserved memory regions - this fix will be pushed upstream */
- if ( !page_is_ram_type(i, mem_type) ||
- xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) )
+ /* Set up 1:1 mapping for dom0 */
+ if ( !page_is_ram_type(i, RAM_TYPE_CONVENTIONAL) )
+ {
+ /* Default it to use only conventional RAM areas and let RMRRs include needed reserved regions */
+ if (iommu_inclusive_mapping)
+ {
+ /* When set, the inclusive mapping maps in everything below 4GB except unusable ranges */
+ if ( (i >= 0x100000) || page_is_ram_type(i, RAM_TYPE_UNUSABLE) )
+ continue;
+ }
+ else
+ continue;
+ }
+
+ /* Exclude Xen bits */
+ if ( xen_in_range(i << PAGE_SHIFT, (i + 1) << PAGE_SHIFT) )
continue;
iommu_map_page(d, i, i);
#define RAM_TYPE_CONVENTIONAL 0x00000001
#define RAM_TYPE_RESERVED 0x00000002
+#define RAM_TYPE_UNUSABLE 0x00000004
+#define RAM_TYPE_ACPI 0x00000008
/* Returns TRUE if the whole page at @mfn is of the requested RAM type(s) above. */
int page_is_ram_type(unsigned long mfn, unsigned long mem_type);