[PULL,13/14] vfio-ccw: Factor out the ccw0-to-ccw1 transition
diff mbox series

Message ID 20190621143355.29175-14-cohuck@redhat.com
State New
Headers show
Series
  • [PULL,01/14] s390/cio: Squash cp_free() and cp_unpin_free()
Related show

Commit Message

Cornelia Huck June 21, 2019, 2:33 p.m. UTC
From: Eric Farman <farman@linux.ibm.com>

This is a really useful function, but it's buried in the
copy_ccw_from_iova() routine so that ccwchain_calc_length()
can just work with Format-1 CCWs while doing its counting.
But it means we're translating a full 2K of "CCWs" to Format-1,
when in reality there's probably far fewer in that space.

Let's factor it out, so maybe we can do something with it later.

Signed-off-by: Eric Farman <farman@linux.ibm.com>
Message-Id: <20190618202352.39702-5-farman@linux.ibm.com>
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
---
 drivers/s390/cio/vfio_ccw_cp.c | 48 ++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 23 deletions(-)

Comments

Eric Farman June 21, 2019, 7:13 p.m. UTC | #1
Conny,

I'm bad at things, because I thought for sure I had checked for and
fixed this before I sent the patches.  This one gets a sparse warning,
fixed below.

Eric

On 6/21/19 10:33 AM, Cornelia Huck wrote:
> From: Eric Farman <farman@linux.ibm.com>
> 
> This is a really useful function, but it's buried in the
> copy_ccw_from_iova() routine so that ccwchain_calc_length()
> can just work with Format-1 CCWs while doing its counting.
> But it means we're translating a full 2K of "CCWs" to Format-1,
> when in reality there's probably far fewer in that space.
> 
> Let's factor it out, so maybe we can do something with it later.
> 
> Signed-off-by: Eric Farman <farman@linux.ibm.com>
> Message-Id: <20190618202352.39702-5-farman@linux.ibm.com>
> Reviewed-by: Cornelia Huck <cohuck@redhat.com>
> Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> ---
>  drivers/s390/cio/vfio_ccw_cp.c | 48 ++++++++++++++++++----------------
>  1 file changed, 25 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c
> index a55f8d110920..9a8bf06281e0 100644
> --- a/drivers/s390/cio/vfio_ccw_cp.c
> +++ b/drivers/s390/cio/vfio_ccw_cp.c
> @@ -161,6 +161,27 @@ static inline void pfn_array_idal_create_words(
>  	idaws[0] += pa->pa_iova & (PAGE_SIZE - 1);
>  }
>  
> +void convert_ccw0_to_ccw1(struct ccw1 *source, unsigned long len)

static void convert_...

> +{
> +	struct ccw0 ccw0;
> +	struct ccw1 *pccw1 = source;
> +	int i;
> +
> +	for (i = 0; i < len; i++) {
> +		ccw0 = *(struct ccw0 *)pccw1;
> +		if ((pccw1->cmd_code & 0x0f) == CCW_CMD_TIC) {
> +			pccw1->cmd_code = CCW_CMD_TIC;
> +			pccw1->flags = 0;
> +			pccw1->count = 0;
> +		} else {
> +			pccw1->cmd_code = ccw0.cmd_code;
> +			pccw1->flags = ccw0.flags;
> +			pccw1->count = ccw0.count;
> +		}
> +		pccw1->cda = ccw0.cda;
> +		pccw1++;
> +	}
> +}
>  
>  /*
>   * Within the domain (@mdev), copy @n bytes from a guest physical
> @@ -211,32 +232,9 @@ static long copy_ccw_from_iova(struct channel_program *cp,
>  			       struct ccw1 *to, u64 iova,
>  			       unsigned long len)
>  {
> -	struct ccw0 ccw0;
> -	struct ccw1 *pccw1;
>  	int ret;
> -	int i;
>  
>  	ret = copy_from_iova(cp->mdev, to, iova, len * sizeof(struct ccw1));
> -	if (ret)
> -		return ret;
> -
> -	if (!cp->orb.cmd.fmt) {
> -		pccw1 = to;
> -		for (i = 0; i < len; i++) {
> -			ccw0 = *(struct ccw0 *)pccw1;
> -			if ((pccw1->cmd_code & 0x0f) == CCW_CMD_TIC) {
> -				pccw1->cmd_code = CCW_CMD_TIC;
> -				pccw1->flags = 0;
> -				pccw1->count = 0;
> -			} else {
> -				pccw1->cmd_code = ccw0.cmd_code;
> -				pccw1->flags = ccw0.flags;
> -				pccw1->count = ccw0.count;
> -			}
> -			pccw1->cda = ccw0.cda;
> -			pccw1++;
> -		}
> -	}
>  
>  	return ret;
>  }
> @@ -441,6 +439,10 @@ static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
>  	if (len)
>  		return len;
>  
> +	/* Convert any Format-0 CCWs to Format-1 */
> +	if (!cp->orb.cmd.fmt)
> +		convert_ccw0_to_ccw1(cp->guest_cp, len);
> +
>  	/* Count the CCWs in the current chain */
>  	len = ccwchain_calc_length(cda, cp);
>  	if (len < 0)
>
Heiko Carstens June 22, 2019, 8:38 a.m. UTC | #2
On Fri, Jun 21, 2019 at 03:13:20PM -0400, Eric Farman wrote:
> Conny,
> 
> I'm bad at things, because I thought for sure I had checked for and
> fixed this before I sent the patches.  This one gets a sparse warning,
> fixed below.
> 
> Eric
> 
> On 6/21/19 10:33 AM, Cornelia Huck wrote:
> > From: Eric Farman <farman@linux.ibm.com>
> > 
> > This is a really useful function, but it's buried in the
> > copy_ccw_from_iova() routine so that ccwchain_calc_length()
> > can just work with Format-1 CCWs while doing its counting.
> > But it means we're translating a full 2K of "CCWs" to Format-1,
> > when in reality there's probably far fewer in that space.
> > 
> > Let's factor it out, so maybe we can do something with it later.
> > 
> > Signed-off-by: Eric Farman <farman@linux.ibm.com>
> > Message-Id: <20190618202352.39702-5-farman@linux.ibm.com>
> > Reviewed-by: Cornelia Huck <cohuck@redhat.com>
> > Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
> > Signed-off-by: Cornelia Huck <cohuck@redhat.com>
> > ---
> >  drivers/s390/cio/vfio_ccw_cp.c | 48 ++++++++++++++++++----------------
> >  1 file changed, 25 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c
> > index a55f8d110920..9a8bf06281e0 100644
> > --- a/drivers/s390/cio/vfio_ccw_cp.c
> > +++ b/drivers/s390/cio/vfio_ccw_cp.c
> > @@ -161,6 +161,27 @@ static inline void pfn_array_idal_create_words(
> >  	idaws[0] += pa->pa_iova & (PAGE_SIZE - 1);
> >  }
> >  
> > +void convert_ccw0_to_ccw1(struct ccw1 *source, unsigned long len)
> 
> static void convert_...

Please send an add-on patch. Code is already in our internal tree for
testing purposes and will be push out next week.

Patch
diff mbox series

diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c
index a55f8d110920..9a8bf06281e0 100644
--- a/drivers/s390/cio/vfio_ccw_cp.c
+++ b/drivers/s390/cio/vfio_ccw_cp.c
@@ -161,6 +161,27 @@  static inline void pfn_array_idal_create_words(
 	idaws[0] += pa->pa_iova & (PAGE_SIZE - 1);
 }
 
+void convert_ccw0_to_ccw1(struct ccw1 *source, unsigned long len)
+{
+	struct ccw0 ccw0;
+	struct ccw1 *pccw1 = source;
+	int i;
+
+	for (i = 0; i < len; i++) {
+		ccw0 = *(struct ccw0 *)pccw1;
+		if ((pccw1->cmd_code & 0x0f) == CCW_CMD_TIC) {
+			pccw1->cmd_code = CCW_CMD_TIC;
+			pccw1->flags = 0;
+			pccw1->count = 0;
+		} else {
+			pccw1->cmd_code = ccw0.cmd_code;
+			pccw1->flags = ccw0.flags;
+			pccw1->count = ccw0.count;
+		}
+		pccw1->cda = ccw0.cda;
+		pccw1++;
+	}
+}
 
 /*
  * Within the domain (@mdev), copy @n bytes from a guest physical
@@ -211,32 +232,9 @@  static long copy_ccw_from_iova(struct channel_program *cp,
 			       struct ccw1 *to, u64 iova,
 			       unsigned long len)
 {
-	struct ccw0 ccw0;
-	struct ccw1 *pccw1;
 	int ret;
-	int i;
 
 	ret = copy_from_iova(cp->mdev, to, iova, len * sizeof(struct ccw1));
-	if (ret)
-		return ret;
-
-	if (!cp->orb.cmd.fmt) {
-		pccw1 = to;
-		for (i = 0; i < len; i++) {
-			ccw0 = *(struct ccw0 *)pccw1;
-			if ((pccw1->cmd_code & 0x0f) == CCW_CMD_TIC) {
-				pccw1->cmd_code = CCW_CMD_TIC;
-				pccw1->flags = 0;
-				pccw1->count = 0;
-			} else {
-				pccw1->cmd_code = ccw0.cmd_code;
-				pccw1->flags = ccw0.flags;
-				pccw1->count = ccw0.count;
-			}
-			pccw1->cda = ccw0.cda;
-			pccw1++;
-		}
-	}
 
 	return ret;
 }
@@ -441,6 +439,10 @@  static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
 	if (len)
 		return len;
 
+	/* Convert any Format-0 CCWs to Format-1 */
+	if (!cp->orb.cmd.fmt)
+		convert_ccw0_to_ccw1(cp->guest_cp, len);
+
 	/* Count the CCWs in the current chain */
 	len = ccwchain_calc_length(cda, cp);
 	if (len < 0)