On Thu, Sep 11, 2014 at 03:52:21PM +0100, Marc Zyngier wrote: > On 11/09/14 15:41, Ard Biesheuvel wrote: > > Hello all, > > > > I spent most of the day chasing a particularly weird heisenbug in the > > QEMU+KVM+UEFI combo. > > The symptom was that UEFI init would hang on the first write to the > > second NOR flash (to initialize the variable store) but *only* when > > using the -bios option (instead of -pflash) and a boot image of > > exactly 64 MB in size. Note that this implies that the second NOR > > flash was not file backed. > > > > As it turns out, the choice of the -bios option and the size of the > > file affect whether KVM ends up using sections or pages to back the > > NOR flash, and in my failure case, it was using the latter. That > > resulted in KVM going down a code path where the memory backing the > > NOR was writable, which breaks the MMIO emulation, and resulted in the > > hang on init of the variable store. > > > > The patch below fixes it for me. > > > > diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c > > index c68ec28f17c3..121abc6fef97 100644 > > --- a/arch/arm/kvm/mmu.c > > +++ b/arch/arm/kvm/mmu.c > > @@ -817,7 +817,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, > > phys_addr_t fault_ipa, > > pfn = gfn_to_pfn_prot(kvm, gfn, write_fault, &writable); > > if (is_error_pfn(pfn)) > > return -EFAULT; > > > > - if (kvm_is_mmio_pfn(pfn)) > > + if (writable && kvm_is_mmio_pfn(pfn)) > > mem_type = PAGE_S2_DEVICE; > > > > spin_lock(&kvm->mmu_lock); > > > > Here is the definition of kvm_is_mmio() for completeness. I am a bit > > out of my depth here, so perhaps someone else can shed some light on > > this? > > > > bool kvm_is_mmio_pfn(pfn_t pfn) > > { > > if (pfn_valid(pfn)) > > return PageReserved(pfn_to_page(pfn)); > > > > return true; > > } > > > > To me, it is particularly puzzling what PageReserved() has to do with > > anything, as I couldn't find any other uses of it under kvm/ > > > > My understanding is that kvm_is_mmio_pfn() is used for *devices* that > are mapped directly mapped (think device assignment). PageReserved() > would make sense there. > Why does PageReserved() make sense here? Is reserved pages used to indicated MMIO regions? (I'm exposing holes in my knowledge about the Linux mm subsystem here.) -Christoffer _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm