All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Beulich <jbeulich@suse.com>
To: Oleksandr Andrushchenko <Oleksandr_Andrushchenko@epam.com>,
	Oleksandr Andrushchenko <andr2000@gmail.com>
Cc: "julien@xen.org" <julien@xen.org>,
	"sstabellini@kernel.org" <sstabellini@kernel.org>,
	Oleksandr Tyshchenko <Oleksandr_Tyshchenko@epam.com>,
	Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>,
	Artem Mygaiev <Artem_Mygaiev@epam.com>,
	"roger.pau@citrix.com" <roger.pau@citrix.com>,
	Bertrand Marquis <bertrand.marquis@arm.com>,
	Rahul Singh <rahul.singh@arm.com>,
	"xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>
Subject: Re: [PATCH 5/9] vpci/header: Implement guest BAR register handlers
Date: Tue, 7 Sep 2021 18:30:51 +0200	[thread overview]
Message-ID: <2e0c2ff5-7228-a439-c8a6-50f7a022e77b@suse.com> (raw)
In-Reply-To: <eda075b5-eafd-2367-2f1e-7f6b9730beb0@epam.com>

On 07.09.2021 15:33, Oleksandr Andrushchenko wrote:
> On 06.09.21 17:31, Jan Beulich wrote:
>> On 03.09.2021 12:08, Oleksandr Andrushchenko wrote:
>>> --- a/xen/drivers/vpci/header.c
>>> +++ b/xen/drivers/vpci/header.c
>>> @@ -400,12 +400,72 @@ static void bar_write(const struct pci_dev *pdev, unsigned int reg,
>>>   static void guest_bar_write(const struct pci_dev *pdev, unsigned int reg,
>>>                               uint32_t val, void *data)
>>>   {
>>> +    struct vpci_bar *bar = data;
>>> +    bool hi = false;
>>> +
>>> +    if ( bar->type == VPCI_BAR_MEM64_HI )
>>> +    {
>>> +        ASSERT(reg > PCI_BASE_ADDRESS_0);
>>> +        bar--;
>>> +        hi = true;
>>> +    }
>>> +    else
>>> +        val &= PCI_BASE_ADDRESS_MEM_MASK;
>>> +    bar->guest_addr &= ~(0xffffffffull << (hi ? 32 : 0));
>>> +    bar->guest_addr |= (uint64_t)val << (hi ? 32 : 0);
>> What you store here is not the address that's going to be used,
> 
> bar->guest_addr is never used directly to be reported to a guest.

And this is what I question, as an approach. Your model _may_ work,
but its needlessly deviating from how people like me would expect
this to work. And if it's intended to be this way, how would I
have known?

> It is always used as an initial value which is then modified to reflect
> lower bits, e.g. BAR type and if prefetchable, so I think this is perfectly
> fine to have it this way.

And it is also perfectly fine to store the value to be handed
back to guests on the next read. Keeps the read path simple,
which I think can be assumed to be taken more frequently than
the write one. Plus stored values reflect reality.

Plus - if what you say was really the case, why do you mask off
PCI_BASE_ADDRESS_MEM_MASK here? You should then simply store
the written value and do _all_ the processing in the read path.
No point having partial logic in two places.

>>   as
>> you don't mask off the low bits (to account for the BAR's size).
>> When a BAR gets written with all ones, all writable bits get these
>> ones stored. The address of the BAR, aiui, really changes to
>> (typically) close below 4Gb (in the case of a 32-bit BAR), which
>> is why memory / I/O decoding should be off while sizing BARs.
>> Therefore you shouldn't look for the specific "all writable bits
>> are ones" pattern (or worse, as you presently do, the "all bits
>> outside of the type specifier are ones" one) on the read path.
>> Instead mask the value appropriately here, and simply return back
>> the stored value from the read path.
> "PCI LOCAL BUS SPECIFICATION, REV. 3.0", "IMPLEMENTATION NOTE
> 
> Sizing a 32-bit Base Address Register Example" says, that
> 
> "Software saves the original value of the Base Address register, writes
> 0 FFFF FFFFh to the register, then reads it back."
> 
> The same applies for 64-bit BARs. So what's wrong if I try to catch such
> a write when a guest tries to size the BAR? The only difference is that
> I compare as
>          if ( (val & PCI_BASE_ADDRESS_MEM_MASK_32) == PCI_BASE_ADDRESS_MEM_MASK_32 )
> which is because val in the question has lower bits cleared.

Because while this matches what the spec says, it's not enough to
match how hardware behaves. Yet you want to mimic hardware behavior
as closely as possible here. There is (iirc) at least one other
place in the source tree were we had to adjust a similar initial
implementation to be closer to one expected by guests, no matter
that they may not be following the spec to the letter. Don't
forget that there may be bugs in kernels which don't surface until
the kernel gets run on an overly simplistic emulation.

>>> @@ -522,6 +582,13 @@ static int add_bar_handlers(struct pci_dev *pdev, bool is_hwdom)
>>>               if ( rc )
>>>                   return rc;
>>>           }
>>> +        /*
>>> +         * It is neither safe nor secure to initialize guest's view of the BARs
>>> +         * with real values which are used by the hardware domain, so assign
>>> +         * all zeros to guest's view of the BARs, so the guest can perform
>>> +         * proper PCI device enumeration and assign BARs on its own.
>>> +         */
>>> +        bars[i].guest_addr = 0;
>> I'm afraid I don't understand the comment: Without memory decoding
>> enabled, the BARs are simple registers (with a few r/o bits).
> 
> My first implementation was that bar->guest_addr was initialized with
> the value of bar->addr (physical BAR value), but talking on IRC with
> Roger he suggested that this might be a security issue to let guest
> a hint about physical values, so then I changed the assignment to be 0.

Well, yes, that's certainly correct. It's perhaps too unobvious to me
why one may want to use the host value here in the first place. It
simply has no meaning here.

>>> --- a/xen/include/xen/pci_regs.h
>>> +++ b/xen/include/xen/pci_regs.h
>>> @@ -103,6 +103,7 @@
>>>   #define  PCI_BASE_ADDRESS_MEM_TYPE_64	0x04	/* 64 bit address */
>>>   #define  PCI_BASE_ADDRESS_MEM_PREFETCH	0x08	/* prefetchable? */
>>>   #define  PCI_BASE_ADDRESS_MEM_MASK	(~0x0fUL)
>>> +#define  PCI_BASE_ADDRESS_MEM_MASK_32	(~0x0fU)
>> Please don't introduce an identical constant that's merely of
>> different type. (uint32_t)PCI_BASE_ADDRESS_MEM_MASK at the use
>> site (if actually still needed as per the comment above) would
>> seem more clear to me.
> Ok, I thought type casting is a bigger evil here

Often it is, but imo here it is not. I hope you realize that ~0x0fU
if not necessarily 0xfffffff0? We make certain assumptions on type
widths. For unsigned int we assume it to be at least 32 bits wide.
We should avoid assumptions of it being exactly 32 bits wide. Just
like we cannot (more obviously) assume the width of unsigned long.
(Which tells us that for 32-bit arches PCI_BASE_ADDRESS_MEM_MASK is
actually of the wrong type. This constant should be the same no
matter the bitness.)

