Re: KVM 12 and BUG with preempt kernel

roucaries bastien
2007-01-24T10:47:55Z

teThis time cc kvm-devel
Problem summary:
My host kernel oops:
Unable to handle kernel paging request at 00000000b7f8143d RIP:
> > [<ffffffff88376d73>] :kvm:paging32_gva_to_gpa+0x43/0x120

On 1/24/07, Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org> wrote:
> roucaries bastien wrote:
> > Hi,
> >
> > First thank for your nice piece of software kvm.
> > However I have to report some bugs and oops on the host side
> > that seems to be related to preempt:
>
> Please post bugs to kvm-devel or to the sourceforge bug tracker.
>
>
> > -----------------------------------------------------------------------------------------------------------------
> >
> > Unable to handle kernel paging request at 00000000b7f8143d RIP:
> > [<ffffffff88376d73>] :kvm:paging32_gva_to_gpa+0x43/0x120
>
> Does the attached patch fix the bug?

It seems yes (10 boots). Nethertheless I think it is time to report
another bug (present without this patch therefore unrelated).
Unfortunatly I have no trace because it crash my machine and I do not
manage to find it.

If I booot my debian guest with framebuffer activated after 20s to 15
minutes I see on my host screen a cloud of colorfull pixel. These
pixel flash and seems related to guest frame buffer (same colors
scheme but because it not the same resolution I can't read it). About
3s latter my box crash and is dead (cap lock does not even toggles the
keyboard led). Therefore it seems that the guest achieve to write the
host memory :-(, the good point is that he does not poke to my hard
drive registers.

This behavior is 100% reproductible. If I run the host and I switch to
the text console I can't even get a trace because the screen is
corrupted. Unfortunatly I have no serial port on this box (laptop).

>Index: paging_tmpl.h
>===================================================================
>--- paging_tmpl.h (revision 4320)
>+++ paging_tmpl.h (working copy)
>@@ -443,31 +443,17 @@
>static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr)
> {
struct guest_walker walker;
- pt_element_t guest_pte;
- gpa_t gpa;
+ gpa_t gpa = UNMAPPED_GVA;
+ int r;

- FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0);
- guest_pte = *walker.ptep;
- FNAME(release_walker)(&walker);
+ r = FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0);

- if (!is_present_pte(guest_pte))
- return UNMAPPED_GVA;
-
- if (walker.level == PT_DIRECTORY_LEVEL) {
- ASSERT((guest_pte & PT_PAGE_SIZE_MASK));
- ASSERT(PTTYPE == 64 || is_pse(vcpu));
-
- gpa = (guest_pte & PT_DIR_BASE_ADDR_MASK) | (vaddr &
- (PT_LEVEL_MASK(PT_PAGE_TABLE_LEVEL) | ~PAGE_MASK));
-
- if (PTTYPE == 32 && is_cpuid_PSE36())
- gpa |= (guest_pte & PT32_DIR_PSE36_MASK) <<
- (32 - PT32_DIR_PSE36_SHIFT);
- } else {
- gpa = (guest_pte & PT_BASE_ADDR_MASK);
- gpa |= (vaddr & ~PAGE_MASK);
+ if (r) {
+ gpa = (gpa_t)walker.gfn << PAGE_SHIFT;
+ gpa |= vaddr & ~PAGE_MASK;
}

+ FNAME(release_walker)(&walker);
return gpa;
}