xen: Use newly added dmops for mapping VGA memory
Xen unstable (to be in 4.11) has two new dmops, relocate_memory and pin_memory_cacheattr. Use these to set up the VGA memory, replacing the previous calls to libxc. This allows the VGA console to work properly when QEMU is running restricted (-xen-domid-restrict). Wrapper functions are provided to allow QEMU to work with older versions of Xen. Tweak the error handling while making this change: * Report pin_memory_cacheattr errors. * Report errors even when DEBUG_HVM is not set. This is useful for trying to understand why VGA is not working, since otherwise it just fails silently. * Fix the return values when an error occurs. The functions now consistently return -1 and set errno. CC: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com> Reviewed-by: Ian Jackson <ian.jackson@eu.citrix.com> Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> Acked-by: Anthony PERARD <anthony.perard@citrix.com>
This commit is contained in:
		
							parent
							
								
									2c42f1e801
								
							
						
					
					
						commit
						2cbf890353
					
				
							
								
								
									
										19
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								configure
									
									
									
									
										vendored
									
									
								
							| @ -2221,6 +2221,25 @@ EOF | ||||
|     # Xen unstable | ||||
|     elif | ||||
|         cat > $TMPC <<EOF && | ||||
| #undef XC_WANT_COMPAT_DEVICEMODEL_API | ||||
| #define __XEN_TOOLS__ | ||||
| #include <xendevicemodel.h> | ||||
| int main(void) { | ||||
|   xendevicemodel_handle *xd; | ||||
| 
 | ||||
|   xd = xendevicemodel_open(0, 0); | ||||
|   xendevicemodel_pin_memory_cacheattr(xd, 0, 0, 0, 0); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| EOF | ||||
|         compile_prog "" "$xen_libs -lxendevicemodel $xen_stable_libs -lxentoolcore" | ||||
|       then | ||||
|       xen_stable_libs="-lxendevicemodel $xen_stable_libs -lxentoolcore" | ||||
|       xen_ctrl_version=41100 | ||||
|       xen=yes | ||||
|     elif | ||||
|         cat > $TMPC <<EOF && | ||||
| #undef XC_WANT_COMPAT_MAP_FOREIGN_API | ||||
| #include <xenforeignmemory.h> | ||||
| #include <xentoolcore.h> | ||||
|  | ||||
| @ -347,7 +347,7 @@ static int xen_add_to_physmap(XenIOState *state, | ||||
|                               MemoryRegion *mr, | ||||
|                               hwaddr offset_within_region) | ||||
| { | ||||
|     unsigned long i = 0; | ||||
|     unsigned long nr_pages; | ||||
|     int rc = 0; | ||||
|     XenPhysmap *physmap = NULL; | ||||
|     hwaddr pfn, start_gpfn; | ||||
| @ -396,22 +396,26 @@ go_physmap: | ||||
| 
 | ||||
|     pfn = phys_offset >> TARGET_PAGE_BITS; | ||||
|     start_gpfn = start_addr >> TARGET_PAGE_BITS; | ||||
|     for (i = 0; i < size >> TARGET_PAGE_BITS; i++) { | ||||
|         unsigned long idx = pfn + i; | ||||
|         xen_pfn_t gpfn = start_gpfn + i; | ||||
|     nr_pages = size >> TARGET_PAGE_BITS; | ||||
|     rc = xendevicemodel_relocate_memory(xen_dmod, xen_domid, nr_pages, pfn, | ||||
|                                         start_gpfn); | ||||
|     if (rc) { | ||||
|         int saved_errno = errno; | ||||
| 
 | ||||
|         rc = xen_xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn); | ||||
|         if (rc) { | ||||
|             DPRINTF("add_to_physmap MFN %"PRI_xen_pfn" to PFN %" | ||||
|                     PRI_xen_pfn" failed: %d (errno: %d)\n", idx, gpfn, rc, errno); | ||||
|             return -rc; | ||||
|         } | ||||
|         error_report("relocate_memory %lu pages from GFN %"HWADDR_PRIx | ||||
|                      " to GFN %"HWADDR_PRIx" failed: %s", | ||||
|                      nr_pages, pfn, start_gpfn, strerror(saved_errno)); | ||||
|         errno = saved_errno; | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     xc_domain_pin_memory_cacheattr(xen_xc, xen_domid, | ||||
|     rc = xendevicemodel_pin_memory_cacheattr(xen_dmod, xen_domid, | ||||
|                                    start_addr >> TARGET_PAGE_BITS, | ||||
|                                    (start_addr + size - 1) >> TARGET_PAGE_BITS, | ||||
|                                    XEN_DOMCTL_MEM_CACHEATTR_WB); | ||||
|     if (rc) { | ||||
|         error_report("pin_memory_cacheattr failed: %s", strerror(errno)); | ||||
|     } | ||||
|     return xen_save_physmap(state, physmap); | ||||
| } | ||||
| 
 | ||||
| @ -419,7 +423,6 @@ static int xen_remove_from_physmap(XenIOState *state, | ||||
|                                    hwaddr start_addr, | ||||
|                                    ram_addr_t size) | ||||
| { | ||||
|     unsigned long i = 0; | ||||
|     int rc = 0; | ||||
|     XenPhysmap *physmap = NULL; | ||||
|     hwaddr phys_offset = 0; | ||||
| @ -438,16 +441,17 @@ static int xen_remove_from_physmap(XenIOState *state, | ||||
|     size >>= TARGET_PAGE_BITS; | ||||
|     start_addr >>= TARGET_PAGE_BITS; | ||||
|     phys_offset >>= TARGET_PAGE_BITS; | ||||
|     for (i = 0; i < size; i++) { | ||||
|         xen_pfn_t idx = start_addr + i; | ||||
|         xen_pfn_t gpfn = phys_offset + i; | ||||
|     rc = xendevicemodel_relocate_memory(xen_dmod, xen_domid, size, start_addr, | ||||
|                                         phys_offset); | ||||
|     if (rc) { | ||||
|         int saved_errno = errno; | ||||
| 
 | ||||
|         rc = xen_xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn); | ||||
|         if (rc) { | ||||
|             fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %" | ||||
|                     PRI_xen_pfn" failed: %d (errno: %d)\n", idx, gpfn, rc, errno); | ||||
|             return -rc; | ||||
|         } | ||||
|         error_report("relocate_memory "RAM_ADDR_FMT" pages" | ||||
|                      " from GFN %"HWADDR_PRIx | ||||
|                      " to GFN %"HWADDR_PRIx" failed: %s", | ||||
|                      size, start_addr, phys_offset, strerror(saved_errno)); | ||||
|         errno = saved_errno; | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     QLIST_REMOVE(physmap, list); | ||||
|  | ||||
| @ -89,6 +89,38 @@ typedef xc_interface xendevicemodel_handle; | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41100 | ||||
| 
 | ||||
| static inline int xendevicemodel_relocate_memory( | ||||
|     xendevicemodel_handle *dmod, domid_t domid, uint32_t size, uint64_t src_gfn, | ||||
|     uint64_t dst_gfn) | ||||
| { | ||||
|     uint32_t i; | ||||
|     int rc; | ||||
| 
 | ||||
|     for (i = 0; i < size; i++) { | ||||
|         unsigned long idx = src_gfn + i; | ||||
|         xen_pfn_t gpfn = dst_gfn + i; | ||||
| 
 | ||||
|         rc = xc_domain_add_to_physmap(xen_xc, domid, XENMAPSPACE_gmfn, idx, | ||||
|                                       gpfn); | ||||
|         if (rc) { | ||||
|             return rc; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static inline int xendevicemodel_pin_memory_cacheattr( | ||||
|     xendevicemodel_handle *dmod, domid_t domid, uint64_t start, uint64_t end, | ||||
|     uint32_t type) | ||||
| { | ||||
|     return xc_domain_pin_memory_cacheattr(xen_xc, domid, start, end, type); | ||||
| } | ||||
| 
 | ||||
| #endif /* CONFIG_XEN_CTRL_INTERFACE_VERSION < 41100 */ | ||||
| 
 | ||||
| #if CONFIG_XEN_CTRL_INTERFACE_VERSION < 41000 | ||||
| 
 | ||||
| #define XEN_COMPAT_PHYSMAP | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Ross Lagerwall
						Ross Lagerwall