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

Re: [PATCH v2 2/5] x86/ioapic: RTE modifications must use ioapic_write_entry


  • To: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Thu, 20 Jul 2023 08:32:12 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.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=/QrQlmWNReCfKkSixbiF3LTUVtYE7p21S9RunLoKOpE=; b=a3UzlQrKoWF2mwPJYpSNuuVIx0ZXgVOanUuPuGzrmTsA4gkzQ1Ya7zWNXduHAQd/Cq4RG/pvSIm+g9Vh3DVX4xz6A0SJfx9XF9Rg2W3SPBJC/2HuODut1VmxKQ5d1yLeb9j+DA7szLfGKQYs5KGRkTpckm/VU6efM0ocpBgzgD0oVlRX8WVg2W11Y8zZNeX1lRuYNraNLR6var/+2fNvwjRiTLOMCa8rCVGT9HDeij6yeWJNOGkKf7CJl93zQcUAv7Ck/KPcX86e6GD5Kq70sSNf0fZROpnGMOG82VvNFZCFOIBmsxUCNbBK4bquToVdkb2qxFeM4v00zS3GbKaiJQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=e93HzS+mEEZj0k7tFoD+ijA6gv5hqIvEkd6sJlW04lf546/pMvOtKmcA83JkuG/klvJB18glQkk+aI4Vu3T5F1AxFeuwYjRj900J/L3aHqu/NarfNArMBhpbdJkzpAt75lIXtJlom25byUf/eaMHxb0rl8+g9uZkxKknVpgryzqZ2W6no7DHjo3WPRvj+NudRMRgg1U9SGrmtEYqkgavEIsnpaJb01uCJTYSoKUXw7RBgIwUfQvmDLMzx92AzljDUWvVtQf3ChHrMifEEnQxZLg+mt2shV37a9h2sBrV4f0De0IrkcDWGNfLGwkBKaHo+MoeV8b38a8NyLxeofY19g==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Thu, 20 Jul 2023 06:32:32 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 19.07.2023 17:20, Roger Pau Monné wrote:
> On Tue, Jul 18, 2023 at 05:40:18PM +0200, Jan Beulich wrote:
>> On 18.07.2023 14:43, Roger Pau Monne wrote:
>>> --- a/xen/arch/x86/io_apic.c
>>> +++ b/xen/arch/x86/io_apic.c
>>> @@ -269,15 +269,15 @@ void __ioapic_write_entry(
>>>  {
>>>      union entry_union eu = { .entry = e };
>>>  
>>> -    if ( raw )
>>> +    if ( raw || !iommu_intremap )
>>>      {
>>>          __io_apic_write(apic, 0x11 + 2 * pin, eu.w2);
>>>          __io_apic_write(apic, 0x10 + 2 * pin, eu.w1);
>>>      }
>>>      else
>>>      {
>>> -        io_apic_write(apic, 0x11 + 2 * pin, eu.w2);
>>> -        io_apic_write(apic, 0x10 + 2 * pin, eu.w1);
>>> +        iommu_update_ire_from_apic(apic, 0x11 + 2 * pin, eu.w2);
>>> +        iommu_update_ire_from_apic(apic, 0x10 + 2 * pin, eu.w1);
>>>      }
>>>  }
>>
>> I think __ioapic_read_entry() wants updating similarly, so that both
>> remain consistent.
> 
> My plan was to deal with __ioapic_read_entry() separately, as I would
> also like to convert iommu_read_apic_from_ire() to get passed a pin
> instead of a register, but I could make your requested adjustment here
> for consistency with __ioapic_write_entry().

I would indeed prefer if you did, to avoid the functions going out of
sync.

>>> @@ -433,16 +433,17 @@ static void modify_IO_APIC_irq(unsigned int irq, 
>>> unsigned int enable,
>>>                                 unsigned int disable)
>>>  {
>>>      struct irq_pin_list *entry = irq_2_pin + irq;
>>> -    unsigned int pin, reg;
>>>  
>>>      for (;;) {
>>> -        pin = entry->pin;
>>> +        unsigned int pin = entry->pin;
>>> +        struct IO_APIC_route_entry rte;
>>> +
>>>          if (pin == -1)
>>>              break;
>>> -        reg = io_apic_read(entry->apic, 0x10 + pin*2);
>>> -        reg &= ~disable;
>>> -        reg |= enable;
>>> -        io_apic_modify(entry->apic, 0x10 + pin*2, reg);
>>> +        rte = __ioapic_read_entry(entry->apic, pin, false);
>>> +        rte.raw &= ~(uint64_t)disable;
>>> +        rte.raw |= enable;
>>> +        __ioapic_write_entry(entry->apic, pin, false, rte);
>>
>> While this isn't going to happen overly often, ...
>>
>>> @@ -584,16 +585,16 @@ set_ioapic_affinity_irq(struct irq_desc *desc, const 
>>> cpumask_t *mask)
>>>              dest = SET_APIC_LOGICAL_ID(dest);
>>>          entry = irq_2_pin + irq;
>>>          for (;;) {
>>> -            unsigned int data;
>>> +            struct IO_APIC_route_entry rte;
>>> +
>>>              pin = entry->pin;
>>>              if (pin == -1)
>>>                  break;
>>>  
>>> -            io_apic_write(entry->apic, 0x10 + 1 + pin*2, dest);
>>> -            data = io_apic_read(entry->apic, 0x10 + pin*2);
>>> -            data &= ~IO_APIC_REDIR_VECTOR_MASK;
>>> -            data |= MASK_INSR(desc->arch.vector, 
>>> IO_APIC_REDIR_VECTOR_MASK);
>>> -            io_apic_modify(entry->apic, 0x10 + pin*2, data);
>>> +            rte = __ioapic_read_entry(entry->apic, pin, false);
>>> +            rte.dest.dest32 = dest;
>>> +            rte.vector = desc->arch.vector;
>>> +            __ioapic_write_entry(entry->apic, pin, false, rte);
>>
>> ... this makes me wonder whether there shouldn't be an
>> __ioapic_modify_entry() capable of suppressing one of the two
>> writes (but still being handed the full RTE).
> 
> We would then need the original RTE to be passed to
> __ioapic_modify_entry() in order for it to decide whether one of the
> accesses can be eliminated (as I don't think we want to read the RTE
> to check for differences, as we would then perform even more
> accesses).

I was actually thinking of a 2-bit hint that the caller would pass:
Low half unmodified and high half unmodified.

> This would only be relevant for systems without IOMMU IRTEs, as
> otherwise the IO-APIC RTE gets modified by the IOMMU handlers.

Initially yes. I think there's room there to avoid one half of the
write as well.

Jan



 


Rackspace

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