git: 5001c579baff - main - [PowerPC64LE] pseries: Fix input buffering logic.

Brandon Bergren bdragon at FreeBSD.org
Thu Feb 25 20:51:31 UTC 2021


The branch main has been updated by bdragon:

URL: https://cgit.FreeBSD.org/src/commit/?id=5001c579baff78719919d79ec054207aa2938dbd

commit 5001c579baff78719919d79ec054207aa2938dbd
Author:     Brandon Bergren <bdragon at FreeBSD.org>
AuthorDate: 2021-02-25 18:55:58 +0000
Commit:     Brandon Bergren <bdragon at FreeBSD.org>
CommitDate: 2021-02-25 20:50:13 +0000

    [PowerPC64LE] pseries: Fix input buffering logic.
    
    In uart_phyp_get(), when the internal buffer is empty, we make a
    hypercall to retrieve up to 16 bytes of input data from the
    hypervisor. As this is specified to be returned in BE format, we need
    to do a 64-bit byte swap on the first and second half of the data.
    
    If the buffer being passed in was insufficient to return the fetched
    data, we store the remainder in the internal buffer and use it to
    satisfy the following calls to uart_phyp_get() until it is drained.
    
    However, in this case, we were accidentally byteswapping the internal
    buffer again.
    
    Move the byteswapping code to just after the hypercall so it only gets
    swapped when we're filling the buffer.
    
    Fixes arrow keys in qemu on pseries, among other console oddities.
    
    Sponsored by:   Tag1 Consulting, Inc.
    MFC after:      3 days
---
 sys/powerpc/pseries/phyp_console.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/sys/powerpc/pseries/phyp_console.c b/sys/powerpc/pseries/phyp_console.c
index 84ab292dae94..484952177d51 100644
--- a/sys/powerpc/pseries/phyp_console.c
+++ b/sys/powerpc/pseries/phyp_console.c
@@ -295,6 +295,10 @@ uart_phyp_get(struct uart_phyp_softc *sc, void *buffer, size_t bufsize)
 		err = phyp_pft_hcall(H_GET_TERM_CHAR, sc->vtermid,
 		    0, 0, 0, &sc->inbuflen, &sc->phyp_inbuf.u64[0],
 		    &sc->phyp_inbuf.u64[1]);
+#if BYTE_ORDER == LITTLE_ENDIAN
+		sc->phyp_inbuf.u64[0] = be64toh(sc->phyp_inbuf.u64[0]);
+		sc->phyp_inbuf.u64[1] = be64toh(sc->phyp_inbuf.u64[1]);
+#endif
 		if (err != H_SUCCESS) {
 			uart_unlock(&sc->sc_mtx);
 			return (-1);
@@ -307,11 +311,6 @@ uart_phyp_get(struct uart_phyp_softc *sc, void *buffer, size_t bufsize)
 		return (0);
 	}
 
-#if BYTE_ORDER == LITTLE_ENDIAN
-	sc->phyp_inbuf.u64[0] = be64toh(sc->phyp_inbuf.u64[0]);
-	sc->phyp_inbuf.u64[1] = be64toh(sc->phyp_inbuf.u64[1]);
-#endif
-
 	if ((sc->protocol == HVTERMPROT) && (hdr == 1)) {
 		sc->inbuflen = sc->inbuflen - 4;
 		/* The VTERM protocol has a 4 byte header, skip it here. */


More information about the dev-commits-src-main mailing list