Jan



  reply	other threads:[~2021-09-07 16:31 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-03 10:08 [PATCH 0/9] PCI devices passthrough on Arm, part 3 Oleksandr Andrushchenko
2021-09-03 10:08 ` [PATCH 1/9] vpci: Make vpci registers removal a dedicated function Oleksandr Andrushchenko
2021-09-03 10:08 ` [PATCH 2/9] vpci: Add hooks for PCI device assign/de-assign Oleksandr Andrushchenko
2021-09-06 13:23   ` Jan Beulich
2021-09-07  8:33     ` Oleksandr Andrushchenko
2021-09-07  8:44       ` Jan Beulich
2021-09-03 10:08 ` [PATCH 3/9] vpci/header: Move register assignments from init_bars Oleksandr Andrushchenko
2021-09-06 13:53   ` Jan Beulich
2021-09-07 10:04     ` Oleksandr Andrushchenko
2021-09-03 10:08 ` [PATCH 4/9] vpci/header: Add and remove register handlers dynamically Oleksandr Andrushchenko
2021-09-06 14:11   ` Jan Beulich
2021-09-07 10:11     ` Oleksandr Andrushchenko
2021-09-07 10:43       ` Jan Beulich
2021-09-07 11:10         ` Oleksandr Andrushchenko
2021-09-07 11:49           ` Jan Beulich
2021-09-07 12:16             ` Oleksandr Andrushchenko
2021-09-07 12:20               ` Jan Beulich
2021-09-07 12:23                 ` Oleksandr Andrushchenko
2021-09-10 21:14   ` Stefano Stabellini
2021-09-03 10:08 ` [PATCH 5/9] vpci/header: Implement guest BAR register handlers Oleksandr Andrushchenko
2021-09-06 14:31   ` Jan Beulich
2021-09-07 13:33     ` Oleksandr Andrushchenko
2021-09-07 16:30       ` Jan Beulich [this message]
2021-09-07 17:39         ` Oleksandr Andrushchenko
2021-09-08  9:27           ` Jan Beulich
2021-09-08  9:43             ` Oleksandr Andrushchenko
2021-09-08 10:03               ` Jan Beulich
2021-09-08 13:33                 ` Oleksandr Andrushchenko
2021-09-08 14:46                   ` Jan Beulich
2021-09-08 15:14                     ` Oleksandr Andrushchenko
2021-09-08 15:29                       ` Jan Beulich
2021-09-08 15:35                         ` Oleksandr Andrushchenko
2021-09-03 10:08 ` [PATCH 6/9] vpci/header: Handle p2m range sets per BAR Oleksandr Andrushchenko
2021-09-06 14:47   ` Jan Beulich
2021-09-08 14:31     ` Oleksandr Andrushchenko
2021-09-08 15:00       ` Jan Beulich
2021-09-09  5:22         ` Oleksandr Andrushchenko
2021-09-09  8:24           ` Jan Beulich
2021-09-09  9:12             ` Oleksandr Andrushchenko
2021-09-09  9:39               ` Jan Beulich
2021-09-09 10:03                 ` Oleksandr Andrushchenko
2021-09-09 10:46                   ` Jan Beulich
2021-09-09 11:30                     ` Oleksandr Andrushchenko
2021-09-09 11:51                       ` Jan Beulich
2021-09-03 10:08 ` [PATCH 7/9] vpci/header: program p2m with guest BAR view Oleksandr Andrushchenko
2021-09-06 14:51   ` Jan Beulich
2021-09-09  6:13     ` Oleksandr Andrushchenko
2021-09-09  8:26       ` Jan Beulich
2021-09-09  9:16         ` Oleksandr Andrushchenko
2021-09-09  9:40           ` Jan Beulich
2021-09-09  9:53             ` Oleksandr Andrushchenko
2021-09-03 10:08 ` [PATCH 8/9] vpci/header: Reset the command register when adding devices Oleksandr Andrushchenko
2021-09-06 14:55   ` Jan Beulich
2021-09-07  7:43     ` Oleksandr Andrushchenko
2021-09-07  8:00       ` Jan Beulich
2021-09-07  8:18         ` Oleksandr Andrushchenko
2021-09-07  8:49           ` Jan Beulich
2021-09-07  9:07             ` Oleksandr Andrushchenko
2021-09-07  9:19               ` Jan Beulich
2021-09-07  9:52                 ` Oleksandr Andrushchenko
2021-09-07 10:06                   ` Jan Beulich
2021-09-09  8:39                     ` Oleksandr Andrushchenko
2021-09-09  8:43                       ` Jan Beulich
2021-09-09  8:50                         ` Oleksandr Andrushchenko
2021-09-09  9:21                           ` Jan Beulich
2021-09-09 11:48                             ` Oleksandr Andrushchenko
2021-09-09 11:53                               ` Jan Beulich
2021-09-09 12:42                                 ` Oleksandr Andrushchenko
2021-09-09 12:47                                   ` Jan Beulich
2021-09-09 12:48                                     ` Oleksandr Andrushchenko
2021-09-09 13:17                                     ` Oleksandr Andrushchenko
2021-09-09 11:48                             ` Oleksandr Andrushchenko
2021-09-03 10:08 ` [PATCH 9/9] vpci/header: Use pdev's domain instead of vCPU Oleksandr Andrushchenko
2021-09-06 14:57   ` Jan Beulich
2021-09-09  4:23     ` Oleksandr Andrushchenko

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=2e0c2ff5-7228-a439-c8a6-50f7a022e77b@suse.com \
    --to=jbeulich@suse.com \
    --cc=Artem_Mygaiev@epam.com \
    --cc=Oleksandr_Andrushchenko@epam.com \
    --cc=Oleksandr_Tyshchenko@epam.com \
    --cc=Volodymyr_Babchuk@epam.com \
    --cc=andr2000@gmail.com \
    --cc=bertrand.marquis@arm.com \
    --cc=julien@xen.org \
    --cc=rahul.singh@arm.com \
    --cc=roger.pau@citrix.com \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.