From 91c8bdb1e6690fa2b6f107613271ae923126f098 Mon Sep 17 00:00:00 2001 From: Xinyu Li Date: Fri, 13 Dec 2019 10:29:19 +0800 Subject: [PATCH 01/17] linux-user:Fix align mistake when mmap guest space In init_guest_space, we need to mmap guest space. If the return address of first mmap is not aligned with align, which was set to MAX(SHMLBA, qemu_host_page_size), we need unmap and a new mmap(space is larger than first size). The new size is named real_size, which is aligned_size + qemu_host_page_size. alugned_size is the guest space size. And add a qemu_host_page_size to avoid memory error when we align real_start manually (ROUND_UP(real_start, align)). But when SHMLBA > qemu_host_page_size, the added size will smaller than the size to align, which can make a mistake(in a mips machine, it appears). So change real_size from aligned_size +qemu_host_page_size to aligned_size + align will solve it. Signed-off-by: Xinyu Li Reviewed-by: Richard Henderson Message-Id: <20191213022919.5934-1-precinct@mail.ustc.edu.cn> Signed-off-by: Laurent Vivier --- linux-user/elfload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 07b16cc0f4..511e450078 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -2191,7 +2191,7 @@ unsigned long init_guest_space(unsigned long host_start, * to where we need to put the commpage. */ munmap((void *)real_start, host_size); - real_size = aligned_size + qemu_host_page_size; + real_size = aligned_size + align; real_start = (unsigned long) mmap((void *)real_start, real_size, PROT_NONE, flags, -1, 0); if (real_start == (unsigned long)-1) { From 6fd5944980f4ccee728ce34bdaffc117db50b34d Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 17 Jan 2020 13:02:45 -1000 Subject: [PATCH 02/17] linux-user: Reserve space for brk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With bad luck, we can wind up with no space at all for brk, which will generally cause the guest malloc to fail. This bad luck is easier to come by with ET_DYN (PIE) binaries, where either the stack or the interpreter (ld.so) gets placed immediately after the main executable. But there's nothing preventing this same thing from happening with ET_EXEC (normal) binaries, during probe_guest_base(). In both cases, reserve some extra space via mmap and release it back to the system after loading the interpreter and allocating the stack. The choice of 16MB is somewhat arbitrary. It's enough for libc to get going, but without being so large that 32-bit guests or 32-bit hosts are in danger of running out of virtual address space. It is expected that libc will be able to fall back to mmap arenas after the limited brk space is exhausted. Launchpad: https://bugs.launchpad.net/qemu/+bug/1749393 Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée Tested-by: Alex Bennée Message-Id: <20200117230245.5040-1-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/elfload.c | 73 +++++++++++++++++++++++++++++++++----------- linux-user/qemu.h | 1 + 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 511e450078..f3080a1635 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -10,6 +10,7 @@ #include "qemu/path.h" #include "qemu/queue.h" #include "qemu/guest-random.h" +#include "qemu/units.h" #ifdef _ARCH_PPC64 #undef ARCH_DLINFO @@ -2364,24 +2365,51 @@ static void load_elf_image(const char *image_name, int image_fd, } } - load_addr = loaddr; - if (ehdr->e_type == ET_DYN) { - /* The image indicates that it can be loaded anywhere. Find a - location that can hold the memory space required. If the - image is pre-linked, LOADDR will be non-zero. Since we do - not supply MAP_FIXED here we'll use that address if and - only if it remains available. */ - load_addr = target_mmap(loaddr, hiaddr - loaddr, PROT_NONE, - MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, - -1, 0); - if (load_addr == -1) { - goto exit_perror; + if (pinterp_name != NULL) { + /* + * This is the main executable. + * + * Reserve extra space for brk. + * We hold on to this space while placing the interpreter + * and the stack, lest they be placed immediately after + * the data segment and block allocation from the brk. + * + * 16MB is chosen as "large enough" without being so large + * as to allow the result to not fit with a 32-bit guest on + * a 32-bit host. + */ + info->reserve_brk = 16 * MiB; + hiaddr += info->reserve_brk; + + if (ehdr->e_type == ET_EXEC) { + /* + * Make sure that the low address does not conflict with + * MMAP_MIN_ADDR or the QEMU application itself. + */ + probe_guest_base(image_name, loaddr, hiaddr); } - } else if (pinterp_name != NULL) { - /* This is the main executable. Make sure that the low - address does not conflict with MMAP_MIN_ADDR or the - QEMU application itself. */ - probe_guest_base(image_name, loaddr, hiaddr); + } + + /* + * Reserve address space for all of this. + * + * In the case of ET_EXEC, we supply MAP_FIXED so that we get + * exactly the address range that is required. + * + * Otherwise this is ET_DYN, and we are searching for a location + * that can hold the memory space required. If the image is + * pre-linked, LOADDR will be non-zero, and the kernel should + * honor that address if it happens to be free. + * + * In both cases, we will overwrite pages in this range with mappings + * from the executable. + */ + load_addr = target_mmap(loaddr, hiaddr - loaddr, PROT_NONE, + MAP_PRIVATE | MAP_ANON | MAP_NORESERVE | + (ehdr->e_type == ET_EXEC ? MAP_FIXED : 0), + -1, 0); + if (load_addr == -1) { + goto exit_perror; } load_bias = load_addr - loaddr; @@ -2860,6 +2888,17 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info) bprm->core_dump = &elf_core_dump; #endif + /* + * If we reserved extra space for brk, release it now. + * The implementation of do_brk in syscalls.c expects to be able + * to mmap pages in this space. + */ + if (info->reserve_brk) { + abi_ulong start_brk = HOST_PAGE_ALIGN(info->brk); + abi_ulong end_brk = HOST_PAGE_ALIGN(info->brk + info->reserve_brk); + target_munmap(start_brk, end_brk - start_brk); + } + return 0; } diff --git a/linux-user/qemu.h b/linux-user/qemu.h index f6f5fe5fbb..560a68090e 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -35,6 +35,7 @@ struct image_info { abi_ulong end_data; abi_ulong start_brk; abi_ulong brk; + abi_ulong reserve_brk; abi_ulong start_mmap; abi_ulong start_stack; abi_ulong stack_limit; From 5ae774a91f9a4b33996b62c18b16063edcf3b0b0 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Thu, 16 Jan 2020 23:49:40 +0100 Subject: [PATCH 03/17] linux-user: Add support for FS_IOC_VERSION ioctls A very specific thing for these two ioctls is that their code implies that their third argument is of type 'long', but the kernel uses that argument as if it is of type 'int'. This anomaly is recognized also in commit 6080723 (linux-user: Implement FS_IOC_GETFLAGS and FS_IOC_SETFLAGS ioctls). Reviewed-by: Laurent Vivier Signed-off-by: Aleksandar Markovic Message-Id: <1579214991-19602-2-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 2 ++ linux-user/syscall_defs.h | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index c6b9d6ad66..c44f42eaf4 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -138,6 +138,8 @@ IOCTL(FS_IOC_GETFLAGS, IOC_R, MK_PTR(TYPE_INT)) IOCTL(FS_IOC_SETFLAGS, IOC_W, MK_PTR(TYPE_INT)) + IOCTL(FS_IOC_GETVERSION, IOC_R, MK_PTR(TYPE_INT)) + IOCTL(FS_IOC_SETVERSION, IOC_W, MK_PTR(TYPE_INT)) #ifdef CONFIG_USBFS /* USB ioctls */ diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 98c2119de9..f68a8b6e8e 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -911,12 +911,14 @@ struct target_pollfd { #define TARGET_FICLONE TARGET_IOW(0x94, 9, int) #define TARGET_FICLONERANGE TARGET_IOW(0x94, 13, struct file_clone_range) -/* Note that the ioctl numbers claim type "long" but the actual type - * used by the kernel is "int". +/* + * Note that the ioctl numbers for FS_IOC_ + * claim type "long" but the actual type used by the kernel is "int". */ #define TARGET_FS_IOC_GETFLAGS TARGET_IOR('f', 1, abi_long) #define TARGET_FS_IOC_SETFLAGS TARGET_IOW('f', 2, abi_long) - +#define TARGET_FS_IOC_GETVERSION TARGET_IOR('v', 1, abi_long) +#define TARGET_FS_IOC_SETVERSION TARGET_IOW('v', 2, abi_long) #define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap) /* usb ioctls */ From 0b471ba6984264fb9e52bf8b5d9faa50919f0bbc Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Thu, 16 Jan 2020 23:49:41 +0100 Subject: [PATCH 04/17] linux-user: Add support for FS_IOC32_FLAGS ioctls These FS_IOC32_FLAGS ioctls are identical to FS_IOC_FLAGS ioctls, but without the anomaly of their number defined as if their third argument is of type long, while it is treated internally in kernel as is of type int. Reviewed-by: Laurent Vivier Signed-off-by: Aleksandar Markovic Message-Id: <1579214991-19602-3-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 2 ++ linux-user/syscall_defs.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index c44f42eaf4..4fd693984e 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -140,6 +140,8 @@ IOCTL(FS_IOC_SETFLAGS, IOC_W, MK_PTR(TYPE_INT)) IOCTL(FS_IOC_GETVERSION, IOC_R, MK_PTR(TYPE_INT)) IOCTL(FS_IOC_SETVERSION, IOC_W, MK_PTR(TYPE_INT)) + IOCTL(FS_IOC32_GETFLAGS, IOC_R, MK_PTR(TYPE_INT)) + IOCTL(FS_IOC32_SETFLAGS, IOC_W, MK_PTR(TYPE_INT)) #ifdef CONFIG_USBFS /* USB ioctls */ diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index f68a8b6e8e..964b2b458d 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -920,6 +920,8 @@ struct target_pollfd { #define TARGET_FS_IOC_GETVERSION TARGET_IOR('v', 1, abi_long) #define TARGET_FS_IOC_SETVERSION TARGET_IOW('v', 2, abi_long) #define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap) +#define TARGET_FS_IOC32_GETFLAGS TARGET_IOR('f', 1, int) +#define TARGET_FS_IOC32_SETFLAGS TARGET_IOW('f', 2, int) /* usb ioctls */ #define TARGET_USBDEVFS_CONTROL TARGET_IOWRU('U', 0) From 0d899cd61a37c8ced2f40c0b171df1e23fd4615b Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Thu, 16 Jan 2020 23:49:42 +0100 Subject: [PATCH 05/17] linux-user: Add support for FS_IOC32_VERSION ioctls These FS_IOC32_VERSION ioctls are identical to FS_IOC_VERSION ioctls, but without the anomaly of their number defined as if their third argument is of type long, while it is treated internally in kernel as is of type int. Reviewed-by: Laurent Vivier Signed-off-by: Aleksandar Markovic Message-Id: <1579214991-19602-4-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 2 ++ linux-user/syscall_defs.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 4fd693984e..3affd8814a 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -142,6 +142,8 @@ IOCTL(FS_IOC_SETVERSION, IOC_W, MK_PTR(TYPE_INT)) IOCTL(FS_IOC32_GETFLAGS, IOC_R, MK_PTR(TYPE_INT)) IOCTL(FS_IOC32_SETFLAGS, IOC_W, MK_PTR(TYPE_INT)) + IOCTL(FS_IOC32_GETVERSION, IOC_R, MK_PTR(TYPE_INT)) + IOCTL(FS_IOC32_SETVERSION, IOC_W, MK_PTR(TYPE_INT)) #ifdef CONFIG_USBFS /* USB ioctls */ diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 964b2b458d..a73cc3d067 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -922,6 +922,8 @@ struct target_pollfd { #define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap) #define TARGET_FS_IOC32_GETFLAGS TARGET_IOR('f', 1, int) #define TARGET_FS_IOC32_SETFLAGS TARGET_IOW('f', 2, int) +#define TARGET_FS_IOC32_GETVERSION TARGET_IOR('v', 1, int) +#define TARGET_FS_IOC32_SETVERSION TARGET_IOW('v', 2, int) /* usb ioctls */ #define TARGET_USBDEVFS_CONTROL TARGET_IOWRU('U', 0) From 81eb1a369da5f9cb282b65f1221899cc07711df2 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Thu, 16 Jan 2020 23:49:46 +0100 Subject: [PATCH 06/17] linux-user: Add support for FD ioctls FDSETEMSGTRESH, FDSETMAXERRS, and FDGETMAXERRS ioctls are commands for controlling error reporting of a floppy drive. FDSETEMSGTRESH's third agrument is a pointer to the structure: struct floppy_max_errors { unsigned int abort, /* number of errors to be reached before aborting */ read_track, /* maximal number of errors permitted to read an * entire track at once */ reset, /* maximal number of errors before a reset is tried */ recal, /* maximal number of errors before a recalibrate is * tried */ /* * Threshold for reporting FDC errors to the console. * Setting this to zero may flood your screen when using * ultra cheap floppies ;-) */ reporting; }; defined in Linux kernel header . Since all fields of the structure are of type 'unsigned int', there is no need to define "target_floppy_max_errors". FDSETMAXERRS and FDGETMAXERRS ioctls do not use the third argument. Reviewed-by: Laurent Vivier Signed-off-by: Aleksandar Markovic Message-Id: <1579214991-19602-8-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 3 +++ linux-user/syscall_defs.h | 3 +++ linux-user/syscall_types.h | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 3affd8814a..2c3d798842 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -114,7 +114,10 @@ IOCTL(FDMSGON, 0, TYPE_NULL) IOCTL(FDMSGOFF, 0, TYPE_NULL) + IOCTL(FDSETEMSGTRESH, 0, TYPE_NULL) IOCTL(FDFLUSH, 0, TYPE_NULL) + IOCTL(FDSETMAXERRS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_floppy_max_errors))) + IOCTL(FDGETMAXERRS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_floppy_max_errors))) IOCTL(FDRESET, 0, TYPE_NULL) IOCTL(FDRAWCMD, 0, TYPE_NULL) IOCTL(FDTWADDLE, 0, TYPE_NULL) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index a73cc3d067..48de76145f 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -899,7 +899,10 @@ struct target_pollfd { #define TARGET_FDMSGON TARGET_IO(2, 0x45) #define TARGET_FDMSGOFF TARGET_IO(2, 0x46) +#define TARGET_FDSETEMSGTRESH TARGET_IO(2, 0x4a) #define TARGET_FDFLUSH TARGET_IO(2, 0x4b) +#define TARGET_FDSETMAXERRS TARGET_IOW(2, 0x4c, struct floppy_max_errors) +#define TARGET_FDGETMAXERRS TARGET_IOR(2, 0x0e, struct floppy_max_errors) #define TARGET_FDRESET TARGET_IO(2, 0x54) #define TARGET_FDRAWCMD TARGET_IO(2, 0x58) #define TARGET_FDTWADDLE TARGET_IO(2, 0x59) diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index 4e36983826..e4e0429637 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -261,6 +261,13 @@ STRUCT(blkpg_ioctl_arg, TYPE_INT, /* datalen */ TYPE_PTRVOID) /* data */ +STRUCT(floppy_max_errors, + TYPE_INT, /* abort */ + TYPE_INT, /* read_track */ + TYPE_INT, /* reset */ + TYPE_INT, /* recal */ + TYPE_INT) /* reporting */ + #if defined(CONFIG_USBFS) /* usb device ioctls */ STRUCT(usbdevfs_ctrltransfer, From 08e3ce59fcf4a83c5be078e9783161310c769c20 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Thu, 16 Jan 2020 23:49:47 +0100 Subject: [PATCH 07/17] linux-user: Add support for FDFMT ioctls FDFMTBEG, FDFMTTRK, and FDFMTEND ioctls provide means for controlling formatting of a floppy drive. FDFMTTRK's third agrument is a pointer to the structure: struct format_descr { unsigned int device,head,track; }; defined in Linux kernel header . Since all fields of the structure are of type 'unsigned int', there is no need to define "target_format_descr". FDFMTBEG and FDFMTEND ioctls do not use the third argument. Reviewed-by: Laurent Vivier Signed-off-by: Aleksandar Markovic Message-Id: <1579214991-19602-9-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 3 +++ linux-user/syscall_defs.h | 3 +++ linux-user/syscall_types.h | 5 +++++ 3 files changed, 11 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 2c3d798842..29969e2f2f 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -115,6 +115,9 @@ IOCTL(FDMSGON, 0, TYPE_NULL) IOCTL(FDMSGOFF, 0, TYPE_NULL) IOCTL(FDSETEMSGTRESH, 0, TYPE_NULL) + IOCTL(FDFMTBEG, 0, TYPE_NULL) + IOCTL(FDFMTTRK, IOC_W, MK_PTR(MK_STRUCT(STRUCT_format_descr))) + IOCTL(FDFMTEND, 0, TYPE_NULL) IOCTL(FDFLUSH, 0, TYPE_NULL) IOCTL(FDSETMAXERRS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_floppy_max_errors))) IOCTL(FDGETMAXERRS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_floppy_max_errors))) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 48de76145f..b3acf85a6b 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -899,6 +899,9 @@ struct target_pollfd { #define TARGET_FDMSGON TARGET_IO(2, 0x45) #define TARGET_FDMSGOFF TARGET_IO(2, 0x46) +#define TARGET_FDFMTBEG TARGET_IO(2, 0x47) +#define TARGET_FDFMTTRK TARGET_IOW(2, 0x48, struct format_descr) +#define TARGET_FDFMTEND TARGET_IO(2, 0x49) #define TARGET_FDSETEMSGTRESH TARGET_IO(2, 0x4a) #define TARGET_FDFLUSH TARGET_IO(2, 0x4b) #define TARGET_FDSETMAXERRS TARGET_IOW(2, 0x4c, struct floppy_max_errors) diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index e4e0429637..8ff78a625a 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -261,6 +261,11 @@ STRUCT(blkpg_ioctl_arg, TYPE_INT, /* datalen */ TYPE_PTRVOID) /* data */ +STRUCT(format_descr, + TYPE_INT, /* device */ + TYPE_INT, /* head */ + TYPE_INT) /* track */ + STRUCT(floppy_max_errors, TYPE_INT, /* abort */ TYPE_INT, /* read_track */ From db37dd89d663a2891d2b70c753a41389ae7893e4 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Thu, 16 Jan 2020 23:49:49 +0100 Subject: [PATCH 08/17] configure: Detect kcov support and introduce CONFIG_KCOV kcov is kernel code coverage tracing tool. It requires kernel 4.4+ compiled with certain kernel options. This patch checks if kcov header "sys/kcov.h" is present on build machine, and stores the result in variable CONFIG_KCOV, meant to be used in linux-user code related to the support for three ioctls that were introduced at the same time as the mentioned header (their definition was a part of the first version of that header). Signed-off-by: Aleksandar Markovic Reviewed-by: Laurent Vivier Message-Id: <1579214991-19602-11-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- configure | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configure b/configure index 557e4382ea..d91eab4d65 100755 --- a/configure +++ b/configure @@ -4761,6 +4761,12 @@ if compile_prog "" "" ; then syncfs=yes fi +# check for kcov support (kernel must be 4.4+, compiled with certain options) +kcov=no +if check_include sys/kcov.h ; then + kcov=yes +fi + # Check we have a new enough version of sphinx-build has_sphinx_build() { # This is a bit awkward but works: create a trivial document and @@ -6874,6 +6880,9 @@ fi if test "$syncfs" = "yes" ; then echo "CONFIG_SYNCFS=y" >> $config_host_mak fi +if test "$kcov" = "yes" ; then + echo "CONFIG_KCOV=y" >> $config_host_mak +fi if test "$inotify" = "yes" ; then echo "CONFIG_INOTIFY=y" >> $config_host_mak fi From bd27e675d33d829fdb89a8604e0aba6f9f38ab79 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Thu, 16 Jan 2020 23:49:50 +0100 Subject: [PATCH 09/17] linux-user: Add support for KCOV_ ioctls KCOV_ENABLE and KCOV_DISABLE play the role in kernel coverage tracing. These ioctls do not use the third argument of ioctl() system call and are straightforward to implement in QEMU. Reviewed-by: Laurent Vivier Signed-off-by: Aleksandar Markovic Message-Id: <1579214991-19602-12-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 5 +++++ linux-user/syscall.c | 3 +++ linux-user/syscall_defs.h | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 29969e2f2f..6220dd8cf7 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -534,3 +534,8 @@ IOCTL_IGNORE(TIOCSTART) IOCTL_IGNORE(TIOCSTOP) #endif + +#ifdef CONFIG_KCOV + IOCTL(KCOV_ENABLE, 0, TYPE_NULL) + IOCTL(KCOV_DISABLE, 0, TYPE_NULL) +#endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 249e4b95fc..c5bda60b45 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -73,6 +73,9 @@ #ifdef CONFIG_SENDFILE #include #endif +#ifdef CONFIG_KCOV +#include +#endif #define termios host_termios #define winsize host_winsize diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index b3acf85a6b..7b0b60d253 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -2434,6 +2434,10 @@ struct target_mtpos { #define TARGET_MTIOCGET TARGET_IOR('m', 2, struct target_mtget) #define TARGET_MTIOCPOS TARGET_IOR('m', 3, struct target_mtpos) +/* kcov ioctls */ +#define TARGET_KCOV_ENABLE TARGET_IO('c', 100) +#define TARGET_KCOV_DISABLE TARGET_IO('c', 101) + struct target_sysinfo { abi_long uptime; /* Seconds since boot */ abi_ulong loads[3]; /* 1, 5, and 15 minute load averages */ From f7dbd8fe5665a1161b5f8af3e2d2044f3bd349d2 Mon Sep 17 00:00:00 2001 From: Aleksandar Markovic Date: Thu, 16 Jan 2020 23:49:51 +0100 Subject: [PATCH 10/17] linux-user: Add support for KCOV_INIT_TRACE ioctl KCOV_INIT_TRACE ioctl plays the role in kernel coverage tracing. This ioctl's third argument is of type 'unsigned long', and the implementation in QEMU is straightforward. Reviewed-by: Laurent Vivier Signed-off-by: Aleksandar Markovic Message-Id: <1579214991-19602-13-git-send-email-aleksandar.markovic@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 1 + linux-user/syscall_defs.h | 1 + 2 files changed, 2 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 6220dd8cf7..23f6d3feb5 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -538,4 +538,5 @@ #ifdef CONFIG_KCOV IOCTL(KCOV_ENABLE, 0, TYPE_NULL) IOCTL(KCOV_DISABLE, 0, TYPE_NULL) + IOCTL(KCOV_INIT_TRACE, IOC_R, TYPE_ULONG) #endif diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 7b0b60d253..fb8318d121 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -2437,6 +2437,7 @@ struct target_mtpos { /* kcov ioctls */ #define TARGET_KCOV_ENABLE TARGET_IO('c', 100) #define TARGET_KCOV_DISABLE TARGET_IO('c', 101) +#define TARGET_KCOV_INIT_TRACE TARGET_IOR('c', 1, abi_ulong) struct target_sysinfo { abi_long uptime; /* Seconds since boot */ From c858e537a9eb2e2b788ec323125462ea0991bd93 Mon Sep 17 00:00:00 2001 From: Filip Bozuta Date: Wed, 15 Jan 2020 20:36:47 +0100 Subject: [PATCH 11/17] linux-user: Add support for TYPE_LONG and TYPE_ULONG in do_ioctl() Function "do_ioctl()" located in file "syscall.c" was missing an option for TYPE_LONG and TYPE_ULONG. This caused some ioctls to not be recognised because they had the third argument that was of type 'long' or 'unsigned long'. For example: Since implemented ioctls RTC_IRQP_SET and RTC_EPOCH_SET are of type IOW(writing type) that have unsigned long as their third argument, they were not recognised in QEMU before the changes of this patch. Signed-off-by: Filip Bozuta Reviewed-by: Laurent Vivier Message-Id: <1579117007-7565-14-git-send-email-Filip.Bozuta@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/syscall.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index c5bda60b45..bd2436b310 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -5178,6 +5178,8 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg) break; case TYPE_PTRVOID: case TYPE_INT: + case TYPE_LONG: + case TYPE_ULONG: ret = get_errno(safe_ioctl(fd, ie->host_cmd, arg)); break; case TYPE_PTR: From 68365f969c8229b0a9c111bafcd6683bb0ec6a55 Mon Sep 17 00:00:00 2001 From: Filip Bozuta Date: Wed, 15 Jan 2020 20:36:35 +0100 Subject: [PATCH 12/17] linux-user: Add support for enabling/disabling RTC features using ioctls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch implements functionalities of following ioctls: RTC_AIE_ON, RTC_AIE_OFF - Alarm interrupt enabling on/off Enable or disable the alarm interrupt, for RTCs that support alarms. The third ioctl's argument is ignored. RTC_UIE_ON, RTC_UIE_OFF - Update interrupt enabling on/off Enable or disable the interrupt on every clock update, for RTCs that support this once-per-second interrupt. The third ioctl's argument is ignored. RTC_PIE_ON, RTC_PIE_OFF - Periodic interrupt enabling on/off Enable or disable the periodic interrupt, for RTCs that sup‐ port these periodic interrupts. The third ioctl's argument is ignored. Only a privileged process (i.e., one having the CAP_SYS_RESOURCE capability) can enable the periodic interrupt if the frequency is currently set above the value specified in /proc/sys/dev/rtc/max-user-freq. RTC_WIE_ON, RTC_WIE_OFF - Watchdog interrupt enabling on/off Enable or disable the Watchdog interrupt, for RTCs that sup- port this Watchdog interrupt. The third ioctl's argument is ignored. Implementation notes: Since all of involved ioctls have NULL as their third argument, their implementation was straightforward. The line '#include ' was added to recognize preprocessor definitions for these ioctls. This needs to be done only once in this series of commits. Also, the content of this file (with respect to ioctl definitions) remained unchanged for a long time, therefore there is no need to worry about supporting older Linux kernel version. Reviewed-by: Laurent Vivier Signed-off-by: Filip Bozuta Message-Id: <1579117007-7565-2-git-send-email-Filip.Bozuta@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 9 +++++++++ linux-user/syscall.c | 1 + linux-user/syscall_defs.h | 10 ++++++++++ 3 files changed, 20 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 23f6d3feb5..55ad47186d 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -69,6 +69,15 @@ IOCTL(KDSETLED, 0, TYPE_INT) IOCTL_SPECIAL(KDSIGACCEPT, 0, do_ioctl_kdsigaccept, TYPE_INT) + IOCTL(RTC_AIE_ON, 0, TYPE_NULL) + IOCTL(RTC_AIE_OFF, 0, TYPE_NULL) + IOCTL(RTC_UIE_ON, 0, TYPE_NULL) + IOCTL(RTC_UIE_OFF, 0, TYPE_NULL) + IOCTL(RTC_PIE_ON, 0, TYPE_NULL) + IOCTL(RTC_PIE_OFF, 0, TYPE_NULL) + IOCTL(RTC_WIE_ON, 0, TYPE_NULL) + IOCTL(RTC_WIE_OFF, 0, TYPE_NULL) + IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT)) IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT)) IOCTL(BLKRRPART, 0, TYPE_NULL) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index bd2436b310..d60142f069 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -110,6 +110,7 @@ #include #include #include +#include #include "linux_loop.h" #include "uname.h" diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index fb8318d121..fc3d79ab97 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -763,6 +763,16 @@ struct target_pollfd { #define TARGET_KDSETLED 0x4B32 /* set led state [lights, not flags] */ #define TARGET_KDSIGACCEPT 0x4B4E +/* real time clock ioctls */ +#define TARGET_RTC_AIE_ON TARGET_IO('p', 0x01) +#define TARGET_RTC_AIE_OFF TARGET_IO('p', 0x02) +#define TARGET_RTC_UIE_ON TARGET_IO('p', 0x03) +#define TARGET_RTC_UIE_OFF TARGET_IO('p', 0x04) +#define TARGET_RTC_PIE_ON TARGET_IO('p', 0x05) +#define TARGET_RTC_PIE_OFF TARGET_IO('p', 0x06) +#define TARGET_RTC_WIE_ON TARGET_IO('p', 0x0f) +#define TARGET_RTC_WIE_OFF TARGET_IO('p', 0x10) + #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4) || \ defined(TARGET_XTENSA) #define TARGET_FIOGETOWN TARGET_IOR('f', 123, int) From 178b14a0cd8b9063265035aa9ceee37304ef1b9b Mon Sep 17 00:00:00 2001 From: Filip Bozuta Date: Wed, 15 Jan 2020 20:36:36 +0100 Subject: [PATCH 13/17] linux-user: Add support for getting/setting RTC time and alarm using ioctls This patch implements functionalities of following ioctls: RTC_RD_TIME - Getting RTC time Returns this RTC's time in the following structure: struct rtc_time { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; /* unused */ int tm_yday; /* unused */ int tm_isdst; /* unused */ }; The fields in this structure have the same meaning and ranges as the tm structure described in gmtime man page. A pointer to this structure should be passed as the third ioctl's argument. RTC_SET_TIME - Setting RTC time Sets this RTC's time to the time specified by the rtc_time structure pointed to by the third ioctl's argument. To set the RTC's time the process must be privileged (i.e., have the CAP_SYS_TIME capability). RTC_ALM_READ, RTC_ALM_SET - Getting/Setting alarm time Read and set the alarm time, for RTCs that support alarms. The alarm interrupt must be separately enabled or disabled using the RTC_AIE_ON, RTC_AIE_OFF requests. The third ioctl's argument is a pointer to a rtc_time structure. Only the tm_sec, tm_min, and tm_hour fields of this structure are used. Implementation notes: All ioctls in this patch have pointer to a structure rtc_time as their third argument. That is the reason why corresponding definition is added in linux-user/syscall_types.h. Since all elements of this structure are of type 'int', the rest of the implementation is straightforward. Reviewed-by: Laurent Vivier Signed-off-by: Filip Bozuta Message-Id: <1579117007-7565-3-git-send-email-Filip.Bozuta@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 4 ++++ linux-user/syscall_defs.h | 4 ++++ linux-user/syscall_types.h | 11 +++++++++++ 3 files changed, 19 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 55ad47186d..c39dd0128a 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -77,6 +77,10 @@ IOCTL(RTC_PIE_OFF, 0, TYPE_NULL) IOCTL(RTC_WIE_ON, 0, TYPE_NULL) IOCTL(RTC_WIE_OFF, 0, TYPE_NULL) + IOCTL(RTC_ALM_READ, IOC_R, MK_PTR(MK_STRUCT(STRUCT_rtc_time))) + IOCTL(RTC_ALM_SET, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_time))) + IOCTL(RTC_RD_TIME, IOC_R, MK_PTR(MK_STRUCT(STRUCT_rtc_time))) + IOCTL(RTC_SET_TIME, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_time))) IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT)) IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT)) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index fc3d79ab97..dc36dd4751 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -772,6 +772,10 @@ struct target_pollfd { #define TARGET_RTC_PIE_OFF TARGET_IO('p', 0x06) #define TARGET_RTC_WIE_ON TARGET_IO('p', 0x0f) #define TARGET_RTC_WIE_OFF TARGET_IO('p', 0x10) +#define TARGET_RTC_ALM_READ TARGET_IOR('p', 0x08, struct rtc_time) +#define TARGET_RTC_ALM_SET TARGET_IOW('p', 0x07, struct rtc_time) +#define TARGET_RTC_RD_TIME TARGET_IOR('p', 0x09, struct rtc_time) +#define TARGET_RTC_SET_TIME TARGET_IOW('p', 0x0a, struct rtc_time) #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4) || \ defined(TARGET_XTENSA) diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index 8ff78a625a..bddc89a664 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -255,6 +255,17 @@ STRUCT(blkpg_partition, MK_ARRAY(TYPE_CHAR, BLKPG_DEVNAMELTH), /* devname */ MK_ARRAY(TYPE_CHAR, BLKPG_VOLNAMELTH)) /* volname */ +STRUCT(rtc_time, + TYPE_INT, /* tm_sec */ + TYPE_INT, /* tm_min */ + TYPE_INT, /* tm_hour */ + TYPE_INT, /* tm_mday */ + TYPE_INT, /* tm_mon */ + TYPE_INT, /* tm_year */ + TYPE_INT, /* tm_wday */ + TYPE_INT, /* tm_yday */ + TYPE_INT) /* tm_isdst */ + STRUCT(blkpg_ioctl_arg, TYPE_INT, /* op */ TYPE_INT, /* flags */ From fa857eb570bb7ee05a171c59f9b2864dab2357c9 Mon Sep 17 00:00:00 2001 From: Filip Bozuta Date: Wed, 15 Jan 2020 20:36:37 +0100 Subject: [PATCH 14/17] linux-user: Add support for getting/setting RTC periodic interrupt and epoch using ioctls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch implements functionalities of following ioctls: RTC_IRQP_READ, RTC_IRQP_SET - Getting/Setting IRQ rate Read and set the frequency for periodic interrupts, for RTCs that support periodic interrupts. The periodic interrupt must be separately enabled or disabled using the RTC_PIE_ON, RTC_PIE_OFF requests. The third ioctl's argument is an unsigned long * or an unsigned long, respectively. The value is the frequency in interrupts per second. The set of allow‐ able frequencies is the multiples of two in the range 2 to 8192. Only a privileged process (i.e., one having the CAP_SYS_RESOURCE capability) can set frequencies above the value specified in /proc/sys/dev/rtc/max-user-freq. (This file contains the value 64 by default.) RTC_EPOCH_READ, RTC_EPOCH_SET - Getting/Setting epoch Many RTCs encode the year in an 8-bit register which is either interpreted as an 8-bit binary number or as a BCD number. In both cases, the number is interpreted relative to this RTC's Epoch. The RTC's Epoch is initialized to 1900 on most systems but on Alpha and MIPS it might also be initialized to 1952, 1980, or 2000, depending on the value of an RTC register for the year. With some RTCs, these operations can be used to read or to set the RTC's Epoch, respectively. The third ioctl's argument is an unsigned long * or an unsigned long, respectively, and the value returned (or assigned) is the Epoch. To set the RTC's Epoch the process must be privileged (i.e., have the CAP_SYS_TIME capability). Implementation notes: All ioctls in this patch have a pointer to 'ulong' as their third argument. That is the reason why corresponding parts of added code in linux-user/syscall_defs.h contain special handling related to 'ulong' type: they use 'abi_ulong' type to make sure that ioctl's code is calculated correctly for both 32-bit and 64-bit targets. Also, 'MK_PTR(TYPE_ULONG)' is used for the similar reason in linux-user/ioctls.h. Reviewed-by: Laurent Vivier Signed-off-by: Filip Bozuta Message-Id: <1579117007-7565-4-git-send-email-Filip.Bozuta@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 4 ++++ linux-user/syscall_defs.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index c39dd0128a..9e91eaae77 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -81,6 +81,10 @@ IOCTL(RTC_ALM_SET, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_time))) IOCTL(RTC_RD_TIME, IOC_R, MK_PTR(MK_STRUCT(STRUCT_rtc_time))) IOCTL(RTC_SET_TIME, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_time))) + IOCTL(RTC_IRQP_READ, IOC_R, MK_PTR(TYPE_ULONG)) + IOCTL(RTC_IRQP_SET, IOC_W, TYPE_ULONG) + IOCTL(RTC_EPOCH_READ, IOC_R, MK_PTR(TYPE_ULONG)) + IOCTL(RTC_EPOCH_SET, IOC_W, TYPE_ULONG) IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT)) IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT)) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index dc36dd4751..fcbb2ee9a3 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -776,6 +776,10 @@ struct target_pollfd { #define TARGET_RTC_ALM_SET TARGET_IOW('p', 0x07, struct rtc_time) #define TARGET_RTC_RD_TIME TARGET_IOR('p', 0x09, struct rtc_time) #define TARGET_RTC_SET_TIME TARGET_IOW('p', 0x0a, struct rtc_time) +#define TARGET_RTC_IRQP_READ TARGET_IOR('p', 0x0b, abi_ulong) +#define TARGET_RTC_IRQP_SET TARGET_IOW('p', 0x0c, abi_ulong) +#define TARGET_RTC_EPOCH_READ TARGET_IOR('p', 0x0d, abi_ulong) +#define TARGET_RTC_EPOCH_SET TARGET_IOW('p', 0x0e, abi_ulong) #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4) || \ defined(TARGET_XTENSA) From abc81bf678941abfb1c003e71cc833bd8b46c7c6 Mon Sep 17 00:00:00 2001 From: Filip Bozuta Date: Wed, 15 Jan 2020 20:36:38 +0100 Subject: [PATCH 15/17] linux-user: Add support for getting/setting RTC wakeup alarm using ioctls This patch implements functionalities of following ioctls: RTC_WKALM_SET, RTC_WKALM_GET - Getting/Setting wakeup alarm Some RTCs support a more powerful alarm interface, using these ioctls to read or write the RTC's alarm time (respectively) with this structure: struct rtc_wkalrm { unsigned char enabled; unsigned char pending; struct rtc_time time; }; The enabled flag is used to enable or disable the alarm interrupt, or to read its current status; when using these calls, RTC_AIE_ON and RTC_AIE_OFF are not used. The pending flag is used by RTC_WKALM_RD to report a pending interrupt (so it's mostly useless on Linux, except when talking to the RTC managed by EFI firmware). The time field is as used with RTC_ALM_READ and RTC_ALM_SET except that the tm_mday, tm_mon, and tm_year fields are also valid. A pointer to this structure should be passed as the third ioctl's argument. Implementation notes: All ioctls in this patch have a pointer to a structure rtc_wkalrm as their third argument. That is the reason why corresponding definition is added in linux-user/syscall_types.h. Since all elements of this structure are either of type 'unsigned char' or 'struct rtc_time' (that was covered in one of previous patches), the rest of the implementation is straightforward. Reviewed-by: Laurent Vivier Signed-off-by: Filip Bozuta Message-Id: <1579117007-7565-5-git-send-email-Filip.Bozuta@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 2 ++ linux-user/syscall_defs.h | 2 ++ linux-user/syscall_types.h | 5 +++++ 3 files changed, 9 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 9e91eaae77..e4c1fbf52b 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -85,6 +85,8 @@ IOCTL(RTC_IRQP_SET, IOC_W, TYPE_ULONG) IOCTL(RTC_EPOCH_READ, IOC_R, MK_PTR(TYPE_ULONG)) IOCTL(RTC_EPOCH_SET, IOC_W, TYPE_ULONG) + IOCTL(RTC_WKALM_RD, IOC_R, MK_PTR(MK_STRUCT(STRUCT_rtc_wkalrm))) + IOCTL(RTC_WKALM_SET, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_wkalrm))) IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT)) IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT)) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index fcbb2ee9a3..c33432a374 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -780,6 +780,8 @@ struct target_pollfd { #define TARGET_RTC_IRQP_SET TARGET_IOW('p', 0x0c, abi_ulong) #define TARGET_RTC_EPOCH_READ TARGET_IOR('p', 0x0d, abi_ulong) #define TARGET_RTC_EPOCH_SET TARGET_IOW('p', 0x0e, abi_ulong) +#define TARGET_RTC_WKALM_RD TARGET_IOR('p', 0x10, struct rtc_wkalrm) +#define TARGET_RTC_WKALM_SET TARGET_IOW('p', 0x0f, struct rtc_wkalrm) #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4) || \ defined(TARGET_XTENSA) diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index bddc89a664..3efa9536cc 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -266,6 +266,11 @@ STRUCT(rtc_time, TYPE_INT, /* tm_yday */ TYPE_INT) /* tm_isdst */ +STRUCT(rtc_wkalrm, + TYPE_CHAR, /* enabled */ + TYPE_CHAR, /* pending */ + MK_STRUCT(STRUCT_rtc_time)) /* time */ + STRUCT(blkpg_ioctl_arg, TYPE_INT, /* op */ TYPE_INT, /* flags */ From 373b067ff077d92bf23abd2224b49cccf5dea846 Mon Sep 17 00:00:00 2001 From: Filip Bozuta Date: Wed, 15 Jan 2020 20:36:39 +0100 Subject: [PATCH 16/17] linux-user: Add support for getting/setting RTC PLL correction using ioctls This patch implements functionalities of following ioctls: RTC_PLL_GET - Getting PLL correction Read the PLL correction for RTCs that support PLL. The PLL correction is returned in the following structure: struct rtc_pll_info { int pll_ctrl; /* placeholder for fancier control */ int pll_value; /* get/set correction value */ int pll_max; /* max +ve (faster) adjustment value */ int pll_min; /* max -ve (slower) adjustment value */ int pll_posmult; /* factor for +ve correction */ int pll_negmult; /* factor for -ve correction */ long pll_clock; /* base PLL frequency */ }; A pointer to this structure should be passed as the third ioctl's argument. RTC_PLL_SET - Setting PLL correction Sets the PLL correction for RTCs that support PLL. The PLL correction that is set is specified by the rtc_pll_info structure pointed to by the third ioctl's' argument. Implementation notes: All ioctls in this patch have a pointer to a structure rtc_pll_info as their third argument. All elements of this structure are of type 'int', except the last one that is of type 'long'. That is the reason why a separate target structure (target_rtc_pll_info) is defined in linux-user/syscall_defs. The rest of the implementation is straightforward. Reviewed-by: Laurent Vivier Signed-off-by: Filip Bozuta Message-Id: <1579117007-7565-6-git-send-email-Filip.Bozuta@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 2 ++ linux-user/syscall_defs.h | 14 ++++++++++++++ linux-user/syscall_types.h | 9 +++++++++ 3 files changed, 25 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index e4c1fbf52b..789764d113 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -87,6 +87,8 @@ IOCTL(RTC_EPOCH_SET, IOC_W, TYPE_ULONG) IOCTL(RTC_WKALM_RD, IOC_R, MK_PTR(MK_STRUCT(STRUCT_rtc_wkalrm))) IOCTL(RTC_WKALM_SET, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_wkalrm))) + IOCTL(RTC_PLL_GET, IOC_R, MK_PTR(MK_STRUCT(STRUCT_rtc_pll_info))) + IOCTL(RTC_PLL_SET, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_pll_info))) IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT)) IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT)) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index c33432a374..9f7aad49c6 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -763,6 +763,16 @@ struct target_pollfd { #define TARGET_KDSETLED 0x4B32 /* set led state [lights, not flags] */ #define TARGET_KDSIGACCEPT 0x4B4E +struct target_rtc_pll_info { + int pll_ctrl; + int pll_value; + int pll_max; + int pll_min; + int pll_posmult; + int pll_negmult; + abi_long pll_clock; +}; + /* real time clock ioctls */ #define TARGET_RTC_AIE_ON TARGET_IO('p', 0x01) #define TARGET_RTC_AIE_OFF TARGET_IO('p', 0x02) @@ -782,6 +792,10 @@ struct target_pollfd { #define TARGET_RTC_EPOCH_SET TARGET_IOW('p', 0x0e, abi_ulong) #define TARGET_RTC_WKALM_RD TARGET_IOR('p', 0x10, struct rtc_wkalrm) #define TARGET_RTC_WKALM_SET TARGET_IOW('p', 0x0f, struct rtc_wkalrm) +#define TARGET_RTC_PLL_GET TARGET_IOR('p', 0x11, \ + struct target_rtc_pll_info) +#define TARGET_RTC_PLL_SET TARGET_IOW('p', 0x12, \ + struct target_rtc_pll_info) #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4) || \ defined(TARGET_XTENSA) diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h index 3efa9536cc..5ba4155047 100644 --- a/linux-user/syscall_types.h +++ b/linux-user/syscall_types.h @@ -271,6 +271,15 @@ STRUCT(rtc_wkalrm, TYPE_CHAR, /* pending */ MK_STRUCT(STRUCT_rtc_time)) /* time */ +STRUCT(rtc_pll_info, + TYPE_INT, /* pll_ctrl */ + TYPE_INT, /* pll_value */ + TYPE_INT, /* pll_max */ + TYPE_INT, /* pll_min */ + TYPE_INT, /* pll_posmult */ + TYPE_INT, /* pll_negmult */ + TYPE_LONG) /* pll_clock */ + STRUCT(blkpg_ioctl_arg, TYPE_INT, /* op */ TYPE_INT, /* flags */ From a7b09746679c1815115249ec69197e454efdfb15 Mon Sep 17 00:00:00 2001 From: Filip Bozuta Date: Wed, 15 Jan 2020 20:36:40 +0100 Subject: [PATCH 17/17] linux-user: Add support for read/clear RTC voltage low detector using ioctls This patch implements functionalities of following ioctls: RTC_VL_READ - Read voltage low detection information Read the voltage low for RTCs that support voltage low. The third ioctl's' argument points to an int in which the voltage low is returned. RTC_VL_CLR - Clear voltage low information Clear the information about voltage low for RTCs that support voltage low. The third ioctl(2) argument is ignored. Implementation notes: Since one ioctl has a pointer to 'int' as its third agrument, and another ioctl has NULL as its third argument, their implementation was straightforward. Reviewed-by: Laurent Vivier Signed-off-by: Filip Bozuta Message-Id: <1579117007-7565-7-git-send-email-Filip.Bozuta@rt-rk.com> Signed-off-by: Laurent Vivier --- linux-user/ioctls.h | 2 ++ linux-user/syscall_defs.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h index 789764d113..73dcc761e6 100644 --- a/linux-user/ioctls.h +++ b/linux-user/ioctls.h @@ -89,6 +89,8 @@ IOCTL(RTC_WKALM_SET, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_wkalrm))) IOCTL(RTC_PLL_GET, IOC_R, MK_PTR(MK_STRUCT(STRUCT_rtc_pll_info))) IOCTL(RTC_PLL_SET, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtc_pll_info))) + IOCTL(RTC_VL_READ, IOC_R, MK_PTR(TYPE_INT)) + IOCTL(RTC_VL_CLR, 0, TYPE_NULL) IOCTL(BLKROSET, IOC_W, MK_PTR(TYPE_INT)) IOCTL(BLKROGET, IOC_R, MK_PTR(TYPE_INT)) diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 9f7aad49c6..9b61ae8547 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -796,6 +796,8 @@ struct target_rtc_pll_info { struct target_rtc_pll_info) #define TARGET_RTC_PLL_SET TARGET_IOW('p', 0x12, \ struct target_rtc_pll_info) +#define TARGET_RTC_VL_READ TARGET_IOR('p', 0x13, int) +#define TARGET_RTC_VL_CLR TARGET_IO('p', 0x14) #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4) || \ defined(TARGET_XTENSA)