2
2
/*
3
3
* handling kvm guest interrupts
4
4
*
5
- * Copyright IBM Corp. 2008, 2015
5
+ * Copyright IBM Corp. 2008, 2020
6
6
*
7
7
* Author(s): Carsten Otte <[email protected] >
8
8
*/
@@ -2327,9 +2327,6 @@ static int register_io_adapter(struct kvm_device *dev,
2327
2327
if (!adapter )
2328
2328
return - ENOMEM ;
2329
2329
2330
- INIT_LIST_HEAD (& adapter -> maps );
2331
- init_rwsem (& adapter -> maps_lock );
2332
- atomic_set (& adapter -> nr_maps , 0 );
2333
2330
adapter -> id = adapter_info .id ;
2334
2331
adapter -> isc = adapter_info .isc ;
2335
2332
adapter -> maskable = adapter_info .maskable ;
@@ -2354,87 +2351,12 @@ int kvm_s390_mask_adapter(struct kvm *kvm, unsigned int id, bool masked)
2354
2351
return ret ;
2355
2352
}
2356
2353
2357
- static int kvm_s390_adapter_map (struct kvm * kvm , unsigned int id , __u64 addr )
2358
- {
2359
- struct s390_io_adapter * adapter = get_io_adapter (kvm , id );
2360
- struct s390_map_info * map ;
2361
- int ret ;
2362
-
2363
- if (!adapter || !addr )
2364
- return - EINVAL ;
2365
-
2366
- map = kzalloc (sizeof (* map ), GFP_KERNEL );
2367
- if (!map ) {
2368
- ret = - ENOMEM ;
2369
- goto out ;
2370
- }
2371
- INIT_LIST_HEAD (& map -> list );
2372
- map -> guest_addr = addr ;
2373
- map -> addr = gmap_translate (kvm -> arch .gmap , addr );
2374
- if (map -> addr == - EFAULT ) {
2375
- ret = - EFAULT ;
2376
- goto out ;
2377
- }
2378
- ret = get_user_pages_fast (map -> addr , 1 , FOLL_WRITE , & map -> page );
2379
- if (ret < 0 )
2380
- goto out ;
2381
- BUG_ON (ret != 1 );
2382
- down_write (& adapter -> maps_lock );
2383
- if (atomic_inc_return (& adapter -> nr_maps ) < MAX_S390_ADAPTER_MAPS ) {
2384
- list_add_tail (& map -> list , & adapter -> maps );
2385
- ret = 0 ;
2386
- } else {
2387
- put_page (map -> page );
2388
- ret = - EINVAL ;
2389
- }
2390
- up_write (& adapter -> maps_lock );
2391
- out :
2392
- if (ret )
2393
- kfree (map );
2394
- return ret ;
2395
- }
2396
-
2397
- static int kvm_s390_adapter_unmap (struct kvm * kvm , unsigned int id , __u64 addr )
2398
- {
2399
- struct s390_io_adapter * adapter = get_io_adapter (kvm , id );
2400
- struct s390_map_info * map , * tmp ;
2401
- int found = 0 ;
2402
-
2403
- if (!adapter || !addr )
2404
- return - EINVAL ;
2405
-
2406
- down_write (& adapter -> maps_lock );
2407
- list_for_each_entry_safe (map , tmp , & adapter -> maps , list ) {
2408
- if (map -> guest_addr == addr ) {
2409
- found = 1 ;
2410
- atomic_dec (& adapter -> nr_maps );
2411
- list_del (& map -> list );
2412
- put_page (map -> page );
2413
- kfree (map );
2414
- break ;
2415
- }
2416
- }
2417
- up_write (& adapter -> maps_lock );
2418
-
2419
- return found ? 0 : - EINVAL ;
2420
- }
2421
-
2422
2354
void kvm_s390_destroy_adapters (struct kvm * kvm )
2423
2355
{
2424
2356
int i ;
2425
- struct s390_map_info * map , * tmp ;
2426
2357
2427
- for (i = 0 ; i < MAX_S390_IO_ADAPTERS ; i ++ ) {
2428
- if (!kvm -> arch .adapters [i ])
2429
- continue ;
2430
- list_for_each_entry_safe (map , tmp ,
2431
- & kvm -> arch .adapters [i ]-> maps , list ) {
2432
- list_del (& map -> list );
2433
- put_page (map -> page );
2434
- kfree (map );
2435
- }
2358
+ for (i = 0 ; i < MAX_S390_IO_ADAPTERS ; i ++ )
2436
2359
kfree (kvm -> arch .adapters [i ]);
2437
- }
2438
2360
}
2439
2361
2440
2362
static int modify_io_adapter (struct kvm_device * dev ,
@@ -2456,11 +2378,14 @@ static int modify_io_adapter(struct kvm_device *dev,
2456
2378
if (ret > 0 )
2457
2379
ret = 0 ;
2458
2380
break ;
2381
+ /*
2382
+ * The following operations are no longer needed and therefore no-ops.
2383
+ * The gpa to hva translation is done when an IRQ route is set up. The
2384
+ * set_irq code uses get_user_pages_remote() to do the actual write.
2385
+ */
2459
2386
case KVM_S390_IO_ADAPTER_MAP :
2460
- ret = kvm_s390_adapter_map (dev -> kvm , req .id , req .addr );
2461
- break ;
2462
2387
case KVM_S390_IO_ADAPTER_UNMAP :
2463
- ret = kvm_s390_adapter_unmap ( dev -> kvm , req . id , req . addr ) ;
2388
+ ret = 0 ;
2464
2389
break ;
2465
2390
default :
2466
2391
ret = - EINVAL ;
@@ -2699,19 +2624,15 @@ static unsigned long get_ind_bit(__u64 addr, unsigned long bit_nr, bool swap)
2699
2624
return swap ? (bit ^ (BITS_PER_LONG - 1 )) : bit ;
2700
2625
}
2701
2626
2702
- static struct s390_map_info * get_map_info (struct s390_io_adapter * adapter ,
2703
- u64 addr )
2627
+ static struct page * get_map_page (struct kvm * kvm , u64 uaddr )
2704
2628
{
2705
- struct s390_map_info * map ;
2629
+ struct page * page = NULL ;
2706
2630
2707
- if (!adapter )
2708
- return NULL ;
2709
-
2710
- list_for_each_entry (map , & adapter -> maps , list ) {
2711
- if (map -> guest_addr == addr )
2712
- return map ;
2713
- }
2714
- return NULL ;
2631
+ down_read (& kvm -> mm -> mmap_sem );
2632
+ get_user_pages_remote (NULL , kvm -> mm , uaddr , 1 , FOLL_WRITE ,
2633
+ & page , NULL , NULL );
2634
+ up_read (& kvm -> mm -> mmap_sem );
2635
+ return page ;
2715
2636
}
2716
2637
2717
2638
static int adapter_indicators_set (struct kvm * kvm ,
@@ -2720,30 +2641,35 @@ static int adapter_indicators_set(struct kvm *kvm,
2720
2641
{
2721
2642
unsigned long bit ;
2722
2643
int summary_set , idx ;
2723
- struct s390_map_info * info ;
2644
+ struct page * ind_page , * summary_page ;
2724
2645
void * map ;
2725
2646
2726
- info = get_map_info ( adapter , adapter_int -> ind_addr );
2727
- if (!info )
2647
+ ind_page = get_map_page ( kvm , adapter_int -> ind_addr );
2648
+ if (!ind_page )
2728
2649
return -1 ;
2729
- map = page_address (info -> page );
2730
- bit = get_ind_bit (info -> addr , adapter_int -> ind_offset , adapter -> swap );
2731
- set_bit (bit , map );
2732
- idx = srcu_read_lock (& kvm -> srcu );
2733
- mark_page_dirty (kvm , info -> guest_addr >> PAGE_SHIFT );
2734
- set_page_dirty_lock (info -> page );
2735
- info = get_map_info (adapter , adapter_int -> summary_addr );
2736
- if (!info ) {
2737
- srcu_read_unlock (& kvm -> srcu , idx );
2650
+ summary_page = get_map_page (kvm , adapter_int -> summary_addr );
2651
+ if (!summary_page ) {
2652
+ put_page (ind_page );
2738
2653
return -1 ;
2739
2654
}
2740
- map = page_address (info -> page );
2741
- bit = get_ind_bit (info -> addr , adapter_int -> summary_offset ,
2742
- adapter -> swap );
2655
+
2656
+ idx = srcu_read_lock (& kvm -> srcu );
2657
+ map = page_address (ind_page );
2658
+ bit = get_ind_bit (adapter_int -> ind_addr ,
2659
+ adapter_int -> ind_offset , adapter -> swap );
2660
+ set_bit (bit , map );
2661
+ mark_page_dirty (kvm , adapter_int -> ind_addr >> PAGE_SHIFT );
2662
+ set_page_dirty_lock (ind_page );
2663
+ map = page_address (summary_page );
2664
+ bit = get_ind_bit (adapter_int -> summary_addr ,
2665
+ adapter_int -> summary_offset , adapter -> swap );
2743
2666
summary_set = test_and_set_bit (bit , map );
2744
- mark_page_dirty (kvm , info -> guest_addr >> PAGE_SHIFT );
2745
- set_page_dirty_lock (info -> page );
2667
+ mark_page_dirty (kvm , adapter_int -> summary_addr >> PAGE_SHIFT );
2668
+ set_page_dirty_lock (summary_page );
2746
2669
srcu_read_unlock (& kvm -> srcu , idx );
2670
+
2671
+ put_page (ind_page );
2672
+ put_page (summary_page );
2747
2673
return summary_set ? 0 : 1 ;
2748
2674
}
2749
2675
@@ -2765,9 +2691,7 @@ static int set_adapter_int(struct kvm_kernel_irq_routing_entry *e,
2765
2691
adapter = get_io_adapter (kvm , e -> adapter .adapter_id );
2766
2692
if (!adapter )
2767
2693
return -1 ;
2768
- down_read (& adapter -> maps_lock );
2769
2694
ret = adapter_indicators_set (kvm , adapter , & e -> adapter );
2770
- up_read (& adapter -> maps_lock );
2771
2695
if ((ret > 0 ) && !adapter -> masked ) {
2772
2696
ret = kvm_s390_inject_airq (kvm , adapter );
2773
2697
if (ret == 0 )
@@ -2818,23 +2742,27 @@ int kvm_set_routing_entry(struct kvm *kvm,
2818
2742
struct kvm_kernel_irq_routing_entry * e ,
2819
2743
const struct kvm_irq_routing_entry * ue )
2820
2744
{
2821
- int ret ;
2745
+ u64 uaddr ;
2822
2746
2823
2747
switch (ue -> type ) {
2748
+ /* we store the userspace addresses instead of the guest addresses */
2824
2749
case KVM_IRQ_ROUTING_S390_ADAPTER :
2825
2750
e -> set = set_adapter_int ;
2826
- e -> adapter .summary_addr = ue -> u .adapter .summary_addr ;
2827
- e -> adapter .ind_addr = ue -> u .adapter .ind_addr ;
2751
+ uaddr = gmap_translate (kvm -> arch .gmap , ue -> u .adapter .summary_addr );
2752
+ if (uaddr == - EFAULT )
2753
+ return - EFAULT ;
2754
+ e -> adapter .summary_addr = uaddr ;
2755
+ uaddr = gmap_translate (kvm -> arch .gmap , ue -> u .adapter .ind_addr );
2756
+ if (uaddr == - EFAULT )
2757
+ return - EFAULT ;
2758
+ e -> adapter .ind_addr = uaddr ;
2828
2759
e -> adapter .summary_offset = ue -> u .adapter .summary_offset ;
2829
2760
e -> adapter .ind_offset = ue -> u .adapter .ind_offset ;
2830
2761
e -> adapter .adapter_id = ue -> u .adapter .adapter_id ;
2831
- ret = 0 ;
2832
- break ;
2762
+ return 0 ;
2833
2763
default :
2834
- ret = - EINVAL ;
2764
+ return - EINVAL ;
2835
2765
}
2836
-
2837
- return ret ;
2838
2766
}
2839
2767
2840
2768
int kvm_set_msi (struct kvm_kernel_irq_routing_entry * e , struct kvm * kvm ,
0 commit comments