|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 09/39] xen/riscv: implement virtual APLIC MMIO emulation
On 9/2/26 2:31 PM, Baptiste Le Duc wrote:
Agree, if() written in this way is incorrect in the way what is going before this if(). I think that we don't need it at all and what we want instead is ignoring write to others bits then D (bit10) and SM(bits 2:0) as they are reserved and read as zeros.
/*
* Only D (bit 10) and SM (bits 2:0) are implemented, the rest
of the
* bits are reserved and read as zero, so ignore what a guest
writes
* to them.
*/
value &= (APLIC_SOURCECFG_D | APLIC_SOURCECFG_SM);
Probably it make sense to introduce and use it above:
/*
* All other bits of sourcecfg[] are reserved and read as zero, so drop
them on a write.
*/#define APLIC_SOURCECFG_WMASK (APLIC_SOURCECFG_D | APLIC_SOURCECFG_SM) And ... SM is WARL. If SM invalid but other fields valid, shouldn't reject whole write. Instead override value.SM with current valid SM in this branch, so other valid fields still get written. ... considering that SM is WARL it means that technically any value could be written to this field but read of this register should be return always something valid. So considering that in the case of SOURCECFG we don't have a shadow copy for vAPLIC and use just real h/w we could ignore fully the value it is trying to write to SM field as even it is something illegal h/w will choose something legal instead. If one day we will need a copy of SOURCECFG for vAPLIC we will need to do something like this to emulate behavior of real SOURCECFG:
/*
* SM is a WARL field. If the guest wrote reserved values (2 or 3),
* optionally coerce them to a supported default (e.g.,
Inactive/0).
*/
if ( value == 2 || value == 3 )
value = APLIC_SOURCECFG_SM_INACTIVE;
For now we can do nothing. I can put TODO:
/*
* SM is WARL, so the reserved values 0x2 and 0x3 need no handling
* here: vAPLIC keeps no shadow copy of sourcecfg[], the value is
* written straight to the h/w register and is read back from
it, so
* it is the h/w which substitutes a legal value for an illegal
one.
*
* TODO: when vAPLIC starts to shadow sourcecfg[], the WARL
behaviour
* will have to be emulated here instead, e.g.:
* if ( value == 0x2 || value == 0x3 )
* value = APLIC_SOURCECFG_SM_INACTIVE;
*/
Note that here it is okay not to use MASK_EXTR as we have always D=0 so
sourcecfg[i] value is basically SM field (as other bits are reserved and
are read only)
So my final suggestion is:
case APLIC_SOURCECFG_BASE ... APLIC_SOURCECFG_LAST:
+ /*
+ * Only D (bit 10) and SM (bits 2:0) are implemented, the rest
of the
+ * bits are reserved and read as zero, so ignore what a guest
writes
+ * to them.
+ */
+ value &= APLIC_SOURCECFG_WMASK;
+
if ( value & APLIC_SOURCECFG_D )
{
dprintk(XENLOG_ERR, "APLIC_SOURCECFG_D isn't supported\n");
@@ -169,6 +176,18 @@ static bool vaplic_emulate_store(const struct vcpu
*curr, paddr_t addr,
goto fail;
}
+ /*
+ * SM is WARL, so the reserved values 0x2 and 0x3 need no handling
+ * here: vAPLIC keeps no shadow copy of sourcecfg[], the value is
+ * written straight to the h/w register and is read back from
it, so
+ * it is the h/w which substitutes a legal value for an illegal
one.
+ *+ * TODO: when vAPLIC starts to shadow sourcecfg[], the WARL behaviour
+ * will have to be emulated here instead, e.g.:
+ * if ( value == 0x2 || value == 0x3 )
+ * value = APLIC_SOURCECFG_SM_INACTIVE;
+ */
+
/*
* As sourcecfg register starts from 1:
* 0x0000 domaincfg
@@ -184,15 +203,6 @@ static bool vaplic_emulate_store(const struct vcpu
*curr, paddr_t addr,
/* Interrupt not enabled, ignore it */
return true;
- if ( value > APLIC_SOURCECFG_SM_LEVEL_LOW )
- {
- gdprintk(XENLOG_ERR,
- "value(%#x) is incorrect for sourcecfg register\n",
- value);
-
- return true;
- }
-
break;
Does it make sense? Or I still missing something.
It looks like the same question in the other thread [1] at the end. If you don't mind lets continue discussion there. I responded there.[1] https://lore.kernel.org/xen-devel/cover.1787838835.git.oleksii.kurochko@xxxxxxxxx/T/#m0de75013bd31481a2f6abd6f36ccccb8ede87a20
Yes, it is expected as we are supporting now only APLIC+IMSIC in Xen and it is the reason why we here started to provided a shadow copy of domaincfg register for vAPLIC instead of using real APLIC domaincfg register. Moreover, I saw that d8fbe0bbc7's commit message claims: "a guest's domaincfg.DM reads back as a fixed one, so is there situation where we would allow direct delivery mode? If not, the else branch should be dropped. At the moment, we started with a support only when we are working in MSI mode but commonly it is possible that IMSIC will be absent and we don't have any other choice as started to support delivery mode. Thanks for review! ~ Oleksii
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |