All of lore.kernel.org
 help / color / mirror / Atom feed
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: "jeremy@goop.org" <jeremy@goop.org>,
	"Xen-devel@lists.xensource.com" <Xen-devel@lists.xensource.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Ian Campbell <Ian.Campbell@eu.citrix.com>,
	"konrad@kernel.org" <konrad@kernel.org>,
	"hpa@zytor.com" <hpa@zytor.com>
Subject: Re: [Xen-devel] Re: [PATCH 11/11] xen/m2p: Check whether the MFN has IDENTITY_FRAME bit set..
Date: Wed, 2 Feb 2011 11:43:07 -0500	[thread overview]
Message-ID: <20110202164307.GB14834@dumpdata.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1102021128350.7277@kaball-desktop>

> > Not sure I understand.
> 
> Considering that getting in this function with an identity mfn passed as
> argument shouldn't happen at all, and considering that there are cases

True, unless a developer wants to check that p2m(m2p(mfn))=mfn and 
supplies the MFNs that cover the PCI BAR spaces.. but that is mostly
done when trying to troubleshoot something and normal folks won't do this.


> in which the same mfn can correspond to a normal mapping, a 1:1 mapping
> or even a granted page, it is a good idea to check the m2p_override
> *before* checking if the mfn is an identity mfn.
> So that if there are two identical mfns, one granted and the other
> one belonging to an identity mapping, we would return the pfn

How can you have that? Are you passing through a PCI device to
a PV domain, making the PV domain have the netback/blkback device,
and then granting those pages to another domain?

> corresponding to the granted mfn, that is the right answer because we
> shouldn't even be here if the argument was an identity mfn.
> 
> 
> > > 3) the returned pfn might be 0xfffff or 0xeeeee.

>From the machine_to_phys_mapping array. OK.
> > > We should use the mfn value directly as pfn value to check for possible
> > > identity mappings.
> > 
> > Aren't we doing that via 'get_phys_to_machine' ? It returns the value
> > and if it has the IDENTITY_FRAME_BIT it is an identity.
> > 
> > Or are you thinking of abolishing the IDENTITY_FRAME_BIT and check the
> > M2P in conjunction with the P2M to see if the mfn is a 1-1 mapping?
> > 
> 
> Not at all.
> The problem is the following:
> 
> pfn = m2p(mfn);

You are assuming that the 'mfn' is outside the scope off our machine_to_phys array
or that it is "garbage", such as 0xdeadbeef for example, I think.

In which case the pfn value is either 0xdeadbeef or INVALID_P2M_ENTRY.

If you provide that to get_phys_to_machine(0xdeadbeef) you get INVALID_P2M_ENTRY,
and you would call:
  pfn = m2p_find_override_pfn(mfn, pfn);

So we still end up checking the M2P override. If the pfn supplied
was INVALID_P2M_ENTRY, you would get the same value and still check the P2M override.


> 
> let's suppose that pfn is garbage (0xFFFFF.. or 0x55555..), in this case

0xFFFF or 0x5555 are not garbage. They are valid values. Garbage is the
value zero. 0xFFFF.. has two meanings: It is a missing page that can be
balloon-ed in, or it belongs to the DOMID_IO. The 0x5555.. means it is
a shared DOMID_IO page.

> get_phys_to_machine(pfn) will return INVALID_P2M_ENTRY that is not what
> we want.
> So we check for
> 
> get_phys_to_machine(mfn) == IDENTITY_FRAME(mfn)
>                     ---
> if it is true than it means that the mfn passed as argument belongs to
> an identity mapping.

