On 09.09.21 15:47, Jan Beulich wrote:
> On 09.09.2021 14:42, Oleksandr Andrushchenko wrote:
>> On 09.09.21 14:53, Jan Beulich wrote:
>>> On 09.09.2021 13:48, Oleksandr Andrushchenko wrote:
>>>> On 09.09.21 12:21, Jan Beulich wrote:
>>>>> For the bit in question, where the goal appears to be to have hardware
>>>>> hold the OR of guest and host values, an approach similar to that used
>>>>> for some of the MSI / MSI-X bits might be chosen: Maintain guest and
>>>>> host bits in software, and update hardware (at least) when the
>>>>> effective resulting value changes. A complicating fact here is, though,
>>>>> that unlike for the MSI / MSI-X bits here Dom0 (pciback or its PCI
>>>>> susbstem) may also have a view on what the setting ought to be.
>>>> The bigger question here is what can we take as the reference for INTx
>>>> bit, e.g. if Dom0 didn't enable/configured the device being passed through
>>>> than its COMMAND register may still be in after reset state and IMO there 
>>>> is
>>>> no guarantee it has the values we can say are "as host wants them"
>>> In the absence of Dom0 controlling the device, I think we ought to take
>>> Xen's view as the "host" one.
>> Agree
>>>    Which will want the bit set at least as
>>> long as either MSI or MSI-X is enabled for the device.
>> But what is the INTx relation to MSI/MSI-X here?
> Devices are not supposed to signal interrupts two different ways at a
> time. They may enable only one - pin based, MSI, or MSI-X.

Ok, so I see that we can partially emulate the command register as:

static void guest_cmd_write(const struct pci_dev *pdev, unsigned int reg,
                             uint32_t cmd, void *data)
{
     /* TODO: Add proper emulation for all bits of the command register. */

     if ( (cmd & PCI_COMMAND_INTX_DISABLE) == 0 )
     {
         /*
          * Guest wants to enable INTx. It can't be enabled if:
          *  - host has INTx disabled
          *  - MSI/MSI-X enabled
          */
         if ( pdev->vpci->msi->enabled )
             cmd |= PCI_COMMAND_INTX_DISABLE;
         else
         {
             uint16_t current_cmd = pci_conf_read16(pdev->sbdf, reg);

             if ( current_cmd & PCI_COMMAND_INTX_DISABLE )
                 cmd |= PCI_COMMAND_INTX_DISABLE;
         }
     }

     cmd_write(pdev, reg, cmd, data);
}

and of course have grand TODO for the rest.

>
> Jan
>
Thank you,

Oleksandr

Reply via email to