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

Re: [PATCH v2 31/39] xen/riscv: implement APLIC-hart sync barrier for vCPU migration





On 9/14/26 3:27 PM, Jan Beulich wrote:
On 27.08.2026 17:21, Oleksii Kurochko wrote:
During migration of a virtual hart to a different guest interrupt file,
straggler MSIs from the APLIC could arrive at the old interrupt file
after the switch.

genmsi is used despite not supporting guest interrupt files because the
AIA spec guarantees that all MSIs previously sent from the APLIC to the
same hart are visible at the hart's IMSIC before the extempore MSI from
genmsi becomes visible.

Hmm. As indicated, I'm learning RISC-V as I'm reviewing patches. This
paragraph, if left as is, would make sure I simply can't ack the patch.
I just don't understand what is being talked about. I can guess parts,
but for example I don't know what "genmsi" is.

I will reword then commit message in the following way:

```
When a vCPU is moved to a different guest interrupt file, MSIs that the
APLIC has already sent towards the old file may still be in flight. They
must land before the old file's state is saved and the switch is done,
otherwise they would be lost.

To wait for them, use the APLIC's genmsi register. Writing it makes the
APLIC itself send an MSI (an "extempore" MSI) with a given interrupt
identity to a given hart. genmsi can only target the hart's supervisor-
level interrupt file, not a guest one, but the AIA spec guarantees that
all MSIs previously sent by the same APLIC to the same hart become
visible at the hart's IMSIC before the extempore MSI does. So once the
extempore MSI has been delivered, no older MSI from this APLIC to the
hart can still be in flight, whichever interrupt file it targets.

The last interrupt identity (nr_ids) is reserved for this purpose.
```


@@ -205,6 +207,30 @@ void aplic_hw_write_reg(unsigned int offset, uint32_t 
value)
      spin_unlock_irqrestore(&aplic.lock, flags);
  }
+/*
+ * As needed, synchronize with all IOMMUs and APLICs to ensure that no
+ * straggler MSIs will arrive at the old interrupt file after this step.
+ */
+void aplic_genmsi_barrier(void)
+{
+    const struct imsic_config *imsic = imsic_get_config();
+    unsigned int cpu = smp_processor_id();
+    unsigned long flags;
+    uint32_t val;
+
+    val = MASK_INSR(aplic_hart_field(cpu), APLIC_TARGET_HART_IDX) |
+          (imsic->sync_id & APLIC_TARGET_EIID);

Along the lines of a question on an earlier patch: What if this ANDing
actually chops off bits?

I will do then the same as I did in aplic_set_irq_affinity() (i mentioned that in the one of the replies connected to this function in this patch series):

    /*
     * sync_id is nr_ids, which imsic_parse_node() limits to IMSIC_MAX_ID,
     * so it always fits into the EIID field.
     */
    BUILD_BUG_ON(IMSIC_MAX_ID > MASK_EXTR(~0U, APLIC_TARGET_EIID));
    ASSERT(imsic->sync_id <= IMSIC_MAX_ID);

    val = MASK_INSR(aplic_hart_index(cpu), APLIC_TARGET_HART_IDX) |
          imsic->sync_id;

Thanks.

~ Oleksii




 


Rackspace

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