kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Alex Williamson <alex.williamson@redhat.com>
To: Fred Gao <fred.gao@intel.com>
Cc: kvm@vger.kernel.org, intel-gfx@lists.freedesktop.org,
	Zhenyu Wang <zhenyuw@linux.intel.com>,
	Swee Yee Fonn <swee.yee.fonn@intel.com>
Subject: Re: [PATCH v1] vfio/pci: Add support for opregion v2.0+
Date: Wed, 2 Dec 2020 11:57:23 -0700	[thread overview]
Message-ID: <20201202115723.27df527b@w520.home> (raw)
In-Reply-To: <20201202171249.17083-1-fred.gao@intel.com>

On Thu,  3 Dec 2020 01:12:49 +0800
Fred Gao <fred.gao@intel.com> wrote:

> When VBT data exceeds 6KB size and cannot be within mailbox #4 starting
> from opregion v2.0+, Extended VBT region, next to opregion, is used to
> hold the VBT data, so the total size will be opregion size plus
> extended VBT region size.
> 
> For opregion 2.1+: since rvda is relative offset from opregion base,
> rvda as extended VBT start offset should be same as opregion size.
> 
> For opregion 2.0: the only difference between opregion 2.0 and 2.1 is
> rvda addressing mode besides the version. since rvda is physical host
> VBT address and cannot be directly used in guest, it is faked into
> opregion 2.1's relative offset.
> 
> Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
> Signed-off-by: Swee Yee Fonn <swee.yee.fonn@intel.com>
> Signed-off-by: Fred Gao <fred.gao@intel.com>
> ---
>  drivers/vfio/pci/vfio_pci_igd.c | 44 +++++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_igd.c b/drivers/vfio/pci/vfio_pci_igd.c
> index 53d97f459252..78919a289914 100644
> --- a/drivers/vfio/pci/vfio_pci_igd.c
> +++ b/drivers/vfio/pci/vfio_pci_igd.c
> @@ -21,6 +21,17 @@
>  #define OPREGION_SIZE		(8 * 1024)
>  #define OPREGION_PCI_ADDR	0xfc
>  
> +/*
> + * opregion 2.0: rvda is the physical VBT address.

What's rvda?  What's VBT?

> + *
> + * opregion 2.1+: rvda is unsigned, relative offset from
> + * opregion base, and should never point within opregion.
> + */
> +#define OPREGION_RDVA		0x3ba
> +#define OPREGION_RDVS		0x3c2
> +#define OPREGION_VERSION	22

Why is this specified as decimal and the others in hex?  This makes it
seem like the actual version rather than the offset of a version
register.

> +
> +
>  static size_t vfio_pci_igd_rw(struct vfio_pci_device *vdev, char __user *buf,
>  			      size_t count, loff_t *ppos, bool iswrite)
>  {
> @@ -58,6 +69,7 @@ static int vfio_pci_igd_opregion_init(struct vfio_pci_device *vdev)
>  	u32 addr, size;
>  	void *base;
>  	int ret;
> +	u16 version;
>  
>  	ret = pci_read_config_dword(vdev->pdev, OPREGION_PCI_ADDR, &addr);
>  	if (ret)
> @@ -83,6 +95,38 @@ static int vfio_pci_igd_opregion_init(struct vfio_pci_device *vdev)
>  
>  	size *= 1024; /* In KB */
>  
> +	/* Support opregion v2.0+ */
> +	version = le16_to_cpu(*(__le16 *)(base + OPREGION_VERSION));
> +	if (version >= 0x0200) {
> +		u64 rvda;
> +		u32 rvds;
> +
> +		rvda = le64_to_cpu(*(__le64 *)(base + OPREGION_RDVA));
> +		rvds = le32_to_cpu(*(__le32 *)(base + OPREGION_RDVS));
> +		if (rvda && rvds) {
> +			u32 offset;
> +
> +			if (version == 0x0200)
> +				offset = (rvda - (u64)addr);

Unnecessary outer ()

> +			else
> +				offset = rvda;
> +
> +			pci_WARN(vdev->pdev, offset != size,
> +				"Extended VBT does not follow opregion !\n"
> +				"opregion version 0x%x:offset 0x%x\n", version, offset);
> +
> +			if (version == 0x0200) {
> +				/* opregion version v2.0 faked to v2.1 */
> +				*(__le16 *)(base + OPREGION_VERSION) =
> +					cpu_to_le16(0x0201);
> +				/* rvda faked to relative offset */
> +				(*(__le64 *)(base + OPREGION_RDVA)) =
> +					cpu_to_le64((rvda - (u64)addr));

We're writing to the OpRegion and affecting all future use of it, seems
dangerous.


> +			}
> +			size = offset + rvds;


We warn about VBT (whatever that is) not immediately following the
OpRegion, but then we go ahead and size the thing that we expose to
userspace to allow read access to everything between the OpRegion and
VBT??

> +		}
> +	}
> +
>  	if (size != OPREGION_SIZE) {
>  		memunmap(base);
>  		base = memremap(addr, size, MEMREMAP_WB);


  reply	other threads:[~2020-12-02 18:59 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-02 17:12 [PATCH v1] vfio/pci: Add support for opregion v2.0+ Fred Gao
2020-12-02 18:57 ` Alex Williamson [this message]
2020-12-03  9:21   ` Gao, Fred
2020-12-03 23:38     ` Alex Williamson
2021-01-18 12:38 ` [PATCH v2] " Fred Gao
2021-01-21 20:33   ` Alex Williamson
2021-02-02  5:09     ` Zhenyu Wang
2021-02-08 17:02   ` [PATCH v3] vfio/pci: Add support for opregion v2.1+ Fred Gao
2021-03-02 13:02     ` [PATCH v4] " Fred Gao
2021-03-19 19:26       ` Alex Williamson
2021-03-25  8:50         ` Gao, Fred
2021-03-25 17:09       ` [PATCH v5] " Fred Gao
2021-03-30  9:08         ` Zhenyu Wang
2021-04-06 19:37         ` Alex Williamson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201202115723.27df527b@w520.home \
    --to=alex.williamson@redhat.com \
    --cc=fred.gao@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=kvm@vger.kernel.org \
    --cc=swee.yee.fonn@intel.com \
    --cc=zhenyuw@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).