<nods> Yup.
> 
> 
> 
> > > 
> > > The resulting patch looks like the following:
> > > 
> > > ---
> > > 
> > > 
> > > diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
> > > index ed46ec2..7f9bae2 100644
> > > --- a/arch/x86/include/asm/xen/page.h
> > > +++ b/arch/x86/include/asm/xen/page.h
> > > @@ -80,6 +80,7 @@ static inline int phys_to_machine_mapping_valid(unsigned long pfn)
> > >  
> > >  static inline unsigned long mfn_to_pfn(unsigned long mfn)
> > >  {
> > > +	int ret = 0;
> > >  	unsigned long pfn;
> > >  
> > >  	if (xen_feature(XENFEAT_auto_translated_physmap))
> > > @@ -95,15 +96,21 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
> > >  	 * In such cases it doesn't matter what we return (we return garbage),
> > >  	 * but we must handle the fault without crashing!
> > >  	 */
> > > -	__get_user(pfn, &machine_to_phys_mapping[mfn]);
> > > +	ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
> > >  try_override:
> > >  	/*
> > >  	 * If this appears to be a foreign mfn (because the pfn
> > >  	 * doesn't map back to the mfn), then check the local override
> > >  	 * table to see if there's a better pfn to use.
> > >  	 */
> > > -	if (get_phys_to_machine(pfn) != mfn)
> > > -		pfn = m2p_find_override_pfn(mfn, pfn);
> > > +	if (ret < 0)
> > > +		pfn = ~0;
> > > +	else if (get_phys_to_machine(pfn) != mfn)
> > > +		pfn = m2p_find_override_pfn(mfn, ~0);
> > > +
> > > +	if (pfn == ~0 &&
> > 
> > You should also check for 0x55555... then.
> 
> that is not necessary because pfn == ~0 at this point, this is the code
> path:
> 
> ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); /* ret is >= 0 and
>                                                        pfn is 0x55555.. */
> get_phys_to_machine(0x55555) != mfn /* true, I am assuming there are no
>                                      valid p2m mappings at 0x55555.. */

> pfn = m2p_find_override_pfn(mfn, ~0); /* the m2p_ovverride doesn't find
>                                          anything so it returns ~0 (the
>                                          second argument), pfn == ~0 now */
> if (pfn == ~0 && /* true */
> 
> 
> maybe I should add a comment (and drink less caffeine)?

The first time I saw the patch I missed that you passed in 'mfn' to
the second get_phys_to_machine .. Comments are good here I think.
> 
> 
> > > +			get_phys_to_machine(mfn) == IDENTITY_FRAME(mfn))
> > > +		pfn = mfn;
> > 
> > So for identity type mfns we end up calling 'get_phys_to_machine(mfn)' twice
> > I think?
> > 
> > Would it make sense to save the result of 'get_phys_to_machine(mfn)'
> > the first call?
> 
> the first call is get_phys_to_machine(pfn), with pfn potentially
> garbage; this call is get_phys_to_machine(mfn).

I think what you are telling me is that it is pointless to check for
the IDENTITY_FRAME b/c it won't happen often or at all.

So moving the code so that we do the hot-paths first makes more
sense and we should structure the code as so, right?

I agree with that sentiment, do you want to prep another patch that
has this patch and also some more comments?

WARNING: multiple messages have this Message-ID (diff)
From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
To: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: "jeremy@goop.org" <jeremy@goop.org>,
	"Xen-devel@lists.xensource.com" <Xen-devel@lists.xensource.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Ian Campbell <Ian.Campbell@eu.citrix.com>,
	"konrad@kernel.org" <konrad@kernel.org>,
	"hpa@zytor.com" <hpa@zytor.com>
Subject: Re: Re: [PATCH 11/11] xen/m2p: Check whether the MFN has IDENTITY_FRAME bit set..
Date: Wed, 2 Feb 2011 11:43:07 -0500	[thread overview]
Message-ID: <20110202164307.GB14834@dumpdata.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1102021128350.7277@kaball-desktop>

> > Not sure I understand.
> 
> Considering that getting in this function with an identity mfn passed as
> argument shouldn't happen at all, and considering that there are cases

True, unless a developer wants to check that p2m(m2p(mfn))=mfn and 
supplies the MFNs that cover the PCI BAR spaces.. but that is mostly
done when trying to troubleshoot something and normal folks won't do this.


> in which the same mfn can correspond to a normal mapping, a 1:1 mapping
> or even a granted page, it is a good idea to check the m2p_override
> *before* checking if the mfn is an identity mfn.
> So that if there are two identical mfns, one granted and the other
> one belonging to an identity mapping, we would return the pfn

How can you have that? Are you passing through a PCI device to
a PV domain, making the PV domain have the netback/blkback device,
and then granting those pages to another domain?

> corresponding to the granted mfn, that is the right answer because we
> shouldn't even be here if the argument was an identity mfn.
> 
> 
> > > 3) the returned pfn might be 0xfffff or 0xeeeee.

