diff mbox series

[v2,1/3] xen/riscv: implement virt_to_maddr()

Message ID 25a0fa030db90c929379a799aa5e03bed0197665.1728057657.git.oleksii.kurochko@gmail.com (mailing list archive)
State Superseded
Headers show
Series Register Xen's load address as a boot module | expand

Commit Message

Oleksii Kurochko Oct. 4, 2024, 4:04 p.m. UTC
Implement the virt_to_maddr() function to convert virtual addresses
to machine addresses, including checks for address ranges such as
the direct mapping area (DIRECTMAP_VIRT_START) and the Xen virtual
address space. To implement this, the phys_offset variable is made
accessible outside of riscv/mm.c.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
---
Changes in V2:
  - Drop casts in virt_to_maddr() for ASSERT which checks that VA is
    in the range of where Xen is located.
  - Add UL suffix for or XEN_VIRT_START by using _AC(..., UL) and add inclusion
    of <xen/const.h>
  - Add the comment above return which explains why there is no need
    to do " - XEN_VIRT_START.
---
 xen/arch/riscv/include/asm/config.h |  4 ++++
 xen/arch/riscv/include/asm/mm.h     | 17 ++++++++++++++++-
 xen/arch/riscv/mm.c                 |  2 +-
 3 files changed, 21 insertions(+), 2 deletions(-)

Comments

