All of lore.kernel.org
 help / color / mirror / Atom feed
From: Drew Fustini <fustini@kernel.org>
To: Prajwal N <prajwal.n@oss.qualcomm.com>
Cc: qemu-devel@nongnu.org, qemu-riscv@nongnu.org,
	"Palmer Dabbelt" <palmer@dabbelt.com>,
	"Alistair Francis" <alistair.francis@wdc.com>,
	"Sunil V L" <sunilvl@oss.qualcomm.com>,
	"Anup Patel" <anup.patel@oss.qualcomm.com>,
	"Weiwei Li" <liwei1518@gmail.com>,
	"Daniel Henrique Barboza" <daniel.barboza@oss.qualcomm.com>,
	"Liu Zhiwei" <zhiwei_liu@linux.alibaba.com>,
	"Chao Liu" <chao.liu@processmission.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Nicolas Pitre" <npitre@baylibre.com>,
	"Kornel Dulęba" <mindal@semihalf.com>,
	"Atish Patra" <atish.patra@linux.dev>,
	"Radim Krčmář" <radim.krcmar@oss.qualcomm.com>,
	"yunhui cui" <cuiyunhui@bytedance.com>,
	"Chen Pei" <cp0613@linux.alibaba.com>,
	guo.wenjia23@zte.com.cn, liu.qingtao2@zte.com.cn,
	prajwal.n.oss@gmail.com
Subject: Re: [PATCH v6 3/6] hw/riscv: implement CBQRI capacity controller
Date: Thu, 29 Oct 2026 16:46:57 -0700	[thread overview]
Message-ID: <auPa8dDH6tj8nZfH@thelio> (raw)
In-Reply-To: <b789deea-1d49-4d3e-8203-58ff42fcb930@oss.qualcomm.com>