>From the machine_to_phys_mapping array. OK.
> > > We should use the mfn value directly as pfn value to check for possible
> > > identity mappings.
> > 
> > Aren't we doing that via 'get_phys_to_machine' ? It returns the value
> > and if it has the IDENTITY_FRAME_BIT it is an identity.
> > 
> > Or are you thinking of abolishing the IDENTITY_FRAME_BIT and check the
> > M2P in conjunction with the P2M to see if the mfn is a 1-1 mapping?
> > 
> 
> Not at all.
> The problem is the following:
> 
> pfn = m2p(mfn);

You are assuming that the 'mfn' is outside the scope off our machine_to_phys array
or that it is "garbage", such as 0xdeadbeef for example, I think.

In which case the pfn value is either 0xdeadbeef or INVALID_P2M_ENTRY.

If you provide that to get_phys_to_machine(0xdeadbeef) you get INVALID_P2M_ENTRY,
and you would call:
  pfn = m2p_find_override_pfn(mfn, pfn);

So we still end up checking the M2P override. If the pfn supplied
was INVALID_P2M_ENTRY, you would get the same value and still check the P2M override.


> 
> let's suppose that pfn is garbage (0xFFFFF.. or 0x55555..), in this case

0xFFFF or 0x5555 are not garbage. They are valid values. Garbage is the
value zero. 0xFFFF.. has two meanings: It is a missing page that can be
balloon-ed in, or it belongs to the DOMID_IO. The 0x5555.. means it is
a shared DOMID_IO page.

> get_phys_to_machine(pfn) will return INVALID_P2M_ENTRY that is not what
> we want.
> So we check for
> 
> get_phys_to_machine(mfn) == IDENTITY_FRAME(mfn)
>                     ---
> if it is true than it means that the mfn passed as argument belongs to
> an identity mapping.

