Re: [kvm-unit-tests PATCH v8 00/12] PCI bus support

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

 



On Fri, Oct 21, 2016 at 06:41:47PM +0200, Andrew Jones wrote:
> On Thu, Oct 20, 2016 at 03:10:19PM +0200, Alexander Gordeev wrote:
> > Hi Andrew et al,
> > 
> > This is 8th version of PCI support. The only noticeable change since v7
> > is no failure in case no requested memory type is found for a BAR.
> > 
> > Sources are avalable at:
> > https://github.com/a-gordeev/kvm-unit-tests.git pci-testdev-v7
>                                                               ^^ v8
> 
> I tested this with/without the attached patch and works for me.
> 
> Thanks,
> drew

> diff --git a/lib/pci-host-generic.c b/lib/pci-host-generic.c
> index 96f4b4b37d34e..04e9681190308 100644
> --- a/lib/pci-host-generic.c
> +++ b/lib/pci-host-generic.c
> @@ -165,20 +165,35 @@ static struct pci_host_bridge *pci_dt_probe(void)
>  	return host;
>  }
>  
> -static bool pci_alloc_resource(u64 *addr, u32 bar, u64 size)
> +static bool pci_alloc_resource(pcidevaddr_t dev, int bar_num, u64 *addr)
>  {
>  	struct pci_host_bridge *host = pci_host_bridge;
>  	struct pci_addr_space *as = &host->addr_space[0];
> -	u32 mask;
> -	int i;
> +	u32 mask, bar;
> +	u64 size;
> +	int type, i;

To correct this addon patch taking my own output-setting advice, here I
should have done

  *addr = ~0;

to make sure it's set before the first possible 'return false'


> +
> +	size = pci_bar_size(dev, bar_num);
> +	if (!size)
> +		return false;
> +
> +	bar = pci_bar_get(dev, bar_num);
> +	type = pci_bar_type(bar);
> +	if (type & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
> +		type &= ~PCI_BASE_ADDRESS_MEM_PREFETCH;
>  
>  	for (i = 0; i < host->nr_addr_spaces; i++) {
> -		if (as->type == pci_bar_type(bar))
> +		if (as->type == type)
>  			break;
>  		as++;
>  	}
>  	if (i >= host->nr_addr_spaces) {
> -		printf("No PCI resource matching a device found\n");
> +		printf("%s: warning: can't satisfy request for ", __func__);
> +		pci_dev_print_id(dev);
> +		printf(" ");
> +		pci_bar_print(dev, bar_num);
> +		printf("\n");
> +		*addr = 0;

and the *addr = 0 here should be removed.

>  		return false;
>  	}
>  
> @@ -216,15 +231,9 @@ bool pci_probe(void)
>  		cmd = PCI_COMMAND_SERR;
>  
>  		for (i = 0; i < 6; i++) {
> -			u64 addr, size;
> -			u32 bar;
> +			u64 addr;
>  
> -			size = pci_bar_size(dev, i);
> -			if (!size)
> -				continue;
> -
> -			bar = pci_bar_get(dev, i);
> -			if (pci_alloc_resource(&addr, bar, size)) {
> +			if (pci_alloc_resource(dev, i, &addr)) {
>  				pci_bar_set_addr(dev, i, addr);
>  
>  				if (pci_bar_is_memory(dev, i))
> diff --git a/lib/pci.c b/lib/pci.c
> index 2dbbba4281442..6bd54cbac1bbd 100644
> --- a/lib/pci.c
> +++ b/lib/pci.c
> @@ -127,53 +127,31 @@ bool pci_bar_is64(pcidevaddr_t dev, int bar_num)
>  		      PCI_BASE_ADDRESS_MEM_TYPE_64;
>  }
>  
> -static void pci_dev_print(pcidevaddr_t dev)
> +void pci_bar_print(pcidevaddr_t dev, int bar_num)
>  {
> -	uint16_t vendor_id = pci_config_readw(dev, PCI_VENDOR_ID);
> -	uint16_t device_id = pci_config_readw(dev, PCI_DEVICE_ID);
> -	uint8_t header = pci_config_readb(dev, PCI_HEADER_TYPE);
> -	uint8_t progif = pci_config_readb(dev, PCI_CLASS_PROG);
> -	uint8_t subclass = pci_config_readb(dev, PCI_CLASS_DEVICE);
> -	uint8_t class = pci_config_readb(dev, PCI_CLASS_DEVICE + 1);
> -	int i;
> +	phys_addr_t size, start, end;
> +	uint32_t bar;
>  
> -	printf("dev %2d fn %d vendor_id %04x device_id %04x type %02x "
> -	       "progif %02x class %02x subclass %02x\n",
> -	       dev / 8, dev % 8, vendor_id, device_id, header,
> -	       progif, class, subclass);
> -
> -	if ((header & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_NORMAL)
> +	size = pci_bar_size(dev, bar_num);
> +	if (!size)
>  		return;
>  
> -	for (i = 0; i < 6; i++) {
> -		phys_addr_t size, start, end;
> -		uint32_t bar;
> -
> -		size = pci_bar_size(dev, i);
> -		if (!size)
> -			continue;
> -
> -		start = pci_bar_get_addr(dev, i);
> -		end = start + size - 1;
> -
> -		if (pci_bar_is64(dev, i)) {
> -			printf("\tBAR#%d,%d [%" PRIx64 "-%" PRIx64 " ",
> -			       i, i + 1, start, end);
> -			i++;
> -		} else {
> -			printf("\tBAR#%d    [%02x-%02x ",
> -			       i, (uint32_t)start, (uint32_t)end);
> -		}
> -
> -		bar = pci_bar_get(dev, i);
> -
> -		if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
> -			printf("PIO]\n");
> -			continue;
> -		}
> -
> +	bar = pci_bar_get(dev, bar_num);
> +	start = pci_bar_get_addr(dev, bar_num);
> +	end = start + size - 1;
> +
> +	if (pci_bar_is64(dev, bar_num)) {
> +		printf("BAR#%d,%d [%" PRIx64 "-%" PRIx64 " ",
> +		       bar_num, bar_num + 1, start, end);
> +	} else {
> +		printf("BAR#%d [%02x-%02x ",
> +		       bar_num, (uint32_t)start, (uint32_t)end);
> +	}
> +
> +	if (bar & PCI_BASE_ADDRESS_SPACE_IO) {
> +		printf("PIO");
> +	} else {
>  		printf("MEM");
> -
>  		switch (bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {
>  		case PCI_BASE_ADDRESS_MEM_TYPE_32:
>  			printf("32");
> @@ -187,11 +165,44 @@ static void pci_dev_print(pcidevaddr_t dev)
>  		default:
>  			assert(0);
>  		}
> +	}
>  
> -		if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH)
> -			printf("/p");
> +	if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH)
> +		printf("/p");
>  
> -		printf("]\n");
> +	printf("]");
> +}
> +
> +void pci_dev_print_id(pcidevaddr_t dev)
> +{
> +	printf("00.%02x.%1x %04x:%04x", dev / 8, dev % 8,
> +		pci_config_readw(dev, PCI_VENDOR_ID),
> +		pci_config_readw(dev, PCI_DEVICE_ID));
> +}
> +
> +static void pci_dev_print(pcidevaddr_t dev)
> +{
> +	uint8_t header = pci_config_readb(dev, PCI_HEADER_TYPE);
> +	uint8_t progif = pci_config_readb(dev, PCI_CLASS_PROG);
> +	uint8_t subclass = pci_config_readb(dev, PCI_CLASS_DEVICE);
> +	uint8_t class = pci_config_readb(dev, PCI_CLASS_DEVICE + 1);
> +	int i;
> +
> +	pci_dev_print_id(dev);
> +	printf(" type %02x progif %02x class %02x subclass %02x\n",
> +	       header, progif, class, subclass);
> +
> +	if ((header & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_NORMAL)
> +		return;
> +
> +	for (i = 0; i < 6; i++) {
> +		if (pci_bar_size(dev, i)) {
> +			printf("\t");
> +			pci_bar_print(dev, i);
> +			printf("\n");
> +		}
> +		if (pci_bar_is64(dev, i))
> +			i++;
>  	}
>  }
>  
> diff --git a/lib/pci.h b/lib/pci.h
> index 40e11a892783c..30f5381106108 100644
> --- a/lib/pci.h
> +++ b/lib/pci.h
> @@ -40,6 +40,8 @@ extern uint32_t pci_bar_mask(uint32_t bar);
>  extern bool pci_bar_is64(pcidevaddr_t dev, int bar_num);
>  extern bool pci_bar_is_memory(pcidevaddr_t dev, int bar_num);
>  extern bool pci_bar_is_valid(pcidevaddr_t dev, int bar_num);
> +extern void pci_bar_print(pcidevaddr_t dev, int bar_num);
> +extern void pci_dev_print_id(pcidevaddr_t dev);
>  
>  int pci_testdev(void);
>  

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux