From nobody Tue Nov 11 15:58:11 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=bt.com ARC-Seal: i=1; a=rsa-sha256; t=1564048624; cv=none; d=zoho.com; s=zohoarc; b=cCVZU1bD50rSScojpdXRWNzDdAc/pdRXGlZjJoiR6hRsGmCuYrYCQt3mIgToA3D6TfPjaZRs426diMa9fTvd97G6CFeUFhfPTj7Xb85aFBjWwOncsuhq/g1sYHfZ2OJI12/LnnF/DkuG69zghxyEKkIeIB7ArcbcjqK0WUunnhQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1564048624; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=gkDNkp2/mwgLpw7zTnQZpfRaz/LQ+NVEh0/3LxB5Xjs=; b=MLDP2F+SdigOQigfyw7CjJarSYqk14Q95VuYfOZMY89VyPr50ZmVXOeNGnoMlYxaOSHehmKFGXG4O6wjH2TWmgs0W1WkK7cAhGks0Deqpvjv2F9t+9Nz5GYBQSy4N7gtUEZ6s4ZFeM5AoGNDZ23tvQIyt7T5zlX63AbMpA9z2UY= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1564048623974985.6503510638206; Thu, 25 Jul 2019 02:57:03 -0700 (PDT) Received: from localhost ([::1]:57972 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hqaUg-0000nO-H8 for importer@patchew.org; Thu, 25 Jul 2019 05:57:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45893) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hqaUT-0000DP-Cl for qemu-devel@nongnu.org; Thu, 25 Jul 2019 05:56:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hqaUR-0001fx-6a for qemu-devel@nongnu.org; Thu, 25 Jul 2019 05:56:49 -0400 Received: from smtpe1.intersmtp.com ([213.121.35.71]:7761) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hqaU9-0001a1-IV; Thu, 25 Jul 2019 05:56:29 -0400 Received: from tpw09926dag18h.domain1.systemhost.net (10.9.212.42) by BWP09926076.bt.com (10.36.82.107) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.1713.5; Thu, 25 Jul 2019 10:56:25 +0100 Received: from tpw09926dag18e.domain1.systemhost.net (10.9.212.18) by tpw09926dag18h.domain1.systemhost.net (10.9.212.42) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Thu, 25 Jul 2019 10:56:25 +0100 Received: from tpw09926dag18e.domain1.systemhost.net ([fe80::a946:6348:ccf4:fa6c]) by tpw09926dag18e.domain1.systemhost.net ([fe80::a946:6348:ccf4:fa6c%12]) with mapi id 15.00.1395.000; Thu, 25 Jul 2019 10:56:25 +0100 From: To: Thread-Topic: [Qemu-devel] [PATCH v4 11/15] memory: Single byte swap along the I/O path Thread-Index: AQHVQs84mhFGsCX+Aki9Mff0U403tw== Date: Thu, 25 Jul 2019 09:56:25 +0000 Message-ID: <1564048584882.52438@bt.com> References: <45d1ebe4b2ed4c039c9da20a738652df@tpw09926dag18e.domain1.systemhost.net> In-Reply-To: <45d1ebe4b2ed4c039c9da20a738652df@tpw09926dag18e.domain1.systemhost.net> Accept-Language: en-AU, en-GB, en-US Content-Language: en-AU X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.187.101.42] MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 213.121.35.71 Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.23 Subject: [Qemu-devel] [PATCH v4 11/15] memory: Single byte swap along the I/O path X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, walling@linux.ibm.com, sagark@eecs.berkeley.edu, david@redhat.com, palmer@sifive.com, mark.cave-ayland@ilande.co.uk, laurent@vivier.eu, Alistair.Francis@wdc.com, edgar.iglesias@gmail.com, arikalo@wavecomp.com, pasic@linux.ibm.com, borntraeger@de.ibm.com, rth@twiddle.net, atar4qemu@gmail.com, ehabkost@redhat.com, qemu-s390x@nongnu.org, qemu-arm@nongnu.org, stefanha@redhat.com, shorne@gmail.com, david@gibson.dropbear.id.au, qemu-riscv@nongnu.org, kbastian@mail.uni-paderborn.de, cohuck@redhat.com, alex.williamson@redhat.com, qemu-ppc@nongnu.org, amarkovic@wavecomp.com, pbonzini@redhat.com, aurelien@aurel32.net Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Now that MemOp has been pushed down into the memory API, we can collapse the two byte swaps adjust_endianness and handle_bswap into the former. Collapsing byte swaps along the I/O path enables additional endian inversion logic, e.g. SPARC64 Invert Endian TTE bit, with redundant byte swaps cancelling out. Signed-off-by: Tony Nguyen --- accel/tcg/cputlb.c | 58 +++++++++++++++++++++++++-------------------------= ---- memory.c | 30 ++++++++++++++++------------ 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c index a4a0bf7..e61b1eb 100644 --- a/accel/tcg/cputlb.c +++ b/accel/tcg/cputlb.c @@ -881,7 +881,7 @@ static void tlb_fill(CPUState *cpu, target_ulong addr, = int size, static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry, int mmu_idx, target_ulong addr, uintptr_t retaddr, - MMUAccessType access_type, int size) + MMUAccessType access_type, MemOp op) { CPUState *cpu =3D env_cpu(env); hwaddr mr_offset; @@ -906,14 +906,13 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBE= ntry *iotlbentry, qemu_mutex_lock_iothread(); locked =3D true; } - r =3D memory_region_dispatch_read(mr, mr_offset, &val, SIZE_MEMOP(size= ), - iotlbentry->attrs); + r =3D memory_region_dispatch_read(mr, mr_offset, &val, op, iotlbentry-= >attrs); if (r !=3D MEMTX_OK) { hwaddr physaddr =3D mr_offset + section->offset_within_address_space - section->offset_within_region; - cpu_transaction_failed(cpu, physaddr, addr, size, access_type, + cpu_transaction_failed(cpu, physaddr, addr, MEMOP_SIZE(op), access= _type, mmu_idx, iotlbentry->attrs, r, retaddr); } if (locked) { @@ -925,7 +924,7 @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEnt= ry *iotlbentry, static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry, int mmu_idx, uint64_t val, target_ulong addr, - uintptr_t retaddr, int size) + uintptr_t retaddr, MemOp op) { CPUState *cpu =3D env_cpu(env); hwaddr mr_offset; @@ -947,15 +946,15 @@ static void io_writex(CPUArchState *env, CPUIOTLBEntr= y *iotlbentry, qemu_mutex_lock_iothread(); locked =3D true; } - r =3D memory_region_dispatch_write(mr, mr_offset, val, SIZE_MEMOP(size= ), - iotlbentry->attrs); + r =3D memory_region_dispatch_write(mr, mr_offset, val, op, iotlbentry-= >attrs); if (r !=3D MEMTX_OK) { hwaddr physaddr =3D mr_offset + section->offset_within_address_space - section->offset_within_region; - cpu_transaction_failed(cpu, physaddr, addr, size, MMU_DATA_STORE, - mmu_idx, iotlbentry->attrs, r, retaddr); + cpu_transaction_failed(cpu, physaddr, addr, MEMOP_SIZE(op), + MMU_DATA_STORE, mmu_idx, iotlbentry->attrs,= r, + retaddr); } if (locked) { qemu_mutex_unlock_iothread(); @@ -1210,26 +1209,13 @@ static void *atomic_mmu_lookup(CPUArchState *env, t= arget_ulong addr, #endif /* - * Byte Swap Helper + * Byte Swap Checker * - * This should all dead code away depending on the build host and - * access type. + * Dead code should all go away depending on the build host and access typ= e. */ - -static inline uint64_t handle_bswap(uint64_t val, int size, bool big_endia= n) +static inline bool need_bswap(bool big_endian) { - if ((big_endian && NEED_BE_BSWAP) || (!big_endian && NEED_LE_BSWAP)) { - switch (size) { - case 1: return val; - case 2: return bswap16(val); - case 4: return bswap32(val); - case 8: return bswap64(val); - default: - g_assert_not_reached(); - } - } else { - return val; - } + return (big_endian && NEED_BE_BSWAP) || (!big_endian && NEED_LE_BSWAP); } /* @@ -1260,6 +1246,7 @@ load_helper(CPUArchState *env, target_ulong addr, TCG= MemOpIdx oi, unsigned a_bits =3D get_alignment_bits(get_memop(oi)); void *haddr; uint64_t res; + MemOp op; /* Handle CPU specific unaligned behaviour */ if (addr & ((1 << a_bits) - 1)) { @@ -1305,9 +1292,13 @@ load_helper(CPUArchState *env, target_ulong addr, TC= GMemOpIdx oi, } } - res =3D io_readx(env, &env_tlb(env)->d[mmu_idx].iotlb[index], - mmu_idx, addr, retaddr, access_type, size); - return handle_bswap(res, size, big_endian); + op =3D SIZE_MEMOP(size); + if (need_bswap(big_endian)) { + op ^=3D MO_BSWAP; + } + + return io_readx(env, &env_tlb(env)->d[mmu_idx].iotlb[index], + mmu_idx, addr, retaddr, access_type, op); } /* Handle slow unaligned access (it spans two pages or IO). */ @@ -1508,6 +1499,7 @@ store_helper(CPUArchState *env, target_ulong addr, ui= nt64_t val, const size_t tlb_off =3D offsetof(CPUTLBEntry, addr_write); unsigned a_bits =3D get_alignment_bits(get_memop(oi)); void *haddr; + MemOp op; /* Handle CPU specific unaligned behaviour */ if (addr & ((1 << a_bits) - 1)) { @@ -1553,9 +1545,13 @@ store_helper(CPUArchState *env, target_ulong addr, u= int64_t val, } } + op =3D SIZE_MEMOP(size); + if (need_bswap(big_endian)) { + op ^=3D MO_BSWAP; + } + io_writex(env, &env_tlb(env)->d[mmu_idx].iotlb[index], mmu_idx, - handle_bswap(val, size, big_endian), - addr, retaddr, size); + val, addr, retaddr, op); return; } diff --git a/memory.c b/memory.c index 6982e19..0277d3d 100644 --- a/memory.c +++ b/memory.c @@ -352,7 +352,7 @@ static bool memory_region_big_endian(MemoryRegion *mr) #endif } -static bool memory_region_wrong_endianness(MemoryRegion *mr) +static bool memory_region_endianness_inverted(MemoryRegion *mr) { #ifdef TARGET_WORDS_BIGENDIAN return mr->ops->endianness =3D=3D DEVICE_LITTLE_ENDIAN; @@ -361,23 +361,27 @@ static bool memory_region_wrong_endianness(MemoryRegi= on *mr) #endif } -static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned s= ize) +static void adjust_endianness(MemoryRegion *mr, uint64_t *data, MemOp op) { - if (memory_region_wrong_endianness(mr)) { - switch (size) { - case 1: + if (memory_region_endianness_inverted(mr)) { + op ^=3D MO_BSWAP; + } + + if (op & MO_BSWAP) { + switch (op & MO_SIZE) { + case MO_8: break; - case 2: + case MO_16: *data =3D bswap16(*data); break; - case 4: + case MO_32: *data =3D bswap32(*data); break; - case 8: + case MO_64: *data =3D bswap64(*data); break; default: - abort(); + g_assert_not_reached(); } } } @@ -1451,7 +1455,7 @@ MemTxResult memory_region_dispatch_read(MemoryRegion = *mr, } r =3D memory_region_dispatch_read1(mr, addr, pval, size, attrs); - adjust_endianness(mr, pval, size); + adjust_endianness(mr, pval, op); return r; } @@ -1494,7 +1498,7 @@ MemTxResult memory_region_dispatch_write(MemoryRegion= *mr, return MEMTX_DECODE_ERROR; } - adjust_endianness(mr, &data, size); + adjust_endianness(mr, &data, op); if ((!kvm_eventfds_enabled()) && memory_region_dispatch_write_eventfds(mr, addr, data, size, attrs)= ) { @@ -2340,7 +2344,7 @@ void memory_region_add_eventfd(MemoryRegion *mr, } if (size) { - adjust_endianness(mr, &mrfd.data, size); + adjust_endianness(mr, &mrfd.data, SIZE_MEMOP(size)); } memory_region_transaction_begin(); for (i =3D 0; i < mr->ioeventfd_nb; ++i) { @@ -2375,7 +2379,7 @@ void memory_region_del_eventfd(MemoryRegion *mr, unsigned i; if (size) { - adjust_endianness(mr, &mrfd.data, size); + adjust_endianness(mr, &mrfd.data, SIZE_MEMOP(size)); } memory_region_transaction_begin(); for (i =3D 0; i < mr->ioeventfd_nb; ++i) { -- 1.8.3.1