diff mbox series

[Xen-devel,for-next,1/9] xen/arm: Use mfn_to_pdx instead of pfn_to_pdx when possible

Message ID 20190218113600.9540-2-julien.grall@arm.com
State Superseded
Headers show
Series xen/arm: Properly disable M2P on Arm. | expand

Commit Message

Julien Grall Feb. 18, 2019, 11:35 a.m. UTC
mfn_to_pdx adds more safety than pfn_to_pdx. Replace all but on place in
the Arm code to use the former.

No functional changes.

Signed-off-by: Julien Grall <julien.grall@arm.com>
---
 xen/arch/arm/mm.c        | 2 +-
 xen/include/asm-arm/mm.h | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

Comments

Stefano Stabellini April 15, 2019, 9:55 p.m. UTC | #1
On Mon, 18 Feb 2019, Julien Grall wrote:
> mfn_to_pdx adds more safety than pfn_to_pdx. Replace all but on place in
> the Arm code to use the former.

This is good but maybe we can go even further.

You should also be able to replace one call site of pfn_to_pdx in
mfn_valid and the one in maddr_to_virt. Something like this:


diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index eafa26f..b3455ea 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -209,7 +209,7 @@ static inline void __iomem *ioremap_wc(paddr_t start, size_t len)
 /* XXX -- account for base */
 #define mfn_valid(mfn)        ({                                              \
     unsigned long __m_f_n = mfn_x(mfn);                                       \
-    likely(pfn_to_pdx(__m_f_n) >= frametable_base_pdx && __mfn_valid(__m_f_n)); \
+    likely(mfn_to_pdx(mfn) >= frametable_base_pdx && __mfn_valid(__m_f_n)); \
 })
 
 /* Convert between machine frame numbers and page-info structures. */
