@@ -162,21 +162,25 @@ void spapr_tce_free(DMAContext *dma)
}
}
-static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
- target_ulong tce)
+static int put_tce_emu(target_ulong liobn, target_ulong ioba, target_ulong tce)
{
+ sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
sPAPRTCE *tcep;
+ if (!tcet) {
+ return 1;
+ }
+
if (ioba >= tcet->window_size) {
hcall_dprintf("spapr_vio_put_tce on out-of-boards IOBA 0x"
TARGET_FMT_lx "\n", ioba);
- return H_PARAMETER;
+ return -1;
}
tcep = tcet->table + (ioba >> SPAPR_TCE_PAGE_SHIFT);
tcep->tce = tce;
- return H_SUCCESS;
+ return 0;
}
static target_ulong h_put_tce(CPUPPCState *env, sPAPREnvironment *spapr,
@@ -185,7 +189,7 @@ static target_ulong h_put_tce(CPUPPCState *env, sPAPREnvironment *spapr,
target_ulong liobn = args[0];
target_ulong ioba = args[1];
target_ulong tce = args[2];
- sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
+ int ret;
if (liobn & 0xFFFFFFFF00000000ULL) {
hcall_dprintf("spapr_vio_put_tce on out-of-boundsw LIOBN "
@@ -195,13 +199,14 @@ static target_ulong h_put_tce(CPUPPCState *env, sPAPREnvironment *spapr,
ioba &= ~(SPAPR_TCE_PAGE_SIZE - 1);
- if (tcet) {
- return put_tce_emu(tcet, ioba, tce);
+ ret = put_tce_emu(liobn, ioba, tce);
+ if (0 >= ret) {
+ return ret ? H_PARAMETER : H_SUCCESS;
}
#ifdef DEBUG_TCE
- fprintf(stderr, "%s on liobn=" TARGET_FMT_lx /*%s*/
- " ioba 0x" TARGET_FMT_lx " TCE 0x" TARGET_FMT_lx "\n",
- __func__, liobn, /*dev->qdev.id, */ioba, tce);
+ fprintf(stderr, "%s on liobn=" TARGET_FMT_lx
+ " ioba 0x" TARGET_FMT_lx " TCE 0x" TARGET_FMT_lx " ret=%d\n",
+ __func__, liobn, ioba, tce, ret);
#endif
return H_PARAMETER;
sPAPR IOMMU RTAS handler is split to common h_put_tce() part and emulated IOMMU implementation called put_tce_emu(). Further patches will extend h_put_tce() with put_tce_vfio() in order to support other types of IOMMU such as VFIO. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> --- hw/spapr_iommu.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-)