[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v1 05/17] xen/riscv: implement virtual APLIC MMIO emulation



On 2026-08-07 18:08:21+02:00, Oleksii Kurochko wrote:
> On 8/6/26 4:28 PM, Jan Beulich wrote:
> 
> > On 20.07.2026 18:02, Oleksii Kurochko wrote:
> > 
> > For this tag to have any meaning, it should move ahead of the --- above;
> > the explanations ...
> > 
> > 
> > ... here rather explain the restriction on the R-b, not its odd placement.
> > 
> > 
> > As this looks to be recurring - please get versioning of your series right.
> > The series is supposedly v1, but here you give the impression of it being
> > v3. If there really was an earlier v2 posting, why isn't the entire series
> > here v3?
> 
> It is v3 before before it was a part of another patch series connected 
> to dom0less config enablement.
> 
> Would it be better to just write in "Change in v3" that it is moved from 
> another patch series + link to that patch series? Or it will be enough 
> just to drop "Changes in v2 and v1" and just start from v1?
> 
> > PLease can you, before submitting, self-review your patches? I'm really
> > getting tired of having to repeatedly point out basic style issues, like
> > the overlong line here.
> 
> Sorry for that, I will write an extra checker for such cases to not miss 
> them.
> 
> > It extends to the other local variables here, but I'll use these two to
> > try to make my point: I'm struggling to associate the names with the
> > values they are set to. Likely "hxw" is an abbreviation of hart index
> > width, but (a) what's the leading 'l' then and (b) why is there no 'g'
> > in "hhxw"? By using hard to grasp names, you make it hard to actually
> > understand the subsequent expressions, in particular ...
> 
> The names it taken directly from AIA spec:
> 
> The use of this value and fields HHXS (High Hart Index Shift), LHXS (Low 
> Hart Index Shift), HHXW (High Hart Index Width), and LHXW (Low Hart 
> Index Width) for determining target addresses for MSIs is described 
> later, in Section 4.9.1.
> 
> The AIA specification interprets the machine-level hart index as a 
> combination of the **group index** (`g`) and the **hart index within the 
> group** (`h`), according to the following formulas:
> 
> ```
> (1) g = (machine-level hart index >> LHXW) & (2^HHXW − 1)
> (2) h = machine-level hart index & (2^LHXW − 1)
> ```
> 
> (In our case, the machine-level hart index is equal to `mhartid`, i.e. 
> the hart index.)
Therefore, if I understand correclty, if we take the Hart Index as
defined in the AIA spec, we should have:
Hart Index = (g << LHXW) | h
Is it correct?
> 
> For systems that use IMSIC groups, the IMSIC address layout is defined 
> by the following parameters:
> 
> * `lhxw` (Low Hart Index Width, or *k*): the number of bits used for the 
> hart number within a group.
> * `hhxw` (High Hart Index Width, or *j*): the number of bits used for 
> the group number.
Is group number appelation equivalent to group index?

I think with if what I wrote above is correct, the proper definition for
`hhxw` and `hhxs` should be:
* `hhxw` (High Hart Index Width, or *j*): the number of bits used for
the `Hart Index` field within the physical address.
> * `hhxs` (High Hart Index Shift): the bit offset of the combined 
> hart/group index field within the physical address.
* `hhxs` (High Hart Index Shift): the bit offset of the `Hart Index`
field within the physical address.
> To extract the group index, we first shift the address by `hhxs` so that 
> the group index bits are aligned, and then apply a mask derived from 
> `hhxw` to isolate those bits.
> 
> The hardware performs the same operation to extract the hart index from 
> the MSI address. However, in our case we already know which hart should 
> receive the interrupt (`hartid`), so there is no need to extract the 
> hart index from the base address. We only need to recover the group 
> index and combine it with `hartid` to construct the value expected by 
> the `target` register.