@@ -253,7 +253,7 @@ static inline void *maddr_to_virt(paddr_t ma)
 #else
 static inline void *maddr_to_virt(paddr_t ma)
 {
-    ASSERT(pfn_to_pdx(ma >> PAGE_SHIFT) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
+    ASSERT(mfn_to_pdx(maddr_to_mfn(ma)) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
     return (void *)(XENHEAP_VIRT_START -
                     mfn_to_maddr(xenheap_mfn_start) +
                     ((ma & ma_va_bottom_mask) |



> No functional changes.
> 
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> ---
>  xen/arch/arm/mm.c        | 2 +-
>  xen/include/asm-arm/mm.h | 6 +++---
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
> index 01ae2cccc0..be5338bb4c 100644
> --- a/xen/arch/arm/mm.c
> +++ b/xen/arch/arm/mm.c
> @@ -886,7 +886,7 @@ void __init setup_frametable_mappings(paddr_t ps, paddr_t pe)
>      int i;
>  #endif
>  
> -    frametable_base_pdx = pfn_to_pdx(ps >> PAGE_SHIFT);
> +    frametable_base_pdx = mfn_to_pdx(maddr_to_mfn(ps));
>      /* Round up to 2M or 32M boundary, as appropriate. */
>      frametable_size = ROUNDUP(frametable_size, mapping_size);
>      base_mfn = alloc_boot_pages(frametable_size >> PAGE_SHIFT, 32<<(20-12));
> diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
> index eafa26f56e..7b6aaf5e3f 100644
> --- a/xen/include/asm-arm/mm.h
> +++ b/xen/include/asm-arm/mm.h
> @@ -225,7 +225,7 @@ static inline void __iomem *ioremap_wc(paddr_t start, size_t len)
>  /* Convert between frame number and address formats.  */
>  #define pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT)
>  #define paddr_to_pfn(pa)  ((unsigned long)((pa) >> PAGE_SHIFT))
> -#define paddr_to_pdx(pa)    pfn_to_pdx(paddr_to_pfn(pa))
> +#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
>  #define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
>  #define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
>  #define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
> @@ -253,7 +253,7 @@ static inline void *maddr_to_virt(paddr_t ma)
>  #else
>  static inline void *maddr_to_virt(paddr_t ma)
>  {
> -    ASSERT(pfn_to_pdx(ma >> PAGE_SHIFT) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
> +    ASSERT(mfn_to_pdx(maddr_to_mfn(ma)) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
>      return (void *)(XENHEAP_VIRT_START -
>                      mfn_to_maddr(xenheap_mfn_start) +
>                      ((ma & ma_va_bottom_mask) |
> @@ -301,7 +301,7 @@ static inline struct page_info *virt_to_page(const void *v)
>      ASSERT(va < xenheap_virt_end);
>  
>      pdx = (va - XENHEAP_VIRT_START) >> PAGE_SHIFT;
> -    pdx += pfn_to_pdx(mfn_x(xenheap_mfn_start));
> +    pdx += mfn_to_pdx(xenheap_mfn_start);
>      return frame_table + pdx - frametable_base_pdx;
>  }
>  
> -- 
> 2.11.0
>
Julien Grall April 15, 2019, 10:03 p.m. UTC | #2
Hi,

On 4/15/19 10:55 PM, Stefano Stabellini wrote:
> On Mon, 18 Feb 2019, Julien Grall wrote:
>> mfn_to_pdx adds more safety than pfn_to_pdx. Replace all but on place in
>> the Arm code to use the former.
> 
> This is good but maybe we can go even further.
> 
> You should also be able to replace one call site of pfn_to_pdx in
> mfn_valid and the one in maddr_to_virt. Something like this:
> 
> 
> diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
> index eafa26f..b3455ea 100644
> --- a/xen/include/asm-arm/mm.h
> +++ b/xen/include/asm-arm/mm.h
> @@ -209,7 +209,7 @@ static inline void __iomem *ioremap_wc(paddr_t start, size_t len)
>   /* XXX -- account for base */
>   #define mfn_valid(mfn)        ({                                              \
>       unsigned long __m_f_n = mfn_x(mfn);                                       \
> -    likely(pfn_to_pdx(__m_f_n) >= frametable_base_pdx && __mfn_valid(__m_f_n)); \
> +    likely(mfn_to_pdx(mfn) >= frametable_base_pdx && __mfn_valid(__m_f_n)); \

This is quite undesirable, you will end up to evaluate mfn twice here.

The other solution is to turn _m_f_n to an mfn_t but then it does make 
much difference as you would need to use a mfn_x(mfn) in the code.

>   })
>   
>   /* Convert between machine frame numbers and page-info structures. */
> @@ -253,7 +253,7 @@ static inline void *maddr_to_virt(paddr_t ma)
>   #else
>   static inline void *maddr_to_virt(paddr_t ma)
>   {
> -    ASSERT(pfn_to_pdx(ma >> PAGE_SHIFT) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
> +    ASSERT(mfn_to_pdx(maddr_to_mfn(ma)) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
>       return (void *)(XENHEAP_VIRT_START -
>                       mfn_to_maddr(xenheap_mfn_start) +
>                       ((ma & ma_va_bottom_mask) |
> 

I fail to see what this chunk adds compare to the existing one...

>> @@ -253,7 +253,7 @@ static inline void *maddr_to_virt(paddr_t ma)
>>   #else
>>   static inline void *maddr_to_virt(paddr_t ma)
>>   {
>> -    ASSERT(pfn_to_pdx(ma >> PAGE_SHIFT) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
>> +    ASSERT(mfn_to_pdx(maddr_to_mfn(ma)) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
>>       return (void *)(XENHEAP_VIRT_START -
>>                       mfn_to_maddr(xenheap_mfn_start) +
>>                       ((ma & ma_va_bottom_mask) |
... here.

Cheers,
Stefano Stabellini April 15, 2019, 10:25 p.m. UTC | #3
On Mon, 15 Apr 2019, Julien Grall wrote:
> Hi,
> 
> On 4/15/19 10:55 PM, Stefano Stabellini wrote:
> > On Mon, 18 Feb 2019, Julien Grall wrote:
> > > mfn_to_pdx adds more safety than pfn_to_pdx. Replace all but on place in
> > > the Arm code to use the former.
> > 
> > This is good but maybe we can go even further.
> > 
> > You should also be able to replace one call site of pfn_to_pdx in
> > mfn_valid and the one in maddr_to_virt. Something like this:
> > 
> > 
> > diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
> > index eafa26f..b3455ea 100644
> > --- a/xen/include/asm-arm/mm.h
> > +++ b/xen/include/asm-arm/mm.h
> > @@ -209,7 +209,7 @@ static inline void __iomem *ioremap_wc(paddr_t start,
> > size_t len)
> >   /* XXX -- account for base */
> >   #define mfn_valid(mfn)        ({
> > \
> >       unsigned long __m_f_n = mfn_x(mfn);
> > \
> > -    likely(pfn_to_pdx(__m_f_n) >= frametable_base_pdx &&
> > __mfn_valid(__m_f_n)); \
> > +    likely(mfn_to_pdx(mfn) >= frametable_base_pdx && __mfn_valid(__m_f_n));
> > \
> 
> This is quite undesirable, you will end up to evaluate mfn twice here.

Yes you are right


> The other solution is to turn _m_f_n to an mfn_t but then it does make much
> difference as you would need to use a mfn_x(mfn) in the code.

I think that would be better


> >   })
> >     /* Convert between machine frame numbers and page-info structures. */
> > @@ -253,7 +253,7 @@ static inline void *maddr_to_virt(paddr_t ma)
> >   #else
> >   static inline void *maddr_to_virt(paddr_t ma)
> >   {
> > -    ASSERT(pfn_to_pdx(ma >> PAGE_SHIFT) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
> > +    ASSERT(mfn_to_pdx(maddr_to_mfn(ma)) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
> >       return (void *)(XENHEAP_VIRT_START -
> >                       mfn_to_maddr(xenheap_mfn_start) +
> >                       ((ma & ma_va_bottom_mask) |
> > 
> 
> I fail to see what this chunk adds compare to the existing one...
> 
> > > @@ -253,7 +253,7 @@ static inline void *maddr_to_virt(paddr_t ma)
> > >   #else
> > >   static inline void *maddr_to_virt(paddr_t ma)
> > >   {
> > > -    ASSERT(pfn_to_pdx(ma >> PAGE_SHIFT) < (DIRECTMAP_SIZE >>
> > > PAGE_SHIFT));
> > > +    ASSERT(mfn_to_pdx(maddr_to_mfn(ma)) < (DIRECTMAP_SIZE >>
> > > PAGE_SHIFT));
> > >       return (void *)(XENHEAP_VIRT_START -
> > >                       mfn_to_maddr(xenheap_mfn_start) +
> > >                       ((ma & ma_va_bottom_mask) |
> ... here.

That's weird. I think `patch' didn't apply completely the patch to my
tree. Great you already have it.
Julien Grall April 15, 2019, 10:42 p.m. UTC | #4
Hi,

On 4/15/19 11:25 PM, Stefano Stabellini wrote:
> On Mon, 15 Apr 2019, Julien Grall wrote:
>> Hi,
>>
>> On 4/15/19 10:55 PM, Stefano Stabellini wrote:
>>> On Mon, 18 Feb 2019, Julien Grall wrote:
>>>> mfn_to_pdx adds more safety than pfn_to_pdx. Replace all but on place in
>>>> the Arm code to use the former.
>>>
>>> This is good but maybe we can go even further.
>>>
>>> You should also be able to replace one call site of pfn_to_pdx in
>>> mfn_valid and the one in maddr_to_virt. Something like this:
>>>
>>>
>>> diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
>>> index eafa26f..b3455ea 100644
>>> --- a/xen/include/asm-arm/mm.h
>>> +++ b/xen/include/asm-arm/mm.h
>>> @@ -209,7 +209,7 @@ static inline void __iomem *ioremap_wc(paddr_t start,
>>> size_t len)
>>>    /* XXX -- account for base */
>>>    #define mfn_valid(mfn)        ({
>>> \
>>>        unsigned long __m_f_n = mfn_x(mfn);
>>> \
>>> -    likely(pfn_to_pdx(__m_f_n) >= frametable_base_pdx &&
>>> __mfn_valid(__m_f_n)); \
>>> +    likely(mfn_to_pdx(mfn) >= frametable_base_pdx && __mfn_valid(__m_f_n));
>>> \
>>
>> This is quite undesirable, you will end up to evaluate mfn twice here.
> 
> Yes you are right
> 
> 
>> The other solution is to turn _m_f_n to an mfn_t but then it does make much
>> difference as you would need to use a mfn_x(mfn) in the code.
> 
> I think that would be better

I should have probably said that I haven't done that in the patch 
because adding the mfn_x(...) is breached the 80-characters limit. So we 
would need to split the line.

I don't really think this will make easier to read the code in this context.

I am curious to know how this would make it better.

Cheers,
Julien Grall April 17, 2019, 5:07 p.m. UTC | #5
(+ Andrew and Jan)

On 15/04/2019 23:42, Julien Grall wrote:
> Hi,
> 
> On 4/15/19 11:25 PM, Stefano Stabellini wrote:
>> On Mon, 15 Apr 2019, Julien Grall wrote:
>>> Hi,
>>>
>>> On 4/15/19 10:55 PM, Stefano Stabellini wrote:
>>>> On Mon, 18 Feb 2019, Julien Grall wrote:
>>>>> mfn_to_pdx adds more safety than pfn_to_pdx. Replace all but on place in
>>>>> the Arm code to use the former.
>>>>
>>>> This is good but maybe we can go even further.
>>>>
>>>> You should also be able to replace one call site of pfn_to_pdx in
>>>> mfn_valid and the one in maddr_to_virt. Something like this:
>>>>
>>>>
>>>> diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
>>>> index eafa26f..b3455ea 100644
>>>> --- a/xen/include/asm-arm/mm.h
>>>> +++ b/xen/include/asm-arm/mm.h
>>>> @@ -209,7 +209,7 @@ static inline void __iomem *ioremap_wc(paddr_t start,
>>>> size_t len)
>>>>    /* XXX -- account for base */
>>>>    #define mfn_valid(mfn)        ({
>>>> \
>>>>        unsigned long __m_f_n = mfn_x(mfn);
>>>> \
>>>> -    likely(pfn_to_pdx(__m_f_n) >= frametable_base_pdx &&
>>>> __mfn_valid(__m_f_n)); \
>>>> +    likely(mfn_to_pdx(mfn) >= frametable_base_pdx && __mfn_valid(__m_f_n));
>>>> \
>>>
>>> This is quite undesirable, you will end up to evaluate mfn twice here.

I have been looking at making __mfn_valid(...) typesafe. While it compiles
on Arm, I have a build error on x86:

In file included from /home/julieng/works/xen/xen/include/asm/x86_64/page.h:47:0,
                 from /home/julieng/works/xen/xen/include/asm/page.h:23,
                 from /home/julieng/works/xen/xen/include/asm/current.h:12,
                 from /home/julieng/works/xen/xen/include/asm/smp.h:10,
                 from /home/julieng/works/xen/xen/include/xen/smp.h:4,
                 from /home/julieng/works/xen/xen/include/xen/perfc.h:7,
                 from x86_64/asm-offsets.c:8:
/home/julieng/works/xen/xen/include/xen/pdx.h:24:18: error: unknown type name ‘mfn_t’
 bool __mfn_valid(mfn_t mfn);
                  ^~~~~
In file included from /home/julieng/works/xen/xen/include/xen/config.h:13:0,
                 from <command-line>:0:
/home/julieng/works/xen/xen/include/asm/mm.h: In function ‘get_page_from_mfn’:
/home/julieng/works/xen/xen/include/asm/page.h:262:29: error: implicit declaration of function ‘__mfn_valid’ [-Werror=implicit-function-declaration]
 #define mfn_valid(mfn)      __mfn_valid(mfn)
                             ^
/home/julieng/works/xen/xen/include/xen/compiler.h:11:43: note: in definition of macro ‘unlikely’
 #define unlikely(x)   __builtin_expect(!!(x),0)

We get away on Arm because mfn_valid is implemented in mm.h. On x86 it is implemented
in page.h. I am quite impressed we never had build failure in common code until now...

Anyway, it is not the first time I see build error when trying to make the code using
typesafe gfn/mfn. The headers dependency are quite messy in general.

Andrew, Jan do you have a suggestion how to process on the x86 side?

Cheers,
Jan Beulich April 25, 2019, 11:20 a.m. UTC | #6
>>> On 17.04.19 at 19:07, <julien.grall@arm.com> wrote:
> Anyway, it is not the first time I see build error when trying to make the code using
> typesafe gfn/mfn. The headers dependency are quite messy in general.

Because of this, ...

> Andrew, Jan do you have a suggestion how to process on the x86 side?

... I don't, I'm sorry, without being able to invest some time to
play with this myself.

Jan
Julien Grall April 29, 2019, 4:30 p.m. UTC | #7
Hi Jan,

On 25/04/2019 12:20, Jan Beulich wrote:
>>>> On 17.04.19 at 19:07, <julien.grall@arm.com> wrote:
>> Anyway, it is not the first time I see build error when trying to make the code using
>> typesafe gfn/mfn. The headers dependency are quite messy in general.
> 
> Because of this, ...
> 
>> Andrew, Jan do you have a suggestion how to process on the x86 side?
> 
> ... I don't, I'm sorry, without being able to invest some time to
> play with this myself.

I thought I would CCed you just in case you have an idea to quickly fix it. 
Anyway, this is more a cleanup and not a priority for me.

Cheers,
diff mbox series

Patch

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 01ae2cccc0..be5338bb4c 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -886,7 +886,7 @@  void __init setup_frametable_mappings(paddr_t ps, paddr_t pe)
     int i;
 #endif
 
-    frametable_base_pdx = pfn_to_pdx(ps >> PAGE_SHIFT);
+    frametable_base_pdx = mfn_to_pdx(maddr_to_mfn(ps));
     /* Round up to 2M or 32M boundary, as appropriate. */
     frametable_size = ROUNDUP(frametable_size, mapping_size);
     base_mfn = alloc_boot_pages(frametable_size >> PAGE_SHIFT, 32<<(20-12));
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index eafa26f56e..7b6aaf5e3f 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -225,7 +225,7 @@  static inline void __iomem *ioremap_wc(paddr_t start, size_t len)
 /* Convert between frame number and address formats.  */
 #define pfn_to_paddr(pfn) ((paddr_t)(pfn) << PAGE_SHIFT)
 #define paddr_to_pfn(pa)  ((unsigned long)((pa) >> PAGE_SHIFT))
-#define paddr_to_pdx(pa)    pfn_to_pdx(paddr_to_pfn(pa))
+#define paddr_to_pdx(pa)    mfn_to_pdx(maddr_to_mfn(pa))
 #define gfn_to_gaddr(gfn)   pfn_to_paddr(gfn_x(gfn))
 #define gaddr_to_gfn(ga)    _gfn(paddr_to_pfn(ga))
 #define mfn_to_maddr(mfn)   pfn_to_paddr(mfn_x(mfn))
@@ -253,7 +253,7 @@  static inline void *maddr_to_virt(paddr_t ma)
 #else
 static inline void *maddr_to_virt(paddr_t ma)
 {
-    ASSERT(pfn_to_pdx(ma >> PAGE_SHIFT) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
+    ASSERT(mfn_to_pdx(maddr_to_mfn(ma)) < (DIRECTMAP_SIZE >> PAGE_SHIFT));
     return (void *)(XENHEAP_VIRT_START -
                     mfn_to_maddr(xenheap_mfn_start) +
                     ((ma & ma_va_bottom_mask) |
@@ -301,7 +301,7 @@  static inline struct page_info *virt_to_page(const void *v)
     ASSERT(va < xenheap_virt_end);
 
     pdx = (va - XENHEAP_VIRT_START) >> PAGE_SHIFT;
-    pdx += pfn_to_pdx(mfn_x(xenheap_mfn_start));
+    pdx += mfn_to_pdx(xenheap_mfn_start);
     return frame_table + pdx - frametable_base_pdx;
 }