[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH RFC 6/6] x86/ioapic: mask entry while updating
- To: xen-devel@xxxxxxxxxxxxxxxxxxxx
- From: Roger Pau Monne <roger.pau@xxxxxxxxxx>
- Date: Thu, 21 Apr 2022 15:21:14 +0200
- Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
- Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=726ON294pXNt7c/3gsJ1Z+Ba/nN1vU6Da+G2qEPvwDg=; b=InHwxIemJPfVUmwg1QUudFLEgbO9AyoQoBY3PX21CtPT6J+KU9jvl+cYovnfIY4o8raD6Xwc0MRgma/+rJNPuzQrwwGBhDHPSilY8wbci+LN73/FUWGUimLaYdA5EDDjblBiHNbjA5N2SlRdRJI1r1jA1ayuqpN3ZCHfK8EuSvy0yIuORkZRbb6U+6P8mgJiN4gw1im2Q4gjMP0I0StEBQNCh3TXooi3r9q6vR+TMqliXaW51poqlmHuHL51tGBeTkfLX/pbbQJzJDP+KE6gBoEwBimAYFHcu/5Bozcz081wFMl8hGHF1dIAjrRtaNUInHdlK872LXGRfLm8ITxwSA==
- Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lX2SthwrUQ/YIADe5wZ0yXXTWPCtgLF1RH2dAeo+TITMiwhQPE7y0Obm/vp5otIPpfVvrEnr7Fq2A/S3tHYav6f6s9j7kWkq2S/wTvhP1PSXvD5o2o1vbQW3TCrRux+Mol4i0d6IUhp7Nn+/3UAgvHEdpUmoX94xzFm1/EPIOqHMZwzIQ87sFaymIslg7CFo8PF8PqvuYKOp+0/zvhDFos7yDaY9KctbKMeJ8yisJLQ94rB25S4P8joGCN6ZLjjMP+vtJwgkv/kNnToI1qfe553GBcri6ILZmIN/Xj0nwTO14FvAZLvU8QrsaeSkQo6Jz5ZLJsqmTcyGfHotbo1T5w==
- Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
- Cc: Roger Pau Monne <roger.pau@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>
- Delivery-date: Thu, 21 Apr 2022 13:22:21 +0000
- Ironport-data: A9a23:QYDs6qsTWUENs+y4/n18U5bdb+fnVCJfMUV32f8akzHdYApBsoF/q tZmKT/Saf2LZmPzeY1yboS2/E0Av8Tcztc1TwVrr3wzEC4V+JbJXdiXEBz9bniYRiHhoOOLz Cm8hv3odp1coqr0/0/1WlTZhSAgk/nOHNIQMcacUsxLbVYMpBwJ1FQyw4bVvqYy2YLjW1/X4 IuryyHiEATNNwBcYzp8B52r8HuDjNyq0N/PlgVjDRzjlAa2e0g9VPrzF4noR5fLatA88tqBb /TC1NmEElbxpH/BPD8HfoHTKSXmSpaKVeSHZ+E/t6KK2nCurQRquko32WZ1he66RFxlkvgoo Oihu6BcRi8lFPDlt99FECBeGh5gbaJ3pYb7C1ug5Jn7I03uKxMAwt1IJWRvZMg037gyBmtDs /sFNDoKcxaPwfqsx662QfVtgcJlK9T3OIQYuTdryjSx4fQOGMifBfmVo4IHmm5v36iiHt6HD yYdQSBoYxnaJQVGJ38cCY4knffujX76G9FdgAzE/fJouTeIpOB3+In/MNHKKsy0fMFQlFSpo X7Ap27lLjhPYbRzzhLAqBpAnNTnjS79HY4fCrC83vprm0GIgHweDgUMUlm2quX/jVSxM/pdI UEJ/islrYAp6VemCNL6WnWQv3qsrhMaHd1KHIUHBBqlz6PV50OVAzYCRzsYMdg+7pZpHHoty 0ODmM7vCXp3qrqJRHmB97CS6zSvJSwSKmxEbigBJecY3+TeTEgIpkqnZr5e/GSd1LUZxRmYL +i2kRUD
- Ironport-hdrordr: A9a23:acri96vzyyHP2ORWQFueMeMb7skC5IMji2hC6mlwRA09TyXGra 2TdaUgvyMc1gx7ZJhBo7+90We7MBHhHPlOkPMs1NaZLXLbUQ6TQL2KgrGSpwEIdxefygcZ79 YYT0EcMqyOMbEFt7ec3ODQKb9Jrri6GeKT9J/jJh9WPH1XgspbnmJE42igYy5LrF4sP+tFKH PQ3LsPmxOQPVAsKuirDHgMWObO4/XNiZLdeBYDQzoq8hOHgz+E4KPzV0Hw5GZUbxp/hZMZtU TVmQ3w4auu99m91x/nzmfWq7BbgsHoxNdvDNGFzuIVNjLvoAC1Y5kJYczLgBkF5MWUrHo6mt jFpBkte+x19nPqZ2mw5SDg3gHxuQxen0PK+Bu9uz/OsMb5TDU1B45qnoRCaCbU7EImoZVVzL 9L93jxjesZMTrw2ADGo/TYXRBjkUS55VA4l/QIsnBZWYwCLJdMsI0k+l9PGptoJlO31GkeKp guMCjg3ocXTbvDBEqp/VWHgebcE0jbJy32DHTr4aeuonprdHMQ9Tps+CVQpAZEyHsHceg02w 31CNUXqFhwdL5nUUsEPpZmfSKWMB27ffueChPlHbzYfJt3SE7lmtrQ3Igfwt2MVdgh8KYS8a 6xIm+w81RCMX7TNQ==
- List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
When writing an IO-APIC RTE entry make sure incoming interrupts never
see a partially updated entry, by masking the pin while doing the
update when necessary. Add some logic to attempt to limit the number
of writes.
With the masking now handled by __ioapic_write_entry itself when
necessary, we can drop the setting of the disable hook for IO-APIC
edge triggered interrupts.
Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Note this includes a revert of the first patch in the series.
---
xen/arch/x86/io_apic.c | 45 +++++++++++++++++++++++++++++++++++++-----
1 file changed, 40 insertions(+), 5 deletions(-)
diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c
index f61e56f3d1..1860af7353 100644
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -267,12 +267,47 @@ void __ioapic_write_entry(
unsigned int apic, unsigned int pin, bool raw,
struct IO_APIC_route_entry e)
{
- union entry_union eu = { .entry = e };
-
if ( raw || !iommu_intremap )
{
- __io_apic_write(apic, 0x11 + 2 * pin, eu.w2);
- __io_apic_write(apic, 0x10 + 2 * pin, eu.w1);
+ union entry_union eu = { .entry = e };
+ union entry_union curr = {
+ .entry = __ioapic_read_entry(apic, pin, true),
+ };
+ bool masked = true;
+
+ if ( curr.entry.mask )
+ {
+ /*
+ * If pin is currently masked we can update the high part first
+ * without worrying about the RTE being in an inconsistent state.
+ */
+ if ( curr.w2 != eu.w2 )
+ __io_apic_write(apic, 0x11 + 2 * pin, eu.w2);
+ if ( curr.w1 != eu.w1 )
+ __io_apic_write(apic, 0x10 + 2 * pin, eu.w1);
+ return;
+ }
+
+ if ( curr.w1 != eu.w1 && curr.w2 != eu.w2 && !eu.entry.mask )
+ {
+ /*
+ * If updating both halves mask the entry while updating so
+ * interrupts are not injected with an inconsistent RTE.
+ */
+ eu.entry.mask = 1;
+ masked = false;
+ }
+
+ if ( curr.w1 != eu.w1 )
+ __io_apic_write(apic, 0x10 + 2 * pin, eu.w1);
+ if ( curr.w2 != eu.w2 )
+ __io_apic_write(apic, 0x11 + 2 * pin, eu.w2);
+
+ if ( !masked )
+ {
+ eu.entry.mask = 0;
+ __io_apic_write(apic, 0x10 + 2 * pin, eu.w1);
+ }
}
else
iommu_update_ire_from_apic(apic, pin, e.raw);
@@ -1780,7 +1815,7 @@ static hw_irq_controller ioapic_edge_type = {
.startup = startup_edge_ioapic_irq,
.shutdown = irq_shutdown_none,
.enable = unmask_IO_APIC_irq,
- .disable = mask_IO_APIC_irq,
+ .disable = irq_disable_none,
.ack = ack_edge_ioapic_irq,
.set_affinity = set_ioapic_affinity_irq,
};
--
2.35.1
|