Re: [RFC PATCH v3 01/10] iommupt: Add RISC-V Second-stage (iohgatp) page table support

Jason Gunthorpe <[email protected]>
Newsgroups org.infradead.lists.linux-riscv,dev.linux.lists.iommu,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Fri, Aug 21, 2026 at 09:27:41PM +0800, [email protected] wrote:
> @@ -126,6 +135,15 @@ riscvpt_entry_num_contig_lg2(const struct pt_state *pts)
>  
>  static inline unsigned int riscvpt_num_items_lg2(const struct pt_state *pts)
>  {
> +	/*
> +	 * Second-stage (iohgatp) root page tables have 4x the usual number of
> +	 * entries (2048 = 2^11 instead of 512 = 2^9) to cover the 2 extra GPA
> +	 * bits in Sv39x4/Sv48x4/Sv57x4.  Only the root (top) level is
> +	 * enlarged; all other levels remain at the standard 9-bit index width.
> +	 */
> +	if (pts_feature(pts, PT_FEAT_RISCV_S2) &&
> +	    pts->level == pts->range->top_level)
> +		return PT_TABLEMEM_LG2SZ - ilog2(sizeof(u64)) + 2;

You shouldn't need this, see how ARMv8 is constructed which does the
same thing. Instead 

static inline unsigned int armv8pt_num_items_lg2(const struct pt_state *pts)
{
	/*
	 * It is not allowed to call pt_num_items_lg2() at the top level, this
	 * API restriction is specifically an optimization avoid overheads
	 * dealing with concatenated tables here.
	 */
	PT_WARN_ON(pts->level == pts->range->top_level);

> @@ -272,6 +291,19 @@ riscvpt_iommu_fmt_init(struct pt_iommu_riscv_64 *iommu_table,
>  	case 57:
>  		pt_top_set_level(&table->common, 4);
>  		break;
> +	/*
> +	 * Second-stage (iohgatp): Sv39x4 / Sv48x4 / Sv57x4.
> +	 * The top level is the same as for the first-stage counterpart.
> +	 */
> +	case 41:
> +		pt_top_set_level(&table->common, 2);
> +		break;
> +	case 50:
> +		pt_top_set_level(&table->common, 3);
> +		break;
> +	case 59:
> +		pt_top_set_level(&table->common, 4);
> +		break;

Are all these widths valid for both S1 and S2? It should reject
illegal vasz..

>  struct pt_iommu_riscv_64_hw_info {
>  	u64 ppn;
> -	u8 fsc_iosatp_mode;
> +	union {
> +		/*
> +		 * First-stage (fsc/iosatp) MODE encoding:
> +		 *   8 = Sv39, 9 = Sv48, 10 = Sv57
> +		 * Used to program DC.fsc.iosatp.MODE.
> +		 */
> +		u8 fsc_iosatp_mode;
> +		/*
> +		 * Second-stage (iohgatp) MODE encoding:
> +		 *   8 = Sv39x4, 9 = Sv48x4, 10 = Sv57x4
> +		 * Used to program DC.iohgatp.MODE.
> +		 * The numeric values are identical to fsc_iosatp_mode;
> +		 * the caller selects the interpretation based on domain type.
> +		 */
> +		u8 iohgatp_mode;
> +	};

suggest not using a union and instead have the get_info populate only
the one correct for the fmt. It makes it slightly more robust that
s1/s2 don't get intermixed improperly?

Jason

_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.