diff options
Diffstat (limited to '')
| -rw-r--r-- | linux-user/s390x/cpu_loop.c | 66 | ||||
| -rw-r--r-- | meson.build | 2 | ||||
| -rw-r--r-- | qga/commands-win32.c | 18 | ||||
| -rw-r--r-- | qga/installer/qemu-ga.wxs | 6 | ||||
| -rw-r--r-- | qga/vss-win32/requester.cpp | 2 | ||||
| m--------- | slirp | 0 | ||||
| -rw-r--r-- | tests/tcg/s390x/Makefile.target | 2 | ||||
| -rw-r--r-- | tests/tcg/s390x/trap.c | 102 |
8 files changed, 168 insertions, 30 deletions
diff --git a/linux-user/s390x/cpu_loop.c b/linux-user/s390x/cpu_loop.c index f2d1215fb1..6a69a6dd26 100644 --- a/linux-user/s390x/cpu_loop.c +++ b/linux-user/s390x/cpu_loop.c @@ -25,6 +25,35 @@ /* s390x masks the fault address it reports in si_addr for SIGSEGV and SIGBUS */ #define S390X_FAIL_ADDR_MASK -4096LL +static int get_pgm_data_si_code(int dxc_code) +{ + switch (dxc_code) { + /* Non-simulated IEEE exceptions */ + case 0x80: + return TARGET_FPE_FLTINV; + case 0x40: + return TARGET_FPE_FLTDIV; + case 0x20: + case 0x28: + case 0x2c: + return TARGET_FPE_FLTOVF; + case 0x10: + case 0x18: + case 0x1c: + return TARGET_FPE_FLTUND; + case 0x08: + case 0x0c: + return TARGET_FPE_FLTRES; + } + /* + * Non-IEEE and simulated IEEE: + * Includes compare-and-trap, quantum exception, etc. + * Simulated IEEE are included here to match current + * s390x linux kernel. + */ + return 0; +} + void cpu_loop(CPUS390XState *env) { CPUState *cs = env_cpu(env); @@ -64,7 +93,13 @@ void cpu_loop(CPUS390XState *env) case EXCP_DEBUG: sig = TARGET_SIGTRAP; n = TARGET_TRAP_BRKPT; - goto do_signal_pc; + /* + * For SIGTRAP the PSW must point after the instruction, which it + * already does thanks to s390x_tr_tb_stop(). si_addr doesn't need + * to be filled. + */ + addr = 0; + goto do_signal; case EXCP_PGM: n = env->int_pgm_code; switch (n) { @@ -100,29 +135,14 @@ void cpu_loop(CPUS390XState *env) case PGM_DATA: n = (env->fpc >> 8) & 0xff; - if (n == 0xff) { - /* compare-and-trap */ + if (n == 0) { goto do_sigill_opn; - } else { - /* An IEEE exception, simulated or otherwise. */ - if (n & 0x80) { - n = TARGET_FPE_FLTINV; - } else if (n & 0x40) { - n = TARGET_FPE_FLTDIV; - } else if (n & 0x20) { - n = TARGET_FPE_FLTOVF; - } else if (n & 0x10) { - n = TARGET_FPE_FLTUND; - } else if (n & 0x08) { - n = TARGET_FPE_FLTRES; - } else { - /* ??? Quantum exception; BFP, DFP error. */ - goto do_sigill_opn; - } - sig = TARGET_SIGFPE; - goto do_signal_pc; } + sig = TARGET_SIGFPE; + n = get_pgm_data_si_code(n); + goto do_signal_pc; + default: fprintf(stderr, "Unhandled program exception: %#x\n", n); cpu_dump_state(cs, stderr, 0); @@ -132,6 +152,10 @@ void cpu_loop(CPUS390XState *env) do_signal_pc: addr = env->psw.addr; + /* + * For SIGILL and SIGFPE the PSW must point after the instruction. + */ + env->psw.addr += env->int_pgm_ilen; do_signal: info.si_signo = sig; info.si_errno = 0; diff --git a/meson.build b/meson.build index f2e148eaf9..af9bbb83db 100644 --- a/meson.build +++ b/meson.build @@ -1824,6 +1824,8 @@ if have_system slirp_deps = [] if targetos == 'windows' slirp_deps = cc.find_library('iphlpapi') + elif targetos == 'darwin' + slirp_deps = cc.find_library('resolv') endif slirp_conf = configuration_data() slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0]) diff --git a/qga/commands-win32.c b/qga/commands-win32.c index a099acb34d..7bac0c5d42 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -1091,7 +1091,7 @@ static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp) size_t len; uint64_t i64FreeBytesToCaller, i64TotalBytes, i64FreeBytes; GuestFilesystemInfo *fs = NULL; - HANDLE hLocalDiskHandle = NULL; + HANDLE hLocalDiskHandle = INVALID_HANDLE_VALUE; GetVolumePathNamesForVolumeName(guid, (LPCH)&mnt, 0, &info_size); if (GetLastError() != ERROR_MORE_DATA) { @@ -1149,7 +1149,9 @@ static GuestFilesystemInfo *build_guest_fsinfo(char *guid, Error **errp) fs->type = g_strdup(fs_name); fs->disk = build_guest_disk_info(guid, errp); free: - CloseHandle(hLocalDiskHandle); + if (hLocalDiskHandle != INVALID_HANDLE_VALUE) { + CloseHandle(hLocalDiskHandle); + } g_free(mnt_point); return fs; } @@ -2229,7 +2231,7 @@ static char *ga_get_win_name(OSVERSIONINFOEXW const *os_version, bool id) static char *ga_get_win_product_name(Error **errp) { - HKEY key = NULL; + HKEY key = INVALID_HANDLE_VALUE; DWORD size = 128; char *result = g_malloc0(size); LONG err = ERROR_SUCCESS; @@ -2239,7 +2241,8 @@ static char *ga_get_win_product_name(Error **errp) &key); if (err != ERROR_SUCCESS) { error_setg_win32(errp, err, "failed to open registry key"); - goto fail; + g_free(result); + return NULL; } err = RegQueryValueExA(key, "ProductName", NULL, NULL, @@ -2260,9 +2263,13 @@ static char *ga_get_win_product_name(Error **errp) goto fail; } + RegCloseKey(key); return result; fail: + if (key != INVALID_HANDLE_VALUE) { + RegCloseKey(key); + } g_free(result); return NULL; } @@ -2452,7 +2459,7 @@ GuestDeviceInfoList *qmp_guest_get_devices(Error **errp) continue; } for (j = 0; hw_ids[j] != NULL; j++) { - GMatchInfo *match_info; + g_autoptr(GMatchInfo) match_info; GuestDeviceIdPCI *id; if (!g_regex_match(device_pci_re, hw_ids[j], 0, &match_info)) { continue; @@ -2469,7 +2476,6 @@ GuestDeviceInfoList *qmp_guest_get_devices(Error **errp) id->vendor_id = g_ascii_strtoull(vendor_id, NULL, 16); id->device_id = g_ascii_strtoull(device_id, NULL, 16); - g_match_info_free(match_info); break; } if (skip) { diff --git a/qga/installer/qemu-ga.wxs b/qga/installer/qemu-ga.wxs index 9cb4c3d733..0950e8c6be 100644 --- a/qga/installer/qemu-ga.wxs +++ b/qga/installer/qemu-ga.wxs @@ -31,7 +31,7 @@ <?endif?> <?if $(var.Arch) = "32"?> - <?define ArchLib=libgcc_s_sjlj-1.dll?> + <?define ArchLib=libgcc_s_dw2-1.dll?> <?define GaProgramFilesFolder="ProgramFilesFolder" ?> <?endif?> @@ -84,6 +84,9 @@ <ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="QEMU-GA" Wait="yes" /> </Component> <?ifdef var.InstallVss?> + <Component Id="libstdc++_6_lib" Guid="{55E737B5-9127-4A11-9FC3-A29367714574}"> + <File Id="libstdc++-6.lib" Name="libstdc++-6.dll" Source="$(var.Mingw_bin)/libstdc++-6.dll" KeyPath="yes" DiskId="1"/> + </Component> <Component Id="qga_vss_dll" Guid="{CB19C453-FABB-4BB1-ABAB-6B74F687BFBB}"> <File Id="qga_vss.dll" Name="qga-vss.dll" Source="$(env.BUILD_DIR)/qga/vss-win32/qga-vss.dll" KeyPath="yes" DiskId="1"/> </Component> @@ -164,6 +167,7 @@ <Feature Id="QEMUFeature" Title="QEMU Guest Agent" Level="1"> <ComponentRef Id="qemu_ga" /> <?ifdef var.InstallVss?> + <ComponentRef Id="libstdc++_6_lib" /> <ComponentRef Id="qga_vss_dll" /> <ComponentRef Id="qga_vss_tlb" /> <?endif?> diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp index 5378c55d23..940a2c8f55 100644 --- a/qga/vss-win32/requester.cpp +++ b/qga/vss-win32/requester.cpp @@ -18,7 +18,7 @@ #include <inc/win2003/vsbackup.h> /* Max wait time for frozen event (VSS can only hold writes for 10 seconds) */ -#define VSS_TIMEOUT_FREEZE_MSEC 10000 +#define VSS_TIMEOUT_FREEZE_MSEC 60000 /* Call QueryStatus every 10 ms while waiting for frozen event */ #define VSS_TIMEOUT_EVENT_MSEC 10 diff --git a/slirp b/slirp -Subproject 8f43a99191afb47ca3f3c6972f6306209f367ec +Subproject a88d9ace234a24ce1c17189642ef9104799425e diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target index 5d3de1b27a..bd084c7840 100644 --- a/tests/tcg/s390x/Makefile.target +++ b/tests/tcg/s390x/Makefile.target @@ -8,4 +8,4 @@ TESTS+=exrl-trtr TESTS+=pack TESTS+=mvo TESTS+=mvc - +TESTS+=trap diff --git a/tests/tcg/s390x/trap.c b/tests/tcg/s390x/trap.c new file mode 100644 index 0000000000..d4c61c7f52 --- /dev/null +++ b/tests/tcg/s390x/trap.c @@ -0,0 +1,102 @@ +/* + * Copyright 2021 IBM Corp. + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at + * your option) any later version. See the COPYING file in the top-level + * directory. + */ + +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <signal.h> + +static void error1(const char *filename, int line, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + fprintf(stderr, "%s:%d: ", filename, line); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + exit(1); +} + +static int __chk_error(const char *filename, int line, int ret) +{ + if (ret < 0) { + error1(filename, line, "%m (ret=%d, errno=%d/%s)", + ret, errno, strerror(errno)); + } + return ret; +} + +#define error(fmt, ...) error1(__FILE__, __LINE__, fmt, ## __VA_ARGS__) + +#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret)) + +int sigfpe_count; +int sigill_count; + +static void sig_handler(int sig, siginfo_t *si, void *puc) +{ + if (sig == SIGFPE) { + if (si->si_code != 0) { + error("unexpected si_code: 0x%x != 0", si->si_code); + } + ++sigfpe_count; + return; + } + + if (sig == SIGILL) { + ++sigill_count; + return; + } + + error("unexpected signal 0x%x\n", sig); +} + +int main(int argc, char **argv) +{ + sigfpe_count = sigill_count = 0; + + struct sigaction act; + + /* Set up SIG handler */ + act.sa_sigaction = sig_handler; + sigemptyset(&act.sa_mask); + act.sa_flags = SA_SIGINFO; + chk_error(sigaction(SIGFPE, &act, NULL)); + chk_error(sigaction(SIGILL, &act, NULL)); + + uint64_t z = 0x0ull; + uint64_t lz = 0xffffffffffffffffull; + asm volatile ( + "lg %%r13,%[lz]\n" + "cgitne %%r13,0\n" /* SIGFPE */ + "lg %%r13,%[z]\n" + "cgitne %%r13,0\n" /* no trap */ + "nopr\n" + "lg %%r13,%[lz]\n" + "citne %%r13,0\n" /* SIGFPE */ + "lg %%r13,%[z]\n" + "citne %%r13,0\n" /* no trap */ + "nopr\n" + : + : [z] "m" (z), [lz] "m" (lz) + : "memory", "r13"); + + if (sigfpe_count != 2) { + error("unexpected SIGFPE count: %d != 2", sigfpe_count); + } + if (sigill_count != 0) { + error("unexpected SIGILL count: %d != 0", sigill_count); + } + + printf("PASS\n"); + return 0; +} |