int i;
for ( i = 0; i < HVM_MMIO_HANDLER_NR; i++ )
- if ( hvm_mmio_handlers[i]->check_handler(v, p->addr) )
+ {
+ hvm_mmio_check_t check_handler =
+ hvm_mmio_handlers[i]->check_handler;
+
+ if ( check_handler(v, p->addr) )
+ {
+ if ( unlikely(p->count > 1) &&
+ !check_handler(v, unlikely(p->df)
+ ? p->addr - (p->count - 1LL) * p->size
+ : p->addr + (p->count - 1LL) * p->size) )
+ p->count = 1;
+
return hvm_mmio_access(
v, p,
hvm_mmio_handlers[i]->read_handler,
hvm_mmio_handlers[i]->write_handler);
+ }
+ }
return X86EMUL_UNHANDLEABLE;
}
if ( type == HVM_PORTIO )
return process_portio_intercept(
handler->hdl_list[i].action.portio, p);
+
+ if ( unlikely(p->count > 1) &&
+ (unlikely(p->df)
+ ? p->addr - (p->count - 1LL) * p->size < addr
+ : p->addr + p->count * 1LL * p->size - 1 >= addr + size) )
+ p->count = 1;
+
return handler->hdl_list[i].action.mmio(p);
}
}
rcu_read_lock(&msixtbl_rcu_lock);
entry = msixtbl_find_entry(v, address);
+ if ( !entry )
+ goto out;
offset = address & (PCI_MSIX_ENTRY_SIZE - 1);
if ( offset != PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET )
rcu_read_lock(&msixtbl_rcu_lock);
entry = msixtbl_find_entry(v, address);
+ if ( !entry )
+ goto out;
nr_entry = (address - entry->gtable) / PCI_MSIX_ENTRY_SIZE;
offset = address & (PCI_MSIX_ENTRY_SIZE - 1);