[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v5 4/5] xen/vpci: header: status register handler
On 07.09.2023 23:29, Stewart Hildebrand wrote: > On 9/6/23 04:22, Jan Beulich wrote: >> On 01.09.2023 06:57, Stewart Hildebrand wrote: >>> Introduce a handler for the PCI status register, with ability to mask the >>> capabilities bit. The status register contains reserved bits, read-only >>> bits, >>> and write-1-to-clear bits, so introduce bitmasks to handle these in vPCI. >>> If a >>> bit in the bitmask is set, then the special meaning applies: >>> >>> res_mask: read as zero, write ignore >>> ro_mask: read normal, write ignore >>> rw1c_mask: read normal, write 1 to clear >> >> With the last one's name being descriptive of what the behavior is, would >> it make sense to name the first one "raz_mask"? (Also a question to Roger >> as the maintainer of this code.) > > Another possible name is rsvdz_mask. See below. Ah, yes, that's better even if for now we won't need rsvdp support. >>> --- a/xen/drivers/vpci/header.c >>> +++ b/xen/drivers/vpci/header.c >>> @@ -413,6 +413,18 @@ static void cf_check cmd_write( >>> pci_conf_write16(pdev->sbdf, reg, cmd); >>> } >>> >>> +static uint32_t cf_check status_read(const struct pci_dev *pdev, >>> + unsigned int reg, void *data) >>> +{ >>> + struct vpci_header *header = data; >>> + uint32_t status = pci_conf_read16(pdev->sbdf, reg); >>> + >>> + if ( header->mask_cap_list ) >>> + status &= ~PCI_STATUS_CAP_LIST; >>> + >>> + return status; >>> +} >> >> Do you actually need this function? Can't you ... >> >>> @@ -544,6 +556,12 @@ static int cf_check init_bars(struct pci_dev *pdev) >>> if ( rc ) >>> return rc; >>> >>> + rc = vpci_add_register_mask(pdev->vpci, status_read, vpci_hw_write16, >>> + PCI_STATUS, 2, header, >>> PCI_STATUS_RESERVED_MASK, >>> + PCI_STATUS_RO_MASK, PCI_STATUS_RW1C_MASK); >> >> ... conditionally OR in PCI_STATUS_CAP_LIST right here? Without >> capabilities the CAP_LIST bit becomes kind of reserved anyway. > > Hm. The PCI_STATUS_CAP_LIST bit is a read-only bit according to spec. Given > the rationale below, we would want to preserve the value of r/o bits during > writes, so this would essentially want to become a RsvdP bit. I wasn't > planning on adding support for RsvdP bits here since there aren't any proper > RsvdP bits in the status register. If instead we are okay with treating the > PCI_STATUS_CAP_LIST bit as RsvdZ, then we could do as you suggest, but I'll > plan to keep it as is for now. I'd say leverage rsvdz (with a comment) for the time being, but let's see what Roger thinks. >>> @@ -424,9 +450,13 @@ static void vpci_write_helper(const struct pci_dev >>> *pdev, >>> uint32_t val; >>> >>> val = r->read(pdev, r->offset, r->private); >>> + val &= ~r->res_mask; >>> + val &= ~r->rw1c_mask; >> >> Personally I'd fold these two lines into just one (and similarly below). > > Will do. > >>> data = merge_result(val, data, size, offset); >>> } >>> >>> + data &= ~r->res_mask; >>> + data &= ~r->ro_mask; >> >> This seems risky to me. I'd rather see the same value being written back >> for r/o bits, just in case a device doesn't actually implement a bit as >> mandated. > > Regarding writes to read-only bits: okay, I'll assume that Xen should take > care of preserving the r/o bits (discarding the guests write value for the > r/o bits). > > If, on the other hand, we would want to rely on the guest to preserve the r/o > bits during a write, then the ro_mask would effectively not be doing > anything, so may as well be removed. We may never rely on the guest doing anything the way we want it. > In either case, for partial register writes, Xen will take care of preserving > the r/o bits for the remaining bytes in the register. > > I'll make this change for the next version of the series (assuming Xen will > handle preserving the r/o bits). > >> For reserved flags it's less clear what's best, because in >> principle they could also become rw1c once defined. > > Well, it depends on what version of the spec we read. > > PCI Local Bus 3.0 spec section 6.1 says: "On writes, software must ensure > that the values of reserved bit positions are preserved." PCI Local Bus 3.0 > spec section 6.2.3 also says that we can essentially treat the whole status > register as rw1c. Huh, that's odd. > > PCI Express Base 4.0 spec defines two reserved bit types: > RsvdP: Reserved and Preserved - Reserved for future RW implementations. > Software must preserve the value read for writes to bits. > RsvdZ: Reserved and Zero - Reserved for future RW1C implementations. Software > must use 0b for writes to bits. > Both RsvdP and RsvdZ are read as zero. > > I'm favoring using the definitions in the newer PCI Express Base 4.0 spec > since they are clearer. +1 > Regarding writes to rsvdp bits: there are none of these in the status > register according to the PCI Express Base 4.0 spec. The older PCI Local Bus > 3.0 spec is in conflict with this definition, but at the same time the PCI > Local Bus 3.0 spec also conflicts with itself by saying that the entire > status register is essentially a rw1c register with reserved bits that should > be preserved, which doesn't make sense. The newer PCI Express Base 4.0 spec > is clearer, and appears to have resolved this inconsistency, so I'm favoring > adhering to the newer PCI Express Base 4.0 spec. > > Regarding writes to rsvdz bits: in this case Xen will write zero to the rsvdz > bits (discarding the guests write value). This is how the patch already > behaves with the res_mask, but I think renaming it to rsvdz_mask will make it > more clear, so I'm inclined to rename it for the next revision of the series. > > Regarding reads of rsvdp/rsvdz bits: I'm assuming that Xen should return zero > to the guest for reads of reserved bits, regardless of what is actually read > from the hardware. I think we already are already on the same page about > this, I just wanted to explicitly state it for clarity. Yes, we are. Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |