Skip to contentSkip to conversation

arch/x86/mm/fault.c:1468:34: sparse: sparse: incorrect type in argument 1 (different base types)

PATCH kbuild test robot 2 participants 2 messages Mar 11, 2020

Subsystems (2)
lore
Share & tools
lore

kbuild test robot

author build bot
#0 lore raw
tree:   https://github.com/hnaz/linux-mm master
head:   5d9ee416b5701096536c7a63c04dbe25012baa9e
commit: 79181dfcc4b8c2091126a8b3175957a598ae61e1 [90/340] x86/mm: use helper fault_signal_pending()
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.1-174-g094d5a94-dirty
        git checkout 79181dfcc4b8c2091126a8b3175957a598ae61e1
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'

If you fix the issue, kindly add following tag

sparse warnings: (new ones prefixed by >>)

>> arch/x86/mm/fault.c:1468:34: sparse: sparse: incorrect type in argument 1 (different base types) @@    expected unsigned int fault_flags @@    got restricted vm_fault_t [assignedunsigned int fault_flags @@
>> arch/x86/mm/fault.c:1468:34: sparse:    expected unsigned int fault_flags
>> arch/x86/mm/fault.c:1468:34: sparse:    got restricted vm_fault_t [assigned] [usertype] fault
>> include/linux/sched/signal.h:381:16: sparse: sparse: restricted vm_fault_t degrades to integer

vim +1468 arch/x86/mm/fault.c

1392
1393 /*
1394 * Kernel-mode access to the user address space should only occur
1395 * on well-defined single instructions listed in the exception
1396 * tables. But, an erroneous kernel fault occurring outside one of
1397 * those areas which also holds mmap_sem might deadlock attempting
1398 * to validate the fault against the address space.
1399 *
1400 * Only do the expensive exception table search when we might be at
1401 * risk of a deadlock. This happens if we
1402 * 1. Failed to acquire mmap_sem, and
1403 * 2. The access did not originate in userspace.
1404 */
1405 if (unlikely(!down_read_trylock(&mm->mmap_sem))) {
1406 if (!user_mode(regs) && !search_exception_tables(regs->ip)) {
1407 /*
1408 * Fault from code in kernel from
1409 * which we do not expect faults.
1410 */
1411 bad_area_nosemaphore(regs, hw_error_code, address);
1412 return;
1413 }
1414 retry:
1415 down_read(&mm->mmap_sem);
1416 } else {
1417 /*
1418 * The above down_read_trylock() might have succeeded in
1419 * which case we'll have missed the might_sleep() from
1420 * down_read():
1421 */
1422 might_sleep();
1423 }
1424
1425 vma = find_vma(mm, address);
1426 if (unlikely(!vma)) {
1427 bad_area(regs, hw_error_code, address);
1428 return;
1429 }
1430 if (likely(vma->vm_start <= address))
1431 goto good_area;
1432 if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) {
1433 bad_area(regs, hw_error_code, address);
1434 return;
1435 }
1436 if (unlikely(expand_stack(vma, address))) {
1437 bad_area(regs, hw_error_code, address);
1438 return;
1439 }
1440
1441 /*
1442 * Ok, we have a good vm_area for this memory access, so
1443 * we can handle it..
1444 */
1445 good_area:
1446 if (unlikely(access_error(hw_error_code, vma))) {
1447 bad_area_access_error(regs, hw_error_code, address, vma);
1448 return;
1449 }
1450
1451 /*
1452 * If for any reason at all we couldn't handle the fault,
1453 * make sure we exit gracefully rather than endlessly redo
1454 * the fault. Since we never set FAULT_FLAG_RETRY_NOWAIT, if
1455 * we get VM_FAULT_RETRY back, the mmap_sem has been unlocked.
1456 *
1457 * Note that handle_userfault() may also release and reacquire mmap_sem
1458 * (and not return with VM_FAULT_RETRY), when returning to userland to
1459 * repeat the page fault later with a VM_FAULT_NOPAGE retval
1460 * (potentially after handling any pending signal during the return to
1461 * userland). The return to userland is identified whenever
1462 * FAULT_FLAG_USER|FAULT_FLAG_KILLABLE are both set in flags.
1463 */
1464 fault = handle_mm_fault(vma, address, flags);
1465 major |= fault & VM_FAULT_MAJOR;
1466
1467 /* Quick path to respond to signals */

