|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v7 2/5] xen/riscv: introduce setup_initial_pages
On Tue, 2023-05-16 at 18:02 +0200, Jan Beulich wrote:
> On 11.05.2023 19:09, Oleksii Kurochko wrote:
> > --- /dev/null
> > +++ b/xen/arch/riscv/include/asm/page.h
> > @@ -0,0 +1,58 @@
> > +#ifndef _ASM_RISCV_PAGE_H
> > +#define _ASM_RISCV_PAGE_H
> > +
> > +#include <xen/const.h>
> > +#include <xen/types.h>
> > +
> > +#define VPN_MASK ((unsigned
> > long)(PAGETABLE_ENTRIES - 1))
> > +
> > +#define XEN_PT_LEVEL_ORDER(lvl) ((lvl) * PAGETABLE_ORDER)
> > +#define XEN_PT_LEVEL_SHIFT(lvl) (XEN_PT_LEVEL_ORDER(lvl) +
> > PAGE_SHIFT)
> > +#define XEN_PT_LEVEL_SIZE(lvl) (_AT(paddr_t, 1) <<
> > XEN_PT_LEVEL_SHIFT(lvl))
> > +#define XEN_PT_LEVEL_MAP_MASK(lvl) (~(XEN_PT_LEVEL_SIZE(lvl) -
> > 1))
> > +#define XEN_PT_LEVEL_MASK(lvl) (VPN_MASK <<
> > XEN_PT_LEVEL_SHIFT(lvl))
> > +
> > +#define PTE_VALID BIT(0, UL)
> > +#define PTE_READABLE BIT(1, UL)
> > +#define PTE_WRITABLE BIT(2, UL)
> > +#define PTE_EXECUTABLE BIT(3, UL)
> > +#define PTE_USER BIT(4, UL)
> > +#define PTE_GLOBAL BIT(5, UL)
> > +#define PTE_ACCESSED BIT(6, UL)
> > +#define PTE_DIRTY BIT(7, UL)
> > +#define PTE_RSW (BIT(8, UL) | BIT(9, UL))
> > +
> > +#define PTE_LEAF_DEFAULT (PTE_VALID | PTE_READABLE |
> > PTE_WRITABLE)
> > +#define PTE_TABLE (PTE_VALID)
> > +
> > +/* Calculate the offsets into the pagetables for a given VA */
> > +#define pt_linear_offset(lvl, va) ((va) >>
> > XEN_PT_LEVEL_SHIFT(lvl))
> > +
> > +#define pt_index(lvl, va) (pt_linear_offset(lvl, (va)) & VPN_MASK)
>
> Nit: Please be consistent with parentheses. Here va doesn't need any,
> but if you added / kept them, then lvl should also gain them.
Sure. I'll fix that.
>
> > +/* Page Table entry */
> > +typedef struct {
> > +#ifdef CONFIG_RISCV_64
> > + uint64_t pte;
> > +#else
> > + uint32_t pte;
> > +#endif
> > +} pte_t;
> > +
> > +static inline pte_t paddr_to_pte(paddr_t paddr,
> > + unsigned int permissions)
> > +{
> > + return (pte_t) { .pte = (paddr >> PAGE_SHIFT) << PTE_PPN_SHIFT
> > | permissions };
>
> Please parenthesize the << against the |. I have also previously
> recommended to avoid open-coding of things like PFN_DOWN() (or
> paddr_to_pfn(), if you like that better) or ...
I'll change it to paddr_to_pfn. It sounds more clear than PFN_DOWN()
in this context.
Thanks for reminder.
>
> > +}
> > +
> > +static inline paddr_t pte_to_paddr(pte_t pte)
> > +{
> > + return ((paddr_t)pte.pte >> PTE_PPN_SHIFT) << PAGE_SHIFT;
>
> ... or pfn_to_paddr() (which here would avoid the misplaced cast).
pfn_to_paddr() would be better here so I'll update it.
>
> > --- a/xen/arch/riscv/include/asm/processor.h
> > +++ b/xen/arch/riscv/include/asm/processor.h
> > @@ -69,6 +69,11 @@ static inline void die(void)
> > wfi();
> > }
> >
> > +static inline void sfence_vma(void)
> > +{
> > + __asm__ __volatile__ ("sfence.vma" ::: "memory");
> > +}
>
> Hmm, in switch_stack_and_jump() you use "asm volatile()" (no
> underscores). This is another thing which would nice if it was
> consistent (possibly among headers as one group, and .c files as
> another - there may be reasons why one wants the underscore
> variants in headers, but the "easier" ones in .c files).
I will remove "__" to be consistent here and in future.
>
> Also nit: Style (missing blanks inside the parentheses).
THanks. Missed that.
>
> > +static void __init setup_initial_mapping(struct mmu_desc
> > *mmu_desc,
> > + unsigned long map_start,
> > + unsigned long map_end,
> > + unsigned long pa_start)
> > +{
> > + unsigned int index;
> > + pte_t *pgtbl;
> > + unsigned long page_addr;
> > +
> > + if ( (unsigned long)_start % XEN_PT_LEVEL_SIZE(0) )
> > + {
> > + early_printk("(XEN) Xen should be loaded at 4k
> > boundary\n");
> > + die();
> > + }
> > +
> > + if ( map_start & ~XEN_PT_LEVEL_MAP_MASK(0) ||
> > + pa_start & ~XEN_PT_LEVEL_MAP_MASK(0) )
>
> Nit: Please parenthesize the two & against the ||.
Sure. THanks.
>
> > + {
> > + early_printk("(XEN) map and pa start addresses should be
> > aligned\n");
> > + /* panic(), BUG() or ASSERT() aren't ready now. */
> > + die();
> > + }
> > +
> > + for ( page_addr = map_start;
> > + page_addr < map_end;
> > + page_addr += XEN_PT_LEVEL_SIZE(0) )
> > + {
> > + pgtbl = mmu_desc->pgtbl_base;
> > +
> > + switch ( mmu_desc->num_levels )
> > + {
> > + case 4: /* Level 3 */
> > + HANDLE_PGTBL(3);
> > + case 3: /* Level 2 */
> > + HANDLE_PGTBL(2);
> > + case 2: /* Level 1 */
> > + HANDLE_PGTBL(1);
> > + case 1: /* Level 0 */
> > + {
> > + unsigned long paddr = (page_addr - map_start) +
> > pa_start;
> > + unsigned int permissions = PTE_LEAF_DEFAULT;
> > + pte_t pte_to_be_written;
> > +
> > + index = pt_index(0, page_addr);
> > +
> > + if ( is_kernel_text(LINK_TO_LOAD(page_addr)) ||
> > + is_kernel_inittext(LINK_TO_LOAD(page_addr)) )
> > + permissions =
> > + PTE_EXECUTABLE | PTE_READABLE | PTE_VALID;
> > +
> > + if ( is_kernel_rodata(LINK_TO_LOAD(page_addr)) )
> > + permissions = PTE_READABLE | PTE_VALID;
> > +
> > + pte_to_be_written = paddr_to_pte(paddr,
> > permissions);
> > +
> > + if ( !pte_is_valid(pgtbl[index]) )
> > + pgtbl[index] = pte_to_be_written;
> > + else
> > + {
> > + if ( (pgtbl[index].pte ^
> > pte_to_be_written.pte) &
> > + ~(PTE_DIRTY | PTE_ACCESSED) )
>
> Nit: Style (indentation).
I'll add missed space. Thanks.
~ Oleksii
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |