Hello,

I found a bug in our patch.

> +/**
> + * ps3_lpm_open - Open the logical performance monitor device.
> + * @tb_type: Specifies the type of trace buffer lv1 sould use for this lpm
> + *  instance, specified by one of enum ps3_lpm_tb_type.
> + * @tb_cache: Optional user supplied buffer to use as the trace buffer cache.
> + *  If NULL, the driver will allocate and manage an internal buffer.
> + *  Unused when when @tb_type is PS3_LPM_TB_TYPE_NONE.
> + * @tb_cache_size: The size in bytes of the user supplied @tb_cache buffer.
> + *  Unused when @tb_cache is NULL or @tb_type is PS3_LPM_TB_TYPE_NONE.
> + */
> +
> +int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
> +     u64 tb_cache_size)
> +{
> +     int result;
> +     u64 tb_size;
> +
> +     BUG_ON(!lpm_priv);
> +     BUG_ON(tb_type != PS3_LPM_TB_TYPE_NONE
> +             && tb_type != PS3_LPM_TB_TYPE_INTERNAL);
> +
> +     if (tb_type == PS3_LPM_TB_TYPE_NONE && tb_cache)
> +             dev_dbg(sbd_core(), "%s:%u: bad in vals\n", __func__, __LINE__);
> +
> +     if (!atomic_add_unless(&lpm_priv->open, 1, 1)) {
> +             dev_dbg(sbd_core(), "%s:%u: busy\n", __func__, __LINE__);
> +             return -EBUSY;
> +     }
> +
> +     if (tb_type == PS3_LPM_TB_TYPE_NONE) {
> +             lpm_priv->tb_cache_internal = NULL;
> +             lpm_priv->tb_cache_size = 0;
> +             lpm_priv->tb_cache = NULL;
> +     } else if (tb_cache) {
> +             if (tb_cache != (void *)_ALIGN_UP((unsigned long)tb_cache, 128)
> +                     || tb_cache_size != _ALIGN_UP(tb_cache_size, 128)) {
> +                     dev_err(sbd_core(), "%s:%u: unaligned tb_cache\n",
> +                             __func__, __LINE__);
> +                     result = -EINVAL;
> +                     goto fail_align;
> +             }
> +             lpm_priv->tb_cache_internal = NULL;
> +             lpm_priv->tb_cache_size = tb_cache_size;
> +             lpm_priv->tb_cache = tb_cache;
> +     } else {
> +             /* tb_cache needs 128 byte alignment. */
> +             lpm_priv->tb_cache_size = PS3_LPM_DEFAULT_TB_CACHE_SIZE;
> +             lpm_priv->tb_cache_internal = kzalloc(tb_cache_size + 127,

The first parameter of kzalloc() is wrong.

                lpm_priv->tb_cache_internal = kzalloc(lpm_priv->tb_cache_size + 
127,
                                                      ^^^^^^^^^^

> +                     GFP_KERNEL);
> +             if (!lpm_priv->tb_cache_internal) {
> +                     dev_err(sbd_core(), "%s:%u: alloc internal tb_cache "
> +                             "failed\n", __func__, __LINE__);
> +                     result = -ENOMEM;
> +                     goto fail_malloc;
> +             }
> +             lpm_priv->tb_cache = (void *)_ALIGN_UP(
> +                     (unsigned long)lpm_priv->tb_cache_internal, 128);
> +     }
> +
> +     result = lv1_construct_lpm(0, tb_type, 0, 0,
> +                             ps3_mm_phys_to_lpar(__pa(lpm_priv->tb_cache)),
> +                             lpm_priv->tb_cache_size, &lpm_priv->lpm_id,
> +                             &lpm_priv->outlet_id, &tb_size);
> +
> +     if (result) {
> +             dev_err(sbd_core(), "%s:%u: lv1_construct_lpm failed: %s\n",
> +                     __func__, __LINE__, ps3_result(result));
> +             result = -EINVAL;
> +             goto fail_construct;
> +     }
> +
> +     lpm_priv->shadow.pm_control = PS3_LPM_SHADOW_REG_INIT;
> +     lpm_priv->shadow.pm_start_stop = PS3_LPM_SHADOW_REG_INIT;
> +     lpm_priv->shadow.pm_interval = PS3_LPM_SHADOW_REG_INIT;
> +     lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT;
> +     lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT;
> +
> +     dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%lx, outlet_id 0x%lx, "
> +             "tb_size 0x%lx\n", __func__, __LINE__, lpm_priv->lpm_id,
> +             lpm_priv->outlet_id, tb_size);
> +
> +     return 0;
> +
> +fail_construct:
> +     kfree(lpm_priv->tb_cache_internal);
> +     lpm_priv->tb_cache_internal = NULL;
> +fail_malloc:
> +fail_align:
> +     atomic_dec(&lpm_priv->open);
> +     return result;
> +}
> +EXPORT_SYMBOL_GPL(ps3_lpm_open);

Thanks.
Takashi Yamamoto.

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to