#include "vfio_ccw_cp.h"
 
-/*
- * Max length for ccw chain.
- * XXX: Limit to 256, need to check more?
- */
-#define CCWCHAIN_LEN_MAX       256
-
 struct pfn_array {
        /* Starting guest physical I/O address. */
        unsigned long           pa_iova;
  */
 static int ccwchain_calc_length(u64 iova, struct channel_program *cp)
 {
-       struct ccw1 *ccw, *p;
+       struct ccw1 *ccw = cp->guest_cp;
        int cnt;
 
        /*
         * Currently the chain length is limited to CCWCHAIN_LEN_MAX (256).
         * So copying 2K is enough (safe).
         */
-       p = ccw = kcalloc(CCWCHAIN_LEN_MAX, sizeof(*ccw), GFP_KERNEL);
-       if (!ccw)
-               return -ENOMEM;
-
        cnt = copy_ccw_from_iova(cp, ccw, iova, CCWCHAIN_LEN_MAX);
-       if (cnt) {
-               kfree(ccw);
+       if (cnt)
                return cnt;
-       }
 
        cnt = 0;
        do {
                 * orb specified one of the unsupported formats, we defer
                 * checking for IDAWs in unsupported formats to here.
                 */
-               if ((!cp->orb.cmd.c64 || cp->orb.cmd.i2k) && ccw_is_idal(ccw)) {
-                       kfree(p);
+               if ((!cp->orb.cmd.c64 || cp->orb.cmd.i2k) && ccw_is_idal(ccw))
                        return -EOPNOTSUPP;
-               }
 
                /*
                 * We want to keep counting if the current CCW has the
        if (cnt == CCWCHAIN_LEN_MAX + 1)
                cnt = -EINVAL;
 
-       kfree(p);
        return cnt;
 }
 
        struct ccwchain *chain;
        int len, ret;
 
-       /* Get chain length. */
+       /* Copy the chain from cda to cp, and count the CCWs in it */
        len = ccwchain_calc_length(cda, cp);
        if (len < 0)
                return len;
 
 
 #include "orb.h"
 
+/*
+ * Max length for ccw chain.
+ * XXX: Limit to 256, need to check more?
+ */
+#define CCWCHAIN_LEN_MAX       256
+
 /**
  * struct channel_program - manage information for channel program
  * @ccwchain_list: list head of ccwchains
        union orb orb;
        struct device *mdev;
        bool initialized;
+       struct ccw1 *guest_cp;
 };
 
 extern int cp_init(struct channel_program *cp, struct device *mdev,
 
        if (!private)
                return -ENOMEM;
 
+       private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1),
+                                      GFP_KERNEL);
+       if (!private->cp.guest_cp)
+               goto out_free;
+
        private->io_region = kmem_cache_zalloc(vfio_ccw_io_region,
                                               GFP_KERNEL | GFP_DMA);
        if (!private->io_region)
                kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
        if (private->io_region)
                kmem_cache_free(vfio_ccw_io_region, private->io_region);
+       kfree(private->cp.guest_cp);
        kfree(private);
        return ret;
 }
 
        kmem_cache_free(vfio_ccw_cmd_region, private->cmd_region);
        kmem_cache_free(vfio_ccw_io_region, private->io_region);
+       kfree(private->cp.guest_cp);
        kfree(private);
 
        return 0;