Why don't we direclty extract the Hart Index as target directly needs it
as explained in the 4.5.16.2 point of the AIA spec:
target[31:18] = Hart Index
target[17:12] = Guest Index
target[10:0] = EEID
It'd be easier as we just have to do shift from HHXS and apply HHXW.
> 
> > ... these last two. As it stands, they may be easier to understand if
> > you didn't have the local variables at all, despite them then getting
> > textually longer.
> 
> With the explanation above, do the variable names make sense?
> 
> To be closer to AIA spec I think it would be better to rename 
> group_index to g and hart_id to h. Does it make sense to you?
> 
> >> +
> > 
> > Wouldn't this applying of a mask better be done in those callers which
> > actually need it? It's not the least the asymmetry with ...
> 
> Agree, that to be in sync, I will drop mask argument and apply it on 
> caller side.
> 
> > ... this which I consider unhelpful.
> > 
> > 
> > As to the comment - this indeed looks to be a field, but ...
> > 
> > 
> > ... these look to be values of some other field which isn't described. 
> > Please
> > may I (again) ask that definitions are their commentary at the very least 
> > not
> > misguide readers?
> 
> Thanks for pointing this out. You're right, the comment is misleading as 
> written. APLIC_SOURCECFG_D is a field, whereas the APLIC_SOURCECFG_SM_* 
> definitions are values for the source mode (SM) field, and the comment 
> doesn't make that distinction.
> 
> I'll update the comments to describe the fields more accurately:
> 
> #define APLIC_SOURCECFG_BASE            0x0004
> #define APLIC_SOURCECFG_LAST            0x0ffc
> /*
>   * sourcecfg[] register fields:
>   *  - bit 10 (D) selects the layout of the remaining bits;
>   *  - D = 1: bits [9:0] hold the Child Index, i.e. the source is delegated
>   *           to a child domain (unsupported by Xen);
Just to know, what is a child domain?
>   *  - D = 0: bits [2:0] hold the source mode SM (WARL).
>   */
> #define  APLIC_SOURCECFG_D              BIT(10, U)
> /* SM field values (0x2 and 0x3 are reserved): */
> #define   APLIC_SOURCECFG_SM_INACTIVE   0x0
> #define   APLIC_SOURCECFG_SM_DETACH     0x1
> #define   APLIC_SOURCECFG_SM_EDGE_RISE  0x4
> #define   APLIC_SOURCECFG_SM_EDGE_FALL  0x5
> #define   APLIC_SOURCECFG_SM_LEVEL_HIGH 0x6
> #define   APLIC_SOURCECFG_SM_LEVEL_LOW  0x7
> 
> Does it look better? Probably there is not sense for two extra spaces 
> for APLIC_SOURCECFG_SM_*. I want to show by such identation that it is 
> values for SM field of APLIC_SOURCECFG.
> 
> > And the xxx-es in here mean what exactly? Don't care? Some other, unrelated
> > values? Yet something else?
> 
> The `x` bits denote address bits that are constant across all IMSIC 
> interrupt files. They are not used to encode the group, HART, or guest 
> index; instead, they correspond to the fixed portion of the IMSIC 
> address determined by the platform's memory map.
> 
> For example, consider the IMSIC DT binding:
> 
>      interrupt-controller@28000000 {
>        compatible = "qemu,imsics", "riscv,imsics";
>        interrupts-extended = <&cpu1_intc 9>,
>                              <&cpu2_intc 9>,
>                              <&cpu3_intc 9>,
>                              <&cpu4_intc 9>;
>        reg = <0x28000000 0x2000>, /* Group0 IMSICs */
>              <0x29000000 0x2000>; /* Group1 IMSICs */
>        interrupt-controller;
>        #interrupt-cells = <0>;
>        msi-controller;
>        #msi-cells = <0>;
>        riscv,num-ids = <127>;
>        riscv,group-index-bits = <1>;
>        riscv,group-index-shift = <24>;
>      };
> 
> 
> Here, `hart_index_bits = 2` (4 CPUs) and `guest_index_bits = 0`, so the 
> address layout becomes:
> 
> 31          25 24 23         14 13 12 11          0
> +-------------+-+-------------+-----+-------------+
> | constant    |G|  constant   |HART |    zeros    |
> +-------------+-+-------------+-----+-------------+
> 
> 
> I can update the comment to say:
> "x denotes bits that are constant across all interrupt file addresses."
> 
> or, if you think it's clearer: "x denotes bits whose values are 
> platform-defined and common to all interrupt file addresses."
> 
> Does it make sense any of suggested options?
> 
> > Nit: Indentation.
> 
> I will use the following indentation:
> 
> ... (((irqn) < (d)->arch.vintc->nr_virqs) && \
>       test_bit(irqn, (d)->arch.vintc->used_irqs))
> 
> > Is this really meant to stay?
> 
> For debug purpose it could be useful, so I prefer to have it with 
> changing it to gprintk(XENLOG_DEBUG, ...) to understand which domain is 
> trying to access something wrong.
> 
> > The U suffix is mainly (even if only slightly) obfuscating things, I think.
> 
> Agree, I will drop U.
> 
> > I don't quite understand the need for the cast.
> 
> Functionally it isn't need but it documents that it is expected that 
> translation from unsinged long  to uint32_t will happen. I will drop the 
> cast.
> 
> > Why the cf_check (also for the store counterpart)?
> 
> Missed to drop. Before vaplic_emulate_load() was used to initialize 
> vints_ops. It should be dropped here.
> 
> > You have d as a local variable.
> > 
> > 
> > Use domain_vcpu()?
> 
> It will be better, thanks.
> 
> > Instead of this goto, I think you simply want to move the label here.
> > That'll also make the function more similar to its load counterpart.
> 
> Good point. I am curious how fail label should be aligned:
> 
>      default:
>   fail:
>          gdprintk(XENLOG_WARNING,
>                   "Unhandled APLIC write at offset %#x (value %#x)\n", 
> offset,
>                   value);
> 
>          return rc;
>      }
> 
> or default:
>      fail:
> 
> ?
> 
> > You have v passed in here, but you'd log current. If passing in v is
> > necessary (i.e. here or elsewhere it may be other than current), then you
> > need to either ASSERT(v == current) at the top of the funciton or otherwise
> > handle v != current correctly.
> 
> It makes sense. I will add ASSERT(v == current) here and for 
> vaplic_mmio_write().
> 
> > If all you care about is a boolean result, why not make the function return
> > bool?
> 
> Agree, bool will be enough for vaplic_emulate_load() and 
> vaplic_emulate_save().
> 
> Thanks!
> 
> ~ Oleksii

I will try to draw some schema to make the AIA spec more explicit. Maybe
it could be part of this series, I don't know what is the xen policy
about diagram and stuff like that. Do you know more about that? In order
to not do a job with no needed at all.




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.