msix: track function masked in pci device state
Only go over the table when function is masked. This is not really important for qemu.git but helps fix a bug in qemu-kvm.git. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
		
							parent
							
								
									2923d34fdc
								
							
						
					
					
						commit
						50322249fd
					
				
							
								
								
									
										21
									
								
								hw/msix.c
								
								
								
								
							
							
						
						
									
										21
									
								
								hw/msix.c
								
								
								
								
							| 
						 | 
				
			
			@ -79,6 +79,7 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
 | 
			
		|||
    /* Make flags bit writable. */
 | 
			
		||||
    pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |
 | 
			
		||||
	    MSIX_MASKALL_MASK;
 | 
			
		||||
    pdev->msix_function_masked = true;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -117,16 +118,11 @@ static void msix_clr_pending(PCIDevice *dev, int vector)
 | 
			
		|||
    *msix_pending_byte(dev, vector) &= ~msix_pending_mask(vector);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int msix_function_masked(PCIDevice *dev)
 | 
			
		||||
{
 | 
			
		||||
    return dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int msix_is_masked(PCIDevice *dev, int vector)
 | 
			
		||||
{
 | 
			
		||||
    unsigned offset =
 | 
			
		||||
        vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
 | 
			
		||||
    return msix_function_masked(dev) ||
 | 
			
		||||
    return dev->msix_function_masked ||
 | 
			
		||||
	   dev->msix_table_page[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -138,24 +134,34 @@ static void msix_handle_mask_update(PCIDevice *dev, int vector)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void msix_update_function_masked(PCIDevice *dev)
 | 
			
		||||
{
 | 
			
		||||
    dev->msix_function_masked = !msix_enabled(dev) ||
 | 
			
		||||
        (dev->config[dev->msix_cap + MSIX_CONTROL_OFFSET] & MSIX_MASKALL_MASK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Handle MSI-X capability config write. */
 | 
			
		||||
void msix_write_config(PCIDevice *dev, uint32_t addr,
 | 
			
		||||
                       uint32_t val, int len)
 | 
			
		||||
{
 | 
			
		||||
    unsigned enable_pos = dev->msix_cap + MSIX_CONTROL_OFFSET;
 | 
			
		||||
    int vector;
 | 
			
		||||
    bool was_masked;
 | 
			
		||||
 | 
			
		||||
    if (!range_covers_byte(addr, len, enable_pos)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    was_masked = dev->msix_function_masked;
 | 
			
		||||
    msix_update_function_masked(dev);
 | 
			
		||||
 | 
			
		||||
    if (!msix_enabled(dev)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pci_device_deassert_intx(dev);
 | 
			
		||||
 | 
			
		||||
    if (msix_function_masked(dev)) {
 | 
			
		||||
    if (dev->msix_function_masked == was_masked) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -300,6 +306,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
 | 
			
		|||
    msix_free_irq_entries(dev);
 | 
			
		||||
    qemu_get_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
 | 
			
		||||
    qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
 | 
			
		||||
    msix_update_function_masked(dev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Does device support MSI-X? */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue