MSI-X mask support for assigned device on userspace
cover MSI-X mask support for assigned device on userspace
Sheng Yang (5):
qemu-kvm: Add kvm_enable_cap() interface for x86
qemu-kvm: Ioctl for in-kernel mask support
qemu-kvm: device assignment: Some clean up about MSI-X code
qemu-kvm: device assignment: emulate MSI-X mask bits
qemu-kvm: device assignment: Enable in-kernel MSI-X mask support
hw/device-assignment.c | 239 ++++++++++++++++++++++++++++++++++++++++++------ qemu-kvm.c | 25 +++++ qemu-kvm.h | 12 +++ 3 files changed, 246 insertions(+), 30 deletions(-)
PATCH 1/5 qemu-kvm: Add kvm_enable_cap() interface for x86
--- qemu-kvm.c | 16 ++++++++++++++++ qemu-kvm.h | 8 ++++++++ 2 files changed, 24 insertions(+), 0 deletions(-)
qemu-kvm.c +16 -0
@@ -540,6 +540,22 @@ int kvm_set_xcrs(CPUState *env, struct kvm_xcrs *xcrs) }#endif +#ifdef KVM_CAP_ENABLE_CAP +int kvm_enable_cap (CPUState *env,uint32_t cap) +{ +int r =0 ; +struct kvm_enable_cap enable_cap = { + .cap = cap, + .flags =0 , + }; + + r =kvm_ioctl (kvm_state,KVM_CHECK_EXTENSION ,KVM_CAP_ENABLE_CAP ); +if (r >0 ) + r =kvm_vcpu_ioctl (env,KVM_ENABLE_CAP , &enable_cap); +return r; +} +#endif +static int handle_mmio (CPUState *env) {unsigned long addr = env->kvm_run->mmio.phys_addr;
qemu-kvm.h +8 -0
@@ -316,6 +316,14 @@ int kvm_get_xcrs(CPUState *env, struct kvm_xcrs *xcrs);int kvm_set_xcrs (CPUState *env,struct kvm_xcrs *xcrs);#endif +#ifdef KVM_ENABLE_CAP +/*! +* * \brief Enable specific capability of KVM +* +*/ +int kvm_enable_cap (CPUState *env,uint32_t cap); +#endif +/*! * \brief Simulate an external vectored interrupt *
Signature · 1 line
1.7.0.1
PATCH 2/5 qemu-kvm: Ioctl for in-kernel mask support
In reply to Sheng Yang--- qemu-kvm.c | 9 +++++++++ qemu-kvm.h | 4 ++++ 2 files changed, 13 insertions(+), 0 deletions(-)
qemu-kvm.c +9 -0
@@ -1108,6 +1108,15 @@ int kvm_assign_set_msix_entry(kvm_context_t kvm, {return kvm_vm_ioctl (kvm_state,KVM_ASSIGN_SET_MSIX_ENTRY , entry); } + +#ifdef KVM_CAP_DEVICE_MSIX_MASK +int kvm_assign_reg_msix_mmio (kvm_context_t kvm, +struct kvm_assigned_msix_mmio *msix_mmio) +{ +return kvm_vm_ioctl (kvm_state,KVM_ASSIGN_REG_MSIX_MMIO , msix_mmio); +} +#endif +#endif #if defined(KVM_CAP_IRQFD ) && defined(CONFIG_EVENTFD )
qemu-kvm.h +4 -0
@@ -751,6 +751,10 @@ int kvm_assign_set_msix_nr(kvm_context_t kvm, struct kvm_assigned_msix_nr *msix_nr);int kvm_assign_set_msix_entry (kvm_context_t kvm,struct kvm_assigned_msix_entry *entry); +#ifdef KVM_CAP_DEVICE_MSIX_MASK +int kvm_assign_reg_msix_mmio (kvm_context_t kvm, +struct kvm_assigned_msix_mmio *msix_mmio); +#endif #endif #else /* !CONFIG_KVM */
Signature · 1 line
1.7.0.1
PATCH 3/5 qemu-kvm: device assignment: Some clean up about MSI-X code
In reply to Sheng Yang--- hw/device-assignment.c | 77 ++++++++++++++++++++++++++++++++--------------- 1 files changed, 52 insertions(+), 25 deletions(-)
hw/device-assignment.c +52 -25
@@ -1106,15 +1106,10 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev, unsigned int ctrl_pos)#endif #ifdef KVM_CAP_DEVICE_MSIX -static int assigned_dev_update_msix_mmio (PCIDevice *pci_dev) +static int get_msix_entries_max_nr (AssignedDevice *adev) { -AssignedDevice *adev =container_of (pci_dev, AssignedDevice, dev); -uint16_t entries_nr =0 , entries_max_nr; -int pos =0 , i, r =0 ; -uint32_t msg_addr, msg_upper_addr, msg_data, msg_ctrl; -struct kvm_assigned_msix_nr msix_nr; -struct kvm_assigned_msix_entry msix_entry; -void *va = adev->msix_table_page; +int pos, entries_max_nr; +PCIDevice *pci_dev = &adev->dev;if (adev->cap.available &ASSIGNED_DEVICE_CAP_MSI ) pos = pci_dev->cap.start +PCI_CAPABILITY_CONFIG_MSI_LENGTH ;
@@ -1125,6 +1120,17 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) entries_max_nr &=PCI_MSIX_TABSIZE ; entries_max_nr +=1 ; +return entries_max_nr; +} + +static int get_msix_valid_entries_nr (AssignedDevice *adev, +uint16_t entries_max_nr) +{ +void *va = adev->msix_table_page; +uint32_t msg_data, msg_ctrl; +uint16_t entries_nr =0 ; +int i; +/* Get the usable entry number for allocating */ for (i =0 ; i < entries_max_nr; i++) {memcpy (&msg_ctrl, va + i *16 +12 ,4 );
@@ -1134,11 +1140,20 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)continue ; entries_nr ++; } +return entries_nr; +} + +static int assigned_dev_update_msix_mmio (PCIDevice *pci_dev, +uint16_t entries_nr, +uint16_t entries_max_nr) +{ +AssignedDevice *adev =container_of (pci_dev, AssignedDevice, dev); +int i, r =0 ; +uint32_t msg_addr, msg_upper_addr, msg_data, msg_ctrl; +struct kvm_assigned_msix_nr msix_nr; +struct kvm_assigned_msix_entry msix_entry; +void *va = adev->msix_table_page; -if (entries_nr ==0 ) { -fprintf (stderr,"MSI-X entry number is zero!\n" ); -return -EINVAL ; - } msix_nr.assigned_dev_id =calc_assigned_dev_id (adev->h_segnr, adev->h_busnr, (uint8_t )adev->h_devfn); msix_nr.entry_nr = entries_nr;
@@ -1180,8 +1195,8 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev) adev->entry[entries_nr].u.msi.address_lo = msg_addr; adev->entry[entries_nr].u.msi.address_hi = msg_upper_addr; adev->entry[entries_nr].u.msi.data = msg_data; -DEBUG ("MSI-X data 0x%x, MSI-X addr_lo 0x%x\n!" , msg_data, msg_addr); -kvm_add_routing_entry (&adev->entry[entries_nr]); +DEBUG ("MSI-X data 0x%x, MSI-X addr_lo 0x%x!\n" , msg_data, msg_addr); +kvm_add_routing_entry (&adev->entry[entries_nr]); msix_entry.gsi = adev->entry[entries_nr].gsi; msix_entry.entry = i;
@@ -1190,7 +1205,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)fprintf (stderr,"fail to set MSI-X entry! %s\n" ,strerror (-r));break ; } -DEBUG ("MSI-X entry gsi 0x%x, entry %d\n!" , +DEBUG ("MSI-X entry gsi 0x%x, entry %d!\n" , msix_entry.gsi, msix_entry.entry); entries_nr ++; }
@@ -1203,12 +1218,12 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)return r; } -static void assigned_dev_update_msix (PCIDevice *pci_dev,unsigned int ctrl_pos) +static void assigned_dev_update_msix (PCIDevice *pci_dev,int enable_msix) {struct kvm_assigned_irq assigned_irq_data;AssignedDevice *assigned_dev =container_of (pci_dev, AssignedDevice, dev); -uint16_t *ctrl_word = (uint16_t *)(pci_dev->config + ctrl_pos);int r; +uint16_t entries_nr, entries_max_nr;memset (&assigned_irq_data,0 ,sizeof assigned_irq_data); assigned_irq_data.assigned_dev_id =
@@ -1219,8 +1234,7 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev, unsigned int ctrl_pos)* try to catch this by only deassigning irqs if the guest is using * MSIX or intends to start. */ if ((assigned_dev->irq_requested_type &KVM_DEV_IRQ_GUEST_MSIX ) || - (*ctrl_word &PCI_MSIX_ENABLE )) { - + enable_msix) { assigned_irq_data.flags = assigned_dev->irq_requested_type;free_dev_irq_entries (assigned_dev); r =kvm_deassign_irq (kvm_context, &assigned_irq_data);
@@ -1231,14 +1245,25 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev, unsigned int ctrl_pos) assigned_dev->irq_requested_type =0 ; } -if (*ctrl_word &PCI_MSIX_ENABLE ) { - assigned_irq_data.flags =KVM_DEV_IRQ_HOST_MSIX | -KVM_DEV_IRQ_GUEST_MSIX ; - -if (assigned_dev_update_msix_mmio (pci_dev) <0 ) { + entries_max_nr =get_msix_entries_max_nr (assigned_dev); +if (entries_max_nr ==0 ) { +fprintf (stderr,"assigned_dev_update_msix: MSI-X entries_max_nr == 0" ); +return ; + } + entries_nr =get_msix_valid_entries_nr (assigned_dev, entries_max_nr); +if (entries_nr ==0 ) { +if (enable_msix) +fprintf (stderr,"MSI-X entry number is zero!\n" ); +return ; + } +if (enable_msix) { +if (assigned_dev_update_msix_mmio (pci_dev, + entries_nr, entries_max_nr) <0 ) {perror ("assigned_dev_update_msix_mmio" );return ; } + assigned_irq_data.flags =KVM_DEV_IRQ_HOST_MSIX | +KVM_DEV_IRQ_GUEST_MSIX ;if (kvm_assign_irq (kvm_context, &assigned_irq_data) <0 ) {perror ("assigned_dev_enable_msix: assign irq" );return ;
@@ -1254,6 +1279,7 @@ static void assigned_device_pci_cap_write_config(PCIDevice *pci_dev, uint32_t ad {AssignedDevice *assigned_dev =container_of (pci_dev, AssignedDevice, dev);unsigned int pos = pci_dev->cap.start, ctrl_pos; +uint16_t *ctrl_word;pci_default_cap_write_config (pci_dev, address, val, len);#ifdef KVM_CAP_IRQ_ROUTING
@@ -1270,7 +1296,8 @@ static void assigned_device_pci_cap_write_config(PCIDevice *pci_dev, uint32_t ad ctrl_pos = pos +3 ;if (address <= ctrl_pos && address + len > ctrl_pos) { ctrl_pos--;/* control is word long */ -assigned_dev_update_msix (pci_dev, ctrl_pos); + ctrl_word = (uint16_t *)(pci_dev->config + ctrl_pos); +assigned_dev_update_msix (pci_dev, (*ctrl_word &PCI_MSIX_ENABLE )); } pos +=PCI_CAPABILITY_CONFIG_MSIX_LENGTH ; }
Signature · 1 line
1.7.0.1
PATCH 4/5 qemu-kvm: device assignment: emulate MSI-X mask bits
In reply to Sheng YangThis patch emulated MSI-X per vector mask bit on assigned device.
--- hw/device-assignment.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 145 insertions(+), 6 deletions(-)
hw/device-assignment.c +145 -6
@@ -62,6 +62,11 @@ static void assigned_dev_load_option_rom(AssignedDevice *dev);static void assigned_dev_unregister_msix_mmio (AssignedDevice *dev); +static uint32_t calc_assigned_dev_id (uint16_t seg,uint8_t bus,uint8_t devfn) +{ +return (uint32_t )seg <<16 | (uint32_t )bus <<8 | (uint32_t )devfn; +} +static uint32_t assigned_dev_ioport_rw (AssignedDevRegion *dev_region,uint32_t addr,int len,uint32_t *val) {
@@ -824,11 +829,6 @@ static void free_assigned_device(AssignedDevice *dev) } } -static uint32_t calc_assigned_dev_id (uint16_t seg,uint8_t bus,uint8_t devfn) -{ -return (uint32_t )seg <<16 | (uint32_t )bus <<8 | (uint32_t )devfn; -} -static void assign_failed_examine (AssignedDevice *dev) {char name[PATH_MAX ], dir[PATH_MAX ], driver[PATH_MAX ] = {}, *ns;
@@ -1123,6 +1123,7 @@ static int get_msix_entries_max_nr(AssignedDevice *adev)return entries_max_nr; } +#define MSIX_VECTOR_MASK 0x1static int get_msix_valid_entries_nr (AssignedDevice *adev,uint16_t entries_max_nr) {
@@ -1136,7 +1137,11 @@ static int get_msix_valid_entries_nr(AssignedDevice *adev,memcpy (&msg_ctrl, va + i *16 +12 ,4 );memcpy (&msg_data, va + i *16 +8 ,4 );/* Ignore unused entry even it's unmasked */ +#ifdef KVM_CAP_DEVICE_MSIX_MASK +if (msg_data ==0 || (msg_ctrl &MSIX_VECTOR_MASK )) +#else if (msg_data == 0) +#endif continue ; entries_nr ++; }
@@ -1165,6 +1170,8 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev, }free_dev_irq_entries (adev); +memset (pci_dev->msix_entry_used,0 ,KVM_MAX_MSIX_PER_DEV * +sizeof (*pci_dev->msix_entry_used)); adev->irq_entries_nr = entries_nr; adev->entry =calloc (entries_nr,sizeof (struct kvm_irq_routing_entry ));if (!adev->entry) {
@@ -1179,7 +1186,11 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev,break ;memcpy (&msg_ctrl, va + i *16 +12 ,4 );memcpy (&msg_data, va + i *16 +8 ,4 ); +#ifdef KVM_CAP_DEVICE_MSIX_MASK +if (msg_data ==0 || (msg_ctrl &MSIX_VECTOR_MASK )) +#else if (msg_data == 0) +#endif continue ;memcpy (&msg_addr, va + i *16 ,4 );
@@ -1200,6 +1211,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev, msix_entry.gsi = adev->entry[entries_nr].gsi; msix_entry.entry = i; + pci_dev->msix_entry_used[i] =1 ; r =kvm_assign_set_msix_entry (kvm_context, &msix_entry);if (r) {fprintf (stderr,"fail to set MSI-X entry! %s\n" ,strerror (-r));
@@ -1243,6 +1255,8 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev, int enable_msix)perror ("assigned_dev_update_msix: deassign irq" ); assigned_dev->irq_requested_type =0 ; +memset (pci_dev->msix_entry_used,0 ,KVM_MAX_MSIX_PER_DEV * +sizeof (*pci_dev->msix_entry_used)); } entries_max_nr =get_msix_entries_max_nr (assigned_dev);
@@ -1250,10 +1264,16 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev, int enable_msix)fprintf (stderr,"assigned_dev_update_msix: MSI-X entries_max_nr == 0" );return ; } +/* +* Guest may try to enable MSI-X before setting MSI-X entry done, so +* let's wait until guest unmask the entries. +*/ entries_nr =get_msix_valid_entries_nr (assigned_dev, entries_max_nr);if (entries_nr ==0 ) { +#ifndef KVM_CAP_DEVICE_MSIX_MASK if (enable_msix)fprintf (stderr,"MSI-X entry number is zero!\n" ); +#endif return ; }if (enable_msix) {
@@ -1297,7 +1317,8 @@ static void assigned_device_pci_cap_write_config(PCIDevice *pci_dev, uint32_t adif (address <= ctrl_pos && address + len > ctrl_pos) { ctrl_pos--;/* control is word long */ ctrl_word = (uint16_t *)(pci_dev->config + ctrl_pos); -assigned_dev_update_msix (pci_dev, (*ctrl_word &PCI_MSIX_ENABLE )); +assigned_dev_update_msix (pci_dev, + (*ctrl_word &PCI_MSIX_ENABLE ) && !(*ctrl_word &PCI_MSIX_MASK )); } pos +=PCI_CAPABILITY_CONFIG_MSIX_LENGTH ; }
@@ -1389,6 +1410,104 @@ static uint32_t msix_mmio_readw(void *opaque, target_phys_addr_t addr) (8 * (addr & 3))) & 0xffff; } +#ifdef KVM_CAP_DEVICE_MSIX_MASK +static void msix_mmio_access_mask_bit (AssignedDevice *adev,int index) +{ +void *page = adev->msix_table_page; +uint32_t msg_ctrl, msg_data, msg_upper_addr, msg_addr; +struct kvm_assigned_msix_entry msix_entry; +int r =0 , pos, ctrl_word, entry_idx, entries_max_nr; +struct kvm_irq_routing_entry new_entry = {}; + +memcpy (&msg_addr, (char *)page + index *16 ,4 ); +memcpy (&msg_upper_addr, (char *)page + index *16 +4 ,4 ); +memcpy (&msg_data, (char *)page + index *16 +8 ,4 ); +memcpy (&msg_ctrl, (char *)page + index *16 +12 ,4 ); +DEBUG ("Access mask bit: MSI-X entries index %d: " +"msg_addr 0x%x, msg_upper_addr 0x%x, msg_data 0x%x, vec_ctl 0x%x\n" , + index, msg_addr, msg_upper_addr, msg_data, msg_ctrl); + +if (adev->cap.available &ASSIGNED_DEVICE_CAP_MSI ) + pos = adev->dev.cap.start +PCI_CAPABILITY_CONFIG_MSI_LENGTH ; +else + pos = adev->dev.cap.start; + + ctrl_word = *(uint16_t *)(adev->dev.config + pos +2 ); + +if (!((ctrl_word &PCI_MSIX_ENABLE ) && !(ctrl_word &PCI_MSIX_MASK ))) +return ; + +if (!adev->dev.msix_entry_used[index]) { +if ((msg_ctrl &MSIX_VECTOR_MASK ) ==0 ) { +DEBUG ("Try to modify unenabled MSI-X entry %d's mask. " +"Reenable MSI-X.\n" , + index); +assigned_dev_update_msix (&adev->dev,1 ); + } +return ; + } + +/* find the correlated index of adev->entry */ + entries_max_nr =get_msix_entries_max_nr (adev); + entry_idx =0 ; +while (entry_idx < entries_max_nr) { +if (adev->dev.msix_entry_used[entry_idx] && entry_idx == index) +break ; + entry_idx ++; + } +if (entry_idx >= entries_max_nr) { +fprintf (stderr,"msix_mmio_access_mask_bit: Entry idx exceed limit!\n" ); +return ; + } + + msix_entry.assigned_dev_id =calc_assigned_dev_id (adev->h_segnr, + adev->h_busnr, + (uint8_t )adev->h_devfn); + msix_entry.gsi = adev->entry[entry_idx].gsi; + msix_entry.entry = index; +if (msg_ctrl &MSIX_VECTOR_MASK ) + msix_entry.flags =KVM_MSIX_FLAG_MASK ; +else + msix_entry.flags =0 ; +DEBUG ("set MSI-X index %d, esi 0x%x, mask %d\n" , + index, msix_entry.gsi, msix_entry.flags); + r =kvm_assign_set_msix_entry (kvm_context, &msix_entry); +if (r) { +perror ("msix_mmio_access_mask_bit: " +"fail to set MSI-X entry!" ); +return ; + } + +if (msix_entry.flags ==0 ) { + new_entry.gsi = adev->entry[entry_idx].gsi; + new_entry.type =KVM_IRQ_ROUTING_MSI ; + new_entry.flags =0 ; + new_entry.u.msi.address_lo = msg_addr; + new_entry.u.msi.address_hi = msg_upper_addr; + new_entry.u.msi.data = msg_data; +if (memcmp (&adev->entry[entry_idx].u.msi, &new_entry.u.msi, +sizeof new_entry.u.msi)) { +int r; + r =kvm_update_routing_entry (&adev->entry[entry_idx], &new_entry); +if (r) { +perror ("msix_mmio_access_mask_bit: " +"kvm_update_routing_entry failed\n" ); +return ; + } + r =kvm_commit_irq_routes (); +if (r) { +perror ("msix_mmio_access_mask_bit: " +"kvm_commit_irq_routes failed\n" ); +return ; + } + } + adev->entry[entry_idx].u.msi.address_lo = msg_addr; + adev->entry[entry_idx].u.msi.address_hi = msg_upper_addr; + adev->entry[entry_idx].u.msi.data = msg_data; + } +} +#endif +static void msix_mmio_writel (void *opaque,target_phys_addr_t addr,uint32_t val) {
@@ -1399,6 +1518,12 @@ static void msix_mmio_writel(void *opaque,DEBUG ("write to MSI-X entry table mmio offset 0x%lx, val 0x%x\n" , addr, val);memcpy ((void *)((char *)page + offset), &val,4 ); + +#ifdef KVM_CAP_DEVICE_MSIX_MASK +/* Check if mask bit is being accessed */ +if (offset %16 ==12 ) +msix_mmio_access_mask_bit (adev, offset /16 ); +#endif } static void msix_mmio_writew(void *opaque,
@@ -1425,6 +1550,16 @@ static CPUReadMemoryFunc *msix_mmio_read[] = {static int assigned_dev_register_msix_mmio (AssignedDevice *dev) { +#ifdef KVM_CAP_DEVICE_MSIX_MASK +#ifndef KVM_CAP_DEVICE_MSIX_EXT +#error +#endif +/* Request for MSI-X masking support */ +if (kvm_enable_cap (first_cpu,KVM_CAP_DEVICE_MSIX_EXT ) !=0 ) { +fprintf (stderr,"fail to enable MSI-X extending support!\n" ); +return -EFAULT ; + } +#endif dev->msix_table_page =mmap (NULL ,0x1000 ,PROT_READ |PROT_WRITE ,MAP_ANONYMOUS |MAP_PRIVATE ,0 ,0 );
@@ -1436,6 +1571,8 @@ static int assigned_dev_register_msix_mmio(AssignedDevice *dev)memset (dev->msix_table_page,0 ,0x1000 ); dev->mmio_index =cpu_register_io_memory ( msix_mmio_read, msix_mmio_write, dev); + dev->dev.msix_entry_used =qemu_mallocz (KVM_MAX_MSIX_PER_DEV * +sizeof *dev->dev.msix_entry_used);return 0 ; }
@@ -1452,6 +1589,8 @@ static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev) strerror(errno)); } dev->msix_table_page =NULL ; +free (dev->dev.msix_entry_used); + dev->dev.msix_entry_used =NULL ; }static int assigned_initfn (struct PCIDevice *pci_dev)
Signature · 1 line
1.7.0.1
PATCH 5/5 qemu-kvm: device assignment: Enable in-kernel MSI-X mask support
In reply to Sheng Yang--- hw/device-assignment.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)
hw/device-assignment.c +13 -0
@@ -269,6 +269,9 @@ static void assigned_dev_iomem_map(PCIDevice *pci_dev, int region_num,AssignedDevRegion *region = &r_dev->v_addrs[region_num];PCIRegion *real_region = &r_dev->real_device.regions[region_num];int ret =0 ; +#ifdef KVM_CAP_DEVICE_MSIX_MASK +struct kvm_assigned_msix_mmio msix_mmio; +#endif DEBUG ("e_phys=%08" FMT_PCIBUS " r_virt=%p type=%d len=%08" FMT_PCIBUS " region_num=%d \n" , e_phys, region->u.r_virtbase, type, e_size, region_num);
@@ -287,6 +290,16 @@ static void assigned_dev_iomem_map(PCIDevice *pci_dev, int region_num,cpu_register_physical_memory (e_phys + offset,TARGET_PAGE_SIZE , r_dev->mmio_index); +#ifdef KVM_CAP_DEVICE_MSIX_MASK +memset (&msix_mmio,0 ,sizeof (struct kvm_assigned_msix_mmio )); + msix_mmio.assigned_dev_id =calc_assigned_dev_id (r_dev->h_segnr, + r_dev->h_busnr, r_dev->h_devfn); + msix_mmio.base_addr = e_phys + offset; +if (kvm_assign_reg_msix_mmio (kvm_context, &msix_mmio)) +fprintf (stderr,"fail to register in-kernel msix_mmio!\n" ); +/* We can still continue because the MMIO accessing can fall +* back to QEmu */ +#endif } }
Signature · 1 line
1.7.0.1
Re: [PATCH 5/5] qemu-kvm: device assignment: Enable in-kernel MSI-X mask support
Quoted 23 lines · Sheng Yang
Signed-off-by Sheng Yang <[email protected]>--- hw/device-assignment.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)hw/device-assignment.c +3
-0@@ -269,6 +269,9 @@ static void assigned_dev_iomem_map(PCIDevice *pci_dev, int region_num,AssignedDevRegion *region = &r_dev->v_addrs[region_num];PCIRegion *real_region = &r_dev->real_device.regions[region_num];int ret =0 ; +#ifdef KVM_CAP_DEVICE_MSIX_MASK +struct kvm_assigned_msix_mmio msix_mmio; +#endif DEBUG ("e_phys=%08" FMT_PCIBUS " r_virt=%p type=%d len=%08" FMT_PCIBUS " region_num=%d \n" , e_phys, region->u.r_virtbase, type, e_size, region_num);@@ -287,6 +290,16 @@ static void assigned_dev_iomem_map(PCIDevice *pci_dev, int region_num, cpu_register_physical_memory(e_phys + offset,
hw/device-assignment.c static void assigned_dev_iomem_map(PCIDevice *pci_dev, int region_num, · line 301
Quoted 10 lines
hw/device-assignment.c +9
-0TARGET_PAGE_SIZE, r_dev->mmio_index); +#ifdef KVM_CAP_DEVICE_MSIX_MASK +memset (&msix_mmio,0 ,sizeof (struct kvm_assigned_msix_mmio )); + msix_mmio.assigned_dev_id =calc_assigned_dev_id (r_dev->h_segnr, + r_dev->h_busnr, r_dev->h_devfn); + msix_mmio.base_addr = e_phys + offset; +if (kvm_assign_reg_msix_mmio (kvm_context, &msix_mmio)) +fprintf (stderr,"fail to register in-kernel msix_mmio!\n" ); +/* We can still continue because the MMIO accessing can fall +* back to QEmu */
So let's not print scary messages ...
Quoted 6 lines
hw/device-assignment.c +1
-0+#endif } }Signature · 1 line
1.7.0.1
Re: [PATCH 5/5] qemu-kvm: device assignment: Enable in-kernel MSI-X mask support
Quoted 34 lines · On Thursday 21 October 2010 06:36:56 Michael S. Tsirkin wrote:
Quoted 33 lines · Sheng Yang
Signed-off-by Sheng Yang <[email protected]>---
hw/device-assignment.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)hw/device-assignment.c +3
-0@@ -269,6 +269,9 @@ static void assigned_dev_iomem_map(PCIDevice *pci_dev, int region_num, AssignedDevRegion *region = &r_dev->v_addrs[region_num];PCIRegion *real_region = &r_dev->real_device.regions[region_num];int ret =0 ; +#ifdef KVM_CAP_DEVICE_MSIX_MASK +struct kvm_assigned_msix_mmio msix_mmio; +#endif DEBUG("e_phys=%08" FMT_PCIBUS " r_virt=%p type=%d len=%08" FMT_PCIBUS " region_num=%d \n", e_phys, region->u.r_virtbase, type, e_size, region_num);hw/device-assignment.c +0
-0@@ -287,6 +290,16 @@ static void assigned_dev_iomem_map(PCIDevice *pci_dev, int region_num,cpu_register_physical_memory (e_phys + offset,TARGET_PAGE_SIZE , r_dev->mmio_index);
Quoted 11 lines
Quoted 9 lines
hw/device-assignment.c +7
-0+#ifdef KVM_CAP_DEVICE_MSIX_MASK +memset (&msix_mmio,0 ,sizeof (struct kvm_assigned_msix_mmio )); + msix_mmio.assigned_dev_id =calc_assigned_dev_id (r_dev->h_segnr, + r_dev->h_busnr, r_dev->h_devfn); + msix_mmio.base_addr = e_phys + offset; +if (kvm_assign_reg_msix_mmio (kvm_context, &msix_mmio)) + fprintf(stderr, "fail to register in-kernelmsix_mmio!\n"); + /* We can still continue because the MMIO
accessing can fall + * back to QEmu */So let's not print scary messages ...
OK...
--
regards
Yang, Sheng
Quoted 6 lines
Quoted 6 lines
+#endif
} }