From d1abf3fc6abc01fd5f8985af92726f87b5efd80a Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 7 Jul 2020 19:13:25 +0200 Subject: [PATCH 1/9] configure: fix malloc check Avoid random return value. Fixes commit f2dfe54c74f768a5bf78c9e5918918727f9d9459 Signed-off-by: Olaf Hering Message-Id: <20200707171326.16422-1-olaf@aepfle.de> Reviewed-by: Richard Henderson Signed-off-by: Thomas Huth --- configure | 1 + 1 file changed, 1 insertion(+) diff --git a/configure b/configure index 814ed81279..f59418f6de 100755 --- a/configure +++ b/configure @@ -6343,6 +6343,7 @@ int main(void) { if (tmp != NULL) { return *(int *)(tmp + 2); } + return 1; } EOF if compile_prog "$CPU_CFLAGS -Werror -fsanitize=undefined" ""; then From 0ab6c2384ccae8968517f6883897509cd5f51a40 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Wed, 8 Jul 2020 16:01:03 -0400 Subject: [PATCH 2/9] configure: do not clobber CFLAGS with --enable-fuzzing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When configuring with --enable-fuzzing, we overwrote the CFLAGS added by all the preceding checks. Instead of overwriting CFLAGS, append the ones we need. Fixes: adc28027ff ("fuzz: add configure flag --enable-fuzzing") Reported-by: Li Qiang Signed-off-by: Alexander Bulekov Message-Id: <20200708200104.21978-2-alxndr@bu.edu> Tested-by: Li Qiang Reviewed-by: Li Qiang Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index f59418f6de..69a89113f7 100755 --- a/configure +++ b/configure @@ -7926,7 +7926,7 @@ if test "$fuzzing" = "yes" ; then if test "$have_fuzzer" = "yes"; then FUZZ_LDFLAGS=" -fsanitize=address,fuzzer" FUZZ_CFLAGS=" -fsanitize=address,fuzzer" - CFLAGS=" -fsanitize=address,fuzzer-no-link" + CFLAGS="$CFLAGS -fsanitize=address,fuzzer-no-link" else error_exit "Your compiler doesn't support -fsanitize=address,fuzzer" exit 1 From 230225eaaa47f23acffef2f21f9bfb1e99b27b31 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Wed, 8 Jul 2020 16:01:04 -0400 Subject: [PATCH 3/9] fuzz: add missing header for rcu_enable_atfork MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In 45222b9a90, I fixed a broken check for rcu_enable_atfork introduced in d6919e4cb6. I added a call to rcu_enable_atfork after the call to qemu_init in fuzz.c, but forgot to include the corresponding header, breaking --enable-fuzzing --enable-werror builds. Fixes: 45222b9a90 ("fuzz: fix broken qtest check at rcu_disable_atfork") Signed-off-by: Alexander Bulekov Message-Id: <20200708200104.21978-3-alxndr@bu.edu> Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Thomas Huth Signed-off-by: Thomas Huth --- tests/qtest/fuzz/fuzz.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/qtest/fuzz/fuzz.c b/tests/qtest/fuzz/fuzz.c index a36d9038e0..0b66e43409 100644 --- a/tests/qtest/fuzz/fuzz.c +++ b/tests/qtest/fuzz/fuzz.c @@ -19,6 +19,7 @@ #include "sysemu/runstate.h" #include "sysemu/sysemu.h" #include "qemu/main-loop.h" +#include "qemu/rcu.h" #include "tests/qtest/libqtest.h" #include "tests/qtest/libqos/qgraph.h" #include "fuzz.h" From 2c65fefa054fb8aa60b138efc48aa24e7d8e00bc Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 9 Jul 2020 10:37:19 +0200 Subject: [PATCH 4/9] tests/qtest/fuzz: Add missing spaces in description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There should be a space between "forking" and "for". Message-Id: <20200709083719.22221-1-thuth@redhat.com> Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alexander Bulekov Signed-off-by: Thomas Huth --- tests/qtest/fuzz/virtio_scsi_fuzz.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/qtest/fuzz/virtio_scsi_fuzz.c b/tests/qtest/fuzz/virtio_scsi_fuzz.c index 51dce491ab..3a9ea13736 100644 --- a/tests/qtest/fuzz/virtio_scsi_fuzz.c +++ b/tests/qtest/fuzz/virtio_scsi_fuzz.c @@ -191,7 +191,7 @@ static void register_virtio_scsi_fuzz_targets(void) { fuzz_add_qos_target(&(FuzzTarget){ .name = "virtio-scsi-fuzz", - .description = "Fuzz the virtio-scsi virtual queues, forking" + .description = "Fuzz the virtio-scsi virtual queues, forking " "for each fuzz run", .pre_vm_init = &counter_shm_init, .pre_fuzz = &virtio_scsi_pre_fuzz, @@ -202,7 +202,7 @@ static void register_virtio_scsi_fuzz_targets(void) fuzz_add_qos_target(&(FuzzTarget){ .name = "virtio-scsi-flags-fuzz", - .description = "Fuzz the virtio-scsi virtual queues, forking" + .description = "Fuzz the virtio-scsi virtual queues, forking " "for each fuzz run (also fuzzes the virtio flags)", .pre_vm_init = &counter_shm_init, .pre_fuzz = &virtio_scsi_pre_fuzz, From 590246ead7e5628e9e365c88aeb1ff3eab24de0d Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 9 Jul 2020 10:40:59 +0200 Subject: [PATCH 5/9] docs/devel/fuzzing: Fix bugs in documentation Fix typo - the option is called "--fuzz-target" and not "--fuzz_taget". Also use a different fuzzer in the example, since "virtio-net-fork-fuzz" does not seem to be a valid fuzzer target (anymore?). Signed-off-by: Thomas Huth Message-Id: <20200709084059.22539-1-thuth@redhat.com> --- docs/devel/fuzzing.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/devel/fuzzing.txt b/docs/devel/fuzzing.txt index 324d2cd92b..db5641de74 100644 --- a/docs/devel/fuzzing.txt +++ b/docs/devel/fuzzing.txt @@ -33,11 +33,11 @@ Fuzz targets are built similarly to system/softmmu: This builds ./i386-softmmu/qemu-fuzz-i386 -The first option to this command is: --fuzz_taget=FUZZ_NAME +The first option to this command is: --fuzz-target=FUZZ_NAME To list all of the available fuzzers run qemu-fuzz-i386 with no arguments. -eg: - ./i386-softmmu/qemu-fuzz-i386 --fuzz-target=virtio-net-fork-fuzz +For example: + ./i386-softmmu/qemu-fuzz-i386 --fuzz-target=virtio-scsi-fuzz Internally, libfuzzer parses all arguments that do not begin with "--". Information about these is available by passing -help=1 From 7aa12aa215e12ab2d41c60ba57e82d3e2af9f38e Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 8 Jul 2020 20:19:44 +0200 Subject: [PATCH 6/9] Remove the CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE switch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC supports "#pragma GCC diagnostic" since version 4.6, and Clang seems to support it, too, since its early versions 3.x. That means that our minimum required compiler versions all support this pragma already and we can remove the test from configure and all the related #ifdefs in the code. Reviewed-by: Daniel P. Berrangé Message-Id: <20200710045515.25986-1-thuth@redhat.com> Reviewed-by: Stefan Hajnoczi Signed-off-by: Thomas Huth --- configure | 29 ----------------------------- include/ui/gtk.h | 4 ---- include/ui/qemu-pixman.h | 4 ---- scripts/decodetree.py | 12 ++++-------- ui/gtk.c | 4 ---- util/coroutine-ucontext.c | 4 ++-- 6 files changed, 6 insertions(+), 51 deletions(-) diff --git a/configure b/configure index 69a89113f7..9b6ab9d3ca 100755 --- a/configure +++ b/configure @@ -5728,31 +5728,6 @@ if compile_prog "" "" ; then linux_magic_h=yes fi -######################################## -# check whether we can disable warning option with a pragma (this is needed -# to silence warnings in the headers of some versions of external libraries). -# This test has to be compiled with -Werror as otherwise an unknown pragma is -# only a warning. -# -# If we can't selectively disable warning in the code, disable -Werror so that -# the build doesn't fail anyway. - -pragma_disable_unused_but_set=no -cat > $TMPC << EOF -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wstrict-prototypes" -#pragma GCC diagnostic pop - -int main(void) { - return 0; -} -EOF -if compile_prog "-Werror" "" ; then - pragma_diagnostic_available=yes -else - werror=no -fi - ######################################## # check if we have valgrind/valgrind.h @@ -7689,10 +7664,6 @@ if test "$linux_magic_h" = "yes" ; then echo "CONFIG_LINUX_MAGIC_H=y" >> $config_host_mak fi -if test "$pragma_diagnostic_available" = "yes" ; then - echo "CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE=y" >> $config_host_mak -fi - if test "$valgrind_h" = "yes" ; then echo "CONFIG_VALGRIND_H=y" >> $config_host_mak fi diff --git a/include/ui/gtk.h b/include/ui/gtk.h index d1b230848a..eaeb450f91 100644 --- a/include/ui/gtk.h +++ b/include/ui/gtk.h @@ -1,15 +1,11 @@ #ifndef UI_GTK_H #define UI_GTK_H -#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE /* Work around an -Wstrict-prototypes warning in GTK headers */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstrict-prototypes" -#endif #include -#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE #pragma GCC diagnostic pop -#endif #include diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h index 3b7cf70157..87737a6f16 100644 --- a/include/ui/qemu-pixman.h +++ b/include/ui/qemu-pixman.h @@ -7,14 +7,10 @@ #define QEMU_PIXMAN_H /* pixman-0.16.0 headers have a redundant declaration */ -#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wredundant-decls" -#endif #include -#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE #pragma GCC diagnostic pop -#endif /* * pixman image formats are defined to be native endian, diff --git a/scripts/decodetree.py b/scripts/decodetree.py index 530d41ca62..694757b6c2 100755 --- a/scripts/decodetree.py +++ b/scripts/decodetree.py @@ -1327,12 +1327,10 @@ def main(): # but we can't tell which ones. Prevent issues from the compiler by # suppressing redundant declaration warnings. if anyextern: - output("#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE\n", - "# pragma GCC diagnostic push\n", - "# pragma GCC diagnostic ignored \"-Wredundant-decls\"\n", - "# ifdef __clang__\n" + output("#pragma GCC diagnostic push\n", + "#pragma GCC diagnostic ignored \"-Wredundant-decls\"\n", + "#ifdef __clang__\n" "# pragma GCC diagnostic ignored \"-Wtypedef-redefinition\"\n", - "# endif\n", "#endif\n\n") out_pats = {} @@ -1347,9 +1345,7 @@ def main(): output('\n') if anyextern: - output("#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE\n", - "# pragma GCC diagnostic pop\n", - "#endif\n\n") + output("#pragma GCC diagnostic pop\n\n") for n in sorted(formats.keys()): f = formats[n] diff --git a/ui/gtk.c b/ui/gtk.c index d4b49bd7da..b0cc08ad6d 100644 --- a/ui/gtk.c +++ b/ui/gtk.c @@ -1996,14 +1996,10 @@ static GSList *gd_vc_gfx_init(GtkDisplayState *s, VirtualConsole *vc, * proper replacement (native opengl support) is only * available in 3.16+. Silence the warning if possible. */ -#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif gtk_widget_set_double_buffered(vc->gfx.drawing_area, FALSE); -#ifdef CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE #pragma GCC diagnostic pop -#endif vc->gfx.dcl.ops = &dcl_egl_ops; } } else diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c index fff20aad80..904b375192 100644 --- a/util/coroutine-ucontext.c +++ b/util/coroutine-ucontext.c @@ -251,8 +251,8 @@ Coroutine *qemu_coroutine_new(void) } #ifdef CONFIG_VALGRIND_H -#if defined(CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE) && !defined(__clang__) /* Work around an unused variable in the valgrind.h macro... */ +#if !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-but-set-variable" #endif @@ -260,7 +260,7 @@ static inline void valgrind_stack_deregister(CoroutineUContext *co) { VALGRIND_STACK_DEREGISTER(co->valgrind_stack_id); } -#if defined(CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE) && !defined(__clang__) +#if !defined(__clang__) #pragma GCC diagnostic pop #endif #endif From ccb237090fdafedce56cb8b62f451a09ad5031c9 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 30 Jun 2020 07:03:44 +0200 Subject: [PATCH 7/9] disas/sh4: Add missing fallthrough annotations Add fallthrough annotations to be able to compile the code without warnings with -Wimplicit-fallthrough. Looking at the code, it seems like the fallthrough is indeed intended here, so the comments should be appropriate. Message-Id: <20200630055953.9309-1-thuth@redhat.com> Reviewed-by: Richard Henderson Signed-off-by: Thomas Huth --- disas/sh4.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/disas/sh4.c b/disas/sh4.c index 55ef865a36..dcdbdf26d8 100644 --- a/disas/sh4.c +++ b/disas/sh4.c @@ -1963,6 +1963,7 @@ print_insn_sh (bfd_vma memaddr, struct disassemble_info *info) fprintf_fn (stream, "xd%d", rn & ~1); break; } + /* fallthrough */ case D_REG_N: fprintf_fn (stream, "dr%d", rn); break; @@ -1972,6 +1973,7 @@ print_insn_sh (bfd_vma memaddr, struct disassemble_info *info) fprintf_fn (stream, "xd%d", rm & ~1); break; } + /* fallthrough */ case D_REG_M: fprintf_fn (stream, "dr%d", rm); break; From c02b2eac55ef72dd17b2ea8408c312d83f9e0482 Mon Sep 17 00:00:00 2001 From: Cleber Rosa Date: Wed, 8 Jul 2020 22:46:56 -0400 Subject: [PATCH 8/9] GitLab Gating CI: introduce pipeline-status contrib script This script is intended to be used right after a push to a branch. By default, it will look for the pipeline associated with the commit that is the HEAD of the *local* staging branch. It can be used as a one time check, or with the `--wait` option to wait until the pipeline completes. If the pipeline is successful, then a merge of the staging branch into the master branch should be the next step. Signed-off-by: Cleber Rosa Message-Id: <20200709024657.2500558-2-crosa@redhat.com> [thuth: Added the changes suggested by Erik Skultety] Signed-off-by: Thomas Huth --- scripts/ci/gitlab-pipeline-status | 157 ++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100755 scripts/ci/gitlab-pipeline-status diff --git a/scripts/ci/gitlab-pipeline-status b/scripts/ci/gitlab-pipeline-status new file mode 100755 index 0000000000..348a49b6a4 --- /dev/null +++ b/scripts/ci/gitlab-pipeline-status @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2019-2020 Red Hat, Inc. +# +# Author: +# Cleber Rosa +# +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. + +""" +Checks the GitLab pipeline status for a given commit ID +""" + +# pylint: disable=C0103 + +import argparse +import http.client +import json +import os +import subprocess +import time +import sys + + +def get_local_staging_branch_commit(): + """ + Returns the commit sha1 for the *local* branch named "staging" + """ + result = subprocess.run(['git', 'rev-parse', 'staging'], + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL, + cwd=os.path.dirname(__file__), + universal_newlines=True).stdout.strip() + if result == 'staging': + raise ValueError("There's no local branch named 'staging'") + if len(result) != 40: + raise ValueError("Branch staging HEAD doesn't look like a sha1") + return result + + +def get_pipeline_status(project_id, commit_sha1): + """ + Returns the JSON content of the pipeline status API response + """ + url = '/api/v4/projects/{}/pipelines?sha={}'.format(project_id, + commit_sha1) + connection = http.client.HTTPSConnection('gitlab.com') + connection.request('GET', url=url) + response = connection.getresponse() + if response.code != http.HTTPStatus.OK: + raise ValueError("Failed to receive a successful response") + json_response = json.loads(response.read()) + + # As far as I can tell, there should be only one pipeline for the same + # project + commit. If this assumption is false, we can add further + # filters to the url, such as username, and order_by. + if not json_response: + raise ValueError("No pipeline found") + return json_response[0] + + +def wait_on_pipeline_success(timeout, interval, + project_id, commit_sha): + """ + Waits for the pipeline to finish within the given timeout + """ + start = time.time() + while True: + if time.time() >= (start + timeout): + print("Waiting on the pipeline timed out") + return False + + status = get_pipeline_status(project_id, commit_sha) + if status['status'] == 'running': + time.sleep(interval) + print('running...') + continue + + if status['status'] == 'success': + return True + + msg = "Pipeline failed, check: %s" % status['web_url'] + print(msg) + return False + + +def main(): + """ + Script entry point + """ + parser = argparse.ArgumentParser( + prog='pipeline-status', + description='check or wait on a pipeline status') + + parser.add_argument('-t', '--timeout', type=int, default=7200, + help=('Amount of time (in seconds) to wait for the ' + 'pipeline to complete. Defaults to ' + '%(default)s')) + parser.add_argument('-i', '--interval', type=int, default=60, + help=('Amount of time (in seconds) to wait between ' + 'checks of the pipeline status. Defaults ' + 'to %(default)s')) + parser.add_argument('-w', '--wait', action='store_true', default=False, + help=('Wether to wait, instead of checking only once ' + 'the status of a pipeline')) + parser.add_argument('-p', '--project-id', type=int, default=11167699, + help=('The GitLab project ID. Defaults to the project ' + 'for https://gitlab.com/qemu-project/qemu, that ' + 'is, "%(default)s"')) + try: + default_commit = get_local_staging_branch_commit() + commit_required = False + except ValueError: + default_commit = '' + commit_required = True + parser.add_argument('-c', '--commit', required=commit_required, + default=default_commit, + help=('Look for a pipeline associated with the given ' + 'commit. If one is not explicitly given, the ' + 'commit associated with the local branch named ' + '"staging" is used. Default: %(default)s')) + parser.add_argument('--verbose', action='store_true', default=False, + help=('A minimal verbosity level that prints the ' + 'overall result of the check/wait')) + + args = parser.parse_args() + + try: + if args.wait: + success = wait_on_pipeline_success( + args.timeout, + args.interval, + args.project_id, + args.commit) + else: + status = get_pipeline_status(args.project_id, + args.commit) + success = status['status'] == 'success' + except Exception as error: # pylint: disable=W0703 + success = False + if args.verbose: + print("ERROR: %s" % error.args[0]) + + if success: + if args.verbose: + print('success') + sys.exit(0) + else: + if args.verbose: + print('failure') + sys.exit(1) + + +if __name__ == '__main__': + main() From 2a84f48c2b387877422ee85f6425d2c1b25bace0 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 9 Jul 2020 18:00:39 +0200 Subject: [PATCH 9/9] docs/system/s390x: Improve the 3270 documentation There is some additional information about the 3270 support in our Wiki at https://wiki.qemu.org/Features/3270 - so let's include this information into the main documentation now to have one single source of information (the Wiki page could later be removed). While at it, I also shortened the lines of the first example a little bit. Otherwise they showed up with a horizontal scrollbar in my Firefox browser. Message-Id: <20200713075112.442-1-thuth@redhat.com> Reviewed-by: Cornelia Huck Signed-off-by: Thomas Huth --- docs/system/s390x/3270.rst | 43 ++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/docs/system/s390x/3270.rst b/docs/system/s390x/3270.rst index 1774cdcadf..0554a70a9f 100644 --- a/docs/system/s390x/3270.rst +++ b/docs/system/s390x/3270.rst @@ -1,9 +1,15 @@ 3270 devices ============ -QEMU supports connecting an external 3270 terminal emulator (such as -``x3270``) to make a single 3270 device available to a guest. Note that this -supports basic features only. +The 3270 is the classic 'green-screen' console of the mainframes (see the +`IBM 3270 Wikipedia article `__). + +The 3270 data stream is not implemented within QEMU; the device only provides +TN3270 (a telnet extension; see `RFC 854 `__ +and `RFC 1576 `__) and leaves the heavy +lifting to an external 3270 terminal emulator (such as ``x3270``) to make a +single 3270 device available to a guest. Note that this supports basic +features only. To provide a 3270 device to a guest, create a ``x-terminal3270`` linked to a ``tn3270`` chardev. The guest will see a 3270 channel device. In order @@ -12,10 +18,14 @@ to actually be able to use it, attach the ``x3270`` emulator to the chardev. Example configuration --------------------- +* Make sure that 3270 support is enabled in the guest's Linux kernel. You need + ``CONFIG_TN3270`` and at least one of ``CONFIG_TN3270_TTY`` (for additional + ttys) or ``CONFIG_TN3270_CONSOLE`` (for a 3270 console). + * Add a ``tn3270`` chardev and a ``x-terminal3270`` to the QEMU command line:: - -chardev socket,id=char_0,host=0.0.0.0,port=2300,nowait,server,tn3270 - -device x-terminal3270,chardev=char_0,devno=fe.0.000a,id=terminal_0 + -chardev socket,id=ch0,host=0.0.0.0,port=2300,nowait,server,tn3270 + -device x-terminal3270,chardev=ch0,devno=fe.0.000a,id=terminal0 * Start the guest. In the guest, use ``chccwdev -e 0.0.000a`` to enable the device. @@ -29,4 +39,25 @@ Example configuration systemctl start serial-getty@3270-tty1.service -This should get you an addtional tty for logging into the guest. + This should get you an additional tty for logging into the guest. + +* If you want to use the 3270 device as the Linux kernel console instead of + an additional tty, you can also append ``conmode=3270 condev=000a`` to + the guest's kernel command line. The kernel then should use the 3270 as + console after the next boot. + +Restrictions +------------ + +3270 support is very basic. In particular: + +* Only one 3270 device is supported. + +* It has only been tested with Linux guests and the x3270 emulator. + +* TLS/SSL is not supported. + +* Resizing on reattach is not supported. + +* Multiple commands in one inbound buffer (for example, when the reset key + is pressed while the network is slow) are not supported.