Oleksii Kurochko Oct. 8, 2024, 10:26 a.m. UTC | #1
On Fri, 2024-10-04 at 18:04 +0200, Oleksii Kurochko wrote:
> Implement the virt_to_maddr() function to convert virtual addresses
> to machine addresses, including checks for address ranges such as
> the direct mapping area (DIRECTMAP_VIRT_START) and the Xen virtual
> address space. To implement this, the phys_offset variable is made
> accessible outside of riscv/mm.c.
> 
> Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
> ---
> Changes in V2:
>   - Drop casts in virt_to_maddr() for ASSERT which checks that VA is
>     in the range of where Xen is located.
>   - Add UL suffix for or XEN_VIRT_START by using _AC(..., UL) and add
> inclusion
>     of <xen/const.h>
>   - Add the comment above return which explains why there is no need
>     to do " - XEN_VIRT_START.
> ---
>  xen/arch/riscv/include/asm/config.h |  4 ++++
>  xen/arch/riscv/include/asm/mm.h     | 17 ++++++++++++++++-
>  xen/arch/riscv/mm.c                 |  2 +-
>  3 files changed, 21 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/riscv/include/asm/config.h
> b/xen/arch/riscv/include/asm/config.h
> index 7dbb235685..8884aeab16 100644
> --- a/xen/arch/riscv/include/asm/config.h
> +++ b/xen/arch/riscv/include/asm/config.h
> @@ -155,6 +155,10 @@
>  
>  #define IDENT_AREA_SIZE 64
>  
> +#ifndef __ASSEMBLY__
> +extern unsigned long phys_offset;
> +#endif
> +
>  #endif /* __RISCV_CONFIG_H__ */
>  /*
>   * Local variables:
> diff --git a/xen/arch/riscv/include/asm/mm.h
> b/xen/arch/riscv/include/asm/mm.h
> index 4b7b00b850..0f7879d685 100644
> --- a/xen/arch/riscv/include/asm/mm.h
> +++ b/xen/arch/riscv/include/asm/mm.h
> @@ -5,6 +5,7 @@
>  
>  #include <public/xen.h>
>  #include <xen/bug.h>
> +#include <xen/const.h>
>  #include <xen/mm-frame.h>
>  #include <xen/pdx.h>
>  #include <xen/types.h>
> @@ -28,7 +29,21 @@ static inline void *maddr_to_virt(paddr_t ma)
>      return NULL;
>  }
>  
> -#define virt_to_maddr(va) ({ BUG_ON("unimplemented"); 0; })
> +static inline unsigned long virt_to_maddr(unsigned long va)
> +{
> +    ASSERT(va >= (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE));
It should be ASSERT(va < (...)).

Then I can't use virt_to_maddr() instead of LINK_TO_LOAD() as 
address from Xen's VA space ( XEN_VIRT_START ) are higher then
(DIRECTMAP_VIRT_START + DIRECTMAP_SIZE).

Or as an option we could consider to drop this ASSERT() as if
VA is from directmap range the if below will catch that; otherwise
we have another one ASSERT() which checks that VA is from Xen VA range
where it is sage to use (phys_offset + va).

Could we consider just dropping "ASSERT(va < (DIRECTMAP_VIRT_START +
DIRECTMAP_SIZE))" or I am missing something?

~ Oleksii


> +    if ((va >= DIRECTMAP_VIRT_START) &&
> +        (va < (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE)))
> +        return directmapoff_to_maddr(va - DIRECTMAP_VIRT_START);
> +
> +    BUILD_BUG_ON(XEN_VIRT_SIZE != MB(2));
> +    ASSERT((va >> (PAGETABLE_ORDER + PAGE_SHIFT)) ==
> +           (_AC(XEN_VIRT_START, UL) >> (PAGETABLE_ORDER +
> PAGE_SHIFT)));
> +
> +    /* phys_offset = load_start - XEN_VIRT_START */
> +    return phys_offset + va;
> +}
> +#define virt_to_maddr(va) virt_to_maddr((unsigned long)(va))
>  
>  /* Convert between Xen-heap virtual addresses and machine frame
> numbers. */
>  #define __virt_to_mfn(va)  mfn_x(maddr_to_mfn(virt_to_maddr(va)))
> diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c
> index 4a628aef83..7a1919e07e 100644
> --- a/xen/arch/riscv/mm.c
> +++ b/xen/arch/riscv/mm.c
> @@ -26,7 +26,7 @@ struct mmu_desc {
>      pte_t *pgtbl_base;
>  };
>  
> -static unsigned long __ro_after_init phys_offset;
> +unsigned long __ro_after_init phys_offset;
>  
>  #define LOAD_TO_LINK(addr) ((unsigned long)(addr) - phys_offset)
>  #define LINK_TO_LOAD(addr) ((unsigned long)(addr) + phys_offset)
Jan Beulich Oct. 8, 2024, 10:34 a.m. UTC | #2
On 08.10.2024 12:26, oleksii.kurochko@gmail.com wrote:
> On Fri, 2024-10-04 at 18:04 +0200, Oleksii Kurochko wrote:
>> @@ -28,7 +29,21 @@ static inline void *maddr_to_virt(paddr_t ma)
>>      return NULL;
>>  }
>>  
>> -#define virt_to_maddr(va) ({ BUG_ON("unimplemented"); 0; })
>> +static inline unsigned long virt_to_maddr(unsigned long va)
>> +{
>> +    ASSERT(va >= (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE));
> It should be ASSERT(va < (...)).
> 
> Then I can't use virt_to_maddr() instead of LINK_TO_LOAD() as 
> address from Xen's VA space ( XEN_VIRT_START ) are higher then
> (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE).
> 
> Or as an option we could consider to drop this ASSERT() as if
> VA is from directmap range the if below will catch that; otherwise
> we have another one ASSERT() which checks that VA is from Xen VA range
> where it is sage to use (phys_offset + va).
> 
> Could we consider just dropping "ASSERT(va < (DIRECTMAP_VIRT_START +
> DIRECTMAP_SIZE))" or I am missing something?

Counter question: Why did you put the ASSERT() there when - once
corrected - it's actually pointless? What you want to make sure is
that virt_to_maddr() can't be invoked with bad argument (without
noticing). If that's achieved with just the other assertion (as it
looks to be), then leaving out this assertion ought to be fine.

Jan
Oleksii Kurochko Oct. 9, 2024, 9:44 a.m. UTC | #3
On Tue, 2024-10-08 at 12:34 +0200, Jan Beulich wrote:
> On 08.10.2024 12:26, oleksii.kurochko@gmail.com wrote:
> > On Fri, 2024-10-04 at 18:04 +0200, Oleksii Kurochko wrote:
> > > @@ -28,7 +29,21 @@ static inline void *maddr_to_virt(paddr_t ma)
> > >      return NULL;
> > >  }
> > >  
> > > -#define virt_to_maddr(va) ({ BUG_ON("unimplemented"); 0; })
> > > +static inline unsigned long virt_to_maddr(unsigned long va)
> > > +{
> > > +    ASSERT(va >= (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE));
> > It should be ASSERT(va < (...)).
> > 
> > Then I can't use virt_to_maddr() instead of LINK_TO_LOAD() as 
> > address from Xen's VA space ( XEN_VIRT_START ) are higher then
> > (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE).
> > 
> > Or as an option we could consider to drop this ASSERT() as if
> > VA is from directmap range the if below will catch that; otherwise
> > we have another one ASSERT() which checks that VA is from Xen VA
> > range
> > where it is sage to use (phys_offset + va).
> > 
> > Could we consider just dropping "ASSERT(va < (DIRECTMAP_VIRT_START
> > +
> > DIRECTMAP_SIZE))" or I am missing something?
> 
> Counter question: Why did you put the ASSERT() there when - once
> corrected - it's actually pointless? What you want to make sure is
> that virt_to_maddr() can't be invoked with bad argument (without
> noticing). If that's achieved with just the other assertion (as it
> looks to be), then leaving out this assertion ought to be fine.
Originally, I didn’t include the part after 'if (...)'. The purpose of
ASSERT(va < (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE)) was to ensure that
the virtual address fell within the expected (directmap) range. Later,
I added the part after 'if (...)', which extended the acceptable
virtual address range to also cover addresses from Xen’s linkage
address space. At that point, I should have removed the original
ASSERT() but overlooked it.

I will drop the first ASSERT() and update the commit message / comment
above virt_to_maddr() why it is enough to have only 1 ASSERT() after if
(...).

~ Oleksii
diff mbox series

Patch

diff --git a/xen/arch/riscv/include/asm/config.h b/xen/arch/riscv/include/asm/config.h
index 7dbb235685..8884aeab16 100644
--- a/xen/arch/riscv/include/asm/config.h
+++ b/xen/arch/riscv/include/asm/config.h
@@ -155,6 +155,10 @@ 
 
 #define IDENT_AREA_SIZE 64
 
+#ifndef __ASSEMBLY__
+extern unsigned long phys_offset;
+#endif
+
 #endif /* __RISCV_CONFIG_H__ */
 /*
  * Local variables:
diff --git a/xen/arch/riscv/include/asm/mm.h b/xen/arch/riscv/include/asm/mm.h
index 4b7b00b850..0f7879d685 100644
--- a/xen/arch/riscv/include/asm/mm.h
+++ b/xen/arch/riscv/include/asm/mm.h
@@ -5,6 +5,7 @@ 
 
 #include <public/xen.h>
 #include <xen/bug.h>
+#include <xen/const.h>
 #include <xen/mm-frame.h>
 #include <xen/pdx.h>
 #include <xen/types.h>
@@ -28,7 +29,21 @@  static inline void *maddr_to_virt(paddr_t ma)
     return NULL;
 }
 
-#define virt_to_maddr(va) ({ BUG_ON("unimplemented"); 0; })
+static inline unsigned long virt_to_maddr(unsigned long va)
+{
+    ASSERT(va >= (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE));
+    if ((va >= DIRECTMAP_VIRT_START) &&
+        (va < (DIRECTMAP_VIRT_START + DIRECTMAP_SIZE)))
+        return directmapoff_to_maddr(va - DIRECTMAP_VIRT_START);
+
+    BUILD_BUG_ON(XEN_VIRT_SIZE != MB(2));
+    ASSERT((va >> (PAGETABLE_ORDER + PAGE_SHIFT)) ==
+           (_AC(XEN_VIRT_START, UL) >> (PAGETABLE_ORDER + PAGE_SHIFT)));
+
+    /* phys_offset = load_start - XEN_VIRT_START */
+    return phys_offset + va;
+}
+#define virt_to_maddr(va) virt_to_maddr((unsigned long)(va))
 
 /* Convert between Xen-heap virtual addresses and machine frame numbers. */
 #define __virt_to_mfn(va)  mfn_x(maddr_to_mfn(virt_to_maddr(va)))
diff --git a/xen/arch/riscv/mm.c b/xen/arch/riscv/mm.c
index 4a628aef83..7a1919e07e 100644
--- a/xen/arch/riscv/mm.c
+++ b/xen/arch/riscv/mm.c
@@ -26,7 +26,7 @@  struct mmu_desc {
     pte_t *pgtbl_base;
 };
 
-static unsigned long __ro_after_init phys_offset;
+unsigned long __ro_after_init phys_offset;
 
 #define LOAD_TO_LINK(addr) ((unsigned long)(addr) - phys_offset)
 #define LINK_TO_LOAD(addr) ((unsigned long)(addr) + phys_offset)