@@ -4332,7 +4332,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
4332
4332
void kvm_io_bus_unregister_dev (struct kvm * kvm , enum kvm_bus bus_idx ,
4333
4333
struct kvm_io_device * dev )
4334
4334
{
4335
- int i ;
4335
+ int i , j ;
4336
4336
struct kvm_io_bus * new_bus , * bus ;
4337
4337
4338
4338
bus = kvm_get_bus (kvm , bus_idx );
@@ -4349,17 +4349,20 @@ void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
4349
4349
4350
4350
new_bus = kmalloc (struct_size (bus , range , bus -> dev_count - 1 ),
4351
4351
GFP_KERNEL_ACCOUNT );
4352
- if (!new_bus ) {
4352
+ if (new_bus ) {
4353
+ memcpy (new_bus , bus , sizeof (* bus ) + i * sizeof (struct kvm_io_range ));
4354
+ new_bus -> dev_count -- ;
4355
+ memcpy (new_bus -> range + i , bus -> range + i + 1 ,
4356
+ (new_bus -> dev_count - i ) * sizeof (struct kvm_io_range ));
4357
+ } else {
4353
4358
pr_err ("kvm: failed to shrink bus, removing it completely\n" );
4354
- goto broken ;
4359
+ for (j = 0 ; j < bus -> dev_count ; j ++ ) {
4360
+ if (j == i )
4361
+ continue ;
4362
+ kvm_iodevice_destructor (bus -> range [j ].dev );
4363
+ }
4355
4364
}
4356
4365
4357
- memcpy (new_bus , bus , sizeof (* bus ) + i * sizeof (struct kvm_io_range ));
4358
- new_bus -> dev_count -- ;
4359
- memcpy (new_bus -> range + i , bus -> range + i + 1 ,
4360
- (new_bus -> dev_count - i ) * sizeof (struct kvm_io_range ));
4361
-
4362
- broken :
4363
4366
rcu_assign_pointer (kvm -> buses [bus_idx ], new_bus );
4364
4367
synchronize_srcu_expedited (& kvm -> srcu );
4365
4368
kfree (bus );
0 commit comments