|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v7 2/5] xen/riscv: introduce setup_initial_pages
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.
> +/* 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 ...
> +}
> +
> +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).
> --- 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).
Also nit: Style (missing blanks inside the parentheses).
> +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 ||.
> + {
> + 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).
Jan
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |