static int libxl__e820_alloc(libxl__gc *gc, uint32_t domid, libxl_domain_config *d_config) { libxl_ctx *ctx = libxl__gc_owner(gc); int rc; uint32_t nr; struct e820entry map[E820MAX]; libxl_domain_build_info *b_info; if (d_config == NULL || d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM) return ERROR_INVAL; b_info = &d_config->b_info; if (!libxl_defbool_val(b_info->u.pv.e820_host)) return ERROR_INVAL; nr = E820MAX; rc = e820_host_sanitize(gc, b_info, map, &nr); if (rc) return ERROR_FAIL; rc = xc_domain_set_memory_map(ctx->xch, domid, map, nr); if (rc < 0) return ERROR_FAIL; return 0; }
int xc_domain_set_memmap_limit(xc_interface *xch, uint32_t domid, unsigned long map_limitkb) { struct e820entry e820; e820.addr = 0; e820.size = (uint64_t)map_limitkb << 10; e820.type = E820_RAM; return xc_domain_set_memory_map(xch, domid, &e820, 1); }
static int libxl__e820_alloc(libxl__gc *gc, uint32_t domid, libxl_domain_config *d_config) { libxl_ctx *ctx = libxl__gc_owner(gc); int rc; uint32_t nr; struct e820entry map[E820MAX]; libxl_domain_build_info *b_info; if (d_config == NULL || d_config->c_info.type == LIBXL_DOMAIN_TYPE_HVM) return ERROR_INVAL; b_info = &d_config->b_info; if (!libxl_defbool_val(b_info->u.pv.e820_host)) return ERROR_INVAL; rc = xc_get_machine_memory_map(ctx->xch, map, E820MAX); if (rc < 0) { errno = rc; return ERROR_FAIL; } nr = rc; rc = e820_sanitize(ctx, map, &nr, b_info->target_memkb, (b_info->max_memkb - b_info->target_memkb) + b_info->u.pv.slack_memkb); if (rc) return ERROR_FAIL; rc = xc_domain_set_memory_map(ctx->xch, domid, map, nr); if (rc < 0) { errno = rc; return ERROR_FAIL; } return 0; }
int stub_xc_hvm_build_with_mem(uint64_t max_mem_mib, uint64_t max_start_mib, const char *image) { uint64_t lowmem_end, highmem_start, highmem_end, mmio_start; struct xc_hvm_build_args args = { .mem_size = max_mem_mib << 20, .mem_target = max_start_mib << 20, .mmio_size = HVM_BELOW_4G_MMIO_LENGTH, .image_file_name = image, }; unsigned int i, j, nr = 0; struct e820entry *e820; int rc; unsigned int nr_rdm_entries[MAX_RMRR_DEVICES] = {0}; unsigned int nr_rmrr_devs = 0; struct xen_reserved_device_memory *xrdm[MAX_RMRR_DEVICES] = {0}; unsigned long rmrr_overlapped_ram = 0; char *s; if ( pci_passthrough_sbdf_list ) { s = strtok(pci_passthrough_sbdf_list,","); while ( s != NULL ) { unsigned int seg, bus, device, func; xg_info("Getting RMRRs for device '%s'\n",s); if ( parse_pci_sbdf(s, &seg, &bus, &device, &func) ) { if ( !get_rdm(seg, bus, (device << 3) + func, &nr_rdm_entries[nr_rmrr_devs], &xrdm[nr_rmrr_devs]) ) nr_rmrr_devs++; } if ( nr_rmrr_devs == MAX_RMRR_DEVICES ) { xg_err("Error: hit limit of %d RMRR devices for domain\n", MAX_RMRR_DEVICES); exit(1); } s = strtok (NULL, ","); } } e820 = malloc(sizeof(*e820) * E820MAX); if (!e820) return -ENOMEM; lowmem_end = args.mem_size; highmem_end = highmem_start = 1ull << 32; mmio_start = highmem_start - args.mmio_size; if ( lowmem_end > mmio_start ) { highmem_end = (1ull << 32) + (lowmem_end - mmio_start); lowmem_end = mmio_start; } args.lowmem_end = lowmem_end; args.highmem_end = highmem_end; args.mmio_start = mmio_start; /* Leave low 1MB to HVMLoader... */ e820[nr].addr = 0x100000u; e820[nr].size = args.lowmem_end - 0x100000u; e820[nr].type = E820_RAM; nr++; /* RDM mapping */ for (i = 0; i < nr_rmrr_devs; i++) { for (j = 0; j < nr_rdm_entries[i]; j++) { e820[nr].addr = xrdm[i][j].start_pfn << XC_PAGE_SHIFT; e820[nr].size = xrdm[i][j].nr_pages << XC_PAGE_SHIFT; e820[nr].type = E820_RESERVED; xg_info("Adding RMRR 0x%lx size 0x%lx\n", e820[nr].addr, e820[nr].size); if ( e820[nr].addr < args.lowmem_end ) { rmrr_overlapped_ram += ( args.lowmem_end - e820[nr].addr ); args.lowmem_end = e820[nr].addr; } nr++; } } e820[0].size -= rmrr_overlapped_ram; args.highmem_end += rmrr_overlapped_ram; args.mmio_size += rmrr_overlapped_ram; args.mmio_start -= rmrr_overlapped_ram; for (i = 0; i < nr_rmrr_devs; i++) { free(xrdm[i]); } if ( args.highmem_end > highmem_start ) { e820[nr].addr = highmem_start; e820[nr].size = args.highmem_end - e820[nr].addr; e820[nr].type = E820_RAM; nr++; } rc = xc_hvm_build(xch, domid, &args); if (!rc) rc = xc_domain_set_memory_map(xch, domid, e820, nr); free(e820); return rc; } int stub_xc_hvm_build(int mem_max_mib, int mem_start_mib, const char *image_name, int store_evtchn, int store_domid, int console_evtchn, int console_domid, unsigned long *store_mfn, unsigned long *console_mfn) { int r; struct flags f; get_flags(&f); configure_vcpus(f); configure_tsc(f); r = stub_xc_hvm_build_with_mem(mem_max_mib, mem_start_mib, image_name); if ( r ) failwith_oss_xc("hvm_build"); r = hvm_build_set_params(store_evtchn, store_mfn, console_evtchn, console_mfn, f); if ( r ) failwith_oss_xc("hvm_build_params"); r = construct_cpuid_policy(&f, true); if ( r ) failwith_oss_xc("construct_cpuid_policy"); r = xc_dom_gnttab_hvm_seed(xch, domid, *console_mfn, *store_mfn, console_domid, store_domid); if ( r ) failwith_oss_xc("xc_dom_gnttab_hvm_seed"); free_flags(&f); return 0; }
int libxl__arch_domain_construct_memmap(libxl__gc *gc, libxl_domain_config *d_config, uint32_t domid, struct xc_dom_image *dom) { int rc = 0; unsigned int nr = 0, i; /* We always own at least one lowmem entry. */ unsigned int e820_entries = 1; struct e820entry *e820 = NULL; uint64_t highmem_size = dom->highmem_end ? dom->highmem_end - (1ull << 32) : 0; uint32_t lowmem_start = dom->device_model ? GUEST_LOW_MEM_START_DEFAULT : 0; /* Add all rdm entries. */ for (i = 0; i < d_config->num_rdms; i++) if (d_config->rdms[i].policy != LIBXL_RDM_RESERVE_POLICY_INVALID) e820_entries++; /* If we should have a highmem range. */ if (highmem_size) e820_entries++; if (e820_entries >= E820MAX) { LOG(ERROR, "Ooops! Too many entries in the memory map!"); rc = ERROR_INVAL; goto out; } e820 = libxl__malloc(gc, sizeof(struct e820entry) * e820_entries); /* Low memory */ e820[nr].addr = lowmem_start; e820[nr].size = dom->lowmem_end - lowmem_start; e820[nr].type = E820_RAM; nr++; /* RDM mapping */ for (i = 0; i < d_config->num_rdms; i++) { if (d_config->rdms[i].policy == LIBXL_RDM_RESERVE_POLICY_INVALID) continue; e820[nr].addr = d_config->rdms[i].start; e820[nr].size = d_config->rdms[i].size; e820[nr].type = E820_RESERVED; nr++; } /* High memory */ if (highmem_size) { e820[nr].addr = ((uint64_t)1 << 32); e820[nr].size = highmem_size; e820[nr].type = E820_RAM; } if (xc_domain_set_memory_map(CTX->xch, domid, e820, e820_entries) != 0) { rc = ERROR_FAIL; goto out; } out: return rc; }