@@ -473,188 +473,30 @@ do { \
473
473
474
474
void __cmpxchg_user_key_called_with_bad_pointer (void );
475
475
476
- #define CMPXCHG_USER_KEY_MAX_LOOPS 128
477
-
478
- static __always_inline int __cmpxchg_user_key (unsigned long address , void * uval ,
479
- __uint128_t old , __uint128_t new ,
480
- unsigned long key , int size )
476
+ int __cmpxchg_user_key1 (unsigned long address , unsigned char * uval ,
477
+ unsigned char old , unsigned char new , unsigned long key );
478
+ int __cmpxchg_user_key2 (unsigned long address , unsigned short * uval ,
479
+ unsigned short old , unsigned short new , unsigned long key );
480
+ int __cmpxchg_user_key4 (unsigned long address , unsigned int * uval ,
481
+ unsigned int old , unsigned int new , unsigned long key );
482
+ int __cmpxchg_user_key8 (unsigned long address , unsigned long * uval ,
483
+ unsigned long old , unsigned long new , unsigned long key );
484
+ int __cmpxchg_user_key16 (unsigned long address , __uint128_t * uval ,
485
+ __uint128_t old , __uint128_t new , unsigned long key );
486
+
487
+ static __always_inline int _cmpxchg_user_key (unsigned long address , void * uval ,
488
+ __uint128_t old , __uint128_t new ,
489
+ unsigned long key , int size )
481
490
{
482
- bool sacf_flag ;
483
- int rc = 0 ;
484
-
485
491
switch (size ) {
486
- case 1 : {
487
- unsigned int prev , shift , mask , _old , _new ;
488
- unsigned long count ;
489
-
490
- shift = (3 ^ (address & 3 )) << 3 ;
491
- address ^= address & 3 ;
492
- _old = ((unsigned int )old & 0xff ) << shift ;
493
- _new = ((unsigned int )new & 0xff ) << shift ;
494
- mask = ~(0xff << shift );
495
- sacf_flag = enable_sacf_uaccess ();
496
- asm_inline volatile (
497
- " spka 0(%[key])\n"
498
- " sacf 256\n"
499
- " llill %[count],%[max_loops]\n"
500
- "0: l %[prev],%[address]\n"
501
- "1: nr %[prev],%[mask]\n"
502
- " xilf %[mask],0xffffffff\n"
503
- " or %[new],%[prev]\n"
504
- " or %[prev],%[tmp]\n"
505
- "2: lr %[tmp],%[prev]\n"
506
- "3: cs %[prev],%[new],%[address]\n"
507
- "4: jnl 5f\n"
508
- " xr %[tmp],%[prev]\n"
509
- " xr %[new],%[tmp]\n"
510
- " nr %[tmp],%[mask]\n"
511
- " jnz 5f\n"
512
- " brct %[count],2b\n"
513
- "5: sacf 768\n"
514
- " spka %[default_key]\n"
515
- EX_TABLE_UA_LOAD_REG (0b , 5b , %[rc ], %[prev ])
516
- EX_TABLE_UA_LOAD_REG (1b , 5b , %[rc ], %[prev ])
517
- EX_TABLE_UA_LOAD_REG (3b , 5b , %[rc ], %[prev ])
518
- EX_TABLE_UA_LOAD_REG (4b , 5b , %[rc ], %[prev ])
519
- : [rc ] "+ & d " (rc),
520
- [prev ] "= & d " (prev),
521
- [address ] "+ Q " (*(int *)address),
522
- [tmp ] "+ & d " (_old),
523
- [new ] "+ & d " (_new),
524
- [mask ] "+ & d " (mask),
525
- [count ] "= a " (count)
526
- : [key ] "%[count]" (key << 4 ),
527
- [default_key ] "J" (PAGE_DEFAULT_KEY ),
528
- [max_loops ] "J" (CMPXCHG_USER_KEY_MAX_LOOPS )
529
- : "memory ", " cc ");
530
- disable_sacf_uaccess (sacf_flag );
531
- * (unsigned char * )uval = prev >> shift ;
532
- if (!count )
533
- rc = - EAGAIN ;
534
- return rc ;
535
- }
536
- case 2 : {
537
- unsigned int prev , shift , mask , _old , _new ;
538
- unsigned long count ;
539
-
540
- shift = (2 ^ (address & 2 )) << 3 ;
541
- address ^= address & 2 ;
542
- _old = ((unsigned int )old & 0xffff ) << shift ;
543
- _new = ((unsigned int )new & 0xffff ) << shift ;
544
- mask = ~(0xffff << shift );
545
- sacf_flag = enable_sacf_uaccess ();
546
- asm_inline volatile (
547
- " spka 0(%[key])\n"
548
- " sacf 256\n"
549
- " llill %[count],%[max_loops]\n"
550
- "0: l %[prev],%[address]\n"
551
- "1: nr %[prev],%[mask]\n"
552
- " xilf %[mask],0xffffffff\n"
553
- " or %[new],%[prev]\n"
554
- " or %[prev],%[tmp]\n"
555
- "2: lr %[tmp],%[prev]\n"
556
- "3: cs %[prev],%[new],%[address]\n"
557
- "4: jnl 5f\n"
558
- " xr %[tmp],%[prev]\n"
559
- " xr %[new],%[tmp]\n"
560
- " nr %[tmp],%[mask]\n"
561
- " jnz 5f\n"
562
- " brct %[count],2b\n"
563
- "5: sacf 768\n"
564
- " spka %[default_key]\n"
565
- EX_TABLE_UA_LOAD_REG (0b , 5b , %[rc ], %[prev ])
566
- EX_TABLE_UA_LOAD_REG (1b , 5b , %[rc ], %[prev ])
567
- EX_TABLE_UA_LOAD_REG (3b , 5b , %[rc ], %[prev ])
568
- EX_TABLE_UA_LOAD_REG (4b , 5b , %[rc ], %[prev ])
569
- : [rc ] "+ & d " (rc),
570
- [prev ] "= & d " (prev),
571
- [address ] "+ Q " (*(int *)address),
572
- [tmp ] "+ & d " (_old),
573
- [new ] "+ & d " (_new),
574
- [mask ] "+ & d " (mask),
575
- [count ] "= a " (count)
576
- : [key ] "%[count]" (key << 4 ),
577
- [default_key ] "J" (PAGE_DEFAULT_KEY ),
578
- [max_loops ] "J" (CMPXCHG_USER_KEY_MAX_LOOPS )
579
- : "memory ", " cc ");
580
- disable_sacf_uaccess (sacf_flag );
581
- * (unsigned short * )uval = prev >> shift ;
582
- if (!count )
583
- rc = - EAGAIN ;
584
- return rc ;
585
- }
586
- case 4 : {
587
- unsigned int prev = old ;
588
-
589
- sacf_flag = enable_sacf_uaccess ();
590
- asm_inline volatile (
591
- " spka 0(%[key])\n"
592
- " sacf 256\n"
593
- "0: cs %[prev],%[new],%[address]\n"
594
- "1: sacf 768\n"
595
- " spka %[default_key]\n"
596
- EX_TABLE_UA_LOAD_REG (0b , 1b , %[rc ], %[prev ])
597
- EX_TABLE_UA_LOAD_REG (1b , 1b , %[rc ], %[prev ])
598
- : [rc ] "+ & d " (rc),
599
- [prev ] "+ & d " (prev),
600
- [address ] "+ Q " (*(int *)address)
601
- : [new ] "d" ((unsigned int )new ),
602
- [key ] "a" (key << 4 ),
603
- [default_key ] "J" (PAGE_DEFAULT_KEY )
604
- : "memory ", " cc ");
605
- disable_sacf_uaccess (sacf_flag );
606
- * (unsigned int * )uval = prev ;
607
- return rc ;
608
- }
609
- case 8 : {
610
- unsigned long prev = old ;
611
-
612
- sacf_flag = enable_sacf_uaccess ();
613
- asm_inline volatile (
614
- " spka 0(%[key])\n"
615
- " sacf 256\n"
616
- "0: csg %[prev],%[new],%[address]\n"
617
- "1: sacf 768\n"
618
- " spka %[default_key]\n"
619
- EX_TABLE_UA_LOAD_REG (0b , 1b , %[rc ], %[prev ])
620
- EX_TABLE_UA_LOAD_REG (1b , 1b , %[rc ], %[prev ])
621
- : [rc ] "+ & d " (rc),
622
- [prev ] "+ & d " (prev),
623
- [address ] "+ QS " (*(long *)address)
624
- : [new ] "d" ((unsigned long )new ),
625
- [key ] "a" (key << 4 ),
626
- [default_key ] "J" (PAGE_DEFAULT_KEY )
627
- : "memory ", " cc ");
628
- disable_sacf_uaccess (sacf_flag );
629
- * (unsigned long * )uval = prev ;
630
- return rc ;
631
- }
632
- case 16 : {
633
- __uint128_t prev = old ;
634
-
635
- sacf_flag = enable_sacf_uaccess ();
636
- asm_inline volatile (
637
- " spka 0(%[key])\n"
638
- " sacf 256\n"
639
- "0: cdsg %[prev],%[new],%[address]\n"
640
- "1: sacf 768\n"
641
- " spka %[default_key]\n"
642
- EX_TABLE_UA_LOAD_REGPAIR (0b , 1b , %[rc ], %[prev ])
643
- EX_TABLE_UA_LOAD_REGPAIR (1b , 1b , %[rc ], %[prev ])
644
- : [rc ] "+ & d " (rc),
645
- [prev ] "+ & d " (prev),
646
- [address ] "+ QS " (*(__int128_t *)address)
647
- : [new ] "d" (new ),
648
- [key ] "a" (key << 4 ),
649
- [default_key ] "J" (PAGE_DEFAULT_KEY )
650
- : "memory ", " cc ");
651
- disable_sacf_uaccess (sacf_flag );
652
- * (__uint128_t * )uval = prev ;
653
- return rc ;
654
- }
492
+ case 1 : return __cmpxchg_user_key1 (address , uval , old , new , key );
493
+ case 2 : return __cmpxchg_user_key2 (address , uval , old , new , key );
494
+ case 4 : return __cmpxchg_user_key4 (address , uval , old , new , key );
495
+ case 8 : return __cmpxchg_user_key8 (address , uval , old , new , key );
496
+ case 16 : return __cmpxchg_user_key16 (address , uval , old , new , key );
497
+ default : __cmpxchg_user_key_called_with_bad_pointer ();
655
498
}
656
- __cmpxchg_user_key_called_with_bad_pointer ();
657
- return rc ;
499
+ return 0 ;
658
500
}
659
501
660
502
/**
@@ -686,8 +528,8 @@ static __always_inline int __cmpxchg_user_key(unsigned long address, void *uval,
686
528
BUILD_BUG_ON(sizeof(*(__ptr)) != sizeof(*(__uval))); \
687
529
might_fault(); \
688
530
__chk_user_ptr(__ptr); \
689
- __cmpxchg_user_key ((unsigned long)(__ptr), (void *)(__uval), \
690
- (old), (new), (key), sizeof(*(__ptr))); \
531
+ _cmpxchg_user_key ((unsigned long)(__ptr), (void *)(__uval), \
532
+ (old), (new), (key), sizeof(*(__ptr))); \
691
533
})
692
534
693
535
#endif /* __S390_UACCESS_H */
0 commit comments