On Wed, 9 Nov 2011, Jiageng Yu wrote:
> 2011/11/9 Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
> >
> > On Thu, 27 Oct 2011, Jiageng Yu wrote:
> > > Hi Stefano,
> > >
> > > Â Â Â I have some progress in linux based stubdom project. As shown in
> > > the
> > > attached video, I have started the emulated vga device in the linux
> > > based stubdom.
> > >
> > > Â Â Â In a short conclusion, for the linux based stubdom, there are two
> > > major problems about vga device emulation. The first is the vram
> > > mapping, which we discussed a lot previously and handled it.
> >
> > Do you have an updated version of the patch you used?
> >
> >
> > > Another
> > > is the vga BIOS mapping (address 0xc0000-0xc8fff of hvm guest).
> >
> > This is caused by qemu trying to map that memory area in its own address
> > space, right?
> >
> >
> > > Â Â Â I found the vga BIOS mapping problem in remap_area_mfn_pte_fn()
> > > function. The pte_mkspecial() will return invalid value when I try to
> > > map 0xc0000-0xc8fff into linux based stubdom.
> >
> > What is exactly the error you are seeing?
> >
> >
> > > pte_mkspecial()
> > > Â Â Â ->pte_set_flags()
> > > Â Â Â Â Â Â Â ->native_pte_val()
> > > Â Â Â Â Â Â Â ->native_make_pte()
> > >
> > > Â Â Â According to my test, the root cause of vga BIOS mapping problem
> > > is
> > > native_xxx functions. We could avoid the problem by invoking functions
> > > defined in paravirt.h instead. The patch is as follows. But I think it
> > > is not a good way to handle the problem. Maybe you can give me some
> > > suggestions.
> > >
> > > Â Â Â I also found the hard disk
> > > didn�??�?????�??�????�??�???�??�??�??�?�¢??t work well. I
> > > will investigate it these days.
> > >
> > >
> > > --- a/arch/x86/xen/mmu.c
> > > +++ b/arch/x86/xen/mmu.c
> > > @@ -2639,12 +2640,16 @@ static int remap_area_mfn_pte_fn(pte_t *ptep,
> > > pgtable_t token,
> > > Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â unsigned long addr, void
> > > *data)
> > > Â {
> > > Â Â Â struct remap_data *rmd = data;
> > > - Â Â pte_t pte = pte_mkspecial(pfn_pte(rmd->mfn++, rmd->prot));
> > > + Â Â if((rmd->mfn & 0xfffffff0) == 0xc0){
> > > + Â Â Â Â pte_t pte = pfn_pte(rmd->mfn++, rmd->prot);
> > > + Â Â Â Â rmd->mmu_update->val = pte_val(pte);
> > > + Â Â }else{
> > > + Â Â Â Â pte_t pte = pte_mkspecial(pfn_pte(rmd->mfn++, rmd->prot));
> > > + Â Â Â Â rmd->mmu_update->val = pte_val_ma(pte);
> > > + Â Â }
> >
> > Even if the fix is not the correct one I think I might understand what
> > the real problem is:
> >
> > pfn_pte -> xen_make_pte
> >
> > if (unlikely(pte & _PAGE_IOMAP) &&
> > Â Â Â Â (xen_initial_domain() || addr >= ISA_END_ADDRESS)) {
> > Â Â pte = iomap_pte(pte);
> > } else {
> > Â Â pte &= ~_PAGE_IOMAP;
> > Â Â pte = pte_pfn_to_mfn(pte);
> > }
> >
> > considering that in this case xen_initial_domain() returns false and
> > addr is < ISA_END_ADDRESS (it is a gpfn address), xen_make_pte is going
> > to threat the mfn as a pfn erroneously.
> >
> > In your patch you replaced pte_val_ma with pte_val that does the
> > opposite translation (mfn -> pfn) so the end result is that you get the
> > original mfn in rmd->mmu_update->val.
> >
>
> Indeed!
>
> > The real fix should something along these lines:
> >
> >
> >
> > diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
> > index 3dd53f9..f2fadfc 100644
> > --- a/arch/x86/xen/mmu.c
> > +++ b/arch/x86/xen/mmu.c
> > @@ -422,7 +422,7 @@ static pteval_t xen_pte_val(pte_t pte)
> > Â Â Â Â Â Â Â Â pteval = (pteval & ~_PAGE_PAT) | _PAGE_PWT;
> > Â Â Â Â }
> >
> > - Â Â Â if (xen_initial_domain() && (pteval & _PAGE_IOMAP))
> > + Â Â Â if (pteval & _PAGE_IOMAP)
> > Â Â Â Â Â Â Â Â return pteval;
> >
> > Â Â Â Â return pte_mfn_to_pfn(pteval);
> > @@ -483,8 +483,7 @@ static pte_t xen_make_pte(pteval_t pte)
> > Â Â Â Â * mappings are just dummy local mappings to keep other
> > Â Â Â Â * parts of the kernel happy.
> > Â Â Â Â */
> > - Â Â Â if (unlikely(pte & _PAGE_IOMAP) &&
> > - Â Â Â Â Â (xen_initial_domain() || addr >= ISA_END_ADDRESS)) {
> > + Â Â Â if (unlikely(pte & _PAGE_IOMAP)) {
> > Â Â Â Â Â Â Â Â pte = iomap_pte(pte);
> > Â Â Â Â } else {
> > Â Â Â Â Â Â Â Â pte &= ~_PAGE_IOMAP;
> > ---
> >
> > Could you please confirm whether this patch fixes your problem?
>
>
> Sorry, it did not succeed. The Linux stubdom kernel crashed during
> booting. The debug info is as follows.
The kernel is tring to access some memory < ISA_END_ADDRESS that is
supposed to be translated (pfn->mfn), but it doesn't happen anymore
because of that patch.
At this point the only solution I can think of is changing
remap_area_mfn_pte_fn:
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 3dd53f9..dd088f2 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2350,7 +2350,8 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t
token,
unsigned long addr, void *data)
{
struct remap_data *rmd = data;
- pte_t pte = pte_mkspecial(pfn_pte(rmd->mfn++, rmd->prot));
+ pte_t pte = pte_mkspecial(native_make_pte(((phys_addr_t)(rmd->mfn++)
+ << PAGE_SHIFT) |
massage_pgprot(rmd->prot)));
rmd->mmu_update->ptr = virt_to_machine(ptep).maddr;
rmd->mmu_update->val = pte_val_ma(pte); _______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|