<nods> Yup.
> 
> 
> 
> > > 
> > > The resulting patch looks like the following:
> > > 
> > > ---
> > > 
> > > 
> > > diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
> > > index ed46ec2..7f9bae2 100644
> > > --- a/arch/x86/include/asm/xen/page.h
> > > +++ b/arch/x86/include/asm/xen/page.h
> > > @@ -80,6 +80,7 @@ static inline int phys_to_machine_mapping_valid(unsigned long pfn)
> > >  
> > >  static inline unsigned long mfn_to_pfn(unsigned long mfn)
> > >  {
> > > +	int ret = 0;
> > >  	unsigned long pfn;
> > >  
> > >  	if (xen_feature(XENFEAT_auto_translated_physmap))
> > > @@ -95,15 +96,21 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
> > >  	 * In such cases it doesn't matter what we return (we return garbage),
> > >  	 * but we must handle the fault without crashing!
> > >  	 */
> > > -	__get_user(pfn, &machine_to_phys_mapping[mfn]);
> > > +	ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
> > >  try_override:
> > >  	/*
> > >  	 * If this appears to be a foreign mfn (because the pfn
> > >  	 * doesn't map back to the mfn), then check the local override
> > >  	 * table to see if there's a better pfn to use.
> > >  	 */
> > > -	if (get_phys_to_machine(pfn) != mfn)
> > > -		pfn = m2p_find_override_pfn(mfn, pfn);
> > > +	if (ret < 0)
> > > +		pfn = ~0;
> > > +	else if (get_phys_to_machine(pfn) != mfn)
> > > +		pfn = m2p_find_override_pfn(mfn, ~0);
> > > +
> > > +	if (pfn == ~0 &&
> > 
> > You should also check for 0x55555... then.
> 
> that is not necessary because pfn == ~0 at this point, this is the code
> path:
> 
> ret = __get_user(pfn, &machine_to_phys_mapping[mfn]); /* ret is >= 0 and
>                                                        pfn is 0x55555.. */
> get_phys_to_machine(0x55555) != mfn /* true, I am assuming there are no
>                                      valid p2m mappings at 0x55555.. */

> pfn = m2p_find_override_pfn(mfn, ~0); /* the m2p_ovverride doesn't find
>                                          anything so it returns ~0 (the
>                                          second argument), pfn == ~0 now */
> if (pfn == ~0 && /* true */
> 
> 
> maybe I should add a comment (and drink less caffeine)?

The first time I saw the patch I missed that you passed in 'mfn' to
the second get_phys_to_machine .. Comments are good here I think.
> 
> 
> > > +			get_phys_to_machine(mfn) == IDENTITY_FRAME(mfn))
> > > +		pfn = mfn;
> > 
> > So for identity type mfns we end up calling 'get_phys_to_machine(mfn)' twice
> > I think?
> > 
> > Would it make sense to save the result of 'get_phys_to_machine(mfn)'
> > the first call?
> 
> the first call is get_phys_to_machine(pfn), with pfn potentially
> garbage; this call is get_phys_to_machine(mfn).

I think what you are telling me is that it is pointless to check for
the IDENTITY_FRAME b/c it won't happen often or at all.

So moving the code so that we do the hot-paths first makes more
sense and we should structure the code as so, right?

I agree with that sentiment, do you want to prep another patch that
has this patch and also some more comments?

  reply	other threads:[~2011-02-02 16:44 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-31 22:44 [PATCH v4] Consider E820 non-RAM and E820 gaps as 1-1 mappings Konrad Rzeszutek Wilk
2011-01-31 22:44 ` [PATCH 01/11] xen: Mark all initial reserved pages for the balloon as INVALID_P2M_ENTRY Konrad Rzeszutek Wilk
2011-01-31 22:44 ` [PATCH 02/11] xen/mmu: Add the notion of identity (1-1) mapping Konrad Rzeszutek Wilk
2011-02-01 21:33   ` Jeremy Fitzhardinge
2011-01-31 22:44 ` [PATCH 03/11] xen/mmu: Set _PAGE_IOMAP if PFN is an identity PFN Konrad Rzeszutek Wilk
2011-01-31 22:44 ` [PATCH 04/11] xen/mmu: BUG_ON when racing to swap middle leaf Konrad Rzeszutek Wilk
2011-02-01 21:34   ` Jeremy Fitzhardinge
2011-01-31 22:44 ` [PATCH 05/11] xen/setup: Set identity mapping for non-RAM E820 and E820 gaps Konrad Rzeszutek Wilk
2011-02-01 22:32   ` Konrad Rzeszutek Wilk
2011-02-01 22:32     ` Konrad Rzeszutek Wilk
2011-01-31 22:44 ` [PATCH 06/11] xen/setup: Skip over 1st gap after System RAM Konrad Rzeszutek Wilk
2011-02-01 15:08   ` Ian Campbell
2011-02-01 17:14     ` H. Peter Anvin
2011-02-01 17:14       ` H. Peter Anvin
2011-02-01 22:28     ` Konrad Rzeszutek Wilk
2011-01-31 22:44 ` [PATCH 07/11] x86/setup: Consult the raw E820 for zero sized E820 RAM regions Konrad Rzeszutek Wilk
2011-02-01 17:52   ` Stefano Stabellini
2011-02-01 22:29     ` [Xen-devel] " Konrad Rzeszutek Wilk
2011-01-31 22:44 ` [PATCH 08/11] xen/debugfs: Add 'p2m' file for printing out the P2M layout Konrad Rzeszutek Wilk
2011-01-31 22:44 ` [PATCH 09/11] xen/debug: WARN_ON when identity PFN has no _PAGE_IOMAP flag set Konrad Rzeszutek Wilk
2011-01-31 22:44 ` [PATCH 10/11] xen/m2p: No need to catch exceptions when we know that there is no RAM Konrad Rzeszutek Wilk
2011-01-31 22:44 ` [PATCH 11/11] xen/m2p: Check whether the MFN has IDENTITY_FRAME bit set Konrad Rzeszutek Wilk
2011-02-01 17:52   ` Stefano Stabellini
2011-02-01 20:29     ` Konrad Rzeszutek Wilk
2011-02-01 20:29       ` Konrad Rzeszutek Wilk
2011-02-02 11:52       ` Stefano Stabellini
2011-02-02 16:43         ` Konrad Rzeszutek Wilk [this message]
2011-02-02 16:43           ` Konrad Rzeszutek Wilk
2011-02-02 18:32           ` [Xen-devel] " Stefano Stabellini
2011-02-02 18:32             ` Stefano Stabellini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110202164307.GB14834@dumpdata.com \
    --to=konrad.wilk@oracle.com \
    --cc=Ian.Campbell@eu.citrix.com \
    --cc=Xen-devel@lists.xensource.com \
    --cc=hpa@zytor.com \
    --cc=jeremy@goop.org \
    --cc=konrad@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stefano.stabellini@eu.citrix.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.