Message ID | 20230518161949.11203-21-andy.chiu@sifive.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | riscv: Add vector ISA support | expand |
Hi Andy, kernel test robot noticed the following build errors: [auto build test ERROR on next-20230518] url: https://github.com/intel-lab-lkp/linux/commits/Andy-Chiu/riscv-Rename-__switch_to_aux-fpu/20230519-005938 base: next-20230518 patch link: https://lore.kernel.org/r/20230518161949.11203-21-andy.chiu%40sifive.com patch subject: [PATCH -next v20 20/26] riscv: Add prctl controls for userspace vector management config: arm-sp7021_defconfig compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project b0fb98227c90adf2536c9ad644a74d5e92961111) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install arm cross compiling tool for clang build # apt-get install binutils-arm-linux-gnueabi # https://github.com/intel-lab-lkp/linux/commit/eef6095228f3323db8f2bddd5bde768976888558 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Andy-Chiu/riscv-Rename-__switch_to_aux-fpu/20230519-005938 git checkout eef6095228f3323db8f2bddd5bde768976888558 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202305210917.aS7cWlKv-lkp@intel.com/ All errors (new ones prefixed by >>): >> kernel/sys.c:2718:11: error: call to undeclared function 'RISCV_V_SET_CONTROL'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] error = RISCV_V_SET_CONTROL(arg2); ^ >> kernel/sys.c:2721:11: error: call to undeclared function 'RISCV_V_GET_CONTROL'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] error = RISCV_V_GET_CONTROL(); ^ 2 errors generated. vim +/RISCV_V_SET_CONTROL +2718 kernel/sys.c 2407 2408 SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, 2409 unsigned long, arg4, unsigned long, arg5) 2410 { 2411 struct task_struct *me = current; 2412 unsigned char comm[sizeof(me->comm)]; 2413 long error; 2414 2415 error = security_task_prctl(option, arg2, arg3, arg4, arg5); 2416 if (error != -ENOSYS) 2417 return error; 2418 2419 error = 0; 2420 switch (option) { 2421 case PR_SET_PDEATHSIG: 2422 if (!valid_signal(arg2)) { 2423 error = -EINVAL; 2424 break; 2425 } 2426 me->pdeath_signal = arg2; 2427 break; 2428 case PR_GET_PDEATHSIG: 2429 error = put_user(me->pdeath_signal, (int __user *)arg2); 2430 break; 2431 case PR_GET_DUMPABLE: 2432 error = get_dumpable(me->mm); 2433 break; 2434 case PR_SET_DUMPABLE: 2435 if (arg2 != SUID_DUMP_DISABLE && arg2 != SUID_DUMP_USER) { 2436 error = -EINVAL; 2437 break; 2438 } 2439 set_dumpable(me->mm, arg2); 2440 break; 2441 2442 case PR_SET_UNALIGN: 2443 error = SET_UNALIGN_CTL(me, arg2); 2444 break; 2445 case PR_GET_UNALIGN: 2446 error = GET_UNALIGN_CTL(me, arg2); 2447 break; 2448 case PR_SET_FPEMU: 2449 error = SET_FPEMU_CTL(me, arg2); 2450 break; 2451 case PR_GET_FPEMU: 2452 error = GET_FPEMU_CTL(me, arg2); 2453 break; 2454 case PR_SET_FPEXC: 2455 error = SET_FPEXC_CTL(me, arg2); 2456 break; 2457 case PR_GET_FPEXC: 2458 error = GET_FPEXC_CTL(me, arg2); 2459 break; 2460 case PR_GET_TIMING: 2461 error = PR_TIMING_STATISTICAL; 2462 break; 2463 case PR_SET_TIMING: 2464 if (arg2 != PR_TIMING_STATISTICAL) 2465 error = -EINVAL; 2466 break; 2467 case PR_SET_NAME: 2468 comm[sizeof(me->comm) - 1] = 0; 2469 if (strncpy_from_user(comm, (char __user *)arg2, 2470 sizeof(me->comm) - 1) < 0) 2471 return -EFAULT; 2472 set_task_comm(me, comm); 2473 proc_comm_connector(me); 2474 break; 2475 case PR_GET_NAME: 2476 get_task_comm(comm, me); 2477 if (copy_to_user((char __user *)arg2, comm, sizeof(comm))) 2478 return -EFAULT; 2479 break; 2480 case PR_GET_ENDIAN: 2481 error = GET_ENDIAN(me, arg2); 2482 break; 2483 case PR_SET_ENDIAN: 2484 error = SET_ENDIAN(me, arg2); 2485 break; 2486 case PR_GET_SECCOMP: 2487 error = prctl_get_seccomp(); 2488 break; 2489 case PR_SET_SECCOMP: 2490 error = prctl_set_seccomp(arg2, (char __user *)arg3); 2491 break; 2492 case PR_GET_TSC: 2493 error = GET_TSC_CTL(arg2); 2494 break; 2495 case PR_SET_TSC: 2496 error = SET_TSC_CTL(arg2); 2497 break; 2498 case PR_TASK_PERF_EVENTS_DISABLE: 2499 error = perf_event_task_disable(); 2500 break; 2501 case PR_TASK_PERF_EVENTS_ENABLE: 2502 error = perf_event_task_enable(); 2503 break; 2504 case PR_GET_TIMERSLACK: 2505 if (current->timer_slack_ns > ULONG_MAX) 2506 error = ULONG_MAX; 2507 else 2508 error = current->timer_slack_ns; 2509 break; 2510 case PR_SET_TIMERSLACK: 2511 if (arg2 <= 0) 2512 current->timer_slack_ns = 2513 current->default_timer_slack_ns; 2514 else 2515 current->timer_slack_ns = arg2; 2516 break; 2517 case PR_MCE_KILL: 2518 if (arg4 | arg5) 2519 return -EINVAL; 2520 switch (arg2) { 2521 case PR_MCE_KILL_CLEAR: 2522 if (arg3 != 0) 2523 return -EINVAL; 2524 current->flags &= ~PF_MCE_PROCESS; 2525 break; 2526 case PR_MCE_KILL_SET: 2527 current->flags |= PF_MCE_PROCESS; 2528 if (arg3 == PR_MCE_KILL_EARLY) 2529 current->flags |= PF_MCE_EARLY; 2530 else if (arg3 == PR_MCE_KILL_LATE) 2531 current->flags &= ~PF_MCE_EARLY; 2532 else if (arg3 == PR_MCE_KILL_DEFAULT) 2533 current->flags &= 2534 ~(PF_MCE_EARLY|PF_MCE_PROCESS); 2535 else 2536 return -EINVAL; 2537 break; 2538 case PR_GET_AUXV: 2539 if (arg4 || arg5) 2540 return -EINVAL; 2541 error = prctl_get_auxv((void __user *)arg2, arg3); 2542 break; 2543 default: 2544 return -EINVAL; 2545 } 2546 break; 2547 case PR_MCE_KILL_GET: 2548 if (arg2 | arg3 | arg4 | arg5) 2549 return -EINVAL; 2550 if (current->flags & PF_MCE_PROCESS) 2551 error = (current->flags & PF_MCE_EARLY) ? 2552 PR_MCE_KILL_EARLY : PR_MCE_KILL_LATE; 2553 else 2554 error = PR_MCE_KILL_DEFAULT; 2555 break; 2556 case PR_SET_MM: 2557 error = prctl_set_mm(arg2, arg3, arg4, arg5); 2558 break; 2559 case PR_GET_TID_ADDRESS: 2560 error = prctl_get_tid_address(me, (int __user * __user *)arg2); 2561 break; 2562 case PR_SET_CHILD_SUBREAPER: 2563 me->signal->is_child_subreaper = !!arg2; 2564 if (!arg2) 2565 break; 2566 2567 walk_process_tree(me, propagate_has_child_subreaper, NULL); 2568 break; 2569 case PR_GET_CHILD_SUBREAPER: 2570 error = put_user(me->signal->is_child_subreaper, 2571 (int __user *)arg2); 2572 break; 2573 case PR_SET_NO_NEW_PRIVS: 2574 if (arg2 != 1 || arg3 || arg4 || arg5) 2575 return -EINVAL; 2576 2577 task_set_no_new_privs(current); 2578 break; 2579 case PR_GET_NO_NEW_PRIVS: 2580 if (arg2 || arg3 || arg4 || arg5) 2581 return -EINVAL; 2582 return task_no_new_privs(current) ? 1 : 0; 2583 case PR_GET_THP_DISABLE: 2584 if (arg2 || arg3 || arg4 || arg5) 2585 return -EINVAL; 2586 error = !!test_bit(MMF_DISABLE_THP, &me->mm->flags); 2587 break; 2588 case PR_SET_THP_DISABLE: 2589 if (arg3 || arg4 || arg5) 2590 return -EINVAL; 2591 if (mmap_write_lock_killable(me->mm)) 2592 return -EINTR; 2593 if (arg2) 2594 set_bit(MMF_DISABLE_THP, &me->mm->flags); 2595 else 2596 clear_bit(MMF_DISABLE_THP, &me->mm->flags); 2597 mmap_write_unlock(me->mm); 2598 break; 2599 case PR_MPX_ENABLE_MANAGEMENT: 2600 case PR_MPX_DISABLE_MANAGEMENT: 2601 /* No longer implemented: */ 2602 return -EINVAL; 2603 case PR_SET_FP_MODE: 2604 error = SET_FP_MODE(me, arg2); 2605 break; 2606 case PR_GET_FP_MODE: 2607 error = GET_FP_MODE(me); 2608 break; 2609 case PR_SVE_SET_VL: 2610 error = SVE_SET_VL(arg2); 2611 break; 2612 case PR_SVE_GET_VL: 2613 error = SVE_GET_VL(); 2614 break; 2615 case PR_SME_SET_VL: 2616 error = SME_SET_VL(arg2); 2617 break; 2618 case PR_SME_GET_VL: 2619 error = SME_GET_VL(); 2620 break; 2621 case PR_GET_SPECULATION_CTRL: 2622 if (arg3 || arg4 || arg5) 2623 return -EINVAL; 2624 error = arch_prctl_spec_ctrl_get(me, arg2); 2625 break; 2626 case PR_SET_SPECULATION_CTRL: 2627 if (arg4 || arg5) 2628 return -EINVAL; 2629 error = arch_prctl_spec_ctrl_set(me, arg2, arg3); 2630 break; 2631 case PR_PAC_RESET_KEYS: 2632 if (arg3 || arg4 || arg5) 2633 return -EINVAL; 2634 error = PAC_RESET_KEYS(me, arg2); 2635 break; 2636 case PR_PAC_SET_ENABLED_KEYS: 2637 if (arg4 || arg5) 2638 return -EINVAL; 2639 error = PAC_SET_ENABLED_KEYS(me, arg2, arg3); 2640 break; 2641 case PR_PAC_GET_ENABLED_KEYS: 2642 if (arg2 || arg3 || arg4 || arg5) 2643 return -EINVAL; 2644 error = PAC_GET_ENABLED_KEYS(me); 2645 break; 2646 case PR_SET_TAGGED_ADDR_CTRL: 2647 if (arg3 || arg4 || arg5) 2648 return -EINVAL; 2649 error = SET_TAGGED_ADDR_CTRL(arg2); 2650 break; 2651 case PR_GET_TAGGED_ADDR_CTRL: 2652 if (arg2 || arg3 || arg4 || arg5) 2653 return -EINVAL; 2654 error = GET_TAGGED_ADDR_CTRL(); 2655 break; 2656 case PR_SET_IO_FLUSHER: 2657 if (!capable(CAP_SYS_RESOURCE)) 2658 return -EPERM; 2659 2660 if (arg3 || arg4 || arg5) 2661 return -EINVAL; 2662 2663 if (arg2 == 1) 2664 current->flags |= PR_IO_FLUSHER; 2665 else if (!arg2) 2666 current->flags &= ~PR_IO_FLUSHER; 2667 else 2668 return -EINVAL; 2669 break; 2670 case PR_GET_IO_FLUSHER: 2671 if (!capable(CAP_SYS_RESOURCE)) 2672 return -EPERM; 2673 2674 if (arg2 || arg3 || arg4 || arg5) 2675 return -EINVAL; 2676 2677 error = (current->flags & PR_IO_FLUSHER) == PR_IO_FLUSHER; 2678 break; 2679 case PR_SET_SYSCALL_USER_DISPATCH: 2680 error = set_syscall_user_dispatch(arg2, arg3, arg4, 2681 (char __user *) arg5); 2682 break; 2683 #ifdef CONFIG_SCHED_CORE 2684 case PR_SCHED_CORE: 2685 error = sched_core_share_pid(arg2, arg3, arg4, arg5); 2686 break; 2687 #endif 2688 case PR_SET_MDWE: 2689 error = prctl_set_mdwe(arg2, arg3, arg4, arg5); 2690 break; 2691 case PR_GET_MDWE: 2692 error = prctl_get_mdwe(arg2, arg3, arg4, arg5); 2693 break; 2694 case PR_SET_VMA: 2695 error = prctl_set_vma(arg2, arg3, arg4, arg5); 2696 break; 2697 #ifdef CONFIG_KSM 2698 case PR_SET_MEMORY_MERGE: 2699 if (arg3 || arg4 || arg5) 2700 return -EINVAL; 2701 if (mmap_write_lock_killable(me->mm)) 2702 return -EINTR; 2703 2704 if (arg2) 2705 error = ksm_enable_merge_any(me->mm); 2706 else 2707 error = ksm_disable_merge_any(me->mm); 2708 mmap_write_unlock(me->mm); 2709 break; 2710 case PR_GET_MEMORY_MERGE: 2711 if (arg2 || arg3 || arg4 || arg5) 2712 return -EINVAL; 2713 2714 error = !!test_bit(MMF_VM_MERGE_ANY, &me->mm->flags); 2715 break; 2716 #endif 2717 case PR_RISCV_V_SET_CONTROL: > 2718 error = RISCV_V_SET_CONTROL(arg2); 2719 break; 2720 case PR_RISCV_V_GET_CONTROL: > 2721 error = RISCV_V_GET_CONTROL(); 2722 break; 2723 default: 2724 error = -EINVAL; 2725 break; 2726 } 2727 return error; 2728 } 2729
On Sun, May 21, 2023 at 9:51 AM kernel test robot <lkp@intel.com> wrote: > > Hi Andy, > > kernel test robot noticed the following build errors: > > [auto build test ERROR on next-20230518] > > url: https://github.com/intel-lab-lkp/linux/commits/Andy-Chiu/riscv-Rename-__switch_to_aux-fpu/20230519-005938 > base: next-20230518 > patch link: https://lore.kernel.org/r/20230518161949.11203-21-andy.chiu%40sifive.com > patch subject: [PATCH -next v20 20/26] riscv: Add prctl controls for userspace vector management > config: arm-sp7021_defconfig > compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project b0fb98227c90adf2536c9ad644a74d5e92961111) > reproduce (this is a W=1 build): > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross > chmod +x ~/bin/make.cross > # install arm cross compiling tool for clang build > # apt-get install binutils-arm-linux-gnueabi > # https://github.com/intel-lab-lkp/linux/commit/eef6095228f3323db8f2bddd5bde768976888558 > git remote add linux-review https://github.com/intel-lab-lkp/linux > git fetch --no-tags linux-review Andy-Chiu/riscv-Rename-__switch_to_aux-fpu/20230519-005938 > git checkout eef6095228f3323db8f2bddd5bde768976888558 > # save the config file > mkdir build_dir && cp config build_dir/.config > COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm olddefconfig > COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash > > If you fix the issue, kindly add following tag where applicable > | Reported-by: kernel test robot <lkp@intel.com> > | Closes: https://lore.kernel.org/oe-kbuild-all/202305210917.aS7cWlKv-lkp@intel.com/ > > All errors (new ones prefixed by >>): > > >> kernel/sys.c:2718:11: error: call to undeclared function 'RISCV_V_SET_CONTROL'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] > error = RISCV_V_SET_CONTROL(arg2); > ^ > >> kernel/sys.c:2721:11: error: call to undeclared function 'RISCV_V_GET_CONTROL'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] > error = RISCV_V_GET_CONTROL(); > ^ > 2 errors generated. > > > vim +/RISCV_V_SET_CONTROL +2718 kernel/sys.c > > 2407 > 2408 SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, > 2409 unsigned long, arg4, unsigned long, arg5) > 2410 { > 2411 struct task_struct *me = current; > 2412 unsigned char comm[sizeof(me->comm)]; > 2413 long error; > 2414 > 2415 error = security_task_prctl(option, arg2, arg3, arg4, arg5); > 2416 if (error != -ENOSYS) > 2417 return error; > 2418 > 2419 error = 0; > 2420 switch (option) { > 2421 case PR_SET_PDEATHSIG: > 2422 if (!valid_signal(arg2)) { > 2423 error = -EINVAL; > 2424 break; > 2425 } > 2426 me->pdeath_signal = arg2; > 2427 break; > 2428 case PR_GET_PDEATHSIG: > 2429 error = put_user(me->pdeath_signal, (int __user *)arg2); > 2430 break; > 2431 case PR_GET_DUMPABLE: > 2432 error = get_dumpable(me->mm); > 2433 break; > 2434 case PR_SET_DUMPABLE: > 2435 if (arg2 != SUID_DUMP_DISABLE && arg2 != SUID_DUMP_USER) { > 2436 error = -EINVAL; > 2437 break; > 2438 } > 2439 set_dumpable(me->mm, arg2); > 2440 break; > 2441 > 2442 case PR_SET_UNALIGN: > 2443 error = SET_UNALIGN_CTL(me, arg2); > 2444 break; > 2445 case PR_GET_UNALIGN: > 2446 error = GET_UNALIGN_CTL(me, arg2); > 2447 break; > 2448 case PR_SET_FPEMU: > 2449 error = SET_FPEMU_CTL(me, arg2); > 2450 break; > 2451 case PR_GET_FPEMU: > 2452 error = GET_FPEMU_CTL(me, arg2); > 2453 break; > 2454 case PR_SET_FPEXC: > 2455 error = SET_FPEXC_CTL(me, arg2); > 2456 break; > 2457 case PR_GET_FPEXC: > 2458 error = GET_FPEXC_CTL(me, arg2); > 2459 break; > 2460 case PR_GET_TIMING: > 2461 error = PR_TIMING_STATISTICAL; > 2462 break; > 2463 case PR_SET_TIMING: > 2464 if (arg2 != PR_TIMING_STATISTICAL) > 2465 error = -EINVAL; > 2466 break; > 2467 case PR_SET_NAME: > 2468 comm[sizeof(me->comm) - 1] = 0; > 2469 if (strncpy_from_user(comm, (char __user *)arg2, > 2470 sizeof(me->comm) - 1) < 0) > 2471 return -EFAULT; > 2472 set_task_comm(me, comm); > 2473 proc_comm_connector(me); > 2474 break; > 2475 case PR_GET_NAME: > 2476 get_task_comm(comm, me); > 2477 if (copy_to_user((char __user *)arg2, comm, sizeof(comm))) > 2478 return -EFAULT; > 2479 break; > 2480 case PR_GET_ENDIAN: > 2481 error = GET_ENDIAN(me, arg2); > 2482 break; > 2483 case PR_SET_ENDIAN: > 2484 error = SET_ENDIAN(me, arg2); > 2485 break; > 2486 case PR_GET_SECCOMP: > 2487 error = prctl_get_seccomp(); > 2488 break; > 2489 case PR_SET_SECCOMP: > 2490 error = prctl_set_seccomp(arg2, (char __user *)arg3); > 2491 break; > 2492 case PR_GET_TSC: > 2493 error = GET_TSC_CTL(arg2); > 2494 break; > 2495 case PR_SET_TSC: > 2496 error = SET_TSC_CTL(arg2); > 2497 break; > 2498 case PR_TASK_PERF_EVENTS_DISABLE: > 2499 error = perf_event_task_disable(); > 2500 break; > 2501 case PR_TASK_PERF_EVENTS_ENABLE: > 2502 error = perf_event_task_enable(); > 2503 break; > 2504 case PR_GET_TIMERSLACK: > 2505 if (current->timer_slack_ns > ULONG_MAX) > 2506 error = ULONG_MAX; > 2507 else > 2508 error = current->timer_slack_ns; > 2509 break; > 2510 case PR_SET_TIMERSLACK: > 2511 if (arg2 <= 0) > 2512 current->timer_slack_ns = > 2513 current->default_timer_slack_ns; > 2514 else > 2515 current->timer_slack_ns = arg2; > 2516 break; > 2517 case PR_MCE_KILL: > 2518 if (arg4 | arg5) > 2519 return -EINVAL; > 2520 switch (arg2) { > 2521 case PR_MCE_KILL_CLEAR: > 2522 if (arg3 != 0) > 2523 return -EINVAL; > 2524 current->flags &= ~PF_MCE_PROCESS; > 2525 break; > 2526 case PR_MCE_KILL_SET: > 2527 current->flags |= PF_MCE_PROCESS; > 2528 if (arg3 == PR_MCE_KILL_EARLY) > 2529 current->flags |= PF_MCE_EARLY; > 2530 else if (arg3 == PR_MCE_KILL_LATE) > 2531 current->flags &= ~PF_MCE_EARLY; > 2532 else if (arg3 == PR_MCE_KILL_DEFAULT) > 2533 current->flags &= > 2534 ~(PF_MCE_EARLY|PF_MCE_PROCESS); > 2535 else > 2536 return -EINVAL; > 2537 break; > 2538 case PR_GET_AUXV: > 2539 if (arg4 || arg5) > 2540 return -EINVAL; > 2541 error = prctl_get_auxv((void __user *)arg2, arg3); > 2542 break; > 2543 default: > 2544 return -EINVAL; > 2545 } > 2546 break; > 2547 case PR_MCE_KILL_GET: > 2548 if (arg2 | arg3 | arg4 | arg5) > 2549 return -EINVAL; > 2550 if (current->flags & PF_MCE_PROCESS) > 2551 error = (current->flags & PF_MCE_EARLY) ? > 2552 PR_MCE_KILL_EARLY : PR_MCE_KILL_LATE; > 2553 else > 2554 error = PR_MCE_KILL_DEFAULT; > 2555 break; > 2556 case PR_SET_MM: > 2557 error = prctl_set_mm(arg2, arg3, arg4, arg5); > 2558 break; > 2559 case PR_GET_TID_ADDRESS: > 2560 error = prctl_get_tid_address(me, (int __user * __user *)arg2); > 2561 break; > 2562 case PR_SET_CHILD_SUBREAPER: > 2563 me->signal->is_child_subreaper = !!arg2; > 2564 if (!arg2) > 2565 break; > 2566 > 2567 walk_process_tree(me, propagate_has_child_subreaper, NULL); > 2568 break; > 2569 case PR_GET_CHILD_SUBREAPER: > 2570 error = put_user(me->signal->is_child_subreaper, > 2571 (int __user *)arg2); > 2572 break; > 2573 case PR_SET_NO_NEW_PRIVS: > 2574 if (arg2 != 1 || arg3 || arg4 || arg5) > 2575 return -EINVAL; > 2576 > 2577 task_set_no_new_privs(current); > 2578 break; > 2579 case PR_GET_NO_NEW_PRIVS: > 2580 if (arg2 || arg3 || arg4 || arg5) > 2581 return -EINVAL; > 2582 return task_no_new_privs(current) ? 1 : 0; > 2583 case PR_GET_THP_DISABLE: > 2584 if (arg2 || arg3 || arg4 || arg5) > 2585 return -EINVAL; > 2586 error = !!test_bit(MMF_DISABLE_THP, &me->mm->flags); > 2587 break; > 2588 case PR_SET_THP_DISABLE: > 2589 if (arg3 || arg4 || arg5) > 2590 return -EINVAL; > 2591 if (mmap_write_lock_killable(me->mm)) > 2592 return -EINTR; > 2593 if (arg2) > 2594 set_bit(MMF_DISABLE_THP, &me->mm->flags); > 2595 else > 2596 clear_bit(MMF_DISABLE_THP, &me->mm->flags); > 2597 mmap_write_unlock(me->mm); > 2598 break; > 2599 case PR_MPX_ENABLE_MANAGEMENT: > 2600 case PR_MPX_DISABLE_MANAGEMENT: > 2601 /* No longer implemented: */ > 2602 return -EINVAL; > 2603 case PR_SET_FP_MODE: > 2604 error = SET_FP_MODE(me, arg2); > 2605 break; > 2606 case PR_GET_FP_MODE: > 2607 error = GET_FP_MODE(me); > 2608 break; > 2609 case PR_SVE_SET_VL: > 2610 error = SVE_SET_VL(arg2); > 2611 break; > 2612 case PR_SVE_GET_VL: > 2613 error = SVE_GET_VL(); > 2614 break; > 2615 case PR_SME_SET_VL: > 2616 error = SME_SET_VL(arg2); > 2617 break; > 2618 case PR_SME_GET_VL: > 2619 error = SME_GET_VL(); > 2620 break; > 2621 case PR_GET_SPECULATION_CTRL: > 2622 if (arg3 || arg4 || arg5) > 2623 return -EINVAL; > 2624 error = arch_prctl_spec_ctrl_get(me, arg2); > 2625 break; > 2626 case PR_SET_SPECULATION_CTRL: > 2627 if (arg4 || arg5) > 2628 return -EINVAL; > 2629 error = arch_prctl_spec_ctrl_set(me, arg2, arg3); > 2630 break; > 2631 case PR_PAC_RESET_KEYS: > 2632 if (arg3 || arg4 || arg5) > 2633 return -EINVAL; > 2634 error = PAC_RESET_KEYS(me, arg2); > 2635 break; > 2636 case PR_PAC_SET_ENABLED_KEYS: > 2637 if (arg4 || arg5) > 2638 return -EINVAL; > 2639 error = PAC_SET_ENABLED_KEYS(me, arg2, arg3); > 2640 break; > 2641 case PR_PAC_GET_ENABLED_KEYS: > 2642 if (arg2 || arg3 || arg4 || arg5) > 2643 return -EINVAL; > 2644 error = PAC_GET_ENABLED_KEYS(me); > 2645 break; > 2646 case PR_SET_TAGGED_ADDR_CTRL: > 2647 if (arg3 || arg4 || arg5) > 2648 return -EINVAL; > 2649 error = SET_TAGGED_ADDR_CTRL(arg2); > 2650 break; > 2651 case PR_GET_TAGGED_ADDR_CTRL: > 2652 if (arg2 || arg3 || arg4 || arg5) > 2653 return -EINVAL; > 2654 error = GET_TAGGED_ADDR_CTRL(); > 2655 break; > 2656 case PR_SET_IO_FLUSHER: > 2657 if (!capable(CAP_SYS_RESOURCE)) > 2658 return -EPERM; > 2659 > 2660 if (arg3 || arg4 || arg5) > 2661 return -EINVAL; > 2662 > 2663 if (arg2 == 1) > 2664 current->flags |= PR_IO_FLUSHER; > 2665 else if (!arg2) > 2666 current->flags &= ~PR_IO_FLUSHER; > 2667 else > 2668 return -EINVAL; > 2669 break; > 2670 case PR_GET_IO_FLUSHER: > 2671 if (!capable(CAP_SYS_RESOURCE)) > 2672 return -EPERM; > 2673 > 2674 if (arg2 || arg3 || arg4 || arg5) > 2675 return -EINVAL; > 2676 > 2677 error = (current->flags & PR_IO_FLUSHER) == PR_IO_FLUSHER; > 2678 break; > 2679 case PR_SET_SYSCALL_USER_DISPATCH: > 2680 error = set_syscall_user_dispatch(arg2, arg3, arg4, > 2681 (char __user *) arg5); > 2682 break; > 2683 #ifdef CONFIG_SCHED_CORE > 2684 case PR_SCHED_CORE: > 2685 error = sched_core_share_pid(arg2, arg3, arg4, arg5); > 2686 break; > 2687 #endif > 2688 case PR_SET_MDWE: > 2689 error = prctl_set_mdwe(arg2, arg3, arg4, arg5); > 2690 break; > 2691 case PR_GET_MDWE: > 2692 error = prctl_get_mdwe(arg2, arg3, arg4, arg5); > 2693 break; > 2694 case PR_SET_VMA: > 2695 error = prctl_set_vma(arg2, arg3, arg4, arg5); > 2696 break; > 2697 #ifdef CONFIG_KSM > 2698 case PR_SET_MEMORY_MERGE: > 2699 if (arg3 || arg4 || arg5) > 2700 return -EINVAL; > 2701 if (mmap_write_lock_killable(me->mm)) > 2702 return -EINTR; > 2703 > 2704 if (arg2) > 2705 error = ksm_enable_merge_any(me->mm); > 2706 else > 2707 error = ksm_disable_merge_any(me->mm); > 2708 mmap_write_unlock(me->mm); > 2709 break; > 2710 case PR_GET_MEMORY_MERGE: > 2711 if (arg2 || arg3 || arg4 || arg5) > 2712 return -EINVAL; > 2713 > 2714 error = !!test_bit(MMF_VM_MERGE_ANY, &me->mm->flags); > 2715 break; > 2716 #endif > 2717 case PR_RISCV_V_SET_CONTROL: > > 2718 error = RISCV_V_SET_CONTROL(arg2); > 2719 break; > 2720 case PR_RISCV_V_GET_CONTROL: > > 2721 error = RISCV_V_GET_CONTROL(); > 2722 break; > 2723 default: > 2724 error = -EINVAL; > 2725 break; > 2726 } > 2727 return error; > 2728 } > 2729 > > -- > 0-DAY CI Kernel Test Service > https://github.com/intel/lkp-tests/wiki This is the case that Björn mentioned in v19[1] but I was too careless to address it fully. I am going to repsin v21 and solve it (including the else-clause in processor.h). [1]: https://lore.kernel.org/all/87ttwdhljn.fsf@all.your.base.are.belong.to.us/ Thanks, Andy
Andy Chiu <andy.chiu@sifive.com> writes: > This patch add two riscv-specific prctls, to allow usespace control the > use of vector unit: > > * PR_RISCV_V_SET_CONTROL: control the permission to use Vector at next, > or all following execve for a thread. Turning off a thread's Vector > live is not possible since libraries may have registered ifunc that > may execute Vector instructions. > * PR_RISCV_V_GET_CONTROL: get the same permission setting for the > current thread, and the setting for following execve(s). > > Signed-off-by: Andy Chiu <andy.chiu@sifive.com> > Reviewed-by: Greentime Hu <greentime.hu@sifive.com> > Reviewed-by: Vincent Chen <vincent.chen@sifive.com> > --- > Changelog v20: > - address build issue when KVM is compile as a module (Heiko) > - s/RISCV_V_DISABLE/RISCV_ISA_V_DEFAULT_ENABLE/ (Conor) > - change function names to have better scoping > - check has_vector() before accessing vstate_ctrl > - use proper return type for prctl calls (long instead of uint) > --- > arch/riscv/include/asm/processor.h | 13 ++++ > arch/riscv/include/asm/vector.h | 4 + > arch/riscv/kernel/process.c | 1 + > arch/riscv/kernel/vector.c | 118 +++++++++++++++++++++++++++++ > arch/riscv/kvm/vcpu.c | 2 + > include/uapi/linux/prctl.h | 11 +++ > kernel/sys.c | 12 +++ > 7 files changed, 161 insertions(+) > > diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h > index 38ded8c5f207..17829c3003c8 100644 > --- a/arch/riscv/include/asm/processor.h > +++ b/arch/riscv/include/asm/processor.h > @@ -40,6 +40,7 @@ struct thread_struct { > unsigned long s[12]; /* s[0]: frame pointer */ > struct __riscv_d_ext_state fstate; > unsigned long bad_cause; > + unsigned long vstate_ctrl; > struct __riscv_v_ext_state vstate; > }; > > @@ -83,6 +84,18 @@ extern void riscv_fill_hwcap(void); > extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); > > extern unsigned long signal_minsigstksz __ro_after_init; > + > +#ifdef CONFIG_RISCV_ISA_V > +/* Userspace interface for PR_RISCV_V_{SET,GET}_VS prctl()s: */ > +#define RISCV_V_SET_CONTROL(arg) riscv_v_vstate_ctrl_set_current(arg) > +#define RISCV_V_GET_CONTROL() riscv_v_vstate_ctrl_get_current() > +extern long riscv_v_vstate_ctrl_set_current(unsigned long arg); > +extern long riscv_v_vstate_ctrl_get_current(void); > +#else /* !CONFIG_RISCV_ISA_V */ > +#define RISCV_V_SET_CONTROL(arg) (-EINVAL) > +#define RISCV_V_GET_CONTROL() (-EINVAL) This version doesn't fix the issue I pointed out in [1]. Let me try to be more explicit. RISCV_V_GET_CONTROL and RISCV_V_SET_CONTROL are a function (if CONFIG_RISCV_ISA_V is defined), otherwise (-EINVAL). However, they are redefined below, so you can remove the whole #else to #endif... [...] > diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h > index f23d9a16507f..3c36aeade991 100644 > --- a/include/uapi/linux/prctl.h > +++ b/include/uapi/linux/prctl.h > @@ -294,4 +294,15 @@ struct prctl_mm_map { > > #define PR_SET_MEMORY_MERGE 67 > #define PR_GET_MEMORY_MERGE 68 > + > +#define PR_RISCV_V_SET_CONTROL 69 > +#define PR_RISCV_V_GET_CONTROL 70 > +# define PR_RISCV_V_VSTATE_CTRL_DEFAULT 0 > +# define PR_RISCV_V_VSTATE_CTRL_OFF 1 > +# define PR_RISCV_V_VSTATE_CTRL_ON 2 > +# define PR_RISCV_V_VSTATE_CTRL_INHERIT (1 << 4) > +# define PR_RISCV_V_VSTATE_CTRL_CUR_MASK 0x3 > +# define PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 0xc > +# define PR_RISCV_V_VSTATE_CTRL_MASK 0x1f > + > #endif /* _LINUX_PRCTL_H */ > diff --git a/kernel/sys.c b/kernel/sys.c > index 339fee3eff6a..d0d3106698a1 100644 > --- a/kernel/sys.c > +++ b/kernel/sys.c > @@ -140,6 +140,12 @@ > #ifndef GET_TAGGED_ADDR_CTRL > # define GET_TAGGED_ADDR_CTRL() (-EINVAL) > #endif > +#ifndef PR_RISCV_V_SET_CONTROL > +# define RISCV_V_SET_CONTROL(a) (-EINVAL) > +#endif > +#ifndef PR_RISCV_V_GET_CONTROL > +# define RISCV_V_GET_CONTROL() (-EINVAL) > +#endif ...because they are defined to EINVAL here. Or at least they are supposed to. Now, the 2nd issue was that #ifndef PR_RISCV_V_SET_CONTROL should be #ifndef RISCV_V_SET_CONTROL (and dito for GET). PR_RISCV_V_SET_CONTROL is *always* defined in the uapi header above. So, change to: | #ifndef RISCV_V_SET_CONTROL | # define RISCV_V_SET_CONTROL(a) (-EINVAL) | #endif | #ifndef RISCV_V_GET_CONTROL | # define RISCV_V_GET_CONTROL() (-EINVAL) | #endif and remove the #else above. > > /* > * this is where the system-wide overflow UID and GID are defined, for > @@ -2708,6 +2714,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, > error = !!test_bit(MMF_VM_MERGE_ANY, &me->mm->flags); > break; > #endif > + case PR_RISCV_V_SET_CONTROL: > + error = RISCV_V_SET_CONTROL(arg2); > + break; > + case PR_RISCV_V_GET_CONTROL: > + error = RISCV_V_GET_CONTROL(); PR_RISCV_V_{GET,SET}_CONTROL is always set! Björn [1] https://lore.kernel.org/linux-riscv/87ttwdhljn.fsf@all.your.base.are.belong.to.us/
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h index 38ded8c5f207..17829c3003c8 100644 --- a/arch/riscv/include/asm/processor.h +++ b/arch/riscv/include/asm/processor.h @@ -40,6 +40,7 @@ struct thread_struct { unsigned long s[12]; /* s[0]: frame pointer */ struct __riscv_d_ext_state fstate; unsigned long bad_cause; + unsigned long vstate_ctrl; struct __riscv_v_ext_state vstate; }; @@ -83,6 +84,18 @@ extern void riscv_fill_hwcap(void); extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); extern unsigned long signal_minsigstksz __ro_after_init; + +#ifdef CONFIG_RISCV_ISA_V +/* Userspace interface for PR_RISCV_V_{SET,GET}_VS prctl()s: */ +#define RISCV_V_SET_CONTROL(arg) riscv_v_vstate_ctrl_set_current(arg) +#define RISCV_V_GET_CONTROL() riscv_v_vstate_ctrl_get_current() +extern long riscv_v_vstate_ctrl_set_current(unsigned long arg); +extern long riscv_v_vstate_ctrl_get_current(void); +#else /* !CONFIG_RISCV_ISA_V */ +#define RISCV_V_SET_CONTROL(arg) (-EINVAL) +#define RISCV_V_GET_CONTROL() (-EINVAL) +#endif /* CONFIG_RISCV_ISA_V */ + #endif /* __ASSEMBLY__ */ #endif /* _ASM_RISCV_PROCESSOR_H */ diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h index 8e56da67b5cf..04c0b07bf6cd 100644 --- a/arch/riscv/include/asm/vector.h +++ b/arch/riscv/include/asm/vector.h @@ -160,6 +160,9 @@ static inline void __switch_to_vector(struct task_struct *prev, riscv_v_vstate_restore(next, task_pt_regs(next)); } +void riscv_v_vstate_ctrl_init(struct task_struct *tsk); +bool riscv_v_vstate_ctrl_user_allowed(void); + #else /* ! CONFIG_RISCV_ISA_V */ struct pt_regs; @@ -168,6 +171,7 @@ static inline int riscv_v_setup_vsize(void) { return -EOPNOTSUPP; } static __always_inline bool has_vector(void) { return false; } static inline bool riscv_v_first_use_handler(struct pt_regs *regs) { return false; } static inline bool riscv_v_vstate_query(struct pt_regs *regs) { return false; } +static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; } #define riscv_v_vsize (0) #define riscv_v_vstate_save(task, regs) do {} while (0) #define riscv_v_vstate_restore(task, regs) do {} while (0) diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c index b7a10361ddc6..60278233926c 100644 --- a/arch/riscv/kernel/process.c +++ b/arch/riscv/kernel/process.c @@ -149,6 +149,7 @@ void flush_thread(void) #endif #ifdef CONFIG_RISCV_ISA_V /* Reset vector state */ + riscv_v_vstate_ctrl_init(current); riscv_v_vstate_off(task_pt_regs(current)); kfree(current->thread.vstate.datap); memset(¤t->thread.vstate, 0, sizeof(struct __riscv_v_ext_state)); diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c index 0080798e8d2e..9bee7a201106 100644 --- a/arch/riscv/kernel/vector.c +++ b/arch/riscv/kernel/vector.c @@ -9,6 +9,7 @@ #include <linux/slab.h> #include <linux/sched.h> #include <linux/uaccess.h> +#include <linux/prctl.h> #include <asm/thread_info.h> #include <asm/processor.h> @@ -19,6 +20,8 @@ #include <asm/ptrace.h> #include <asm/bug.h> +static bool riscv_v_implicit_uacc = IS_ENABLED(CONFIG_RISCV_ISA_V_DEFAULT_ENABLE); + unsigned long riscv_v_vsize __read_mostly; EXPORT_SYMBOL_GPL(riscv_v_vsize); @@ -91,6 +94,43 @@ static int riscv_v_thread_zalloc(void) return 0; } +#define VSTATE_CTRL_GET_CUR(x) ((x) & PR_RISCV_V_VSTATE_CTRL_CUR_MASK) +#define VSTATE_CTRL_GET_NEXT(x) (((x) & PR_RISCV_V_VSTATE_CTRL_NEXT_MASK) >> 2) +#define VSTATE_CTRL_MAKE_NEXT(x) (((x) << 2) & PR_RISCV_V_VSTATE_CTRL_NEXT_MASK) +#define VSTATE_CTRL_GET_INHERIT(x) (!!((x) & PR_RISCV_V_VSTATE_CTRL_INHERIT)) +static inline int riscv_v_ctrl_get_cur(struct task_struct *tsk) +{ + return VSTATE_CTRL_GET_CUR(tsk->thread.vstate_ctrl); +} + +static inline int riscv_v_ctrl_get_next(struct task_struct *tsk) +{ + return VSTATE_CTRL_GET_NEXT(tsk->thread.vstate_ctrl); +} + +static inline bool riscv_v_ctrl_test_inherit(struct task_struct *tsk) +{ + return VSTATE_CTRL_GET_INHERIT(tsk->thread.vstate_ctrl); +} + +static inline void riscv_v_ctrl_set(struct task_struct *tsk, int cur, int nxt, + bool inherit) +{ + unsigned long ctrl; + + ctrl = cur & PR_RISCV_V_VSTATE_CTRL_CUR_MASK; + ctrl |= VSTATE_CTRL_MAKE_NEXT(nxt); + if (inherit) + ctrl |= PR_RISCV_V_VSTATE_CTRL_INHERIT; + tsk->thread.vstate_ctrl = ctrl; +} + +bool riscv_v_vstate_ctrl_user_allowed(void) +{ + return riscv_v_ctrl_get_cur(current) == PR_RISCV_V_VSTATE_CTRL_ON; +} +EXPORT_SYMBOL_GPL(riscv_v_vstate_ctrl_user_allowed); + bool riscv_v_first_use_handler(struct pt_regs *regs) { u32 __user *epc = (u32 __user *)regs->epc; @@ -100,6 +140,10 @@ bool riscv_v_first_use_handler(struct pt_regs *regs) if (!has_vector() || !(elf_hwcap & COMPAT_HWCAP_ISA_V)) return false; + /* Do not handle the trap if V is not allowed for this process*/ + if (!riscv_v_vstate_ctrl_user_allowed()) + return false; + /* If V has been enabled then it is not the first-use trap */ if (riscv_v_vstate_query(regs)) return false; @@ -129,3 +173,77 @@ bool riscv_v_first_use_handler(struct pt_regs *regs) riscv_v_vstate_on(regs); return true; } + +void riscv_v_vstate_ctrl_init(struct task_struct *tsk) +{ + bool inherit; + int cur, next; + + if (!has_vector()) + return; + + next = riscv_v_ctrl_get_next(tsk); + if (!next) { + if (riscv_v_implicit_uacc) + cur = PR_RISCV_V_VSTATE_CTRL_ON; + else + cur = PR_RISCV_V_VSTATE_CTRL_OFF; + } else { + cur = next; + } + /* Clear next mask if inherit-bit is not set */ + inherit = riscv_v_ctrl_test_inherit(tsk); + if (!inherit) + next = PR_RISCV_V_VSTATE_CTRL_DEFAULT; + + riscv_v_ctrl_set(tsk, cur, next, inherit); +} + +long riscv_v_vstate_ctrl_get_current(void) +{ + if (!has_vector()) + return -EINVAL; + + return current->thread.vstate_ctrl & PR_RISCV_V_VSTATE_CTRL_MASK; +} + +long riscv_v_vstate_ctrl_set_current(unsigned long arg) +{ + bool inherit; + int cur, next; + + if (!has_vector()) + return -EINVAL; + + if (arg & ~PR_RISCV_V_VSTATE_CTRL_MASK) + return -EINVAL; + + cur = VSTATE_CTRL_GET_CUR(arg); + switch (cur) { + case PR_RISCV_V_VSTATE_CTRL_OFF: + /* Do not allow user to turn off V if current is not off */ + if (riscv_v_ctrl_get_cur(current) != PR_RISCV_V_VSTATE_CTRL_OFF) + return -EPERM; + + break; + case PR_RISCV_V_VSTATE_CTRL_ON: + break; + case PR_RISCV_V_VSTATE_CTRL_DEFAULT: + cur = riscv_v_ctrl_get_cur(current); + break; + default: + return -EINVAL; + } + + next = VSTATE_CTRL_GET_NEXT(arg); + inherit = VSTATE_CTRL_GET_INHERIT(arg); + switch (next) { + case PR_RISCV_V_VSTATE_CTRL_DEFAULT: + case PR_RISCV_V_VSTATE_CTRL_OFF: + case PR_RISCV_V_VSTATE_CTRL_ON: + riscv_v_ctrl_set(current, cur, next, inherit); + return 0; + } + + return -EINVAL; +} diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index e5e045852e6a..de24127e7e93 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -88,6 +88,8 @@ static bool kvm_riscv_vcpu_isa_enable_allowed(unsigned long ext) switch (ext) { case KVM_RISCV_ISA_EXT_H: return false; + case KVM_RISCV_ISA_EXT_V: + return riscv_v_vstate_ctrl_user_allowed(); default: break; } diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index f23d9a16507f..3c36aeade991 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -294,4 +294,15 @@ struct prctl_mm_map { #define PR_SET_MEMORY_MERGE 67 #define PR_GET_MEMORY_MERGE 68 + +#define PR_RISCV_V_SET_CONTROL 69 +#define PR_RISCV_V_GET_CONTROL 70 +# define PR_RISCV_V_VSTATE_CTRL_DEFAULT 0 +# define PR_RISCV_V_VSTATE_CTRL_OFF 1 +# define PR_RISCV_V_VSTATE_CTRL_ON 2 +# define PR_RISCV_V_VSTATE_CTRL_INHERIT (1 << 4) +# define PR_RISCV_V_VSTATE_CTRL_CUR_MASK 0x3 +# define PR_RISCV_V_VSTATE_CTRL_NEXT_MASK 0xc +# define PR_RISCV_V_VSTATE_CTRL_MASK 0x1f + #endif /* _LINUX_PRCTL_H */ diff --git a/kernel/sys.c b/kernel/sys.c index 339fee3eff6a..d0d3106698a1 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -140,6 +140,12 @@ #ifndef GET_TAGGED_ADDR_CTRL # define GET_TAGGED_ADDR_CTRL() (-EINVAL) #endif +#ifndef PR_RISCV_V_SET_CONTROL +# define RISCV_V_SET_CONTROL(a) (-EINVAL) +#endif +#ifndef PR_RISCV_V_GET_CONTROL +# define RISCV_V_GET_CONTROL() (-EINVAL) +#endif /* * this is where the system-wide overflow UID and GID are defined, for @@ -2708,6 +2714,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, error = !!test_bit(MMF_VM_MERGE_ANY, &me->mm->flags); break; #endif + case PR_RISCV_V_SET_CONTROL: + error = RISCV_V_SET_CONTROL(arg2); + break; + case PR_RISCV_V_GET_CONTROL: + error = RISCV_V_GET_CONTROL(); + break; default: error = -EINVAL; break;