> 1468		if (fault_signal_pending(fault, regs)) {

1469 if (!user_mode(regs))
1470 no_context(regs, hw_error_code, address, SIGBUS,
1471 BUS_ADRERR);
1472 return;
1473 }
1474
1475 /*
1476 * If we need to retry the mmap_sem has already been released,
1477 * and if there is a fatal signal pending there is no guarantee
1478 * that we made any progress. Handle this case first.
1479 */
1480 if (unlikely((fault & VM_FAULT_RETRY) &&
1481 (flags & FAULT_FLAG_ALLOW_RETRY))) {
1482 /* Retry at most once */
1483 flags &= ~FAULT_FLAG_ALLOW_RETRY;
1484 flags |= FAULT_FLAG_TRIED;
1485 goto retry;
1486 }
1487
1488 up_read(&mm->mmap_sem);
1489 if (unlikely(fault & VM_FAULT_ERROR)) {
1490 mm_fault_error(regs, hw_error_code, address, fault);
1491 return;
1492 }
1493
1494 /*
1495 * Major/minor page fault accounting. If any of the events
1496 * returned VM_FAULT_MAJOR, we account it as a major fault.
1497 */
1498 if (major) {
1499 tsk->maj_flt++;
1500 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address);
1501 } else {
1502 tsk->min_flt++;
1503 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address);
1504 }
1505
1506 check_v8086_mode(regs, address, tsk);
1507 }
1508 NOKPROBE_SYMBOL(do_user_addr_fault);
1509

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

#1 lore raw
Quoted 10 lines · kbuild test robot
tree:   https://github.com/hnaz/linux-mm master
head:   5d9ee416b5701096536c7a63c04dbe25012baa9e
commit: 79181dfcc4b8c2091126a8b3175957a598ae61e1 [90/340] x86/mm: use helper fault_signal_pending()
reproduce:
        # apt-get install sparse
        # sparse version: v0.6.1-174-g094d5a94-dirty
        git checkout 79181dfcc4b8c2091126a8b3175957a598ae61e1
        make ARCH=x86_64 allmodconfig
        make C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__'
Quoted 10 lines

If you fix the issue, kindly add following tag

sparse warnings: (new ones prefixed by >>)

Quoted 4 lines
Quoted 4 lines

arch/x86/mm/fault.c:1468:34: sparse: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int fault_flags @@ got restricted vm_fault_t [assignedunsigned int fault_flags @@
arch/x86/mm/fault.c:1468:34: sparse: expected unsigned int fault_flags
arch/x86/mm/fault.c:1468:34: sparse: got restricted vm_fault_t [assigned] [usertype] fault
include/linux/sched/signal.h:381:16: sparse: sparse: restricted vm_fault_t degrades to integer

Hi, Andrew,

I'm not sure whether this comes from the extra "-fdiagnostic-prefix" because I didn't encounter that, but if after the previous signal.h fixup squashed into patch "mm: Introduce fault_signal_pending()", then we have linux/mm_types.h included already, and it'll be pretty safe to just use vm_fault_t here.

To be explicit, maybe another squash-in would work to the same patch:

-------------8<-------------

include/linux/sched/signal.h +1 -1
index c8e0e4f801e4..65ea429daaa2 100644
@@ -377,7 +377,7 @@ static inline int signal_pending_state(long state, struct task_struct *p)
  * instead, especially with the case where we've got interrupted with
  * a VM_FAULT_RETRY.
  */
-static inline bool fault_signal_pending(unsigned int fault_flags,
+static inline bool fault_signal_pending(vm_fault_t fault_flags,
                                        struct pt_regs *regs)
 {
        return unlikely((fault_flags & VM_FAULT_RETRY) &&

------------->8-------------

So the whole fixup is (against "mm: Introduce fault_signal_pending()"):

-------------8<-------------

arch/mips/mm/fault.c +1 -1
index fd64b135fd7b..4a0eafe3d932 100644
@@ -154,7 +154,7 @@ static void __kprobes __do_page_fault(struct pt_regs *regs, unsigned long write,
         */
        fault = handle_mm_fault(vma, address, flags);
 
-       if (fault_signal_pending(regs))
+       if (fault_signal_pending(fault, regs))
                return;
 
        perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
include/linux/sched/signal.h +3 -1
index 09d40ce6a162..65ea429daaa2 100644
@@ -10,6 +10,8 @@
 #include <linux/cred.h>
 #include <linux/refcount.h>
 #include <linux/posix-timers.h>
+#include <linux/mm_types.h>
+#include <asm/ptrace.h>
 
 /*
  * Types defining task->signal and task->sighand and APIs using them:
@@ -375,7 +377,7 @@ static inline int signal_pending_state(long state, struct task_struct *p)
  * instead, especially with the case where we've got interrupted with
  * a VM_FAULT_RETRY.
  */
-static inline bool fault_signal_pending(unsigned int fault_flags,
+static inline bool fault_signal_pending(vm_fault_t fault_flags,
                                        struct pt_regs *regs)
 {
        return unlikely((fault_flags & VM_FAULT_RETRY) &&

------------->8-------------

Thanks,

Signature · 1 line
Peter Xu