[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v3 3/3] xen/ppc: Implement initial Radix MMU support



On 8/14/23 8:27 AM, Jan Beulich wrote:
> On 10.08.2023 00:48, Shawn Anastasio wrote:
>> --- /dev/null
>> +++ b/xen/arch/ppc/include/asm/page.h
>> @@ -0,0 +1,181 @@
>> +#ifndef _ASM_PPC_PAGE_H
>> +#define _ASM_PPC_PAGE_H
>> +
>> +#include <xen/types.h>
>> +
>> +#include <asm/bitops.h>
>> +#include <asm/byteorder.h>
>> +
>> +#define PDE_VALID     PPC_BIT(0)
>> +#define PDE_NLB_MASK  0xfffffffffffffUL
>> +#define PDE_NLB_SHIFT 5UL
>> +#define PDE_NLS_MASK  0x1f
>> +
>> +#define PTE_VALID     PPC_BIT(0)
>> +#define PTE_LEAF      PPC_BIT(1)
>> +#define PTE_REFERENCE PPC_BIT(55)
>> +#define PTE_CHANGE    PPC_BIT(56)
>> +
>> +/* PTE Attributes */
>> +#define PTE_ATT_SAO            PPC_BIT(59) /* Strong Access Ordering */
>> +#define PTE_ATT_NON_IDEMPOTENT PPC_BIT(58)
>> +#define PTE_ATT_TOLERANT       (PPC_BIT(58) | PPC_BIT(59))
>> +
>> +/* PTE Encoded Access Authority*/
>> +#define PTE_EAA_PRIVILEGED PPC_BIT(60)
>> +#define PTE_EAA_READ       PPC_BIT(61)
>> +#define PTE_EAA_WRITE      PPC_BIT(62)
>> +#define PTE_EAA_EXECUTE    PPC_BIT(63)
>> +
>> +/* Field shifts/masks */
>> +#define PTE_RPN_MASK  0x1fffffffffffUL
>> +#define PTE_RPN_SHIFT 12UL
> 
> I still don't understand why you need two constants here. Even more so that
> now all their uses are as (PTE_RPN_MASK << PTE_RPN_SHIFT). With (only)
> 
> #define PTE_RPN_MASK  0x1fffffffffff000UL
> 
> instead, as indicated before, you would then (should the need arise) have
> this usable with MASK_EXTR() / MASK_INSR(). The again you likely know much
> better than me what further uses are going to appear.

Yes, this patch was submitted before I saw your follow-up comment to my
MASK_EXTR/INSR comment, but I agree now that just having a single mask
constant with the shift built-in would be perfectly adequate. I'll make
that change.

> 
>> --- /dev/null
>> +++ b/xen/arch/ppc/include/asm/regs.h
>> @@ -0,0 +1,138 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
> 
> There's still an SPDX header and a full license here.
>

Will fix.

>> --- /dev/null
>> +++ b/xen/arch/ppc/mm-radix.c
>> @@ -0,0 +1,265 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +#include <xen/init.h>
>> +#include <xen/kernel.h>
>> +#include <xen/types.h>
>> +#include <xen/lib.h>
>> +
>> +#include <asm/bitops.h>
>> +#include <asm/byteorder.h>
>> +#include <asm/early_printk.h>
>> +#include <asm/mm.h>
>> +#include <asm/page.h>
>> +#include <asm/processor.h>
>> +#include <asm/regs.h>
>> +#include <asm/msr.h>
>> +
>> +void enable_mmu(void);
>> +
>> +#define INITIAL_LVL1_PD_COUNT      1
>> +#define INITIAL_LVL2_LVL3_PD_COUNT 2
>> +#define INITIAL_LVL4_PT_COUNT      256
>> +
>> +static size_t initial_lvl1_pd_pool_used;
>> +static struct lvl1_pd initial_lvl1_pd_pool[INITIAL_LVL1_PD_COUNT];
>> +
>> +static size_t initial_lvl2_lvl3_pd_pool_used;
>> +static struct lvl2_pd initial_lvl2_lvl3_pd_pool[INITIAL_LVL2_LVL3_PD_COUNT];
>> +
>> +static size_t initial_lvl4_pt_pool_used;
>> +static struct lvl4_pt initial_lvl4_pt_pool[INITIAL_LVL4_PT_COUNT];
> 
> The initial_lvl..._pool_used variables can likely all be __initdata?
>

Yes, that's reasonable. I'll do that.

>> +static void __init setup_initial_mapping(struct lvl1_pd *lvl1,
>> +                                         vaddr_t map_start,
>> +                                         vaddr_t map_end,
>> +                                         paddr_t phys_base)
>> +{
>> +    uint64_t page_addr;
>> +
>> +    if ( map_start & ~PAGE_MASK )
>> +    {
>> +        early_printk("Xen _start be aligned to 64k (PAGE_SIZE) boundary\n");
>> +        die();
>> +    }
>> +
>> +    if ( phys_base & ~PAGE_MASK )
>> +    {
>> +        early_printk("Xen should be loaded at 64k (PAGE_SIZE) boundary\n");
>> +        die();
>> +    }
>> +
>> +    for ( page_addr = map_start; page_addr < map_end; page_addr += 
>> PAGE_SIZE )
>> +    {
>> +        struct lvl2_pd *lvl2;
>> +        struct lvl3_pd *lvl3;
>> +        struct lvl4_pt *lvl4;
>> +        pde_t *pde;
>> +        pte_t *pte;
>> +
>> +        /* Allocate LVL 2 PD if necessary */
>> +        pde = pt_entry(lvl1, page_addr);
>> +        if ( !pde_is_valid(*pde) )
>> +        {
>> +            lvl2 = lvl2_pd_pool_alloc();
>> +            *pde = paddr_to_pde(__pa(lvl2), PDE_VALID,
>> +                                XEN_PT_ENTRIES_LOG2_LVL_2);
>> +        }
>> +        else
>> +            lvl2 = (struct lvl2_pd *)__va(pde_to_paddr(*pde));
> 
> I don't think the cast here (and similar ones below) is needed.
>

Good catch. Will drop the explicit casts.

>> +static void __init setup_partition_table(struct lvl1_pd *root)
>> +{
>> +    unsigned long ptcr;
>> +
>> +    /* Configure entry for LPID 0 to enable Radix and point to root PD */
>> +    uint64_t patb0 = RTS_FIELD | __pa(root) | XEN_PT_ENTRIES_LOG2_LVL_1 |
>> +                     PATB0_HR;
>> +    uint64_t patb1 = __pa(initial_prtb) | (PRTB_SIZE_LOG2 - 12) | PATB1_GR;
>> +    initial_patb[0].patb0 = cpu_to_be64(patb0);
>> +    initial_patb[0].patb1 = cpu_to_be64(patb1);
> 
> Nit: Blank line please between declaration(s) and statement(s).
>

Will fix.

>> +    ptcr = __pa(initial_patb) | (PATB_SIZE_LOG2 - 12);
>> +    mtspr(SPRN_PTCR, ptcr);
>> +}
>> +
>> +static void __init setup_process_table(struct lvl1_pd *root)
>> +{
>> +    /* Configure entry for PID 0 to point to root PD */
>> +    uint64_t prtb0 = RTS_FIELD | __pa(root) | XEN_PT_ENTRIES_LOG2_LVL_1;
>> +    initial_prtb[0].prtb0 = cpu_to_be64(prtb0);
> 
> Same here then.
>

Ditto.

> Jan

Thanks,
Shawn



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.