static void update_domain_cpuid_info(struct domain *d, const xen_domctl_cpuid_t *ctl) { switch ( ctl->input[0] ) { case 0: { union { typeof(boot_cpu_data.x86_vendor_id) str; struct { uint32_t ebx, edx, ecx; } reg; } vendor_id = { .reg = { .ebx = ctl->ebx, .edx = ctl->edx, .ecx = ctl->ecx } }; int old_vendor = d->arch.x86_vendor; d->arch.x86_vendor = get_cpu_vendor(vendor_id.str, gcv_guest); if ( is_hvm_domain(d) && (d->arch.x86_vendor != old_vendor) ) { struct vcpu *v; for_each_vcpu( d, v ) hvm_update_guest_vendor(v); } break; } case 1: d->arch.x86 = (ctl->eax >> 8) & 0xf; if ( d->arch.x86 == 0xf ) d->arch.x86 += (ctl->eax >> 20) & 0xff; d->arch.x86_model = (ctl->eax >> 4) & 0xf; if ( d->arch.x86 >= 0x6 ) d->arch.x86_model |= (ctl->eax >> 12) & 0xf0; if ( is_pv_domain(d) && ((levelling_caps & LCAP_1cd) == LCAP_1cd) ) { uint64_t mask = cpuidmask_defaults._1cd; uint32_t ecx = ctl->ecx & pv_featureset[FEATURESET_1c]; uint32_t edx = ctl->edx & pv_featureset[FEATURESET_1d]; /* * Must expose hosts HTT and X2APIC value so a guest using native * CPUID can correctly interpret other leaves which cannot be * masked. */ if ( cpu_has_x2apic ) ecx |= cpufeat_mask(X86_FEATURE_X2APIC); if ( cpu_has_htt ) edx |= cpufeat_mask(X86_FEATURE_HTT); switch ( boot_cpu_data.x86_vendor ) { case X86_VENDOR_INTEL: /* * Intel masking MSRs are documented as AND masks. * Experimentally, they are applied after OSXSAVE and APIC * are fast-forwarded from real hardware state. */ mask &= ((uint64_t)edx << 32) | ecx; if ( ecx & cpufeat_mask(X86_FEATURE_XSAVE) ) ecx = cpufeat_mask(X86_FEATURE_OSXSAVE); else ecx = 0; edx = cpufeat_mask(X86_FEATURE_APIC); mask |= ((uint64_t)edx << 32) | ecx; break; case X86_VENDOR_AMD: mask &= ((uint64_t)ecx << 32) | edx; /* * AMD masking MSRs are documented as overrides. * Experimentally, fast-forwarding of the OSXSAVE and APIC * bits from real hardware state only occurs if the MSR has * the respective bits set. */ if ( ecx & cpufeat_mask(X86_FEATURE_XSAVE) ) ecx = cpufeat_mask(X86_FEATURE_OSXSAVE); else ecx = 0; edx = cpufeat_mask(X86_FEATURE_APIC); mask |= ((uint64_t)ecx << 32) | edx; break; } d->arch.pv_domain.cpuidmasks->_1cd = mask; } break; case 6: if ( is_pv_domain(d) && ((levelling_caps & LCAP_6c) == LCAP_6c) ) { uint64_t mask = cpuidmask_defaults._6c; if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) mask &= (~0ULL << 32) | ctl->ecx; d->arch.pv_domain.cpuidmasks->_6c = mask; } break; case 7: if ( ctl->input[1] != 0 ) break; if ( is_pv_domain(d) && ((levelling_caps & LCAP_7ab0) == LCAP_7ab0) ) { uint64_t mask = cpuidmask_defaults._7ab0; uint32_t eax = ctl->eax; uint32_t ebx = ctl->ebx & pv_featureset[FEATURESET_7b0]; if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) mask &= ((uint64_t)eax << 32) | ebx; d->arch.pv_domain.cpuidmasks->_7ab0 = mask; } break; case 0xd: if ( ctl->input[1] != 1 ) break; if ( is_pv_domain(d) && ((levelling_caps & LCAP_Da1) == LCAP_Da1) ) { uint64_t mask = cpuidmask_defaults.Da1; uint32_t eax = ctl->eax & pv_featureset[FEATURESET_Da1]; if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ) mask &= (~0ULL << 32) | eax; d->arch.pv_domain.cpuidmasks->Da1 = mask; } break; case 0x80000001: if ( is_pv_domain(d) && ((levelling_caps & LCAP_e1cd) == LCAP_e1cd) ) { uint64_t mask = cpuidmask_defaults.e1cd; uint32_t ecx = ctl->ecx & pv_featureset[FEATURESET_e1c]; uint32_t edx = ctl->edx & pv_featureset[FEATURESET_e1d]; /* * Must expose hosts CMP_LEGACY value so a guest using native * CPUID can correctly interpret other leaves which cannot be * masked. */ if ( cpu_has_cmp_legacy ) ecx |= cpufeat_mask(X86_FEATURE_CMP_LEGACY); /* If not emulating AMD, clear the duplicated features in e1d. */ if ( d->arch.x86_vendor != X86_VENDOR_AMD ) edx &= ~CPUID_COMMON_1D_FEATURES; switch ( boot_cpu_data.x86_vendor ) { case X86_VENDOR_INTEL: mask &= ((uint64_t)edx << 32) | ecx; break; case X86_VENDOR_AMD: mask &= ((uint64_t)ecx << 32) | edx; /* * Fast-forward bits - Must be set in the masking MSR for * fast-forwarding to occur in hardware. */ ecx = 0; edx = cpufeat_mask(X86_FEATURE_APIC); mask |= ((uint64_t)ecx << 32) | edx; break; } d->arch.pv_domain.cpuidmasks->e1cd = mask; } break; } }
static void _clean_dirty_bitmap(struct domain *d) { ASSERT(is_pv_domain(d)); }
unsigned long __init dom0_compute_nr_pages( struct domain *d, struct elf_dom_parms *parms, unsigned long initrd_len) { nodeid_t node; unsigned long avail = 0, nr_pages, min_pages, max_pages; bool_t need_paging; for_each_node_mask ( node, dom0_nodes ) avail += avail_domheap_pages_region(node, 0, 0) + initial_images_nrpages(node); /* Reserve memory for further dom0 vcpu-struct allocations... */ avail -= (d->max_vcpus - 1UL) << get_order_from_bytes(sizeof(struct vcpu)); /* ...and compat_l4's, if needed. */ if ( is_pv_32bit_domain(d) ) avail -= d->max_vcpus - 1; /* Reserve memory for iommu_dom0_init() (rough estimate). */ if ( iommu_enabled ) { unsigned int s; for ( s = 9; s < BITS_PER_LONG; s += 9 ) avail -= max_pdx >> s; } need_paging = is_hvm_domain(d) && (!iommu_hap_pt_share || !paging_mode_hap(d)); for ( ; ; need_paging = 0 ) { nr_pages = dom0_nrpages; min_pages = dom0_min_nrpages; max_pages = dom0_max_nrpages; /* * If allocation isn't specified, reserve 1/16th of available memory * for things like DMA buffers. This reservation is clamped to a * maximum of 128MB. */ if ( nr_pages == 0 ) nr_pages = -min(avail / 16, 128UL << (20 - PAGE_SHIFT)); /* Negative specification means "all memory - specified amount". */ if ( (long)nr_pages < 0 ) nr_pages += avail; if ( (long)min_pages < 0 ) min_pages += avail; if ( (long)max_pages < 0 ) max_pages += avail; /* Clamp according to min/max limits and available memory. */ nr_pages = max(nr_pages, min_pages); nr_pages = min(nr_pages, max_pages); nr_pages = min(nr_pages, avail); if ( !need_paging ) break; /* Reserve memory for shadow or HAP. */ avail -= dom0_paging_pages(d, nr_pages); } if ( is_pv_domain(d) && (parms->p2m_base == UNSET_ADDR) && (dom0_nrpages <= 0) && ((dom0_min_nrpages <= 0) || (nr_pages > min_pages)) ) { /* * Legacy Linux kernels (i.e. such without a XEN_ELFNOTE_INIT_P2M * note) require that there is enough virtual space beyond the initial * allocation to set up their initial page tables. This space is * roughly the same size as the p2m table, so make sure the initial * allocation doesn't consume more than about half the space that's * available between params.virt_base and the address space end. */ unsigned long vstart, vend, end; size_t sizeof_long = is_pv_32bit_domain(d) ? sizeof(int) : sizeof(long); vstart = parms->virt_base; vend = round_pgup(parms->virt_kend); if ( !parms->unmapped_initrd ) vend += round_pgup(initrd_len); end = vend + nr_pages * sizeof_long; if ( end > vstart ) end += end - vstart; if ( end <= vstart || (sizeof_long < sizeof(end) && end > (1UL << (8 * sizeof_long))) ) { end = sizeof_long >= sizeof(end) ? 0 : 1UL << (8 * sizeof_long); nr_pages = (end - vend) / (2 * sizeof_long); if ( dom0_min_nrpages > 0 && nr_pages < min_pages ) nr_pages = min_pages; printk("Dom0 memory clipped to %lu pages\n", nr_pages); } } d->max_pages = min_t(unsigned long, max_pages, UINT_MAX); return nr_pages; }