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

Re: [PATCH for-4.17 6/6] vpci: refuse BAR writes only if the BAR is mapped


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Date: Mon, 24 Oct 2022 17:04:16 +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=wY/FMlcRPFDBZIEYTMjtgmpieWNWtqEmprrtNPF4HVs=; b=kPokHmYoLOuGFEcPElIq8jh/RkuBwIZsqdIF5V3gV3i+6e2Yp9L73/JpcEBUixuhCK5oi6TRD/JFiAVrnc9EwBfrLZfrQLAYf6dWNDgVXTnhksqTgwBn1QFg6BBUHYpnrEJX6b/goR8jBpffDXmKb9ioxFlMJzN2oCSx1BWFd/ioDVqbM3QZxvFmmffnQ2sdwTSJFu9HBmsVzlx/6Z/3QfEU8NwRux1BNhqop5c0f0+S7EdhQB/6Z/JcCy2A4Jtzri7X6I2B9Vs6FgMJ5RhhNAgMDZTXFjGipfiubY2+7+fA8JDfAQlg126rj9gbAA/FRHlLgVzdszV5OU09o9T48w==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=b4e1pM0P9wZBLt80cj5oe3PurMKCaHw/QXOaRLCyJk1FJJj2orzD/7CrNb9nyzWe+iOth1ZbvrFpFYX3/MIBm17JzLryaBbA7aUJkMIaB7Ss1PCsGdkLnkdvjaBEztLiejDP81gc21oBoigdYbqxeuYrq9TW1lfWumSjz22Kk+yIBPdHBH33Hj6/CAts5rBxcn9xbap1SUrlzh60rmaB4Tb+PAc3a9tcKVSmF/y3KON5IPupzsMJ0e9yC2OLXijmW7ifBjVj/m/PH3ASG4Tb0fYe6wI2Op03PtpnZ+ICx6vh6fq6ix3wqZj/m3+2KGdDEZSJyYTiiJR57RvUalKdhw==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • Delivery-date: Mon, 24 Oct 2022 15:04:50 +0000
  • Ironport-data: A9a23:K2MAIK+6yRu1n8KNrLRrDrUDl3+TJUtcMsCJ2f8bNWPcYEJGY0x3y WMaWmrSaf6Da2H0cookbI618EoF75+Dy4djSgFk/yE8E34SpcT7XtnIdU2Y0wF+jCHgZBk+s 5hBMImowOQcFCK0SsKFa+C5xZVE/fjUAOC6UIYoAwgpLSd8UiAtlBl/rOAwh49skLCRDhiE/ Nj/uKUzAnf8s9JPGj9Suv/rRC9H5qyo4mpA5ABmP5ingXeF/5UrJMNHTU2OByOQrrl8RoaSW +vFxbelyWLVlz9F5gSNy+uTnuUiG9Y+DCDW4pZkc/HKbitq/0Te5p0TJvsEAXq7vh3S9zxHJ HehgrTrIeshFvWkdO3wyHC0GQkmVUFN0OevzXRSLaV/ZqAJGpfh66wGMa04AWEX0v5wM313x 6cVEy1XQS3a2ruu3rucafY506zPLOGzVG8ekldJ6GiBSNMZG9XESaiM4sJE1jAtgMwIBezZe 8cSdTtoalLHfgFLPVAUTpk5mY9EhFGmK2Ee9A3T+PdxujCKpOBy+OGF3N79YNuFSN8Thk+Fj mnH4374ElcRM9n3JT+toijw1rOUwX+TtIQ6OISqzsF0nASp4DY6URQcT3/qrcmYlRvrMz5YA wlOksY0loAw/kG2Stj2XzWjvWWJ+BUbXrJ4A+A8rQ2A1KfQywKYHXQfCC5MbsQ8s807TiBs0 UWG9+4FHhRqubyRDHeCrLGdqGrqPTBPdDdbIygZUQEC/t/v5pkpiQ7CRcpiF6jzicDpHTb3w HaBqy1Wa6gvsPPnHp6TpTjv6w9AbLCQJuLpzm07hl6Y0z4=
  • Ironport-hdrordr: A9a23:PGzLmammpLli2kDMNMg9x0rGr6XpDfPJimdD5ihNYBxZY6Wkfp +V8cjzhCWftN9OYhodcLC7V5Voj0mskKKdxbNhRYtKPTOWwVdASbsP0WKM+V3d8kHFh41gPO JbAtND4b7LfCRHZKTBkW6F+r8bqbHokZxAx92uqUuFJTsaFp2IhD0JbjpzfHcGJjWvUvECZe ChD4d81k2dUEVSSv7+KmgOXuDFqdGOvJX6YSQeDxpizAWVlzun5JPzDhDdh34lInpy6IZn1V KAvx3y562lvf3+4hjA11XL55ATvNf60NNMCOGFl8BQADTxjQSDYphnRtS5zUYIidDqzGxvvM jHoh8mMcg2w3TNflutqR+o4AXk2CZG0Q6R9XaoxV/Y5eDpTjMzDMRMwahDdAHC1kYmtNZglI pWwmOwrfNsfF79tRW4w+KNewBhl0Kyr3Znu/UUlWZjXYwXb6IUhZAD/XlSDIwLEEvBmcoa+d FVfY7hDcttAB2nhyizhBgv/DXsZAV5Iv6+eDlPhiTPuAIm3EyQzCMjtb8idzk7hdEAoqJ/lp X525RT5c5zp/AtHNxA7cc6ML6K4z/2MGbxGVPXB2jbP4c6HF+Ig6LLwdwOlZGXkdozvdMPpK g=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On Mon, Oct 24, 2022 at 01:51:03PM +0200, Jan Beulich wrote:
> On 20.10.2022 11:46, Roger Pau Monne wrote:
> > Writes to the BARs are ignored if memory decoding is enabled for the
> > device, and the same happen with ROM BARs if the write is an attempt
> > to change the position of the BAR without disabling it first.
> > 
> > The reason of ignoring such writes is a limitation in Xen, as it would
> > need to unmap the BAR, change the address, and remap the BAR at the
> > new position, which the current logic doesn't support.
> > 
> > Some devices however seem to have the memory decoding bit hardcoded to
> > enabled, and attempts to disable it don't get reflected on the
> > command register.
> 
> This isn't compliant with the spec, is it? It looks to contradict both
> "When a 0 is written to this register, the device is logically
> disconnected from the PCI bus for all accesses except configuration
> accesses" and "Devices typically power up with all 0's in this
> register, but Section 6.6 explains some exceptions" (quoting from the
> old 3.0 spec, which I have readily to hand). The referenced section
> then says "Such devices are required to support the Command register
> disabling function described in Section 6.2.2".

It's unclear to me whether setting the bit to 0 is plain ignored, or
just fails to be reflected on the command register.

> How does any arbitrary OS go about sizing the BARs of such a device?

AFAICT from Linux behavior, an OS would just set to 0 the memory
decoding command register bit and write the value, but there's no
check afterwards that the returned value from a read of the register
still has memory decoding disabled.   Xen does exactly the same:
attempt to toggle the bit but don't check the value written.

> > This causes issues for well behaved guests that disable memory
> > decoding and then try to size the BARs, as vPCI will think memory
> > decoding is still enabled and ignore the write.
> > 
> > Since vPCI doesn't explicitly care about whether the memory decoding
> > bit is disabled as long as the BAR is not mapped in the guest p2m use
> > the information in the vpci_bar to check whether the BAR is mapped,
> > and refuse writes only based on that information.
> 
> From purely a vPCI pov this looks to be a plausible solution (or
> should I better say workaround). I guess the two pieces of code that
> you alter would benefit from a comment as to it being intentional to
> _not_ check the command register (anymore).

Ack.

> > --- a/xen/drivers/vpci/header.c
> > +++ b/xen/drivers/vpci/header.c
> > @@ -388,7 +388,7 @@ static void cf_check bar_write(
> >      else
> >          val &= PCI_BASE_ADDRESS_MEM_MASK;
> >  
> > -    if ( pci_conf_read16(pdev->sbdf, PCI_COMMAND) & PCI_COMMAND_MEMORY )
> > +    if ( bar->enabled )
> >      {
> >          /* If the value written is the current one avoid printing a 
> > warning. */
> >          if ( val != (uint32_t)(bar->addr >> (hi ? 32 : 0)) )
> > @@ -425,7 +425,7 @@ static void cf_check rom_write(
> >      uint16_t cmd = pci_conf_read16(pdev->sbdf, PCI_COMMAND);
> >      bool new_enabled = val & PCI_ROM_ADDRESS_ENABLE;
> >  
> > -    if ( (cmd & PCI_COMMAND_MEMORY) && header->rom_enabled && new_enabled )
> > +    if ( rom->enabled && new_enabled )
> >      {
> >          gprintk(XENLOG_WARNING,
> >                  "%pp: ignored ROM BAR write with memory decoding 
> > enabled\n",
> 
> The log message wording then wants adjustment, I guess?

Hm, I think the message is fine for the purposes here, vPCI is indeed
ignoring a write with memory decoding enabled, or else rom->enabled
would be false.

Or are you arguing that the message is already wrong in the current
context and should instead be:

"ignored ROM BAR write with memory decoding and ROM enabled"

> What about
> 
>     if ( !(cmd & PCI_COMMAND_MEMORY) || header->rom_enabled == new_enabled )
> 
> a few lines down from here? Besides still using the command register
> value here not looking very consistent, wouldn't header->rom_enabled
> here an in the intermediate if() also better be converted to
> rom->enabled for consistency?
> 
> Then again - is you also dropping the check of header->rom_enabled
> actually correct?

rom->enabled should only be set when both the ROM is enabled and
memory decoding is also enabled for the device.

> While both are written to the same value by
> modify_decoding(), both rom_write() and init_bars() can bring the
> two booleans out of sync afaics.

Right, bar->enabled is not a clone of header->rom_enabled, as the
later only caches the ROM BAR enable bit, while the former caches both
header->rom_enabled and whether memory decoding is also enabled (and
the BAR is mapped).

The usage of command register value in the checks below is indeed
dubious, as the purpose of the change is tono trust the value of
the memory decoding bit in the command register.

I think the only way is to cache the Xen intended value of the memory
decoding command register bit for it's usage in rom_write().

Thanks, Roger.



 


Rackspace

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