0

When building the latest Linux kernel for CentOS it turns up the following error

CC [M] arch/x86/kernel/iosf_mbi.o CC arch/x86/kvm/../../../virt/kvm/kvm_main.o CC arch/x86/kvm/../../../virt/kvm/coalesced_mmio.o CC arch/x86/kvm/../../../virt/kvm/eventfd.o CC arch/x86/kvm/../../../virt/kvm/irqchip.o CC arch/x86/kvm/../../../virt/kvm/vfio.o CC arch/x86/kvm/../../../virt/kvm/async_pf.o CC arch/x86/kvm/x86.o arch/x86/kvm/x86.c: In function ‘kvm_write_tsc’: arch/x86/kvm/x86.c:1290: warning: ‘already_matched’ may be used uninitialized > in this function CC arch/x86/kvm/mmu.o arch/x86/kvm/mmu.c: In function ‘kvm_mmu_pte_write’: arch/x86/kvm/mmu.c:4219: error: unknown field ‘cr0_wp’ specified in > initializer arch/x86/kvm/mmu.c:4220: error: unknown field ‘cr4_pae’ specified in initializer arch/x86/kvm/mmu.c:4220: warning: excess elements in union initializer arch/x86/kvm/mmu.c:4220: warning: (near initialization for ‘(anonymous)’) arch/x86/kvm/mmu.c:4221: error: unknown field ‘nxe’ specified in initializer arch/x86/kvm/mmu.c:4221: warning: excess elements in union initializer arch/x86/kvm/mmu.c:4221: warning: (near initialization for ‘(anonymous)’) arch/x86/kvm/mmu.c:4222: error: unknown field ‘smep_andnot_wp’ specified in initializer arch/x86/kvm/mmu.c:4222: warning: excess elements in union initializer arch/x86/kvm/mmu.c:4222: warning: (near initialization for ‘(anonymous)’) arch/x86/kvm/mmu.c:4223: error: unknown field ‘smap_andnot_wp’ specified in initializer arch/x86/kvm/mmu.c:4223: warning: excess elements in union initializer arch/x86/kvm/mmu.c:4223: warning: (near initialization for ‘(anonymous)’) make[2]: * [arch/x86/kvm/mmu.o] Error 1 make[1]: * [arch/x86/kvm] Error 2 make: *** [arch/x86] Error 2

I've disabled MMU under the KVM menu but it still comes up in the compile, I've tried a make clean as well

Here's the build config: http://sprunge.us/YdcN

Anything that I'm missing?

0

This is a coding mistake found in linux-4.0.5/arch/x86/kvm/mmu.c file. You can comment those lines because that is a union variable used to allocate page table details as it is not much important.

or:

You can replace the function kvm_mmu_pte_write() definition with below code to correct the mistake

void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
                   const u8 *new, int bytes) {
    gfn_t gfn = gpa >> PAGE_SHIFT;
    struct kvm_mmu_page *sp;
    LIST_HEAD(invalid_list);
    u64 entry, gentry, *spte;
    int npte;
    bool remote_flush, local_flush, zap_page;

    struct kvm_mmu *context = &vcpu->arch.mmu;

    union kvm_mmu_page_role mask = (union kvm_mmu_page_role) {
        context->base_role.cr0_wp = 1,
        context->base_role.cr4_pae = 1,
        context->base_role.nxe = 1,
        context->base_role.smep_andnot_wp = 1,
        context->base_role.smap_andnot_wp = 1
    };

    /*
     * If we don't have indirect shadow pages, it means no page is
     * write-protected, so we can exit simply.
     */
    if (!ACCESS_ONCE(vcpu->kvm->arch.indirect_shadow_pages))
            return;

    zap_page = remote_flush = local_flush = false;

    pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes);

    gentry = mmu_pte_write_fetch_gpte(vcpu, &gpa, new, &bytes);

    /*
     * No need to care whether allocation memory is successful
     * or not since pte prefetch is skiped if it does not have
     * enough objects in the cache.
     */
    mmu_topup_memory_caches(vcpu);

    spin_lock(&vcpu->kvm->mmu_lock);
    ++vcpu->kvm->stat.mmu_pte_write;
    kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE);

    for_each_gfn_indirect_valid_sp(vcpu->kvm, sp, gfn) {
            if (detect_write_misaligned(sp, gpa, bytes) ||
                  detect_write_flooding(sp)) {
                    zap_page |= !!kvm_mmu_prepare_zap_page(vcpu->kvm, sp,
                                                 &invalid_list);
                    ++vcpu->kvm->stat.mmu_flooded;
                    continue;
            }

            spte = get_written_sptes(sp, gpa, &npte);
            if (!spte)
                    continue;

            local_flush = true;
            while (npte--) {
                    entry = *spte;
                    mmu_page_zap_pte(vcpu->kvm, sp, spte);
                    if (gentry &&
                          !((sp->role.word ^ vcpu->arch.mmu.base_role.word)
                          & mask.word) && rmap_can_add(vcpu))
                            mmu_pte_write_new_pte(vcpu, sp, spte, &gentry);
                    if (need_remote_flush(entry, *spte))
                            remote_flush = true;
                    ++spte;
            }
    }
    mmu_pte_write_flush_tlb(vcpu, zap_page, remote_flush, local_flush);
    kvm_mmu_commit_zap_page(vcpu->kvm, &invalid_list);
    kvm_mmu_audit(vcpu, AUDIT_POST_PTE_WRITE);
    spin_unlock(&vcpu->kvm->mmu_lock);
}

Make the changes and compile the code again. it works for me.

2
  • 1
    How do you know that this is a bug? How do you know that this code fixes the problem? – Michael Hampton Jun 10 '15 at 18:42
  • Does this fix exist in 4.1-rc7 ? – Arjit Chaudhary Jun 11 '15 at 12:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.