syscall.c (2bf40d0841b942e7ba12953d515e62a436f0af84) | syscall.c (87e9bf23236d3c9da84f2b6164e06be3ecfd45e0) |
---|---|
1/* 2 * Linux syscalls 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 6280 unchanged lines hidden (view full) --- 6289 break; 6290 default: 6291 ret = -TARGET_EINVAL; 6292 break; 6293 } 6294 return ret; 6295} 6296#endif /* defined(TARGET_ABI32 */ | 1/* 2 * Linux syscalls 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 6280 unchanged lines hidden (view full) --- 6289 break; 6290 default: 6291 ret = -TARGET_EINVAL; 6292 break; 6293 } 6294 return ret; 6295} 6296#endif /* defined(TARGET_ABI32 */ |
6297 | |
6298#endif /* defined(TARGET_I386) */ 6299 | 6297#endif /* defined(TARGET_I386) */ 6298 |
6299/* 6300 * These constants are generic. Supply any that are missing from the host. 6301 */ 6302#ifndef PR_SET_NAME 6303# define PR_SET_NAME 15 6304# define PR_GET_NAME 16 6305#endif 6306#ifndef PR_SET_FP_MODE 6307# define PR_SET_FP_MODE 45 6308# define PR_GET_FP_MODE 46 6309# define PR_FP_MODE_FR (1 << 0) 6310# define PR_FP_MODE_FRE (1 << 1) 6311#endif 6312#ifndef PR_SVE_SET_VL 6313# define PR_SVE_SET_VL 50 6314# define PR_SVE_GET_VL 51 6315# define PR_SVE_VL_LEN_MASK 0xffff 6316# define PR_SVE_VL_INHERIT (1 << 17) 6317#endif 6318#ifndef PR_PAC_RESET_KEYS 6319# define PR_PAC_RESET_KEYS 54 6320# define PR_PAC_APIAKEY (1 << 0) 6321# define PR_PAC_APIBKEY (1 << 1) 6322# define PR_PAC_APDAKEY (1 << 2) 6323# define PR_PAC_APDBKEY (1 << 3) 6324# define PR_PAC_APGAKEY (1 << 4) 6325#endif 6326#ifndef PR_SET_TAGGED_ADDR_CTRL 6327# define PR_SET_TAGGED_ADDR_CTRL 55 6328# define PR_GET_TAGGED_ADDR_CTRL 56 6329# define PR_TAGGED_ADDR_ENABLE (1UL << 0) 6330#endif 6331#ifndef PR_MTE_TCF_SHIFT 6332# define PR_MTE_TCF_SHIFT 1 6333# define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT) 6334# define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT) 6335# define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT) 6336# define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT) 6337# define PR_MTE_TAG_SHIFT 3 6338# define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT) 6339#endif 6340 6341#include "target_prctl.h" 6342 6343static abi_long do_prctl_inval0(CPUArchState *env) 6344{ 6345 return -TARGET_EINVAL; 6346} 6347 6348static abi_long do_prctl_inval1(CPUArchState *env, abi_long arg2) 6349{ 6350 return -TARGET_EINVAL; 6351} 6352 6353#ifndef do_prctl_get_fp_mode 6354#define do_prctl_get_fp_mode do_prctl_inval0 6355#endif 6356#ifndef do_prctl_set_fp_mode 6357#define do_prctl_set_fp_mode do_prctl_inval1 6358#endif 6359#ifndef do_prctl_get_vl 6360#define do_prctl_get_vl do_prctl_inval0 6361#endif 6362#ifndef do_prctl_set_vl 6363#define do_prctl_set_vl do_prctl_inval1 6364#endif 6365#ifndef do_prctl_reset_keys 6366#define do_prctl_reset_keys do_prctl_inval1 6367#endif 6368#ifndef do_prctl_set_tagged_addr_ctrl 6369#define do_prctl_set_tagged_addr_ctrl do_prctl_inval1 6370#endif 6371#ifndef do_prctl_get_tagged_addr_ctrl 6372#define do_prctl_get_tagged_addr_ctrl do_prctl_inval0 6373#endif 6374 6375static abi_long do_prctl(CPUArchState *env, abi_long option, abi_long arg2, 6376 abi_long arg3, abi_long arg4, abi_long arg5) 6377{ 6378 abi_long ret; 6379 6380 switch (option) { 6381 case PR_GET_PDEATHSIG: 6382 { 6383 int deathsig; 6384 ret = get_errno(prctl(PR_GET_PDEATHSIG, &deathsig, 6385 arg3, arg4, arg5)); 6386 if (!is_error(ret) && arg2 && put_user_s32(deathsig, arg2)) { 6387 return -TARGET_EFAULT; 6388 } 6389 return ret; 6390 } 6391 case PR_GET_NAME: 6392 { 6393 void *name = lock_user(VERIFY_WRITE, arg2, 16, 1); 6394 if (!name) { 6395 return -TARGET_EFAULT; 6396 } 6397 ret = get_errno(prctl(PR_GET_NAME, (uintptr_t)name, 6398 arg3, arg4, arg5)); 6399 unlock_user(name, arg2, 16); 6400 return ret; 6401 } 6402 case PR_SET_NAME: 6403 { 6404 void *name = lock_user(VERIFY_READ, arg2, 16, 1); 6405 if (!name) { 6406 return -TARGET_EFAULT; 6407 } 6408 ret = get_errno(prctl(PR_SET_NAME, (uintptr_t)name, 6409 arg3, arg4, arg5)); 6410 unlock_user(name, arg2, 0); 6411 return ret; 6412 } 6413 case PR_GET_FP_MODE: 6414 return do_prctl_get_fp_mode(env); 6415 case PR_SET_FP_MODE: 6416 return do_prctl_set_fp_mode(env, arg2); 6417 case PR_SVE_GET_VL: 6418 return do_prctl_get_vl(env); 6419 case PR_SVE_SET_VL: 6420 return do_prctl_set_vl(env, arg2); 6421 case PR_PAC_RESET_KEYS: 6422 if (arg3 || arg4 || arg5) { 6423 return -TARGET_EINVAL; 6424 } 6425 return do_prctl_reset_keys(env, arg2); 6426 case PR_SET_TAGGED_ADDR_CTRL: 6427 if (arg3 || arg4 || arg5) { 6428 return -TARGET_EINVAL; 6429 } 6430 return do_prctl_set_tagged_addr_ctrl(env, arg2); 6431 case PR_GET_TAGGED_ADDR_CTRL: 6432 if (arg2 || arg3 || arg4 || arg5) { 6433 return -TARGET_EINVAL; 6434 } 6435 return do_prctl_get_tagged_addr_ctrl(env); 6436 case PR_GET_SECCOMP: 6437 case PR_SET_SECCOMP: 6438 /* Disable seccomp to prevent the target disabling syscalls we need. */ 6439 return -TARGET_EINVAL; 6440 default: 6441 /* Most prctl options have no pointer arguments */ 6442 return get_errno(prctl(option, arg2, arg3, arg4, arg5)); 6443 } 6444} 6445 |
|
6300#define NEW_STACK_SIZE 0x40000 6301 6302 6303static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER; 6304typedef struct { 6305 CPUArchState *env; 6306 pthread_mutex_t mutex; 6307 pthread_cond_t cond; --- 4322 unchanged lines hidden (view full) --- 10630 ret = get_errno(safe_nanosleep(&req, &rem)); 10631 if (is_error(ret) && arg2) { 10632 host_to_target_timespec(arg2, &rem); 10633 } 10634 } 10635 return ret; 10636#endif 10637 case TARGET_NR_prctl: | 6446#define NEW_STACK_SIZE 0x40000 6447 6448 6449static pthread_mutex_t clone_lock = PTHREAD_MUTEX_INITIALIZER; 6450typedef struct { 6451 CPUArchState *env; 6452 pthread_mutex_t mutex; 6453 pthread_cond_t cond; --- 4322 unchanged lines hidden (view full) --- 10776 ret = get_errno(safe_nanosleep(&req, &rem)); 10777 if (is_error(ret) && arg2) { 10778 host_to_target_timespec(arg2, &rem); 10779 } 10780 } 10781 return ret; 10782#endif 10783 case TARGET_NR_prctl: |
10638 switch (arg1) { 10639 case PR_GET_PDEATHSIG: 10640 { 10641 int deathsig; 10642 ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5)); 10643 if (!is_error(ret) && arg2 10644 && put_user_s32(deathsig, arg2)) { 10645 return -TARGET_EFAULT; 10646 } 10647 return ret; 10648 } 10649#ifdef PR_GET_NAME 10650 case PR_GET_NAME: 10651 { 10652 void *name = lock_user(VERIFY_WRITE, arg2, 16, 1); 10653 if (!name) { 10654 return -TARGET_EFAULT; 10655 } 10656 ret = get_errno(prctl(arg1, (unsigned long)name, 10657 arg3, arg4, arg5)); 10658 unlock_user(name, arg2, 16); 10659 return ret; 10660 } 10661 case PR_SET_NAME: 10662 { 10663 void *name = lock_user(VERIFY_READ, arg2, 16, 1); 10664 if (!name) { 10665 return -TARGET_EFAULT; 10666 } 10667 ret = get_errno(prctl(arg1, (unsigned long)name, 10668 arg3, arg4, arg5)); 10669 unlock_user(name, arg2, 0); 10670 return ret; 10671 } 10672#endif 10673#ifdef TARGET_MIPS 10674 case TARGET_PR_GET_FP_MODE: 10675 { 10676 CPUMIPSState *env = ((CPUMIPSState *)cpu_env); 10677 ret = 0; 10678 if (env->CP0_Status & (1 << CP0St_FR)) { 10679 ret |= TARGET_PR_FP_MODE_FR; 10680 } 10681 if (env->CP0_Config5 & (1 << CP0C5_FRE)) { 10682 ret |= TARGET_PR_FP_MODE_FRE; 10683 } 10684 return ret; 10685 } 10686 case TARGET_PR_SET_FP_MODE: 10687 { 10688 CPUMIPSState *env = ((CPUMIPSState *)cpu_env); 10689 bool old_fr = env->CP0_Status & (1 << CP0St_FR); 10690 bool old_fre = env->CP0_Config5 & (1 << CP0C5_FRE); 10691 bool new_fr = arg2 & TARGET_PR_FP_MODE_FR; 10692 bool new_fre = arg2 & TARGET_PR_FP_MODE_FRE; 10693 10694 const unsigned int known_bits = TARGET_PR_FP_MODE_FR | 10695 TARGET_PR_FP_MODE_FRE; 10696 10697 /* If nothing to change, return right away, successfully. */ 10698 if (old_fr == new_fr && old_fre == new_fre) { 10699 return 0; 10700 } 10701 /* Check the value is valid */ 10702 if (arg2 & ~known_bits) { 10703 return -TARGET_EOPNOTSUPP; 10704 } 10705 /* Setting FRE without FR is not supported. */ 10706 if (new_fre && !new_fr) { 10707 return -TARGET_EOPNOTSUPP; 10708 } 10709 if (new_fr && !(env->active_fpu.fcr0 & (1 << FCR0_F64))) { 10710 /* FR1 is not supported */ 10711 return -TARGET_EOPNOTSUPP; 10712 } 10713 if (!new_fr && (env->active_fpu.fcr0 & (1 << FCR0_F64)) 10714 && !(env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) { 10715 /* cannot set FR=0 */ 10716 return -TARGET_EOPNOTSUPP; 10717 } 10718 if (new_fre && !(env->active_fpu.fcr0 & (1 << FCR0_FREP))) { 10719 /* Cannot set FRE=1 */ 10720 return -TARGET_EOPNOTSUPP; 10721 } 10722 10723 int i; 10724 fpr_t *fpr = env->active_fpu.fpr; 10725 for (i = 0; i < 32 ; i += 2) { 10726 if (!old_fr && new_fr) { 10727 fpr[i].w[!FP_ENDIAN_IDX] = fpr[i + 1].w[FP_ENDIAN_IDX]; 10728 } else if (old_fr && !new_fr) { 10729 fpr[i + 1].w[FP_ENDIAN_IDX] = fpr[i].w[!FP_ENDIAN_IDX]; 10730 } 10731 } 10732 10733 if (new_fr) { 10734 env->CP0_Status |= (1 << CP0St_FR); 10735 env->hflags |= MIPS_HFLAG_F64; 10736 } else { 10737 env->CP0_Status &= ~(1 << CP0St_FR); 10738 env->hflags &= ~MIPS_HFLAG_F64; 10739 } 10740 if (new_fre) { 10741 env->CP0_Config5 |= (1 << CP0C5_FRE); 10742 if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) { 10743 env->hflags |= MIPS_HFLAG_FRE; 10744 } 10745 } else { 10746 env->CP0_Config5 &= ~(1 << CP0C5_FRE); 10747 env->hflags &= ~MIPS_HFLAG_FRE; 10748 } 10749 10750 return 0; 10751 } 10752#endif /* MIPS */ 10753#ifdef TARGET_AARCH64 10754 case TARGET_PR_SVE_SET_VL: 10755 /* 10756 * We cannot support either PR_SVE_SET_VL_ONEXEC or 10757 * PR_SVE_VL_INHERIT. Note the kernel definition 10758 * of sve_vl_valid allows for VQ=512, i.e. VL=8192, 10759 * even though the current architectural maximum is VQ=16. 10760 */ 10761 ret = -TARGET_EINVAL; 10762 if (cpu_isar_feature(aa64_sve, env_archcpu(cpu_env)) 10763 && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) { 10764 CPUARMState *env = cpu_env; 10765 ARMCPU *cpu = env_archcpu(env); 10766 uint32_t vq, old_vq; 10767 10768 old_vq = (env->vfp.zcr_el[1] & 0xf) + 1; 10769 vq = MAX(arg2 / 16, 1); 10770 vq = MIN(vq, cpu->sve_max_vq); 10771 10772 if (vq < old_vq) { 10773 aarch64_sve_narrow_vq(env, vq); 10774 } 10775 env->vfp.zcr_el[1] = vq - 1; 10776 arm_rebuild_hflags(env); 10777 ret = vq * 16; 10778 } 10779 return ret; 10780 case TARGET_PR_SVE_GET_VL: 10781 ret = -TARGET_EINVAL; 10782 { 10783 ARMCPU *cpu = env_archcpu(cpu_env); 10784 if (cpu_isar_feature(aa64_sve, cpu)) { 10785 ret = ((cpu->env.vfp.zcr_el[1] & 0xf) + 1) * 16; 10786 } 10787 } 10788 return ret; 10789 case TARGET_PR_PAC_RESET_KEYS: 10790 { 10791 CPUARMState *env = cpu_env; 10792 ARMCPU *cpu = env_archcpu(env); 10793 10794 if (arg3 || arg4 || arg5) { 10795 return -TARGET_EINVAL; 10796 } 10797 if (cpu_isar_feature(aa64_pauth, cpu)) { 10798 int all = (TARGET_PR_PAC_APIAKEY | TARGET_PR_PAC_APIBKEY | 10799 TARGET_PR_PAC_APDAKEY | TARGET_PR_PAC_APDBKEY | 10800 TARGET_PR_PAC_APGAKEY); 10801 int ret = 0; 10802 Error *err = NULL; 10803 10804 if (arg2 == 0) { 10805 arg2 = all; 10806 } else if (arg2 & ~all) { 10807 return -TARGET_EINVAL; 10808 } 10809 if (arg2 & TARGET_PR_PAC_APIAKEY) { 10810 ret |= qemu_guest_getrandom(&env->keys.apia, 10811 sizeof(ARMPACKey), &err); 10812 } 10813 if (arg2 & TARGET_PR_PAC_APIBKEY) { 10814 ret |= qemu_guest_getrandom(&env->keys.apib, 10815 sizeof(ARMPACKey), &err); 10816 } 10817 if (arg2 & TARGET_PR_PAC_APDAKEY) { 10818 ret |= qemu_guest_getrandom(&env->keys.apda, 10819 sizeof(ARMPACKey), &err); 10820 } 10821 if (arg2 & TARGET_PR_PAC_APDBKEY) { 10822 ret |= qemu_guest_getrandom(&env->keys.apdb, 10823 sizeof(ARMPACKey), &err); 10824 } 10825 if (arg2 & TARGET_PR_PAC_APGAKEY) { 10826 ret |= qemu_guest_getrandom(&env->keys.apga, 10827 sizeof(ARMPACKey), &err); 10828 } 10829 if (ret != 0) { 10830 /* 10831 * Some unknown failure in the crypto. The best 10832 * we can do is log it and fail the syscall. 10833 * The real syscall cannot fail this way. 10834 */ 10835 qemu_log_mask(LOG_UNIMP, 10836 "PR_PAC_RESET_KEYS: Crypto failure: %s", 10837 error_get_pretty(err)); 10838 error_free(err); 10839 return -TARGET_EIO; 10840 } 10841 return 0; 10842 } 10843 } 10844 return -TARGET_EINVAL; 10845 case TARGET_PR_SET_TAGGED_ADDR_CTRL: 10846 { 10847 abi_ulong valid_mask = TARGET_PR_TAGGED_ADDR_ENABLE; 10848 CPUARMState *env = cpu_env; 10849 ARMCPU *cpu = env_archcpu(env); 10850 10851 if (cpu_isar_feature(aa64_mte, cpu)) { 10852 valid_mask |= TARGET_PR_MTE_TCF_MASK; 10853 valid_mask |= TARGET_PR_MTE_TAG_MASK; 10854 } 10855 10856 if ((arg2 & ~valid_mask) || arg3 || arg4 || arg5) { 10857 return -TARGET_EINVAL; 10858 } 10859 env->tagged_addr_enable = arg2 & TARGET_PR_TAGGED_ADDR_ENABLE; 10860 10861 if (cpu_isar_feature(aa64_mte, cpu)) { 10862 switch (arg2 & TARGET_PR_MTE_TCF_MASK) { 10863 case TARGET_PR_MTE_TCF_NONE: 10864 case TARGET_PR_MTE_TCF_SYNC: 10865 case TARGET_PR_MTE_TCF_ASYNC: 10866 break; 10867 default: 10868 return -EINVAL; 10869 } 10870 10871 /* 10872 * Write PR_MTE_TCF to SCTLR_EL1[TCF0]. 10873 * Note that the syscall values are consistent with hw. 10874 */ 10875 env->cp15.sctlr_el[1] = 10876 deposit64(env->cp15.sctlr_el[1], 38, 2, 10877 arg2 >> TARGET_PR_MTE_TCF_SHIFT); 10878 10879 /* 10880 * Write PR_MTE_TAG to GCR_EL1[Exclude]. 10881 * Note that the syscall uses an include mask, 10882 * and hardware uses an exclude mask -- invert. 10883 */ 10884 env->cp15.gcr_el1 = 10885 deposit64(env->cp15.gcr_el1, 0, 16, 10886 ~arg2 >> TARGET_PR_MTE_TAG_SHIFT); 10887 arm_rebuild_hflags(env); 10888 } 10889 return 0; 10890 } 10891 case TARGET_PR_GET_TAGGED_ADDR_CTRL: 10892 { 10893 abi_long ret = 0; 10894 CPUARMState *env = cpu_env; 10895 ARMCPU *cpu = env_archcpu(env); 10896 10897 if (arg2 || arg3 || arg4 || arg5) { 10898 return -TARGET_EINVAL; 10899 } 10900 if (env->tagged_addr_enable) { 10901 ret |= TARGET_PR_TAGGED_ADDR_ENABLE; 10902 } 10903 if (cpu_isar_feature(aa64_mte, cpu)) { 10904 /* See above. */ 10905 ret |= (extract64(env->cp15.sctlr_el[1], 38, 2) 10906 << TARGET_PR_MTE_TCF_SHIFT); 10907 ret = deposit64(ret, TARGET_PR_MTE_TAG_SHIFT, 16, 10908 ~env->cp15.gcr_el1); 10909 } 10910 return ret; 10911 } 10912#endif /* AARCH64 */ 10913 case PR_GET_SECCOMP: 10914 case PR_SET_SECCOMP: 10915 /* Disable seccomp to prevent the target disabling syscalls we 10916 * need. */ 10917 return -TARGET_EINVAL; 10918 default: 10919 /* Most prctl options have no pointer arguments */ 10920 return get_errno(prctl(arg1, arg2, arg3, arg4, arg5)); 10921 } | 10784 return do_prctl(cpu_env, arg1, arg2, arg3, arg4, arg5); |
10922 break; 10923#ifdef TARGET_NR_arch_prctl 10924 case TARGET_NR_arch_prctl: 10925 return do_arch_prctl(cpu_env, arg1, arg2); 10926#endif 10927#ifdef TARGET_NR_pread64 10928 case TARGET_NR_pread64: 10929 if (regpairs_aligned(cpu_env, num)) { --- 2242 unchanged lines hidden --- | 10785 break; 10786#ifdef TARGET_NR_arch_prctl 10787 case TARGET_NR_arch_prctl: 10788 return do_arch_prctl(cpu_env, arg1, arg2); 10789#endif 10790#ifdef TARGET_NR_pread64 10791 case TARGET_NR_pread64: 10792 if (regpairs_aligned(cpu_env, num)) { --- 2242 unchanged lines hidden --- |