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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Michael S. Tsirkin
						Michael S. Tsirkin