From: Gaurav Batra gbatra@linux.vnet.ibm.com
commit 9d2ccf00bddc268045e3d65a8108d61ada0e4b4e upstream.
Currently in tce_freemulti_pSeriesLP() there is no limit on how many TCEs are passed to the H_STUFF_TCE hcall. This has not caused an issue until now, but newer firmware releases have started enforcing a limit of 512 TCEs per call.
The limit is correct per the specification (PAPR v2.12 ยง 14.5.4.2.3).
The code has been in it's current form since it was initially merged.
Cc: stable@vger.kernel.org Signed-off-by: Gaurav Batra gbatra@linux.vnet.ibm.com Reviewed-by: Brian King brking@linux.vnet.ibm.com [mpe: Tweak change log wording & add PAPR reference] Signed-off-by: Michael Ellerman mpe@ellerman.id.au Link: https://msgid.link/20230525143454.56878-1-gbatra@linux.vnet.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/powerpc/platforms/pseries/iommu.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
--- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -311,13 +311,22 @@ static void tce_free_pSeriesLP(unsigned static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) { u64 rc; + long rpages = npages; + unsigned long limit;
if (!firmware_has_feature(FW_FEATURE_STUFF_TCE)) return tce_free_pSeriesLP(tbl->it_index, tcenum, tbl->it_page_shift, npages);
- rc = plpar_tce_stuff((u64)tbl->it_index, - (u64)tcenum << tbl->it_page_shift, 0, npages); + do { + limit = min_t(unsigned long, rpages, 512); + + rc = plpar_tce_stuff((u64)tbl->it_index, + (u64)tcenum << tbl->it_page_shift, 0, limit); + + rpages -= limit; + tcenum += limit; + } while (rpages > 0 && !rc);
if (rc && printk_ratelimit()) { printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n");