On Wed, Oct 28, 2026 at 07:02:32PM +0530, Prajwal N wrote:
> Hi Drew,
> 
> On 26-10-2026 23:17, Drew Fustini wrote:
> > From: Nicolas Pitre <npitre@baylibre.com>
> > 
> > Implement a capacity controller according to the Capacity and Bandwidth
> > QoS Register Interface (CBQRI) which supports these capabilities:
> > 
> >   - Number of access types: 2 (code and data)
> >   - Usage monitoring operations: CONFIG_EVENT, READ_COUNTER
> >   - Event IDs supported: None, Occupancy
> >   - Capacity allocation ops: CONFIG_LIMIT, READ_LIMIT, FLUSH_RCID
> > 
> > Link: https://github.com/riscv-non-isa/riscv-cbqri/releases/tag/v1.0
> > Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
> > [fustini: add fields introduced in the ratified spec: cunits, rpfx, p]
> > Reviewed-by: Radim Krčmář <radim.krcmar@oss.qualcomm.com>
> > Signed-off-by: Drew Fustini <fustini@kernel.org>
> > ---
> >  MAINTAINERS               |   1 +
> >  hw/riscv/cbqri_capacity.c | 727 ++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 728 insertions(+)
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 2984779ce43a..f230cdbbe1b8 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -408,6 +408,7 @@ M: Nicolas Pitre <npitre@baylibre.com>
> >  M: Drew Fustini <fustini@kernel.org>
> >  L: qemu-riscv@nongnu.org
> >  S: Supported
> > +F: hw/riscv/cbqri_capacity.c
> >  F: include/hw/riscv/cbqri.h
> >  
> >  RISC-V SiFive (Xsf*) extensions
> > diff --git a/hw/riscv/cbqri_capacity.c b/hw/riscv/cbqri_capacity.c
> > new file mode 100644
> > index 000000000000..7ea20532b950
> > --- /dev/null
> > +++ b/hw/riscv/cbqri_capacity.c
> > @@ -0,0 +1,727 @@
> > +/*
> > + * RISC-V Capacity and Bandwidth QoS Register Interface
> > + * URL: https://github.com/riscv-non-isa/riscv-cbqri/releases/tag/v1.0
> > + *
> > + * Copyright (c) 2023 BayLibre SAS
> > + * SPDX-License-Identifier: GPL-2.0-or-later
> > + *
> > + * This file contains the Capacity-controller QoS Register Interface.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qapi/error.h"
> > +#include "qemu/error-report.h"
> > +#include "qemu/log.h"
> > +#include "qemu/module.h"
> > +#include "qemu/bitmap.h"
> > +#include "hw/core/qdev-properties.h"
> > +#include "hw/core/sysbus.h"
> > +#include "target/riscv/cpu.h"
> > +#include "hw/riscv/cbqri.h"
> 
> [...]
> 
> > +static void riscv_cbqri_cc_write(void *opaque, hwaddr addr,
> > +                                 uint64_t value, unsigned size)
> > +{
> > +    RiscvCbqriCapacityState *cc = opaque;
> > +
> > +    assert((addr % 8) == 0);
> > +
> The same comments in the riscv_cbqri_cc_read() below are applicable
> here as well.
> 
> > +    switch (addr) {
> > +    case A_CC_CAPABILITIES:
> > +        /* read-only register */
> > +        break;
> > +    case A_CC_MON_CTL:
> > +        riscv_cbqri_cc_write_mon_ctl(cc, value);
> > +        break;
> > +    case A_CC_ALLOC_CTL:
> > +        riscv_cbqri_cc_write_alloc_ctl(cc, value);
> > +        break;
> > +    case A_CC_MON_CTR_VAL:
> > +        /* read-only register */
> > +        break;
> > +    case A_CC_BLOCK_MASK:
> > +        if (cc->ncblks == 0) {
> > +            break;
> > +        }
> > +        /* fallthrough */
> > +    default:
> > +        uint32_t blkmask_slot = (addr - A_CC_BLOCK_MASK) / 8;
> > +        if (blkmask_slot == get_slots(cc)) {
> > +            /* this is cc_cunits register */
> > +            break;
> > +        } else if (blkmask_slot > get_slots(cc)) {
> > +            qemu_log_mask(LOG_GUEST_ERROR,
> > +                          "%s: out of bounds (addr=0x%x)",
> > +                          __func__, (uint32_t)addr);
> > +            break;
> > +        }
> > +        cc->alloc_blockmasks[blkmask_slot] = value;
> > +    }
> > +}
> > +
> > +static uint64_t riscv_cbqri_cc_read(void *opaque, hwaddr addr, unsigned size)
> > +{
> > +    RiscvCbqriCapacityState *cc = opaque;
> > +    uint64_t value = 0;
> > +
> > +    assert((addr % 8) == 0);
> > +
> To access the 64 bit CBQRI register, the Linux kernel is performing two
> 32 bit reads. The register offsets that are passed to this function are 0x00,
> 0x04, 0x08 ... The assert is triggered for the addr 0x04, 0x0c.. and the
> QEMU exists.
> This check should have been:
> assert((addr %4) == 0)
> 
> The switch statement uses the register offsets that are 8-byte aligned.
> A_CC_CAPABILITIES (0x00), A_CC_MON_CTL (0x08) etc.
> Since the kernel invokes read twice, the second readl() has the offset addr
> 0x04. This does not match any offset and falls into the default case.
> The following change fixes the problem.
> 
>        hwaddr reg_addr = addr & ~7ULL; /* align down to 8-byte boundary */> +    switch (addr) {
>        switch (reg_addr) {> +    case A_CC_CAPABILITIES:
> > +        value = FIELD_DP64(value, CC_CAPABILITIES, VER_MAJOR,
> > +                           RISCV_CBQRI_VERSION_MAJOR);
> > +        value = FIELD_DP64(value, CC_CAPABILITIES, VER_MINOR,
> > +                           RISCV_CBQRI_VERSION_MINOR);
> > +        value = FIELD_DP64(value, CC_CAPABILITIES, NCBLKS,
> > +                           cc->ncblks);
> > +        value = FIELD_DP64(value, CC_CAPABILITIES, FRCID,
> > +                           cc->supports_alloc_op_flush_rcid);
> > +        value = FIELD_DP64(value, CC_CAPABILITIES, CUNITS, 0);
> > +        value = FIELD_DP64(value, CC_CAPABILITIES, RPFX, 0);
> > +        value = FIELD_DP64(value, CC_CAPABILITIES, P, 0);
> > +        break;
> > +    case A_CC_MON_CTL:
> > +        value = cc->cc_mon_ctl;
> > +        break;
> > +    case A_CC_ALLOC_CTL:
> > +        value = cc->cc_alloc_ctl;
> > +        break;
> > +    case A_CC_MON_CTR_VAL:
> > +        value = cc->cc_mon_ctr_val;
> > +        break;
> > +    case A_CC_BLOCK_MASK:
> > +        if (cc->ncblks == 0) {
> > +            break;
> > +        }
> > +        /* fallthrough */
> > +    default:
> > +        unsigned int blkmask_slot = (addr - A_CC_BLOCK_MASK) / 8;
> > +        if (blkmask_slot == get_slots(cc)) {
> > +            /*
> > +             * The cc_cunits register is always the slot following the
> > +             * last slot of cc_blockmask register. Capacity units are
> > +             * not supported by this implementation so must return 0.
> > +             */
> > +            value = 0;
> > +            break;
> > +        } else if (blkmask_slot > get_slots(cc)) {
> > +            qemu_log_mask(LOG_GUEST_ERROR, "%s: out of bounds (addr=0x%x)",
> > +                          __func__, (uint32_t)addr);
> > +            break;
> > +        }
> > +        value = cc->alloc_blockmasks[blkmask_slot];
> > +    }
> > +
> The logic within the switch statement always computes the full 64-bit register
> value. But the Linux kernel requested for 32 bits. The kernel is creating a
> 64-bit value with the two 32-bit values. This should return only the relevant half.
> The following code snippet fixed the problem.
>     /* Return the correct 32-bit */
>     if (size == 4) {
>         if (addr & 4)
>             return value >> 32;   // high word
>         else
>             return value & 0xffffffff;  // low word
>     }
> 
> Thanks,
> Prajwal N

Thank you for reviewing. Did you see that riscv_cbqri_cc_ops actually
invokes riscv_cbqri_cc_read_wrapper() and
riscv_cbqri_cc_write_wrapper()?

Those wrappers were added in v5 based on Radim's feedback on v4.

Thanks,
Drew


  reply	other threads:[~2026-10-29 23:47 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-26 17:47 [PATCH v6 0/6] riscv: implement Ssqosid extension and CBQRI controllers Drew Fustini
2026-10-26 17:47 ` [PATCH v6 1/6] riscv: implement Ssqosid extension and srmcfg CSR Drew Fustini
2026-10-27  0:22   ` Alistair Francis
2026-10-28  2:59     ` Drew Fustini
2026-10-28  3:55       ` Alistair Francis
2026-10-26 17:47 ` [PATCH v6 2/6] hw/riscv: define capabilities of CBQRI controllers Drew Fustini
2026-10-26 17:47 ` [PATCH v6 3/6] hw/riscv: implement CBQRI capacity controller Drew Fustini
2026-10-28 13:32   ` Prajwal N
2026-10-29 23:46     ` Drew Fustini [this message]
2026-10-26 17:47 ` [PATCH v6 4/6] hw/riscv: implement CBQRI bandwidth controller Drew Fustini
2026-10-27  0:18   ` Alistair Francis
2026-10-29 21:00     ` Drew Fustini
2026-10-26 17:47 ` [PATCH v6 5/6] hw/riscv: add CBQRI to Kconfig and build if enabled Drew Fustini
2026-10-26 17:47 ` [PATCH v6 6/6] hw/riscv: add CBQRI controllers to virt machine Drew Fustini
2026-10-28 13:56   ` Prajwal N
2026-10-30  0:18     ` Drew Fustini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=auPa8dDH6tj8nZfH@thelio \
    --to=fustini@kernel.org \
    --cc=alistair.francis@wdc.com \
    --cc=anup.patel@oss.qualcomm.com \
    --cc=atish.patra@linux.dev \
    --cc=chao.liu@processmission.com \
    --cc=cp0613@linux.alibaba.com \
    --cc=cuiyunhui@bytedance.com \
    --cc=daniel.barboza@oss.qualcomm.com \
    --cc=guo.wenjia23@zte.com.cn \
    --cc=liu.qingtao2@zte.com.cn \
    --cc=liwei1518@gmail.com \
    --cc=mindal@semihalf.com \
    --cc=npitre@baylibre.com \
    --cc=palmer@dabbelt.com \
    --cc=pbonzini@redhat.com \
    --cc=prajwal.n.oss@gmail.com \
    --cc=prajwal.n@oss.qualcomm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    --cc=radim.krcmar@oss.qualcomm.com \
    --cc=sunilvl@oss.qualcomm.com \
    --cc=zhiwei_liu@linux.alibaba.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.