* [PATCH V4 1/5] selftests/powerpc: Add header files for GZIP engine test
From: Raphael Moreira Zinsly @ 2020-04-20 20:55 UTC (permalink / raw)
To: linuxppc-dev, linux-crypto, dja; +Cc: abali, haren, herbert, rzinsly
In-Reply-To: <20200420205538.25181-1-rzinsly@linux.ibm.com>
Add files to access the powerpc NX-GZIP engine in user space.
Signed-off-by: Bulent Abali <abali@us.ibm.com>
Signed-off-by: Raphael Moreira Zinsly <rzinsly@linux.ibm.com>
---
.../selftests/powerpc/nx-gzip/include/crb.h | 155 ++++++++++++++++++
.../selftests/powerpc/nx-gzip/include/nx.h | 38 +++++
.../powerpc/nx-gzip/include/vas-api.h | 1 +
3 files changed, 194 insertions(+)
create mode 100644 tools/testing/selftests/powerpc/nx-gzip/include/crb.h
create mode 100644 tools/testing/selftests/powerpc/nx-gzip/include/nx.h
create mode 120000 tools/testing/selftests/powerpc/nx-gzip/include/vas-api.h
diff --git a/tools/testing/selftests/powerpc/nx-gzip/include/crb.h b/tools/testing/selftests/powerpc/nx-gzip/include/crb.h
new file mode 100644
index 000000000000..ab101085fa7e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/include/crb.h
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef __CRB_H
+#define __CRB_H
+#include <linux/types.h>
+#include "nx.h"
+
+/* CCW 842 CI/FC masks
+ * NX P8 workbook, section 4.3.1, figure 4-6
+ * "CI/FC Boundary by NX CT type"
+ */
+#define CCW_CI_842 (0x00003ff8)
+#define CCW_FC_842 (0x00000007)
+
+/* Chapter 6.5.8 Coprocessor-Completion Block (CCB) */
+
+#define CCB_VALUE (0x3fffffffffffffff)
+#define CCB_ADDRESS (0xfffffffffffffff8)
+#define CCB_CM (0x0000000000000007)
+#define CCB_CM0 (0x0000000000000004)
+#define CCB_CM12 (0x0000000000000003)
+
+#define CCB_CM0_ALL_COMPLETIONS (0x0)
+#define CCB_CM0_LAST_IN_CHAIN (0x4)
+#define CCB_CM12_STORE (0x0)
+#define CCB_CM12_INTERRUPT (0x1)
+
+#define CCB_SIZE (0x10)
+#define CCB_ALIGN CCB_SIZE
+
+struct coprocessor_completion_block {
+ __be64 value;
+ __be64 address;
+} __aligned(CCB_ALIGN);
+
+
+/* Chapter 6.5.7 Coprocessor-Status Block (CSB) */
+
+#define CSB_V (0x80)
+#define CSB_F (0x04)
+#define CSB_CH (0x03)
+#define CSB_CE_INCOMPLETE (0x80)
+#define CSB_CE_TERMINATION (0x40)
+#define CSB_CE_TPBC (0x20)
+
+#define CSB_CC_SUCCESS (0)
+#define CSB_CC_INVALID_ALIGN (1)
+#define CSB_CC_OPERAND_OVERLAP (2)
+#define CSB_CC_DATA_LENGTH (3)
+#define CSB_CC_TRANSLATION (5)
+#define CSB_CC_PROTECTION (6)
+#define CSB_CC_RD_EXTERNAL (7)
+#define CSB_CC_INVALID_OPERAND (8)
+#define CSB_CC_PRIVILEGE (9)
+#define CSB_CC_INTERNAL (10)
+#define CSB_CC_WR_EXTERNAL (12)
+#define CSB_CC_NOSPC (13)
+#define CSB_CC_EXCESSIVE_DDE (14)
+#define CSB_CC_WR_TRANSLATION (15)
+#define CSB_CC_WR_PROTECTION (16)
+#define CSB_CC_UNKNOWN_CODE (17)
+#define CSB_CC_ABORT (18)
+#define CSB_CC_TRANSPORT (20)
+#define CSB_CC_SEGMENTED_DDL (31)
+#define CSB_CC_PROGRESS_POINT (32)
+#define CSB_CC_DDE_OVERFLOW (33)
+#define CSB_CC_SESSION (34)
+#define CSB_CC_PROVISION (36)
+#define CSB_CC_CHAIN (37)
+#define CSB_CC_SEQUENCE (38)
+#define CSB_CC_HW (39)
+
+#define CSB_SIZE (0x10)
+#define CSB_ALIGN CSB_SIZE
+
+struct coprocessor_status_block {
+ __u8 flags;
+ __u8 cs;
+ __u8 cc;
+ __u8 ce;
+ __be32 count;
+ __be64 address;
+} __aligned(CSB_ALIGN);
+
+
+/* Chapter 6.5.10 Data-Descriptor List (DDL)
+ * each list contains one or more Data-Descriptor Entries (DDE)
+ */
+
+#define DDE_P (0x8000)
+
+#define DDE_SIZE (0x10)
+#define DDE_ALIGN DDE_SIZE
+
+struct data_descriptor_entry {
+ __be16 flags;
+ __u8 count;
+ __u8 index;
+ __be32 length;
+ __be64 address;
+} __aligned(DDE_ALIGN);
+
+
+/* Chapter 6.5.2 Coprocessor-Request Block (CRB) */
+
+#define CRB_SIZE (0x80)
+#define CRB_ALIGN (0x100) /* Errata: requires 256 alignment */
+
+
+/* Coprocessor Status Block field
+ * ADDRESS address of CSB
+ * C CCB is valid
+ * AT 0 = addrs are virtual, 1 = addrs are phys
+ * M enable perf monitor
+ */
+#define CRB_CSB_ADDRESS (0xfffffffffffffff0)
+#define CRB_CSB_C (0x0000000000000008)
+#define CRB_CSB_AT (0x0000000000000002)
+#define CRB_CSB_M (0x0000000000000001)
+
+struct coprocessor_request_block {
+ __be32 ccw;
+ __be32 flags;
+ __be64 csb_addr;
+
+ struct data_descriptor_entry source;
+ struct data_descriptor_entry target;
+
+ struct coprocessor_completion_block ccb;
+
+ __u8 reserved[48];
+
+ struct coprocessor_status_block csb;
+} __aligned(CRB_ALIGN);
+
+#define crb_csb_addr(c) __be64_to_cpu(c->csb_addr)
+#define crb_nx_fault_addr(c) __be64_to_cpu(c->stamp.nx.fault_storage_addr)
+#define crb_nx_flags(c) c->stamp.nx.flags
+#define crb_nx_fault_status(c) c->stamp.nx.fault_status
+#define crb_nx_pswid(c) c->stamp.nx.pswid
+
+
+/* RFC02167 Initiate Coprocessor Instructions document
+ * Chapter 8.2.1.1.1 RS
+ * Chapter 8.2.3 Coprocessor Directive
+ * Chapter 8.2.4 Execution
+ *
+ * The CCW must be converted to BE before passing to icswx()
+ */
+
+#define CCW_PS (0xff000000)
+#define CCW_CT (0x00ff0000)
+#define CCW_CD (0x0000ffff)
+#define CCW_CL (0x0000c000)
+
+#endif
diff --git a/tools/testing/selftests/powerpc/nx-gzip/include/nx.h b/tools/testing/selftests/powerpc/nx-gzip/include/nx.h
new file mode 100644
index 000000000000..78171b43464d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/include/nx.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright 2020 IBM Corp.
+ *
+ */
+#ifndef _NX_H
+#define _NX_H
+
+#include <stdbool.h>
+
+#define NX_FUNC_COMP_842 1
+#define NX_FUNC_COMP_GZIP 2
+
+#ifndef __aligned
+#define __aligned(x) __attribute__((aligned(x)))
+#endif
+
+struct nx842_func_args {
+ bool use_crc;
+ bool decompress; /* true decompress; false compress */
+ bool move_data;
+ int timeout; /* seconds */
+};
+
+struct nxbuf_t {
+ int len;
+ char *buf;
+};
+
+/* @function should be EFT (aka 842), GZIP etc */
+void *nx_function_begin(int function, int pri);
+
+int nx_function(void *handle, struct nxbuf_t *in, struct nxbuf_t *out,
+ void *arg);
+
+int nx_function_end(void *handle);
+
+#endif /* _NX_H */
diff --git a/tools/testing/selftests/powerpc/nx-gzip/include/vas-api.h b/tools/testing/selftests/powerpc/nx-gzip/include/vas-api.h
new file mode 120000
index 000000000000..77fb4c7236d0
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/include/vas-api.h
@@ -0,0 +1 @@
+../../../../../../arch/powerpc/include/uapi/asm/vas-api.h
\ No newline at end of file
--
2.21.0
^ permalink raw reply related
* [PATCH V4 2/5] selftests/powerpc: Add header files for NX compresion/decompression
From: Raphael Moreira Zinsly @ 2020-04-20 20:55 UTC (permalink / raw)
To: linuxppc-dev, linux-crypto, dja; +Cc: abali, haren, herbert, rzinsly
In-Reply-To: <20200420205538.25181-1-rzinsly@linux.ibm.com>
Add files to be able to compress and decompress files using the
powerpc NX-GZIP engine.
Signed-off-by: Bulent Abali <abali@us.ibm.com>
Signed-off-by: Raphael Moreira Zinsly <rzinsly@linux.ibm.com>
---
.../powerpc/nx-gzip/include/copy-paste.h | 56 ++
.../powerpc/nx-gzip/include/nx_dbg.h | 95 +++
.../selftests/powerpc/nx-gzip/include/nxu.h | 650 ++++++++++++++++++
3 files changed, 801 insertions(+)
create mode 100644 tools/testing/selftests/powerpc/nx-gzip/include/copy-paste.h
create mode 100644 tools/testing/selftests/powerpc/nx-gzip/include/nx_dbg.h
create mode 100644 tools/testing/selftests/powerpc/nx-gzip/include/nxu.h
diff --git a/tools/testing/selftests/powerpc/nx-gzip/include/copy-paste.h b/tools/testing/selftests/powerpc/nx-gzip/include/copy-paste.h
new file mode 100644
index 000000000000..0db2d6485037
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/include/copy-paste.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/* From asm-compat.h */
+#define __stringify_in_c(...) #__VA_ARGS__
+#define stringify_in_c(...) __stringify_in_c(__VA_ARGS__) " "
+
+/*
+ * Macros taken from arch/powerpc/include/asm/ppc-opcode.h and other
+ * header files.
+ */
+#define ___PPC_RA(a) (((a) & 0x1f) << 16)
+#define ___PPC_RB(b) (((b) & 0x1f) << 11)
+
+#define PPC_INST_COPY 0x7c20060c
+#define PPC_INST_PASTE 0x7c20070d
+
+#define PPC_COPY(a, b) stringify_in_c(.long PPC_INST_COPY | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define PPC_PASTE(a, b) stringify_in_c(.long PPC_INST_PASTE | \
+ ___PPC_RA(a) | ___PPC_RB(b))
+#define CR0_SHIFT 28
+#define CR0_MASK 0xF
+/*
+ * Copy/paste instructions:
+ *
+ * copy RA,RB
+ * Copy contents of address (RA) + effective_address(RB)
+ * to internal copy-buffer.
+ *
+ * paste RA,RB
+ * Paste contents of internal copy-buffer to the address
+ * (RA) + effective_address(RB)
+ */
+static inline int vas_copy(void *crb, int offset)
+{
+ asm volatile(PPC_COPY(%0, %1)";"
+ :
+ : "b" (offset), "b" (crb)
+ : "memory");
+
+ return 0;
+}
+
+static inline int vas_paste(void *paste_address, int offset)
+{
+ __u32 cr;
+
+ cr = 0;
+ asm volatile(PPC_PASTE(%1, %2)";"
+ "mfocrf %0, 0x80;"
+ : "=r" (cr)
+ : "b" (offset), "b" (paste_address)
+ : "memory", "cr0");
+
+ return (cr >> CR0_SHIFT) & CR0_MASK;
+}
diff --git a/tools/testing/selftests/powerpc/nx-gzip/include/nx_dbg.h b/tools/testing/selftests/powerpc/nx-gzip/include/nx_dbg.h
new file mode 100644
index 000000000000..f2c0eee2317e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/include/nx_dbg.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright 2020 IBM Corporation
+ *
+ */
+
+#ifndef _NXU_DBG_H_
+#define _NXU_DBG_H_
+
+#include <sys/file.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <time.h>
+#include <pthread.h>
+
+extern FILE * nx_gzip_log;
+extern int nx_gzip_trace;
+extern unsigned int nx_gzip_inflate_impl;
+extern unsigned int nx_gzip_deflate_impl;
+extern unsigned int nx_gzip_inflate_flags;
+extern unsigned int nx_gzip_deflate_flags;
+
+extern int nx_dbg;
+pthread_mutex_t mutex_log;
+
+#define nx_gzip_trace_enabled() (nx_gzip_trace & 0x1)
+#define nx_gzip_hw_trace_enabled() (nx_gzip_trace & 0x2)
+#define nx_gzip_sw_trace_enabled() (nx_gzip_trace & 0x4)
+#define nx_gzip_gather_statistics() (nx_gzip_trace & 0x8)
+#define nx_gzip_per_stream_stat() (nx_gzip_trace & 0x10)
+
+#define prt(fmt, ...) do { \
+ pthread_mutex_lock(&mutex_log); \
+ flock(nx_gzip_log->_fileno, LOCK_EX); \
+ time_t t; struct tm *m; time(&t); m = localtime(&t); \
+ fprintf(nx_gzip_log, "[%04d/%02d/%02d %02d:%02d:%02d] " \
+ "pid %d: " fmt, \
+ (int)m->tm_year + 1900, (int)m->tm_mon+1, (int)m->tm_mday, \
+ (int)m->tm_hour, (int)m->tm_min, (int)m->tm_sec, \
+ (int)getpid(), ## __VA_ARGS__); \
+ fflush(nx_gzip_log); \
+ flock(nx_gzip_log->_fileno, LOCK_UN); \
+ pthread_mutex_unlock(&mutex_log); \
+} while (0)
+
+/* Use in case of an error */
+#define prt_err(fmt, ...) do { if (nx_dbg >= 0) { \
+ prt("%s:%u: Error: "fmt, \
+ __FILE__, __LINE__, ## __VA_ARGS__); \
+}} while (0)
+
+/* Use in case of an warning */
+#define prt_warn(fmt, ...) do { if (nx_dbg >= 1) { \
+ prt("%s:%u: Warning: "fmt, \
+ __FILE__, __LINE__, ## __VA_ARGS__); \
+}} while (0)
+
+/* Informational printouts */
+#define prt_info(fmt, ...) do { if (nx_dbg >= 2) { \
+ prt("Info: "fmt, ## __VA_ARGS__); \
+}} while (0)
+
+/* Trace zlib wrapper code */
+#define prt_trace(fmt, ...) do { if (nx_gzip_trace_enabled()) { \
+ prt("### "fmt, ## __VA_ARGS__); \
+}} while (0)
+
+/* Trace statistics */
+#define prt_stat(fmt, ...) do { if (nx_gzip_gather_statistics()) { \
+ prt("### "fmt, ## __VA_ARGS__); \
+}} while (0)
+
+/* Trace zlib hardware implementation */
+#define hw_trace(fmt, ...) do { \
+ if (nx_gzip_hw_trace_enabled()) \
+ fprintf(nx_gzip_log, "hhh " fmt, ## __VA_ARGS__); \
+ } while (0)
+
+/* Trace zlib software implementation */
+#define sw_trace(fmt, ...) do { \
+ if (nx_gzip_sw_trace_enabled()) \
+ fprintf(nx_gzip_log, "sss " fmt, ## __VA_ARGS__); \
+ } while (0)
+
+
+/**
+ * str_to_num - Convert string into number and copy with endings like
+ * KiB for kilobyte
+ * MiB for megabyte
+ * GiB for gigabyte
+ */
+uint64_t str_to_num(char *str);
+void nx_lib_debug(int onoff);
+
+#endif /* _NXU_DBG_H_ */
diff --git a/tools/testing/selftests/powerpc/nx-gzip/include/nxu.h b/tools/testing/selftests/powerpc/nx-gzip/include/nxu.h
new file mode 100644
index 000000000000..a9f07367b3e6
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/include/nxu.h
@@ -0,0 +1,650 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Hardware interface of the NX-GZIP compression accelerator
+ *
+ * Copyright (C) IBM Corporation, 2020
+ *
+ * Author: Bulent Abali <abali@us.ibm.com>
+ *
+ */
+
+#ifndef _NXU_H
+#define _NXU_H
+
+#include <stdint.h>
+#include <endian.h>
+#include "nx.h"
+
+/* deflate */
+#define LLSZ 286
+#define DSZ 30
+
+/* nx */
+#define DHTSZ 18
+#define DHT_MAXSZ 288
+#define MAX_DDE_COUNT 256
+
+/* util */
+#ifdef NXDBG
+#define NXPRT(X) X
+#else
+#define NXPRT(X)
+#endif
+
+#ifdef NXTIMER
+#include <sys/platform/ppc.h>
+#define NX_CLK(X) X
+#define nx_get_time() __ppc_get_timebase()
+#define nx_get_freq() __ppc_get_timebase_freq()
+#else
+#define NX_CLK(X)
+#define nx_get_time() (-1)
+#define nx_get_freq() (-1)
+#endif
+
+#define NX_MAX_FAULTS 500
+
+/*
+ * Definitions of acronyms used here. See
+ * P9 NX Gzip Accelerator User's Manual for details:
+ * https://github.com/libnxz/power-gzip/blob/develop/doc/power_nx_gzip_um.pdf
+ *
+ * adler/crc: 32 bit checksums appended to stream tail
+ * ce: completion extension
+ * cpb: coprocessor parameter block (metadata)
+ * crb: coprocessor request block (command)
+ * csb: coprocessor status block (status)
+ * dht: dynamic huffman table
+ * dde: data descriptor element (address, length)
+ * ddl: list of ddes
+ * dh/fh: dynamic and fixed huffman types
+ * fc: coprocessor function code
+ * histlen: history/dictionary length
+ * history: sliding window of up to 32KB of data
+ * lzcount: Deflate LZ symbol counts
+ * rembytecnt: remaining byte count
+ * sfbt: source final block type; last block's type during decomp
+ * spbc: source processed byte count
+ * subc: source unprocessed bit count
+ * tebc: target ending bit count; valid bits in the last byte
+ * tpbc: target processed byte count
+ * vas: virtual accelerator switch; the user mode interface
+ */
+
+union nx_qw_t {
+ uint32_t word[4];
+ uint64_t dword[2];
+} __aligned(16);
+
+/*
+ * Note: NX registers with fewer than 32 bits are declared by
+ * convention as uint32_t variables in unions. If *_offset and *_mask
+ * are defined for a variable, then use get_ put_ macros to
+ * conveniently access the register fields for endian conversions.
+ */
+
+struct nx_dde_t {
+ /* Data Descriptor Element, Section 6.4 */
+ union {
+ uint32_t dde_count;
+ /* When dde_count == 0 ddead is a pointer to a data buffer;
+ * ddebc is the buffer length bytes.
+ * When dde_count > 0 dde is an indirect dde; ddead is a
+ * pointer to a contiguous list of direct ddes; ddebc is the
+ * total length of all data pointed to by the list of direct
+ * ddes. Note that only one level of indirection is permitted.
+ * See Section 6.4 of the user manual for additional details.
+ */
+ };
+ uint32_t ddebc; /* dde byte count */
+ uint64_t ddead; /* dde address */
+} __aligned(16);
+
+struct nx_csb_t {
+ /* Coprocessor Status Block, Section 6.6 */
+ union {
+ uint32_t csb_v;
+ /* Valid bit. v must be set to 0 by the program
+ * before submitting the coprocessor command.
+ * Software can poll for the v bit
+ */
+
+ uint32_t csb_f;
+ /* 16B CSB size. Written to 0 by DMA when it writes the CPB */
+
+ uint32_t csb_cs;
+ /* cs completion sequence; unused */
+
+ uint32_t csb_cc;
+ /* cc completion code; cc != 0 exception occurred */
+
+ uint32_t csb_ce;
+ /* ce completion extension */
+
+ };
+ uint32_t tpbc;
+ /* target processed byte count TPBC */
+
+ uint64_t fsaddr;
+ /* Section 6.12.1 CSB NonZero error summary. FSA Failing storage
+ * address. Address where error occurred. When available, written
+ * to A field of CSB
+ */
+} __aligned(16);
+
+struct nx_ccb_t {
+ /* Coprocessor Completion Block, Section 6.7 */
+
+ uint32_t reserved[3];
+ union {
+ /* When crb.c==0 (no ccb defined) it is reserved;
+ * When crb.c==1 (ccb defined) it is cm
+ */
+
+ uint32_t ccb_cm;
+ /* Signal interrupt of crb.c==1 and cm==1 */
+
+ uint32_t word;
+ /* generic access to the 32bit word */
+ };
+} __aligned(16);
+
+struct vas_stamped_crb_t {
+ /*
+ * CRB operand of the paste coprocessor instruction is stamped
+ * in quadword 4 with the information shown here as its written
+ * in to the receive FIFO of the coprocessor
+ */
+
+ union {
+ uint32_t vas_buf_num;
+ /* Verification only vas buffer number which correlates to
+ * the low order bits of the atag in the paste command
+ */
+
+ uint32_t send_wc_id;
+ /* Pointer to Send Window Context that provides for NX address
+ * translation information, such as MSR and LPCR bits, job
+ * completion interrupt RA, PSWID, and job utilization counter.
+ */
+
+ };
+ union {
+ uint32_t recv_wc_id;
+ /* Pointer to Receive Window Context. NX uses this to return
+ * credits to a Receive FIFO as entries are dequeued.
+ */
+
+ };
+ uint32_t reserved2;
+ union {
+ uint32_t vas_invalid;
+ /* Invalid bit. If this bit is 1 the CRB is discarded by
+ * NX upon fetching from the receive FIFO. If this bit is 0
+ * the CRB is processed normally. The bit is stamped to 0
+ * by VAS and may be written to 1 by hypervisor while
+ * the CRB is in the receive FIFO (in memory).
+ */
+
+ };
+};
+
+struct nx_stamped_fault_crb_t {
+ /*
+ * A CRB that has a translation fault is stamped by NX in quadword 4
+ * and pasted to the Fault Send Window in VAS.
+ */
+ uint64_t fsa;
+ union {
+ uint32_t nxsf_t;
+ uint32_t nxsf_fs;
+ };
+ uint32_t pswid;
+};
+
+union stamped_crb_t {
+ struct vas_stamped_crb_t vas;
+ struct nx_stamped_fault_crb_t nx;
+};
+
+struct nx_gzip_cpb_t {
+ /*
+ * Coprocessor Parameter Block In/Out are used to pass metadata
+ * to/from accelerator. Tables 6.5 and 6.6 of the user manual.
+ */
+
+ /* CPBInput */
+
+ struct {
+ union {
+ union nx_qw_t qw0;
+ struct {
+ uint32_t in_adler; /* bits 0:31 */
+ uint32_t in_crc; /* bits 32:63 */
+ union {
+ uint32_t in_histlen; /* bits 64:75 */
+ uint32_t in_subc; /* bits 93:95 */
+ };
+ union {
+ /* bits 108:111 */
+ uint32_t in_sfbt;
+ /* bits 112:127 */
+ uint32_t in_rembytecnt;
+ /* bits 116:127 */
+ uint32_t in_dhtlen;
+ };
+ };
+ };
+ union {
+ union nx_qw_t in_dht[DHTSZ]; /* qw[1:18] */
+ char in_dht_char[DHT_MAXSZ]; /* byte access */
+ };
+ union nx_qw_t reserved[5]; /* qw[19:23] */
+ };
+
+ /* CPBOutput */
+
+ volatile struct {
+ union {
+ union nx_qw_t qw24;
+ struct {
+ uint32_t out_adler; /* bits 0:31 qw[24] */
+ uint32_t out_crc; /* bits 32:63 qw[24] */
+ union {
+ /* bits 77:79 qw[24] */
+ uint32_t out_tebc;
+ /* bits 80:95 qw[24] */
+ uint32_t out_subc;
+ };
+ union {
+ /* bits 108:111 qw[24] */
+ uint32_t out_sfbt;
+ /* bits 112:127 qw[24] */
+ uint32_t out_rembytecnt;
+ /* bits 116:127 qw[24] */
+ uint32_t out_dhtlen;
+ };
+ };
+ };
+ union {
+ union nx_qw_t qw25[79]; /* qw[25:103] */
+ /* qw[25] compress no lzcounts or wrap */
+ uint32_t out_spbc_comp_wrap;
+ uint32_t out_spbc_wrap; /* qw[25] wrap */
+ /* qw[25] compress no lzcounts */
+ uint32_t out_spbc_comp;
+ /* 286 LL and 30 D symbol counts */
+ uint32_t out_lzcount[LLSZ+DSZ];
+ struct {
+ union nx_qw_t out_dht[DHTSZ]; /* qw[25:42] */
+ /* qw[43] decompress */
+ uint32_t out_spbc_decomp;
+ };
+ };
+ /* qw[104] compress with lzcounts */
+ uint32_t out_spbc_comp_with_count;
+ };
+} __aligned(128);
+
+struct nx_gzip_crb_t {
+ union { /* byte[0:3] */
+ uint32_t gzip_fc; /* bits[24-31] */
+ };
+ uint32_t reserved1; /* byte[4:7] */
+ union {
+ uint64_t csb_address; /* byte[8:15] */
+ struct {
+ uint32_t reserved2;
+ union {
+ uint32_t crb_c;
+ /* c==0 no ccb defined */
+
+ uint32_t crb_at;
+ /* at==0 address type is ignored;
+ * all addrs effective assumed.
+ */
+
+ };
+ };
+ };
+ struct nx_dde_t source_dde; /* byte[16:31] */
+ struct nx_dde_t target_dde; /* byte[32:47] */
+ volatile struct nx_ccb_t ccb; /* byte[48:63] */
+ volatile union {
+ /* byte[64:239] shift csb by 128 bytes out of the crb; csb was
+ * in crb earlier; JReilly says csb written with partial inject
+ */
+ union nx_qw_t reserved64[11];
+ union stamped_crb_t stamp; /* byte[64:79] */
+ };
+ volatile struct nx_csb_t csb;
+} __aligned(128);
+
+struct nx_gzip_crb_cpb_t {
+ struct nx_gzip_crb_t crb;
+ struct nx_gzip_cpb_t cpb;
+} __aligned(2048);
+
+
+/*
+ * NX hardware convention has the msb bit on the left numbered 0.
+ * The defines below has *_offset defined as the right most bit
+ * position of a field. x of size_mask(x) is the field width in bits.
+ */
+
+#define size_mask(x) ((1U<<(x))-1)
+
+/*
+ * Offsets and Widths within the containing 32 bits of the various NX
+ * gzip hardware registers. Use the getnn/putnn macros to access
+ * these regs
+ */
+
+#define dde_count_mask size_mask(8)
+#define dde_count_offset 23
+
+/* CSB */
+
+#define csb_v_mask size_mask(1)
+#define csb_v_offset 0
+#define csb_f_mask size_mask(1)
+#define csb_f_offset 6
+#define csb_cs_mask size_mask(8)
+#define csb_cs_offset 15
+#define csb_cc_mask size_mask(8)
+#define csb_cc_offset 23
+#define csb_ce_mask size_mask(8)
+#define csb_ce_offset 31
+
+/* CCB */
+
+#define ccb_cm_mask size_mask(3)
+#define ccb_cm_offset 31
+
+/* VAS stamped CRB fields */
+
+#define vas_buf_num_mask size_mask(6)
+#define vas_buf_num_offset 5
+#define send_wc_id_mask size_mask(16)
+#define send_wc_id_offset 31
+#define recv_wc_id_mask size_mask(16)
+#define recv_wc_id_offset 31
+#define vas_invalid_mask size_mask(1)
+#define vas_invalid_offset 31
+
+/* NX stamped fault CRB fields */
+
+#define nxsf_t_mask size_mask(1)
+#define nxsf_t_offset 23
+#define nxsf_fs_mask size_mask(8)
+#define nxsf_fs_offset 31
+
+/* CPB input */
+
+#define in_histlen_mask size_mask(12)
+#define in_histlen_offset 11
+#define in_dhtlen_mask size_mask(12)
+#define in_dhtlen_offset 31
+#define in_subc_mask size_mask(3)
+#define in_subc_offset 31
+#define in_sfbt_mask size_mask(4)
+#define in_sfbt_offset 15
+#define in_rembytecnt_mask size_mask(16)
+#define in_rembytecnt_offset 31
+
+/* CPB output */
+
+#define out_tebc_mask size_mask(3)
+#define out_tebc_offset 15
+#define out_subc_mask size_mask(16)
+#define out_subc_offset 31
+#define out_sfbt_mask size_mask(4)
+#define out_sfbt_offset 15
+#define out_rembytecnt_mask size_mask(16)
+#define out_rembytecnt_offset 31
+#define out_dhtlen_mask size_mask(12)
+#define out_dhtlen_offset 31
+
+/* CRB */
+
+#define gzip_fc_mask size_mask(8)
+#define gzip_fc_offset 31
+#define crb_c_mask size_mask(1)
+#define crb_c_offset 28
+#define crb_at_mask size_mask(1)
+#define crb_at_offset 30
+#define csb_address_mask ~(15UL) /* mask off bottom 4b */
+
+/*
+ * Access macros for the registers. Do not access registers directly
+ * because of the endian conversion. P9 processor may run either as
+ * Little or Big endian. However the NX coprocessor regs are always
+ * big endian.
+ * Use the 32 and 64b macros to access respective
+ * register sizes.
+ * Use nn forms for the register fields shorter than 32 bits.
+ */
+
+#define getnn(ST, REG) ((be32toh(ST.REG) >> (31-REG##_offset)) \
+ & REG##_mask)
+#define getpnn(ST, REG) ((be32toh((ST)->REG) >> (31-REG##_offset)) \
+ & REG##_mask)
+#define get32(ST, REG) (be32toh(ST.REG))
+#define getp32(ST, REG) (be32toh((ST)->REG))
+#define get64(ST, REG) (be64toh(ST.REG))
+#define getp64(ST, REG) (be64toh((ST)->REG))
+
+#define unget32(ST, REG) (get32(ST, REG) & ~((REG##_mask) \
+ << (31-REG##_offset)))
+/* get 32bits less the REG field */
+
+#define ungetp32(ST, REG) (getp32(ST, REG) & ~((REG##_mask) \
+ << (31-REG##_offset)))
+/* get 32bits less the REG field */
+
+#define clear_regs(ST) memset((void *)(&(ST)), 0, sizeof(ST))
+#define clear_dde(ST) do { ST.dde_count = ST.ddebc = 0; ST.ddead = 0; \
+ } while (0)
+#define clearp_dde(ST) do { (ST)->dde_count = (ST)->ddebc = 0; \
+ (ST)->ddead = 0; \
+ } while (0)
+#define clear_struct(ST) memset((void *)(&(ST)), 0, sizeof(ST))
+#define putnn(ST, REG, X) (ST.REG = htobe32(unget32(ST, REG) | (((X) \
+ & REG##_mask) << (31-REG##_offset))))
+#define putpnn(ST, REG, X) ((ST)->REG = htobe32(ungetp32(ST, REG) \
+ | (((X) & REG##_mask) << (31-REG##_offset))))
+
+#define put32(ST, REG, X) (ST.REG = htobe32(X))
+#define putp32(ST, REG, X) ((ST)->REG = htobe32(X))
+#define put64(ST, REG, X) (ST.REG = htobe64(X))
+#define putp64(ST, REG, X) ((ST)->REG = htobe64(X))
+
+/*
+ * Completion extension ce(0) ce(1) ce(2). Bits ce(3-7)
+ * unused. Section 6.6 Figure 6.7.
+ */
+
+#define get_csb_ce(ST) ((uint32_t)getnn(ST, csb_ce))
+#define get_csb_ce_ms3b(ST) (get_csb_ce(ST) >> 5)
+#define put_csb_ce_ms3b(ST, X) putnn(ST, csb_ce, ((uint32_t)(X) << 5))
+
+#define CSB_CE_PARTIAL 0x4
+#define CSB_CE_TERMINATE 0x2
+#define CSB_CE_TPBC_VALID 0x1
+
+#define csb_ce_termination(X) (!!((X) & CSB_CE_TERMINATE))
+/* termination, output buffers may be modified, SPBC/TPBC invalid Fig.6-7 */
+
+#define csb_ce_check_completion(X) (!csb_ce_termination(X))
+/* if not terminated then check full or partial completion */
+
+#define csb_ce_partial_completion(X) (!!((X) & CSB_CE_PARTIAL))
+#define csb_ce_full_completion(X) (!csb_ce_partial_completion(X))
+#define csb_ce_tpbc_valid(X) (!!((X) & CSB_CE_TPBC_VALID))
+/* TPBC indicates successfully stored data count */
+
+#define csb_ce_default_err(X) csb_ce_termination(X)
+/* most error CEs have CE(0)=0 and CE(1)=1 */
+
+#define csb_ce_cc3_partial(X) csb_ce_partial_completion(X)
+/* some CC=3 are partially completed, Table 6-8 */
+
+#define csb_ce_cc64(X) ((X)&(CSB_CE_PARTIAL \
+ | CSB_CE_TERMINATE) == 0)
+/* Compression: when TPBC>SPBC then CC=64 Table 6-8; target didn't
+ * compress smaller than source.
+ */
+
+/* Decompress SFBT combinations Tables 5-3, 6-4, 6-6 */
+
+#define SFBT_BFINAL 0x1
+#define SFBT_LIT 0x4
+#define SFBT_FHT 0x5
+#define SFBT_DHT 0x6
+#define SFBT_HDR 0x7
+
+/*
+ * NX gzip function codes. Table 6.2.
+ * Bits 0:4 are the FC. Bit 5 is used by the DMA controller to
+ * select one of the two Byte Count Limits.
+ */
+
+#define GZIP_FC_LIMIT_MASK 0x01
+#define GZIP_FC_COMPRESS_FHT 0x00
+#define GZIP_FC_COMPRESS_DHT 0x02
+#define GZIP_FC_COMPRESS_FHT_COUNT 0x04
+#define GZIP_FC_COMPRESS_DHT_COUNT 0x06
+#define GZIP_FC_COMPRESS_RESUME_FHT 0x08
+#define GZIP_FC_COMPRESS_RESUME_DHT 0x0a
+#define GZIP_FC_COMPRESS_RESUME_FHT_COUNT 0x0c
+#define GZIP_FC_COMPRESS_RESUME_DHT_COUNT 0x0e
+#define GZIP_FC_DECOMPRESS 0x10
+#define GZIP_FC_DECOMPRESS_SINGLE_BLK_N_SUSPEND 0x12
+#define GZIP_FC_DECOMPRESS_RESUME 0x14
+#define GZIP_FC_DECOMPRESS_RESUME_SINGLE_BLK_N_SUSPEND 0x16
+#define GZIP_FC_WRAP 0x1e
+
+#define fc_is_compress(fc) (((fc) & 0x10) == 0)
+#define fc_has_count(fc) (fc_is_compress(fc) && (((fc) & 0x4) != 0))
+
+/* CSB.CC Error codes */
+
+#define ERR_NX_OK 0
+#define ERR_NX_ALIGNMENT 1
+#define ERR_NX_OPOVERLAP 2
+#define ERR_NX_DATA_LENGTH 3
+#define ERR_NX_TRANSLATION 5
+#define ERR_NX_PROTECTION 6
+#define ERR_NX_EXTERNAL_UE7 7
+#define ERR_NX_INVALID_OP 8
+#define ERR_NX_PRIVILEGE 9
+#define ERR_NX_INTERNAL_UE 10
+#define ERR_NX_EXTERN_UE_WR 12
+#define ERR_NX_TARGET_SPACE 13
+#define ERR_NX_EXCESSIVE_DDE 14
+#define ERR_NX_TRANSL_WR 15
+#define ERR_NX_PROTECT_WR 16
+#define ERR_NX_SUBFUNCTION 17
+#define ERR_NX_FUNC_ABORT 18
+#define ERR_NX_BYTE_MAX 19
+#define ERR_NX_CORRUPT_CRB 20
+#define ERR_NX_INVALID_CRB 21
+#define ERR_NX_INVALID_DDE 30
+#define ERR_NX_SEGMENTED_DDL 31
+#define ERR_NX_DDE_OVERFLOW 33
+#define ERR_NX_TPBC_GT_SPBC 64
+#define ERR_NX_MISSING_CODE 66
+#define ERR_NX_INVALID_DIST 67
+#define ERR_NX_INVALID_DHT 68
+#define ERR_NX_EXTERNAL_UE90 90
+#define ERR_NX_WDOG_TIMER 224
+#define ERR_NX_AT_FAULT 250
+#define ERR_NX_INTR_SERVER 252
+#define ERR_NX_UE253 253
+#define ERR_NX_NO_HW 254
+#define ERR_NX_HUNG_OP 255
+#define ERR_NX_END 256
+
+/* initial values for non-resume operations */
+#define INIT_CRC 0 /* crc32(0L, Z_NULL, 0) */
+#define INIT_ADLER 1 /* adler32(0L, Z_NULL, 0) adler is initialized to 1 */
+
+/* prototypes */
+int nxu_submit_job(struct nx_gzip_crb_cpb_t *c, void *handle);
+
+extern void nxu_sigsegv_handler(int sig, siginfo_t *info, void *ctx);
+extern int nxu_touch_pages(void *buf, long buf_len, long page_len, int wr);
+
+/* caller supplies a print buffer 4*sizeof(crb) */
+
+char *nx_crb_str(struct nx_gzip_crb_t *crb, char *prbuf);
+char *nx_cpb_str(struct nx_gzip_cpb_t *cpb, char *prbuf);
+char *nx_prt_hex(void *cp, int sz, char *prbuf);
+char *nx_lzcount_str(struct nx_gzip_cpb_t *cpb, char *prbuf);
+char *nx_strerror(int e);
+
+#ifdef NX_SIM
+#include <stdio.h>
+int nx_sim_init(void *ctx);
+int nx_sim_end(void *ctx);
+int nxu_run_sim_job(struct nx_gzip_crb_cpb_t *c, void *ctx);
+#endif /* NX_SIM */
+
+/* Deflate stream manipulation */
+
+#define set_final_bit(x) (x |= (unsigned char)1)
+#define clr_final_bit(x) (x &= ~(unsigned char)1)
+
+#define append_empty_fh_blk(p, b) do { *(p) = (2 | (1&(b))); *((p)+1) = 0; \
+ } while (0)
+/* append 10 bits 0000001b 00...... ;
+ * assumes appending starts on a byte boundary; b is the final bit.
+ */
+
+
+#ifdef NX_842
+
+/* 842 Engine */
+
+struct nx_eft_crb_t {
+ union { /* byte[0:3] */
+ uint32_t eft_fc; /* bits[29-31] */
+ };
+ uint32_t reserved1; /* byte[4:7] */
+ union {
+ uint64_t csb_address; /* byte[8:15] */
+ struct {
+ uint32_t reserved2;
+ union {
+ uint32_t crb_c;
+ /* c==0 no ccb defined */
+
+ uint32_t crb_at;
+ /* at==0 address type is ignored;
+ * all addrs effective assumed.
+ */
+
+ };
+ };
+ };
+ struct nx_dde_t source_dde; /* byte[16:31] */
+ struct nx_dde_t target_dde; /* byte[32:47] */
+ struct nx_ccb_t ccb; /* byte[48:63] */
+ union {
+ union nx_qw_t reserved64[3]; /* byte[64:96] */
+ };
+ struct nx_csb_t csb;
+} __aligned(128);
+
+/* 842 CRB */
+
+#define EFT_FC_MASK size_mask(3)
+#define EFT_FC_OFFSET 31
+#define EFT_FC_COMPRESS 0x0
+#define EFT_FC_COMPRESS_WITH_CRC 0x1
+#define EFT_FC_DECOMPRESS 0x2
+#define EFT_FC_DECOMPRESS_WITH_CRC 0x3
+#define EFT_FC_BLK_DATA_MOVE 0x4
+#endif /* NX_842 */
+
+#endif /* _NXU_H */
--
2.21.0
^ permalink raw reply related
* [PATCH V4 3/5] selftests/powerpc: Add NX-GZIP engine compress testcase
From: Raphael Moreira Zinsly @ 2020-04-20 20:55 UTC (permalink / raw)
To: linuxppc-dev, linux-crypto, dja; +Cc: abali, haren, herbert, rzinsly
In-Reply-To: <20200420205538.25181-1-rzinsly@linux.ibm.com>
Add a compression testcase for the powerpc NX-GZIP engine.
Signed-off-by: Bulent Abali <abali@us.ibm.com>
Signed-off-by: Raphael Moreira Zinsly <rzinsly@linux.ibm.com>
---
tools/testing/selftests/powerpc/Makefile | 1 +
.../selftests/powerpc/nx-gzip/Makefile | 8 +
.../selftests/powerpc/nx-gzip/gzfht_test.c | 433 ++++++++++++++++++
.../selftests/powerpc/nx-gzip/gzip_vas.c | 315 +++++++++++++
.../selftests/powerpc/nx-gzip/nx-gzip-test.sh | 45 ++
5 files changed, 802 insertions(+)
create mode 100644 tools/testing/selftests/powerpc/nx-gzip/Makefile
create mode 100644 tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
create mode 100644 tools/testing/selftests/powerpc/nx-gzip/gzip_vas.c
create mode 100755 tools/testing/selftests/powerpc/nx-gzip/nx-gzip-test.sh
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index 644770c3b754..0830e63818c1 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -19,6 +19,7 @@ SUB_DIRS = alignment \
copyloops \
dscr \
mm \
+ nx-gzip \
pmu \
signal \
primitives \
diff --git a/tools/testing/selftests/powerpc/nx-gzip/Makefile b/tools/testing/selftests/powerpc/nx-gzip/Makefile
new file mode 100644
index 000000000000..016e528a0a94
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/Makefile
@@ -0,0 +1,8 @@
+CFLAGS = -O3 -m64 -I./include
+
+TEST_GEN_FILES := gzfht_test
+TEST_PROGS := nx-gzip-test.sh
+
+include ../../lib.mk
+
+$(TEST_GEN_FILES): gzip_vas.c
diff --git a/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c b/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
new file mode 100644
index 000000000000..7496a83f9c9d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/gzfht_test.c
@@ -0,0 +1,433 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/* P9 gzip sample code for demonstrating the P9 NX hardware interface.
+ * Not intended for productive uses or for performance or compression
+ * ratio measurements. For simplicity of demonstration, this sample
+ * code compresses in to fixed Huffman blocks only (Deflate btype=1)
+ * and has very simple memory management. Dynamic Huffman blocks
+ * (Deflate btype=2) are more involved as detailed in the user guide.
+ * Note also that /dev/crypto/gzip, VAS and skiboot support are
+ * required.
+ *
+ * Copyright 2020 IBM Corp.
+ *
+ * https://github.com/libnxz/power-gzip for zlib api and other utils
+ *
+ * Author: Bulent Abali <abali@us.ibm.com>
+ *
+ * Definitions of acronyms used here. See
+ * P9 NX Gzip Accelerator User's Manual for details:
+ * https://github.com/libnxz/power-gzip/blob/develop/doc/power_nx_gzip_um.pdf
+ *
+ * adler/crc: 32 bit checksums appended to stream tail
+ * ce: completion extension
+ * cpb: coprocessor parameter block (metadata)
+ * crb: coprocessor request block (command)
+ * csb: coprocessor status block (status)
+ * dht: dynamic huffman table
+ * dde: data descriptor element (address, length)
+ * ddl: list of ddes
+ * dh/fh: dynamic and fixed huffman types
+ * fc: coprocessor function code
+ * histlen: history/dictionary length
+ * history: sliding window of up to 32KB of data
+ * lzcount: Deflate LZ symbol counts
+ * rembytecnt: remaining byte count
+ * sfbt: source final block type; last block's type during decomp
+ * spbc: source processed byte count
+ * subc: source unprocessed bit count
+ * tebc: target ending bit count; valid bits in the last byte
+ * tpbc: target processed byte count
+ * vas: virtual accelerator switch; the user mode interface
+ */
+
+#define _ISOC11_SOURCE // For aligned_alloc()
+#define _DEFAULT_SOURCE // For endian.h
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+#include <endian.h>
+#include <bits/endian.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include "nxu.h"
+#include "nx.h"
+
+int nx_dbg;
+FILE *nx_gzip_log;
+
+#define NX_MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+#define FNAME_MAX 1024
+#define FEXT ".nx.gz"
+
+/*
+ * LZ counts returned in the user supplied nx_gzip_crb_cpb_t structure.
+ */
+static int compress_fht_sample(char *src, uint32_t srclen, char *dst,
+ uint32_t dstlen, int with_count,
+ struct nx_gzip_crb_cpb_t *cmdp, void *handle)
+{
+ uint32_t fc;
+
+ assert(!!cmdp);
+
+ put32(cmdp->crb, gzip_fc, 0); /* clear */
+ fc = (with_count) ? GZIP_FC_COMPRESS_RESUME_FHT_COUNT :
+ GZIP_FC_COMPRESS_RESUME_FHT;
+ putnn(cmdp->crb, gzip_fc, fc);
+ putnn(cmdp->cpb, in_histlen, 0); /* resuming with no history */
+ memset((void *) &cmdp->crb.csb, 0, sizeof(cmdp->crb.csb));
+
+ /* Section 6.6 programming notes; spbc may be in two different
+ * places depending on FC.
+ */
+ if (!with_count)
+ put32(cmdp->cpb, out_spbc_comp, 0);
+ else
+ put32(cmdp->cpb, out_spbc_comp_with_count, 0);
+
+ /* Figure 6-3 6-4; CSB location */
+ put64(cmdp->crb, csb_address, 0);
+ put64(cmdp->crb, csb_address,
+ (uint64_t) &cmdp->crb.csb & csb_address_mask);
+
+ /* Source direct dde (scatter-gather list) */
+ clear_dde(cmdp->crb.source_dde);
+ putnn(cmdp->crb.source_dde, dde_count, 0);
+ put32(cmdp->crb.source_dde, ddebc, srclen);
+ put64(cmdp->crb.source_dde, ddead, (uint64_t) src);
+
+ /* Target direct dde (scatter-gather list) */
+ clear_dde(cmdp->crb.target_dde);
+ putnn(cmdp->crb.target_dde, dde_count, 0);
+ put32(cmdp->crb.target_dde, ddebc, dstlen);
+ put64(cmdp->crb.target_dde, ddead, (uint64_t) dst);
+
+ /* Submit the crb, the job descriptor, to the accelerator */
+ return nxu_submit_job(cmdp, handle);
+}
+
+/*
+ * Prepares a blank no filename no timestamp gzip header and returns
+ * the number of bytes written to buf.
+ * Gzip specification at https://tools.ietf.org/html/rfc1952
+ */
+int gzip_header_blank(char *buf)
+{
+ int i = 0;
+
+ buf[i++] = 0x1f; /* ID1 */
+ buf[i++] = 0x8b; /* ID2 */
+ buf[i++] = 0x08; /* CM */
+ buf[i++] = 0x00; /* FLG */
+ buf[i++] = 0x00; /* MTIME */
+ buf[i++] = 0x00; /* MTIME */
+ buf[i++] = 0x00; /* MTIME */
+ buf[i++] = 0x00; /* MTIME */
+ buf[i++] = 0x04; /* XFL 4=fastest */
+ buf[i++] = 0x03; /* OS UNIX */
+
+ return i;
+}
+
+/* Caller must free the allocated buffer return nonzero on error. */
+int read_alloc_input_file(char *fname, char **buf, size_t *bufsize)
+{
+ struct stat statbuf;
+ FILE *fp;
+ char *p;
+ size_t num_bytes;
+
+ if (stat(fname, &statbuf)) {
+ perror(fname);
+ return(-1);
+ }
+ fp = fopen(fname, "r");
+ if (fp == NULL) {
+ perror(fname);
+ return(-1);
+ }
+ assert(NULL != (p = (char *) malloc(statbuf.st_size)));
+ num_bytes = fread(p, 1, statbuf.st_size, fp);
+ if (ferror(fp) || (num_bytes != statbuf.st_size)) {
+ perror(fname);
+ return(-1);
+ }
+ *buf = p;
+ *bufsize = num_bytes;
+ return 0;
+}
+
+/* Returns nonzero on error */
+int write_output_file(char *fname, char *buf, size_t bufsize)
+{
+ FILE *fp;
+ size_t num_bytes;
+
+ fp = fopen(fname, "w");
+ if (fp == NULL) {
+ perror(fname);
+ return(-1);
+ }
+ num_bytes = fwrite(buf, 1, bufsize, fp);
+ if (ferror(fp) || (num_bytes != bufsize)) {
+ perror(fname);
+ return(-1);
+ }
+ fclose(fp);
+ return 0;
+}
+
+/*
+ * Z_SYNC_FLUSH as described in zlib.h.
+ * Returns number of appended bytes
+ */
+int append_sync_flush(char *buf, int tebc, int final)
+{
+ uint64_t flush;
+ int shift = (tebc & 0x7);
+
+ if (tebc > 0) {
+ /* Last byte is partially full */
+ buf = buf - 1;
+ *buf = *buf & (unsigned char) ((1<<tebc)-1);
+ } else
+ *buf = 0;
+ flush = ((0x1ULL & final) << shift) | *buf;
+ shift = shift + 3; /* BFINAL and BTYPE written */
+ shift = (shift <= 8) ? 8 : 16;
+ flush |= (0xFFFF0000ULL) << shift; /* Zero length block */
+ shift = shift + 32;
+ while (shift > 0) {
+ *buf++ = (unsigned char) (flush & 0xffULL);
+ flush = flush >> 8;
+ shift = shift - 8;
+ }
+ return(((tebc > 5) || (tebc == 0)) ? 5 : 4);
+}
+
+/*
+ * Final deflate block bit. This call assumes the block
+ * beginning is byte aligned.
+ */
+static void set_bfinal(void *buf, int bfinal)
+{
+ char *b = buf;
+
+ if (bfinal)
+ *b = *b | (unsigned char) 0x01;
+ else
+ *b = *b & (unsigned char) 0xfe;
+}
+
+int compress_file(int argc, char **argv, void *handle)
+{
+ char *inbuf, *outbuf, *srcbuf, *dstbuf;
+ char outname[FNAME_MAX];
+ uint32_t srclen, dstlen;
+ uint32_t flushlen, chunk;
+ size_t inlen, outlen, dsttotlen, srctotlen;
+ uint32_t crc, spbc, tpbc, tebc;
+ int lzcounts = 0;
+ int cc;
+ int num_hdr_bytes;
+ struct nx_gzip_crb_cpb_t *cmdp;
+ uint32_t pagelen = 65536;
+ int fault_tries = NX_MAX_FAULTS;
+
+ cmdp = (void *)(uintptr_t)
+ aligned_alloc(sizeof(struct nx_gzip_crb_cpb_t),
+ sizeof(struct nx_gzip_crb_cpb_t));
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s <fname>\n", argv[0]);
+ exit(-1);
+ }
+ if (read_alloc_input_file(argv[1], &inbuf, &inlen))
+ exit(-1);
+ fprintf(stderr, "file %s read, %ld bytes\n", argv[1], inlen);
+
+ /* Generous output buffer for header/trailer */
+ outlen = 2 * inlen + 1024;
+
+ assert(NULL != (outbuf = (char *)malloc(outlen)));
+ nxu_touch_pages(outbuf, outlen, pagelen, 1);
+
+ /* Compress piecemeal in smallish chunks */
+ chunk = 1<<22;
+
+ /* Write the gzip header to the stream */
+ num_hdr_bytes = gzip_header_blank(outbuf);
+ dstbuf = outbuf + num_hdr_bytes;
+ outlen = outlen - num_hdr_bytes;
+ dsttotlen = num_hdr_bytes;
+
+ srcbuf = inbuf;
+ srctotlen = 0;
+
+ /* Init the CRB, the coprocessor request block */
+ memset(&cmdp->crb, 0, sizeof(cmdp->crb));
+
+ /* Initial gzip crc32 */
+ put32(cmdp->cpb, in_crc, 0);
+
+ while (inlen > 0) {
+
+ /* Submit chunk size source data per job */
+ srclen = NX_MIN(chunk, inlen);
+ /* Supply large target in case data expands */
+ dstlen = NX_MIN(2*srclen, outlen);
+
+ /* Page faults are handled by the user code */
+
+ /* Fault-in pages; an improved code wouldn't touch so
+ * many pages but would try to estimate the
+ * compression ratio and adjust both the src and dst
+ * touch amounts.
+ */
+ nxu_touch_pages(cmdp, sizeof(struct nx_gzip_crb_cpb_t), pagelen,
+ 1);
+ nxu_touch_pages(srcbuf, srclen, pagelen, 0);
+ nxu_touch_pages(dstbuf, dstlen, pagelen, 1);
+
+ cc = compress_fht_sample(
+ srcbuf, srclen,
+ dstbuf, dstlen,
+ lzcounts, cmdp, handle);
+
+ if (cc != ERR_NX_OK && cc != ERR_NX_TPBC_GT_SPBC &&
+ cc != ERR_NX_TRANSLATION) {
+ fprintf(stderr, "nx error: cc= %d\n", cc);
+ exit(-1);
+ }
+
+ /* Page faults are handled by the user code */
+ if (cc == ERR_NX_TRANSLATION) {
+ NXPRT(fprintf(stderr, "page fault: cc= %d, ", cc));
+ NXPRT(fprintf(stderr, "try= %d, fsa= %08llx\n",
+ fault_tries,
+ (unsigned long long) cmdp->crb.csb.fsaddr));
+ fault_tries--;
+ if (fault_tries > 0) {
+ continue;
+ } else {
+ fprintf(stderr, "error: cannot progress; ");
+ fprintf(stderr, "too many faults\n");
+ exit(-1);
+ };
+ }
+
+ fault_tries = NX_MAX_FAULTS; /* Reset for the next chunk */
+
+ inlen = inlen - srclen;
+ srcbuf = srcbuf + srclen;
+ srctotlen = srctotlen + srclen;
+
+ /* Two possible locations for spbc depending on the function
+ * code.
+ */
+ spbc = (!lzcounts) ? get32(cmdp->cpb, out_spbc_comp) :
+ get32(cmdp->cpb, out_spbc_comp_with_count);
+ assert(spbc == srclen);
+
+ /* Target byte count */
+ tpbc = get32(cmdp->crb.csb, tpbc);
+ /* Target ending bit count */
+ tebc = getnn(cmdp->cpb, out_tebc);
+ NXPRT(fprintf(stderr, "compressed chunk %d ", spbc));
+ NXPRT(fprintf(stderr, "to %d bytes, tebc= %d\n", tpbc, tebc));
+
+ if (inlen > 0) { /* More chunks to go */
+ set_bfinal(dstbuf, 0);
+ dstbuf = dstbuf + tpbc;
+ dsttotlen = dsttotlen + tpbc;
+ outlen = outlen - tpbc;
+ /* Round up to the next byte with a flush
+ * block; do not set the BFINAqL bit.
+ */
+ flushlen = append_sync_flush(dstbuf, tebc, 0);
+ dsttotlen = dsttotlen + flushlen;
+ outlen = outlen - flushlen;
+ dstbuf = dstbuf + flushlen;
+ NXPRT(fprintf(stderr, "added sync_flush %d bytes\n",
+ flushlen));
+ } else { /* Done */
+ /* Set the BFINAL bit of the last block per Deflate
+ * specification.
+ */
+ set_bfinal(dstbuf, 1);
+ dstbuf = dstbuf + tpbc;
+ dsttotlen = dsttotlen + tpbc;
+ outlen = outlen - tpbc;
+ }
+
+ /* Resuming crc32 for the next chunk */
+ crc = get32(cmdp->cpb, out_crc);
+ put32(cmdp->cpb, in_crc, crc);
+ crc = be32toh(crc);
+ }
+
+ /* Append crc32 and ISIZE to the end */
+ memcpy(dstbuf, &crc, 4);
+ memcpy(dstbuf+4, &srctotlen, 4);
+ dsttotlen = dsttotlen + 8;
+ outlen = outlen - 8;
+
+ assert(FNAME_MAX > (strlen(argv[1]) + strlen(FEXT)));
+ strcpy(outname, argv[1]);
+ strcat(outname, FEXT);
+ if (write_output_file(outname, outbuf, dsttotlen)) {
+ fprintf(stderr, "write error: %s\n", outname);
+ exit(-1);
+ }
+
+ fprintf(stderr, "compressed %ld to %ld bytes total, ", srctotlen,
+ dsttotlen);
+ fprintf(stderr, "crc32 checksum = %08x\n", crc);
+
+ if (inbuf != NULL)
+ free(inbuf);
+
+ if (outbuf != NULL)
+ free(outbuf);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc;
+ struct sigaction act;
+ void *handle;
+
+ nx_dbg = 0;
+ nx_gzip_log = NULL;
+ act.sa_handler = 0;
+ act.sa_sigaction = nxu_sigsegv_handler;
+ act.sa_flags = SA_SIGINFO;
+ act.sa_restorer = 0;
+ sigemptyset(&act.sa_mask);
+ sigaction(SIGSEGV, &act, NULL);
+
+ handle = nx_function_begin(NX_FUNC_COMP_GZIP, 0);
+ if (!handle) {
+ fprintf(stderr, "Unable to init NX, errno %d\n", errno);
+ exit(-1);
+ }
+
+ rc = compress_file(argc, argv, handle);
+
+ nx_function_end(handle);
+
+ return rc;
+}
diff --git a/tools/testing/selftests/powerpc/nx-gzip/gzip_vas.c b/tools/testing/selftests/powerpc/nx-gzip/gzip_vas.c
new file mode 100644
index 000000000000..23787d5743db
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/gzip_vas.c
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/* Copyright 2020 IBM Corp.
+ *
+ * Author: Bulent Abali <abali@us.ibm.com>
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+#include <endian.h>
+#include <bits/endian.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include "vas-api.h"
+#include "nx.h"
+#include "copy-paste.h"
+#include "nxu.h"
+#include "nx_dbg.h"
+#include <sys/platform/ppc.h>
+
+#define barrier()
+#define hwsync() ({ asm volatile("sync" ::: "memory"); })
+
+#ifndef NX_NO_CPU_PRI
+#define cpu_pri_default() ({ asm volatile ("or 2, 2, 2"); })
+#define cpu_pri_low() ({ asm volatile ("or 31, 31, 31"); })
+#else
+#define cpu_pri_default()
+#define cpu_pri_low()
+#endif
+
+void *nx_fault_storage_address;
+
+struct nx_handle {
+ int fd;
+ int function;
+ void *paste_addr;
+};
+
+static int open_device_nodes(char *devname, int pri, struct nx_handle *handle)
+{
+ int rc, fd;
+ void *addr;
+ struct vas_tx_win_open_attr txattr;
+
+ fd = open(devname, O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, " open device name %s\n", devname);
+ return -errno;
+ }
+
+ memset(&txattr, 0, sizeof(txattr));
+ txattr.version = 1;
+ txattr.vas_id = pri;
+ rc = ioctl(fd, VAS_TX_WIN_OPEN, (unsigned long)&txattr);
+ if (rc < 0) {
+ fprintf(stderr, "ioctl() n %d, error %d\n", rc, errno);
+ rc = -errno;
+ goto out;
+ }
+
+ addr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0ULL);
+ if (addr == MAP_FAILED) {
+ fprintf(stderr, "mmap() failed, errno %d\n", errno);
+ rc = -errno;
+ goto out;
+ }
+ handle->fd = fd;
+ handle->paste_addr = (void *)((char *)addr + 0x400);
+
+ rc = 0;
+out:
+ close(fd);
+ return rc;
+}
+
+void *nx_function_begin(int function, int pri)
+{
+ int rc;
+ char *devname = "/dev/crypto/nx-gzip";
+ struct nx_handle *nxhandle;
+
+ if (function != NX_FUNC_COMP_GZIP) {
+ errno = EINVAL;
+ fprintf(stderr, " NX_FUNC_COMP_GZIP not found\n");
+ return NULL;
+ }
+
+
+ nxhandle = malloc(sizeof(*nxhandle));
+ if (!nxhandle) {
+ errno = ENOMEM;
+ fprintf(stderr, " No memory\n");
+ return NULL;
+ }
+
+ nxhandle->function = function;
+ rc = open_device_nodes(devname, pri, nxhandle);
+ if (rc < 0) {
+ errno = -rc;
+ fprintf(stderr, " open_device_nodes failed\n");
+ return NULL;
+ }
+
+ return nxhandle;
+}
+
+int nx_function_end(void *handle)
+{
+ int rc = 0;
+ struct nx_handle *nxhandle = handle;
+
+ rc = munmap(nxhandle->paste_addr - 0x400, 4096);
+ if (rc < 0) {
+ fprintf(stderr, "munmap() failed, errno %d\n", errno);
+ return rc;
+ }
+ close(nxhandle->fd);
+ free(nxhandle);
+
+ return rc;
+}
+
+static int nx_wait_for_csb(struct nx_gzip_crb_cpb_t *cmdp)
+{
+ long poll = 0;
+ uint64_t t;
+
+ /* Save power and let other threads use the h/w. top may show
+ * 100% but only because OS doesn't know we slowed the this
+ * h/w thread while polling. We're letting other threads have
+ * higher throughput on the core.
+ */
+ cpu_pri_low();
+
+#define CSB_MAX_POLL 200000000UL
+#define USLEEP_TH 300000UL
+
+ t = __ppc_get_timebase();
+
+ while (getnn(cmdp->crb.csb, csb_v) == 0) {
+ ++poll;
+ hwsync();
+
+ cpu_pri_low();
+
+ /* usleep(0) takes around 29000 ticks ~60 us.
+ * 300000 is spinning for about 600 us then
+ * start sleeping.
+ */
+ if ((__ppc_get_timebase() - t) > USLEEP_TH) {
+ cpu_pri_default();
+ usleep(1);
+ }
+
+ if (poll > CSB_MAX_POLL)
+ break;
+
+ /* Fault address from signal handler */
+ if (nx_fault_storage_address) {
+ cpu_pri_default();
+ return -EAGAIN;
+ }
+
+ }
+
+ cpu_pri_default();
+
+ /* hw has updated csb and output buffer */
+ hwsync();
+
+ /* Check CSB flags. */
+ if (getnn(cmdp->crb.csb, csb_v) == 0) {
+ fprintf(stderr, "CSB still not valid after %d polls.\n",
+ (int) poll);
+ prt_err("CSB still not valid after %d polls, giving up.\n",
+ (int) poll);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int nxu_run_job(struct nx_gzip_crb_cpb_t *cmdp, void *handle)
+{
+ int i, ret, retries;
+ struct nx_handle *nxhandle = handle;
+
+ assert(handle != NULL);
+ i = 0;
+ retries = 5000;
+ while (i++ < retries) {
+ hwsync();
+ vas_copy(&cmdp->crb, 0);
+ ret = vas_paste(nxhandle->paste_addr, 0);
+ hwsync();
+
+ NXPRT(fprintf(stderr, "Paste attempt %d/%d returns 0x%x\n",
+ i, retries, ret));
+
+ if ((ret == 2) || (ret == 3)) {
+
+ ret = nx_wait_for_csb(cmdp);
+ if (!ret) {
+ goto out;
+ } else if (ret == -EAGAIN) {
+ long x;
+
+ prt_err("Touching address %p, 0x%lx\n",
+ nx_fault_storage_address,
+ *(long *) nx_fault_storage_address);
+ x = *(long *) nx_fault_storage_address;
+ *(long *) nx_fault_storage_address = x;
+ nx_fault_storage_address = 0;
+ continue;
+ } else {
+ prt_err("wait_for_csb() returns %d\n", ret);
+ break;
+ }
+ } else {
+ if (i < 10) {
+ /* spin for few ticks */
+#define SPIN_TH 500UL
+ uint64_t fail_spin;
+
+ fail_spin = __ppc_get_timebase();
+ while ((__ppc_get_timebase() - fail_spin) <
+ SPIN_TH)
+ ;
+ } else {
+ /* sleep */
+ unsigned int pr = 0;
+
+ if (pr++ % 100 == 0) {
+ prt_err("Paste attempt %d/", i);
+ prt_err("%d, failed pid= %d\n", retries,
+ getpid());
+ }
+ usleep(1);
+ }
+ continue;
+ }
+ }
+
+out:
+ cpu_pri_default();
+
+ return ret;
+}
+
+int nxu_submit_job(struct nx_gzip_crb_cpb_t *cmdp, void *handle)
+{
+ int cc;
+
+ cc = nxu_run_job(cmdp, handle);
+
+ if (!cc)
+ cc = getnn(cmdp->crb.csb, csb_cc); /* CC Table 6-8 */
+
+ return cc;
+}
+
+
+void nxu_sigsegv_handler(int sig, siginfo_t *info, void *ctx)
+{
+ fprintf(stderr, "%d: Got signal %d si_code %d, si_addr %p\n", getpid(),
+ sig, info->si_code, info->si_addr);
+
+ nx_fault_storage_address = info->si_addr;
+}
+
+/*
+ * Fault in pages prior to NX job submission. wr=1 may be required to
+ * touch writeable pages. System zero pages do not fault-in the page as
+ * intended. Typically set wr=1 for NX target pages and set wr=0 for NX
+ * source pages.
+ */
+int nxu_touch_pages(void *buf, long buf_len, long page_len, int wr)
+{
+ char *begin = buf;
+ char *end = (char *) buf + buf_len - 1;
+ volatile char t;
+
+ assert(buf_len >= 0 && !!buf);
+
+ NXPRT(fprintf(stderr, "touch %p %p len 0x%lx wr=%d\n", buf,
+ (buf + buf_len), buf_len, wr));
+
+ if (buf_len <= 0 || buf == NULL)
+ return -1;
+
+ do {
+ t = *begin;
+ if (wr)
+ *begin = t;
+ begin = begin + page_len;
+ } while (begin < end);
+
+ /* When buf_sz is small or buf tail is in another page */
+ t = *end;
+ if (wr)
+ *end = t;
+
+ return 0;
+}
diff --git a/tools/testing/selftests/powerpc/nx-gzip/nx-gzip-test.sh b/tools/testing/selftests/powerpc/nx-gzip/nx-gzip-test.sh
new file mode 100755
index 000000000000..7cc7256ba1c7
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/nx-gzip-test.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+if [[ ! -w /dev/crypto/nx-gzip ]]; then
+ echo "Can't access /dev/crypto/nx-gzip, skipping"
+ echo "skip: $0"
+ exit 4
+fi
+
+set -e
+
+function cleanup
+{
+ rm -f nx-tempfile*
+}
+
+trap cleanup EXIT
+
+function test_sizes
+{
+ local n=$1
+ local fname="nx-tempfile.$n"
+
+ for size in 4K 64K 1M 64M
+ do
+ echo "Testing $size ($n) ..."
+ dd if=/dev/urandom of=$fname bs=$size count=1
+ ./gzfht_test $fname
+ done
+}
+
+echo "Doing basic test of different sizes ..."
+test_sizes 0
+
+echo "Running tests in parallel ..."
+for i in {1..16}
+do
+ test_sizes $i &
+done
+
+wait
+
+echo "OK"
+
+exit 0
--
2.21.0
^ permalink raw reply related
* [PATCH V4 4/5] selftests/powerpc: Add NX-GZIP engine decompress testcase
From: Raphael Moreira Zinsly @ 2020-04-20 20:55 UTC (permalink / raw)
To: linuxppc-dev, linux-crypto, dja; +Cc: abali, haren, herbert, rzinsly
In-Reply-To: <20200420205538.25181-1-rzinsly@linux.ibm.com>
Include a decompression testcase for the powerpc NX-GZIP
engine.
Signed-off-by: Bulent Abali <abali@us.ibm.com>
Signed-off-by: Raphael Moreira Zinsly <rzinsly@linux.ibm.com>
---
.../selftests/powerpc/nx-gzip/Makefile | 2 +-
.../selftests/powerpc/nx-gzip/gunz_test.c | 1028 +++++++++++++++++
.../selftests/powerpc/nx-gzip/nx-gzip-test.sh | 1 +
3 files changed, 1030 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/nx-gzip/gunz_test.c
diff --git a/tools/testing/selftests/powerpc/nx-gzip/Makefile b/tools/testing/selftests/powerpc/nx-gzip/Makefile
index 016e528a0a94..640fad6cc2c7 100644
--- a/tools/testing/selftests/powerpc/nx-gzip/Makefile
+++ b/tools/testing/selftests/powerpc/nx-gzip/Makefile
@@ -1,6 +1,6 @@
CFLAGS = -O3 -m64 -I./include
-TEST_GEN_FILES := gzfht_test
+TEST_GEN_FILES := gzfht_test gunz_test
TEST_PROGS := nx-gzip-test.sh
include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/nx-gzip/gunz_test.c b/tools/testing/selftests/powerpc/nx-gzip/gunz_test.c
new file mode 100644
index 000000000000..6ee0fded0391
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/gunz_test.c
@@ -0,0 +1,1028 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/* P9 gunzip sample code for demonstrating the P9 NX hardware
+ * interface. Not intended for productive uses or for performance or
+ * compression ratio measurements. Note also that /dev/crypto/gzip,
+ * VAS and skiboot support are required
+ *
+ * Copyright 2020 IBM Corp.
+ *
+ * Author: Bulent Abali <abali@us.ibm.com>
+ *
+ * https://github.com/libnxz/power-gzip for zlib api and other utils
+ * Definitions of acronyms used here. See
+ * P9 NX Gzip Accelerator User's Manual for details:
+ * https://github.com/libnxz/power-gzip/blob/develop/doc/power_nx_gzip_um.pdf
+ *
+ * adler/crc: 32 bit checksums appended to stream tail
+ * ce: completion extension
+ * cpb: coprocessor parameter block (metadata)
+ * crb: coprocessor request block (command)
+ * csb: coprocessor status block (status)
+ * dht: dynamic huffman table
+ * dde: data descriptor element (address, length)
+ * ddl: list of ddes
+ * dh/fh: dynamic and fixed huffman types
+ * fc: coprocessor function code
+ * histlen: history/dictionary length
+ * history: sliding window of up to 32KB of data
+ * lzcount: Deflate LZ symbol counts
+ * rembytecnt: remaining byte count
+ * sfbt: source final block type; last block's type during decomp
+ * spbc: source processed byte count
+ * subc: source unprocessed bit count
+ * tebc: target ending bit count; valid bits in the last byte
+ * tpbc: target processed byte count
+ * vas: virtual accelerator switch; the user mode interface
+ */
+
+#define _ISOC11_SOURCE // For aligned_alloc()
+#define _DEFAULT_SOURCE // For endian.h
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+#include <endian.h>
+#include <bits/endian.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include "nxu.h"
+#include "nx.h"
+#include "crb.h"
+
+int nx_dbg;
+FILE *nx_gzip_log;
+
+#define NX_MIN(X, Y) (((X) < (Y))?(X):(Y))
+#define NX_MAX(X, Y) (((X) > (Y))?(X):(Y))
+
+#define GETINPC(X) fgetc(X)
+#define FNAME_MAX 1024
+
+/* fifo queue management */
+#define fifo_used_bytes(used) (used)
+#define fifo_free_bytes(used, len) ((len)-(used))
+/* amount of free bytes in the first and last parts */
+#define fifo_free_first_bytes(cur, used, len) ((((cur)+(used)) <= (len)) \
+ ? (len)-((cur)+(used)) : 0)
+#define fifo_free_last_bytes(cur, used, len) ((((cur)+(used)) <= (len)) \
+ ? (cur) : (len)-(used))
+/* amount of used bytes in the first and last parts */
+#define fifo_used_first_bytes(cur, used, len) ((((cur)+(used)) <= (len)) \
+ ? (used) : (len)-(cur))
+#define fifo_used_last_bytes(cur, used, len) ((((cur)+(used)) <= (len)) \
+ ? 0 : ((used)+(cur))-(len))
+/* first and last free parts start here */
+#define fifo_free_first_offset(cur, used) ((cur)+(used))
+#define fifo_free_last_offset(cur, used, len) \
+ fifo_used_last_bytes(cur, used, len)
+/* first and last used parts start here */
+#define fifo_used_first_offset(cur) (cur)
+#define fifo_used_last_offset(cur) (0)
+
+const int fifo_in_len = 1<<24;
+const int fifo_out_len = 1<<24;
+const int page_sz = 1<<16;
+const int line_sz = 1<<7;
+const int window_max = 1<<15;
+
+/*
+ * Adds an (address, len) pair to the list of ddes (ddl) and updates
+ * the base dde. ddl[0] is the only dde in a direct dde which
+ * contains a single (addr,len) pair. For more pairs, ddl[0] becomes
+ * the indirect (base) dde that points to a list of direct ddes.
+ * See Section 6.4 of the NX-gzip user manual for DDE description.
+ * Addr=NULL, len=0 clears the ddl[0]. Returns the total number of
+ * bytes in ddl. Caller is responsible for allocting the array of
+ * nx_dde_t *ddl. If N addresses are required in the scatter-gather
+ * list, the ddl array must have N+1 entries minimum.
+ */
+static inline uint32_t nx_append_dde(struct nx_dde_t *ddl, void *addr,
+ uint32_t len)
+{
+ uint32_t ddecnt;
+ uint32_t bytes;
+
+ if (addr == NULL && len == 0) {
+ clearp_dde(ddl);
+ return 0;
+ }
+
+ NXPRT(fprintf(stderr, "%d: %s addr %p len %x\n", __LINE__, addr,
+ __func__, len));
+
+ /* Number of ddes in the dde list ; == 0 when it is a direct dde */
+ ddecnt = getpnn(ddl, dde_count);
+ bytes = getp32(ddl, ddebc);
+
+ if (ddecnt == 0 && bytes == 0) {
+ /* First dde is unused; make it a direct dde */
+ bytes = len;
+ putp32(ddl, ddebc, bytes);
+ putp64(ddl, ddead, (uint64_t) addr);
+ } else if (ddecnt == 0) {
+ /* Converting direct to indirect dde
+ * ddl[0] becomes head dde of ddl
+ * copy direct to indirect first.
+ */
+ ddl[1] = ddl[0];
+
+ /* Add the new dde next */
+ clear_dde(ddl[2]);
+ put32(ddl[2], ddebc, len);
+ put64(ddl[2], ddead, (uint64_t) addr);
+
+ /* Ddl head points to 2 direct ddes */
+ ddecnt = 2;
+ putpnn(ddl, dde_count, ddecnt);
+ bytes = bytes + len;
+ putp32(ddl, ddebc, bytes);
+ /* Pointer to the first direct dde */
+ putp64(ddl, ddead, (uint64_t) &ddl[1]);
+ } else {
+ /* Append a dde to an existing indirect ddl */
+ ++ddecnt;
+ clear_dde(ddl[ddecnt]);
+ put64(ddl[ddecnt], ddead, (uint64_t) addr);
+ put32(ddl[ddecnt], ddebc, len);
+
+ putpnn(ddl, dde_count, ddecnt);
+ bytes = bytes + len;
+ putp32(ddl, ddebc, bytes); /* byte sum of all dde */
+ }
+ return bytes;
+}
+
+/*
+ * Touch specified number of pages represented in number bytes
+ * beginning from the first buffer in a dde list.
+ * Do not touch the pages past buf_sz-th byte's page.
+ *
+ * Set buf_sz = 0 to touch all pages described by the ddep.
+ */
+static int nx_touch_pages_dde(struct nx_dde_t *ddep, long buf_sz, long page_sz,
+ int wr)
+{
+ uint32_t indirect_count;
+ uint32_t buf_len;
+ long total;
+ uint64_t buf_addr;
+ struct nx_dde_t *dde_list;
+ int i;
+
+ assert(!!ddep);
+
+ indirect_count = getpnn(ddep, dde_count);
+
+ NXPRT(fprintf(stderr, "%s dde_count %d request len ", __func__,
+ indirect_count));
+ NXPRT(fprintf(stderr, "0x%lx\n", buf_sz));
+
+ if (indirect_count == 0) {
+ /* Direct dde */
+ buf_len = getp32(ddep, ddebc);
+ buf_addr = getp64(ddep, ddead);
+
+ NXPRT(fprintf(stderr, "touch direct ddebc 0x%x ddead %p\n",
+ buf_len, (void *)buf_addr));
+
+ if (buf_sz == 0)
+ nxu_touch_pages((void *)buf_addr, buf_len, page_sz, wr);
+ else
+ nxu_touch_pages((void *)buf_addr, NX_MIN(buf_len,
+ buf_sz), page_sz, wr);
+
+ return ERR_NX_OK;
+ }
+
+ /* Indirect dde */
+ if (indirect_count > MAX_DDE_COUNT)
+ return ERR_NX_EXCESSIVE_DDE;
+
+ /* First address of the list */
+ dde_list = (struct nx_dde_t *) getp64(ddep, ddead);
+
+ if (buf_sz == 0)
+ buf_sz = getp32(ddep, ddebc);
+
+ total = 0;
+ for (i = 0; i < indirect_count; i++) {
+ buf_len = get32(dde_list[i], ddebc);
+ buf_addr = get64(dde_list[i], ddead);
+ total += buf_len;
+
+ NXPRT(fprintf(stderr, "touch loop len 0x%x ddead %p total ",
+ buf_len, (void *)buf_addr));
+ NXPRT(fprintf(stderr, "0x%lx\n", total));
+
+ /* Touching fewer pages than encoded in the ddebc */
+ if (total > buf_sz) {
+ buf_len = NX_MIN(buf_len, total - buf_sz);
+ nxu_touch_pages((void *)buf_addr, buf_len, page_sz, wr);
+ NXPRT(fprintf(stderr, "touch loop break len 0x%x ",
+ buf_len));
+ NXPRT(fprintf(stderr, "ddead %p\n", (void *)buf_addr));
+ break;
+ }
+ nxu_touch_pages((void *)buf_addr, buf_len, page_sz, wr);
+ }
+ return ERR_NX_OK;
+}
+
+/*
+ * Src and dst buffers are supplied in scatter gather lists.
+ * NX function code and other parameters supplied in cmdp.
+ */
+static int nx_submit_job(struct nx_dde_t *src, struct nx_dde_t *dst,
+ struct nx_gzip_crb_cpb_t *cmdp, void *handle)
+{
+ uint64_t csbaddr;
+
+ memset((void *)&cmdp->crb.csb, 0, sizeof(cmdp->crb.csb));
+
+ cmdp->crb.source_dde = *src;
+ cmdp->crb.target_dde = *dst;
+
+ /* Status, output byte count in tpbc */
+ csbaddr = ((uint64_t) &cmdp->crb.csb) & csb_address_mask;
+ put64(cmdp->crb, csb_address, csbaddr);
+
+ /* NX reports input bytes in spbc; cleared */
+ cmdp->cpb.out_spbc_comp_wrap = 0;
+ cmdp->cpb.out_spbc_comp_with_count = 0;
+ cmdp->cpb.out_spbc_decomp = 0;
+
+ /* Clear output */
+ put32(cmdp->cpb, out_crc, INIT_CRC);
+ put32(cmdp->cpb, out_adler, INIT_ADLER);
+
+ /* Submit the crb, the job descriptor, to the accelerator. */
+ return nxu_submit_job(cmdp, handle);
+}
+
+int decompress_file(int argc, char **argv, void *devhandle)
+{
+ FILE *inpf = NULL;
+ FILE *outf = NULL;
+
+ int c, expect, i, cc, rc = 0;
+ char gzfname[FNAME_MAX];
+
+ /* Queuing, file ops, byte counting */
+ char *fifo_in, *fifo_out;
+ int used_in, cur_in, used_out, cur_out, read_sz, n;
+ int first_free, last_free, first_used, last_used;
+ int first_offset, last_offset;
+ int write_sz, free_space, source_sz;
+ int source_sz_estimate, target_sz_estimate;
+ uint64_t last_comp_ratio = 0; /* 1000 max */
+ uint64_t total_out = 0;
+ int is_final, is_eof;
+
+ /* nx hardware */
+ int sfbt, subc, spbc, tpbc, nx_ce, fc, resuming = 0;
+ int history_len = 0;
+ struct nx_gzip_crb_cpb_t cmd, *cmdp;
+ struct nx_dde_t *ddl_in;
+ struct nx_dde_t dde_in[6] __aligned(128);
+ struct nx_dde_t *ddl_out;
+ struct nx_dde_t dde_out[6] __aligned(128);
+ int pgfault_retries;
+
+ /* when using mmap'ed files */
+ off_t input_file_offset;
+
+ if (argc > 2) {
+ fprintf(stderr, "usage: %s <fname> or stdin\n", argv[0]);
+ fprintf(stderr, " writes to stdout or <fname>.nx.gunzip\n");
+ return -1;
+ }
+
+ if (argc == 1) {
+ inpf = stdin;
+ outf = stdout;
+ } else if (argc == 2) {
+ char w[1024];
+ char *wp;
+
+ inpf = fopen(argv[1], "r");
+ if (inpf == NULL) {
+ perror(argv[1]);
+ return -1;
+ }
+
+ /* Make a new file name to write to. Ignoring '.gz' */
+ wp = (NULL != (wp = strrchr(argv[1], '/'))) ? (wp+1) : argv[1];
+ strcpy(w, wp);
+ strcat(w, ".nx.gunzip");
+
+ outf = fopen(w, "w");
+ if (outf == NULL) {
+ perror(w);
+ return -1;
+ }
+ }
+
+ /* Decode the gzip header */
+ c = GETINPC(inpf); expect = 0x1f; /* ID1 */
+ if (c != expect)
+ goto err1;
+
+ c = GETINPC(inpf); expect = 0x8b; /* ID2 */
+ if (c != expect)
+ goto err1;
+
+ c = GETINPC(inpf); expect = 0x08; /* CM */
+ if (c != expect)
+ goto err1;
+
+ int flg = GETINPC(inpf); /* FLG */
+
+ if (flg & 0xE0 || flg & 0x4 || flg == EOF)
+ goto err2;
+
+ fprintf(stderr, "gzHeader FLG %x\n", flg);
+
+ /* Read 6 bytes; ignoring the MTIME, XFL, OS fields in this
+ * sample code.
+ */
+ for (i = 0; i < 6; i++) {
+ char tmp[10];
+
+ tmp[i] = GETINPC(inpf);
+ if (tmp[i] == EOF)
+ goto err3;
+ fprintf(stderr, "%02x ", tmp[i]);
+ if (i == 5)
+ fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "gzHeader MTIME, XFL, OS ignored\n");
+
+ /* FNAME */
+ if (flg & 0x8) {
+ int k = 0;
+
+ do {
+ c = GETINPC(inpf);
+ if (c == EOF || k >= FNAME_MAX)
+ goto err3;
+ gzfname[k++] = c;
+ } while (c);
+ fprintf(stderr, "gzHeader FNAME: %s\n", gzfname);
+ }
+
+ /* FHCRC */
+ if (flg & 0x2) {
+ c = GETINPC(inpf);
+ if (c == EOF)
+ goto err3;
+ c = GETINPC(inpf);
+ if (c == EOF)
+ goto err3;
+ fprintf(stderr, "gzHeader FHCRC: ignored\n");
+ }
+
+ used_in = cur_in = used_out = cur_out = 0;
+ is_final = is_eof = 0;
+
+ /* Allocate one page larger to prevent page faults due to NX
+ * overfetching.
+ * Either do this (char*)(uintptr_t)aligned_alloc or use
+ * -std=c11 flag to make the int-to-pointer warning go away.
+ */
+ assert((fifo_in = (char *)(uintptr_t)aligned_alloc(line_sz,
+ fifo_in_len + page_sz)) != NULL);
+ assert((fifo_out = (char *)(uintptr_t)aligned_alloc(line_sz,
+ fifo_out_len + page_sz + line_sz)) != NULL);
+ /* Leave unused space due to history rounding rules */
+ fifo_out = fifo_out + line_sz;
+ nxu_touch_pages(fifo_out, fifo_out_len, page_sz, 1);
+
+ ddl_in = &dde_in[0];
+ ddl_out = &dde_out[0];
+ cmdp = &cmd;
+ memset(&cmdp->crb, 0, sizeof(cmdp->crb));
+
+read_state:
+
+ /* Read from .gz file */
+
+ NXPRT(fprintf(stderr, "read_state:\n"));
+
+ if (is_eof != 0)
+ goto write_state;
+
+ /* We read in to fifo_in in two steps: first: read in to from
+ * cur_in to the end of the buffer. last: if free space wrapped
+ * around, read from fifo_in offset 0 to offset cur_in.
+ */
+
+ /* Reset fifo head to reduce unnecessary wrap arounds */
+ cur_in = (used_in == 0) ? 0 : cur_in;
+
+ /* Free space total is reduced by a gap */
+ free_space = NX_MAX(0, fifo_free_bytes(used_in, fifo_in_len)
+ - line_sz);
+
+ /* Free space may wrap around as first and last */
+ first_free = fifo_free_first_bytes(cur_in, used_in, fifo_in_len);
+ last_free = fifo_free_last_bytes(cur_in, used_in, fifo_in_len);
+
+ /* Start offsets of the free memory */
+ first_offset = fifo_free_first_offset(cur_in, used_in);
+ last_offset = fifo_free_last_offset(cur_in, used_in, fifo_in_len);
+
+ /* Reduce read_sz because of the line_sz gap */
+ read_sz = NX_MIN(free_space, first_free);
+ n = 0;
+ if (read_sz > 0) {
+ /* Read in to offset cur_in + used_in */
+ n = fread(fifo_in + first_offset, 1, read_sz, inpf);
+ used_in = used_in + n;
+ free_space = free_space - n;
+ assert(n <= read_sz);
+ if (n != read_sz) {
+ /* Either EOF or error; exit the read loop */
+ is_eof = 1;
+ goto write_state;
+ }
+ }
+
+ /* If free space wrapped around */
+ if (last_free > 0) {
+ /* Reduce read_sz because of the line_sz gap */
+ read_sz = NX_MIN(free_space, last_free);
+ n = 0;
+ if (read_sz > 0) {
+ n = fread(fifo_in + last_offset, 1, read_sz, inpf);
+ used_in = used_in + n; /* Increase used space */
+ free_space = free_space - n; /* Decrease free space */
+ assert(n <= read_sz);
+ if (n != read_sz) {
+ /* Either EOF or error; exit the read loop */
+ is_eof = 1;
+ goto write_state;
+ }
+ }
+ }
+
+ /* At this point we have used_in bytes in fifo_in with the
+ * data head starting at cur_in and possibly wrapping around.
+ */
+
+write_state:
+
+ /* Write decompressed data to output file */
+
+ NXPRT(fprintf(stderr, "write_state:\n"));
+
+ if (used_out == 0)
+ goto decomp_state;
+
+ /* If fifo_out has data waiting, write it out to the file to
+ * make free target space for the accelerator used bytes in
+ * the first and last parts of fifo_out.
+ */
+
+ first_used = fifo_used_first_bytes(cur_out, used_out, fifo_out_len);
+ last_used = fifo_used_last_bytes(cur_out, used_out, fifo_out_len);
+
+ write_sz = first_used;
+
+ n = 0;
+ if (write_sz > 0) {
+ n = fwrite(fifo_out + cur_out, 1, write_sz, outf);
+ used_out = used_out - n;
+ /* Move head of the fifo */
+ cur_out = (cur_out + n) % fifo_out_len;
+ assert(n <= write_sz);
+ if (n != write_sz) {
+ fprintf(stderr, "error: write\n");
+ rc = -1;
+ goto err5;
+ }
+ }
+
+ if (last_used > 0) { /* If more data available in the last part */
+ write_sz = last_used; /* Keep it here for later */
+ n = 0;
+ if (write_sz > 0) {
+ n = fwrite(fifo_out, 1, write_sz, outf);
+ used_out = used_out - n;
+ cur_out = (cur_out + n) % fifo_out_len;
+ assert(n <= write_sz);
+ if (n != write_sz) {
+ fprintf(stderr, "error: write\n");
+ rc = -1;
+ goto err5;
+ }
+ }
+ }
+
+decomp_state:
+
+ /* NX decompresses input data */
+
+ NXPRT(fprintf(stderr, "decomp_state:\n"));
+
+ if (is_final)
+ goto finish_state;
+
+ /* Address/len lists */
+ clearp_dde(ddl_in);
+ clearp_dde(ddl_out);
+
+ /* FC, CRC, HistLen, Table 6-6 */
+ if (resuming) {
+ /* Resuming a partially decompressed input.
+ * The key to resume is supplying the 32KB
+ * dictionary (history) to NX, which is basically
+ * the last 32KB of output produced.
+ */
+ fc = GZIP_FC_DECOMPRESS_RESUME;
+
+ cmdp->cpb.in_crc = cmdp->cpb.out_crc;
+ cmdp->cpb.in_adler = cmdp->cpb.out_adler;
+
+ /* Round up the history size to quadword. Section 2.10 */
+ history_len = (history_len + 15) / 16;
+ putnn(cmdp->cpb, in_histlen, history_len);
+ history_len = history_len * 16; /* bytes */
+
+ if (history_len > 0) {
+ /* Chain in the history buffer to the DDE list */
+ if (cur_out >= history_len) {
+ nx_append_dde(ddl_in, fifo_out
+ + (cur_out - history_len),
+ history_len);
+ } else {
+ nx_append_dde(ddl_in, fifo_out
+ + ((fifo_out_len + cur_out)
+ - history_len),
+ history_len - cur_out);
+ /* Up to 32KB history wraps around fifo_out */
+ nx_append_dde(ddl_in, fifo_out, cur_out);
+ }
+
+ }
+ } else {
+ /* First decompress job */
+ fc = GZIP_FC_DECOMPRESS;
+
+ history_len = 0;
+ /* Writing 0 clears out subc as well */
+ cmdp->cpb.in_histlen = 0;
+ total_out = 0;
+
+ put32(cmdp->cpb, in_crc, INIT_CRC);
+ put32(cmdp->cpb, in_adler, INIT_ADLER);
+ put32(cmdp->cpb, out_crc, INIT_CRC);
+ put32(cmdp->cpb, out_adler, INIT_ADLER);
+
+ /* Assuming 10% compression ratio initially; use the
+ * most recently measured compression ratio as a
+ * heuristic to estimate the input and output
+ * sizes. If we give too much input, the target buffer
+ * overflows and NX cycles are wasted, and then we
+ * must retry with smaller input size. 1000 is 100%.
+ */
+ last_comp_ratio = 100UL;
+ }
+ cmdp->crb.gzip_fc = 0;
+ putnn(cmdp->crb, gzip_fc, fc);
+
+ /*
+ * NX source buffers
+ */
+ first_used = fifo_used_first_bytes(cur_in, used_in, fifo_in_len);
+ last_used = fifo_used_last_bytes(cur_in, used_in, fifo_in_len);
+
+ if (first_used > 0)
+ nx_append_dde(ddl_in, fifo_in + cur_in, first_used);
+
+ if (last_used > 0)
+ nx_append_dde(ddl_in, fifo_in, last_used);
+
+ /*
+ * NX target buffers
+ */
+ first_free = fifo_free_first_bytes(cur_out, used_out, fifo_out_len);
+ last_free = fifo_free_last_bytes(cur_out, used_out, fifo_out_len);
+
+ /* Reduce output free space amount not to overwrite the history */
+ int target_max = NX_MAX(0, fifo_free_bytes(used_out, fifo_out_len)
+ - (1<<16));
+
+ NXPRT(fprintf(stderr, "target_max %d (0x%x)\n", target_max,
+ target_max));
+
+ first_free = NX_MIN(target_max, first_free);
+ if (first_free > 0) {
+ first_offset = fifo_free_first_offset(cur_out, used_out);
+ nx_append_dde(ddl_out, fifo_out + first_offset, first_free);
+ }
+
+ if (last_free > 0) {
+ last_free = NX_MIN(target_max - first_free, last_free);
+ if (last_free > 0) {
+ last_offset = fifo_free_last_offset(cur_out, used_out,
+ fifo_out_len);
+ nx_append_dde(ddl_out, fifo_out + last_offset,
+ last_free);
+ }
+ }
+
+ /* Target buffer size is used to limit the source data size
+ * based on previous measurements of compression ratio.
+ */
+
+ /* source_sz includes history */
+ source_sz = getp32(ddl_in, ddebc);
+ assert(source_sz > history_len);
+ source_sz = source_sz - history_len;
+
+ /* Estimating how much source is needed to 3/4 fill a
+ * target_max size target buffer. If we overshoot, then NX
+ * must repeat the job with smaller input and we waste
+ * bandwidth. If we undershoot then we use more NX calls than
+ * necessary.
+ */
+
+ source_sz_estimate = ((uint64_t)target_max * last_comp_ratio * 3UL)
+ / 4000;
+
+ if (source_sz_estimate < source_sz) {
+ /* Target might be small, therefore limiting the
+ * source data.
+ */
+ source_sz = source_sz_estimate;
+ target_sz_estimate = target_max;
+ } else {
+ /* Source file might be small, therefore limiting target
+ * touch pages to a smaller value to save processor cycles.
+ */
+ target_sz_estimate = ((uint64_t)source_sz * 1000UL)
+ / (last_comp_ratio + 1);
+ target_sz_estimate = NX_MIN(2 * target_sz_estimate,
+ target_max);
+ }
+
+ source_sz = source_sz + history_len;
+
+ /* Some NX condition codes require submitting the NX job again.
+ * Kernel doesn't handle NX page faults. Expects user code to
+ * touch pages.
+ */
+ pgfault_retries = NX_MAX_FAULTS;
+
+restart_nx:
+
+ putp32(ddl_in, ddebc, source_sz);
+
+ /* Fault in pages */
+ nxu_touch_pages(cmdp, sizeof(struct nx_gzip_crb_cpb_t), page_sz, 1);
+ nx_touch_pages_dde(ddl_in, 0, page_sz, 0);
+ nx_touch_pages_dde(ddl_out, target_sz_estimate, page_sz, 1);
+
+ /* Send job to NX */
+ cc = nx_submit_job(ddl_in, ddl_out, cmdp, devhandle);
+
+ switch (cc) {
+
+ case ERR_NX_TRANSLATION:
+
+ /* We touched the pages ahead of time. In the most common case
+ * we shouldn't be here. But may be some pages were paged out.
+ * Kernel should have placed the faulting address to fsaddr.
+ */
+ NXPRT(fprintf(stderr, "ERR_NX_TRANSLATION %p\n",
+ (void *)cmdp->crb.csb.fsaddr));
+
+ if (pgfault_retries == NX_MAX_FAULTS) {
+ /* Try once with exact number of pages */
+ --pgfault_retries;
+ goto restart_nx;
+ } else if (pgfault_retries > 0) {
+ /* If still faulting try fewer input pages
+ * assuming memory outage
+ */
+ if (source_sz > page_sz)
+ source_sz = NX_MAX(source_sz / 2, page_sz);
+ --pgfault_retries;
+ goto restart_nx;
+ } else {
+ fprintf(stderr, "cannot make progress; too many ");
+ fprintf(stderr, "page fault retries cc= %d\n", cc);
+ rc = -1;
+ goto err5;
+ }
+
+ case ERR_NX_DATA_LENGTH:
+
+ NXPRT(fprintf(stderr, "ERR_NX_DATA_LENGTH; "));
+ NXPRT(fprintf(stderr, "stream may have trailing data\n"));
+
+ /* Not an error in the most common case; it just says
+ * there is trailing data that we must examine.
+ *
+ * CC=3 CE(1)=0 CE(0)=1 indicates partial completion
+ * Fig.6-7 and Table 6-8.
+ */
+ nx_ce = get_csb_ce_ms3b(cmdp->crb.csb);
+
+ if (!csb_ce_termination(nx_ce) &&
+ csb_ce_partial_completion(nx_ce)) {
+ /* Check CPB for more information
+ * spbc and tpbc are valid
+ */
+ sfbt = getnn(cmdp->cpb, out_sfbt); /* Table 6-4 */
+ subc = getnn(cmdp->cpb, out_subc); /* Table 6-4 */
+ spbc = get32(cmdp->cpb, out_spbc_decomp);
+ tpbc = get32(cmdp->crb.csb, tpbc);
+ assert(target_max >= tpbc);
+
+ goto ok_cc3; /* not an error */
+ } else {
+ /* History length error when CE(1)=1 CE(0)=0. */
+ rc = -1;
+ fprintf(stderr, "history length error cc= %d\n", cc);
+ goto err5;
+ }
+
+ case ERR_NX_TARGET_SPACE:
+
+ /* Target buffer not large enough; retry smaller input
+ * data; give at least 1 byte. SPBC/TPBC are not valid.
+ */
+ assert(source_sz > history_len);
+ source_sz = ((source_sz - history_len + 2) / 2) + history_len;
+ NXPRT(fprintf(stderr, "ERR_NX_TARGET_SPACE; retry with "));
+ NXPRT(fprintf(stderr, "smaller input data src %d hist %d\n",
+ source_sz, history_len));
+ goto restart_nx;
+
+ case ERR_NX_OK:
+
+ /* This should not happen for gzip formatted data;
+ * we need trailing crc and isize
+ */
+ fprintf(stderr, "ERR_NX_OK\n");
+ spbc = get32(cmdp->cpb, out_spbc_decomp);
+ tpbc = get32(cmdp->crb.csb, tpbc);
+ assert(target_max >= tpbc);
+ assert(spbc >= history_len);
+ source_sz = spbc - history_len;
+ goto offsets_state;
+
+ default:
+ fprintf(stderr, "error: cc= %d\n", cc);
+ rc = -1;
+ goto err5;
+ }
+
+ok_cc3:
+
+ NXPRT(fprintf(stderr, "cc3: sfbt: %x\n", sfbt));
+
+ assert(spbc > history_len);
+ source_sz = spbc - history_len;
+
+ /* Table 6-4: Source Final Block Type (SFBT) describes the
+ * last processed deflate block and clues the software how to
+ * resume the next job. SUBC indicates how many input bits NX
+ * consumed but did not process. SPBC indicates how many
+ * bytes of source were given to the accelerator including
+ * history bytes.
+ */
+
+ switch (sfbt) {
+ int dhtlen;
+
+ case 0x0: /* Deflate final EOB received */
+
+ /* Calculating the checksum start position. */
+
+ source_sz = source_sz - subc / 8;
+ is_final = 1;
+ break;
+
+ /* Resume decompression cases are below. Basically
+ * indicates where NX has suspended and how to resume
+ * the input stream.
+ */
+
+ case 0x8: /* Within a literal block; use rembytecount */
+ case 0x9: /* Within a literal block; use rembytecount; bfinal=1 */
+
+ /* Supply the partially processed source byte again */
+ source_sz = source_sz - ((subc + 7) / 8);
+
+ /* SUBC LS 3bits: number of bits in the first source byte need
+ * to be processed.
+ * 000 means all 8 bits; Table 6-3
+ * Clear subc, histlen, sfbt, rembytecnt, dhtlen
+ */
+ cmdp->cpb.in_subc = 0;
+ cmdp->cpb.in_sfbt = 0;
+ putnn(cmdp->cpb, in_subc, subc % 8);
+ putnn(cmdp->cpb, in_sfbt, sfbt);
+ putnn(cmdp->cpb, in_rembytecnt, getnn(cmdp->cpb,
+ out_rembytecnt));
+ break;
+
+ case 0xA: /* Within a FH block; */
+ case 0xB: /* Within a FH block; bfinal=1 */
+
+ source_sz = source_sz - ((subc + 7) / 8);
+
+ /* Clear subc, histlen, sfbt, rembytecnt, dhtlen */
+ cmdp->cpb.in_subc = 0;
+ cmdp->cpb.in_sfbt = 0;
+ putnn(cmdp->cpb, in_subc, subc % 8);
+ putnn(cmdp->cpb, in_sfbt, sfbt);
+ break;
+
+ case 0xC: /* Within a DH block; */
+ case 0xD: /* Within a DH block; bfinal=1 */
+
+ source_sz = source_sz - ((subc + 7) / 8);
+
+ /* Clear subc, histlen, sfbt, rembytecnt, dhtlen */
+ cmdp->cpb.in_subc = 0;
+ cmdp->cpb.in_sfbt = 0;
+ putnn(cmdp->cpb, in_subc, subc % 8);
+ putnn(cmdp->cpb, in_sfbt, sfbt);
+
+ dhtlen = getnn(cmdp->cpb, out_dhtlen);
+ putnn(cmdp->cpb, in_dhtlen, dhtlen);
+ assert(dhtlen >= 42);
+
+ /* Round up to a qword */
+ dhtlen = (dhtlen + 127) / 128;
+
+ while (dhtlen > 0) { /* Copy dht from cpb.out to cpb.in */
+ --dhtlen;
+ cmdp->cpb.in_dht[dhtlen] = cmdp->cpb.out_dht[dhtlen];
+ }
+ break;
+
+ case 0xE: /* Within a block header; bfinal=0; */
+ /* Also given if source data exactly ends (SUBC=0) with
+ * EOB code with BFINAL=0. Means the next byte will
+ * contain a block header.
+ */
+ case 0xF: /* within a block header with BFINAL=1. */
+
+ source_sz = source_sz - ((subc + 7) / 8);
+
+ /* Clear subc, histlen, sfbt, rembytecnt, dhtlen */
+ cmdp->cpb.in_subc = 0;
+ cmdp->cpb.in_sfbt = 0;
+ putnn(cmdp->cpb, in_subc, subc % 8);
+ putnn(cmdp->cpb, in_sfbt, sfbt);
+
+ /* Engine did not process any data */
+ if (is_eof && (source_sz == 0))
+ is_final = 1;
+ }
+
+offsets_state:
+
+ /* Adjust the source and target buffer offsets and lengths */
+
+ NXPRT(fprintf(stderr, "offsets_state:\n"));
+
+ /* Delete input data from fifo_in */
+ used_in = used_in - source_sz;
+ cur_in = (cur_in + source_sz) % fifo_in_len;
+ input_file_offset = input_file_offset + source_sz;
+
+ /* Add output data to fifo_out */
+ used_out = used_out + tpbc;
+
+ assert(used_out <= fifo_out_len);
+
+ total_out = total_out + tpbc;
+
+ /* Deflate history is 32KB max. No need to supply more
+ * than 32KB on a resume.
+ */
+ history_len = (total_out > window_max) ? window_max : total_out;
+
+ /* To estimate expected expansion in the next NX job; 500 means 50%.
+ * Deflate best case is around 1 to 1000.
+ */
+ last_comp_ratio = (1000UL * ((uint64_t)source_sz + 1))
+ / ((uint64_t)tpbc + 1);
+ last_comp_ratio = NX_MAX(NX_MIN(1000UL, last_comp_ratio), 1);
+ NXPRT(fprintf(stderr, "comp_ratio %ld source_sz %d spbc %d tpbc %d\n",
+ last_comp_ratio, source_sz, spbc, tpbc));
+
+ resuming = 1;
+
+finish_state:
+
+ NXPRT(fprintf(stderr, "finish_state:\n"));
+
+ if (is_final) {
+ if (used_out)
+ goto write_state; /* More data to write out */
+ else if (used_in < 8) {
+ /* Need at least 8 more bytes containing gzip crc
+ * and isize.
+ */
+ rc = -1;
+ goto err4;
+ } else {
+ /* Compare checksums and exit */
+ int i;
+ unsigned char tail[8];
+ uint32_t cksum, isize;
+
+ for (i = 0; i < 8; i++)
+ tail[i] = fifo_in[(cur_in + i) % fifo_in_len];
+ fprintf(stderr, "computed checksum %08x isize %08x\n",
+ cmdp->cpb.out_crc, (uint32_t) (total_out
+ % (1ULL<<32)));
+ cksum = ((uint32_t) tail[0] | (uint32_t) tail[1]<<8
+ | (uint32_t) tail[2]<<16
+ | (uint32_t) tail[3]<<24);
+ isize = ((uint32_t) tail[4] | (uint32_t) tail[5]<<8
+ | (uint32_t) tail[6]<<16
+ | (uint32_t) tail[7]<<24);
+ fprintf(stderr, "stored checksum %08x isize %08x\n",
+ cksum, isize);
+
+ if (cksum == cmdp->cpb.out_crc && isize == (uint32_t)
+ (total_out % (1ULL<<32))) {
+ rc = 0; goto ok1;
+ } else {
+ rc = -1; goto err4;
+ }
+ }
+ } else
+ goto read_state;
+
+ return -1;
+
+err1:
+ fprintf(stderr, "error: not a gzip file, expect %x, read %x\n",
+ expect, c);
+ return -1;
+
+err2:
+ fprintf(stderr, "error: the FLG byte is wrong or not being handled\n");
+ return -1;
+
+err3:
+ fprintf(stderr, "error: gzip header\n");
+ return -1;
+
+err4:
+ fprintf(stderr, "error: checksum missing or mismatch\n");
+
+err5:
+ok1:
+ fprintf(stderr, "decomp is complete: fclose\n");
+ fclose(outf);
+
+ return rc;
+}
+
+
+int main(int argc, char **argv)
+{
+ int rc;
+ struct sigaction act;
+ void *handle;
+
+ nx_dbg = 0;
+ nx_gzip_log = NULL;
+ act.sa_handler = 0;
+ act.sa_sigaction = nxu_sigsegv_handler;
+ act.sa_flags = SA_SIGINFO;
+ act.sa_restorer = 0;
+ sigemptyset(&act.sa_mask);
+ sigaction(SIGSEGV, &act, NULL);
+
+ handle = nx_function_begin(NX_FUNC_COMP_GZIP, 0);
+ if (!handle) {
+ fprintf(stderr, "Unable to init NX, errno %d\n", errno);
+ exit(-1);
+ }
+
+ rc = decompress_file(argc, argv, handle);
+
+ nx_function_end(handle);
+
+ return rc;
+}
diff --git a/tools/testing/selftests/powerpc/nx-gzip/nx-gzip-test.sh b/tools/testing/selftests/powerpc/nx-gzip/nx-gzip-test.sh
index 18949237a001..8d336cdf75c0 100755
--- a/tools/testing/selftests/powerpc/nx-gzip/nx-gzip-test.sh
+++ b/tools/testing/selftests/powerpc/nx-gzip/nx-gzip-test.sh
@@ -25,6 +25,7 @@ function test_sizes
echo "Testing $size ($n) ..."
dd if=/dev/urandom of=$fname bs=$size count=1
./gzfht_test $fname
+ ./gunz_test ${fname}.nx.gz
done
}
--
2.21.0
^ permalink raw reply related
* [PATCH V4 5/5] selftests/powerpc: Add README for GZIP engine tests
From: Raphael Moreira Zinsly @ 2020-04-20 20:55 UTC (permalink / raw)
To: linuxppc-dev, linux-crypto, dja; +Cc: abali, haren, herbert, rzinsly
In-Reply-To: <20200420205538.25181-1-rzinsly@linux.ibm.com>
Include a README file with the instructions to use the
testcases at selftests/powerpc/nx-gzip.
Signed-off-by: Bulent Abali <abali@us.ibm.com>
Signed-off-by: Raphael Moreira Zinsly <rzinsly@linux.ibm.com>
---
.../powerpc/nx-gzip/99-nx-gzip.rules | 1 +
.../testing/selftests/powerpc/nx-gzip/README | 45 +++++++++++++++++++
2 files changed, 46 insertions(+)
create mode 100644 tools/testing/selftests/powerpc/nx-gzip/99-nx-gzip.rules
create mode 100644 tools/testing/selftests/powerpc/nx-gzip/README
diff --git a/tools/testing/selftests/powerpc/nx-gzip/99-nx-gzip.rules b/tools/testing/selftests/powerpc/nx-gzip/99-nx-gzip.rules
new file mode 100644
index 000000000000..5a7118495cb3
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/99-nx-gzip.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="nxgzip", KERNEL=="nx-gzip", MODE="0666"
diff --git a/tools/testing/selftests/powerpc/nx-gzip/README b/tools/testing/selftests/powerpc/nx-gzip/README
new file mode 100644
index 000000000000..9809dbaa1905
--- /dev/null
+++ b/tools/testing/selftests/powerpc/nx-gzip/README
@@ -0,0 +1,45 @@
+Test the nx-gzip function:
+=========================
+
+Verify that following device exists:
+ /dev/crypto/nx-gzip
+If you get a permission error run as sudo or set the device permissions:
+ sudo chmod go+rw /dev/crypto/nx-gzip
+However, chmod may not survive across boots. You may create a udev file such
+as:
+ /etc/udev/rules.d/99-nx-gzip.rules
+
+
+To manually build and run:
+$ gcc -O3 -I./include -o gzfht_test gzfht_test.c gzip_vas.c
+$ gcc -O3 -I./include -o gunz_test gunz_test.c gzip_vas.c
+
+
+Compress any file using Fixed Huffman mode. Output will have a .nx.gz suffix:
+$ ./gzfht_test gzip_vas.c
+file gzip_vas.c read, 6413 bytes
+compressed 6413 to 3124 bytes total, crc32 checksum = abd15e8a
+
+
+Uncompress the previous output. Output will have a .nx.gunzip suffix:
+./gunz_test gzip_vas.c.nx.gz
+gzHeader FLG 0
+00 00 00 00 04 03
+gzHeader MTIME, XFL, OS ignored
+computed checksum abd15e8a isize 0000190d
+stored checksum abd15e8a isize 0000190d
+decomp is complete: fclose
+
+
+Compare two files:
+$ sha1sum gzip_vas.c.nx.gz.nx.gunzip gzip_vas.c
+bf43e3c0c3651f5f22b6f9784cd9b1eeab4120b6 gzip_vas.c.nx.gz.nx.gunzip
+bf43e3c0c3651f5f22b6f9784cd9b1eeab4120b6 gzip_vas.c
+
+
+Note that the code here are intended for testing the nx-gzip hardware function.
+They are not intended for demonstrating performance or compression ratio.
+By being simplistic these selftests expect to allocate the entire set of source
+and target pages in the memory so it needs enough memory to work.
+For more information and source code consider using:
+https://github.com/libnxz/power-gzip
--
2.21.0
^ permalink raw reply related
* Re: [PATCH v8 6/7] ASoC: dt-bindings: fsl_easrc: Add document for EASRC
From: Rob Herring @ 2020-04-20 21:06 UTC (permalink / raw)
To: Shengjiu Wang
Cc: mark.rutland, devicetree, alsa-devel, timur, Xiubo.Lee,
linuxppc-dev, tiwai, lgirdwood, robh+dt, perex, nicoleotsuka,
broonie, festevam, linux-kernel
In-Reply-To: <396a73da2a2fa8b77d0b773d321500b3e504d919.1586845138.git.shengjiu.wang@nxp.com>
On Tue, 14 Apr 2020 14:56:06 +0800, Shengjiu Wang wrote:
> EASRC (Enhanced Asynchronous Sample Rate Converter) is a new
> IP module found on i.MX8MN.
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> ---
> .../devicetree/bindings/sound/fsl,easrc.yaml | 101 ++++++++++++++++++
> 1 file changed, 101 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/sound/fsl,easrc.yaml
>
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* Re: [musl] Powerpc Linux 'scv' system call ABI proposal take 2
From: Szabolcs Nagy @ 2020-04-20 21:17 UTC (permalink / raw)
To: Nicholas Piggin
Cc: libc-dev, Rich Felker, Nicholas Piggin via Libc-alpha,
linuxppc-dev, musl
In-Reply-To: <1587348046.pwnfbo52iq.astroid@bobo.none>
* Nicholas Piggin <npiggin@gmail.com> [2020-04-20 12:08:36 +1000]:
> Excerpts from Rich Felker's message of April 20, 2020 11:29 am:
> > Also, allowing patching of executable pages is generally frowned upon
> > these days because W^X is a desirable hardening property.
>
> Right, it would want be write-protected after being patched.
"frowned upon" means that users may have to update
their security policy setting in pax, selinux, apparmor,
seccomp bpf filters and who knows what else that may
monitor and flag W&X mprotect.
libc update can break systems if the new libc does W&X.
^ permalink raw reply
* Re: [PATCH v3 0/4] Clean up hugetlb boot command line processing
From: Mike Kravetz @ 2020-04-20 21:40 UTC (permalink / raw)
To: Anders Roxell, Will Deacon
Cc: linux-doc, Catalin Marinas, Dave Hansen, Heiko Carstens, Peter Xu,
Linux-MM, Paul Mackerras, sparclinux, linux-riscv, Mina Almasry,
linux-s390, Jonathan Corbet, Christian Borntraeger, Ingo Molnar,
Longpeng, Albert Ou, Vasily Gorbik, Qian Cai, Paul Walmsley,
Thomas Gleixner, Linux ARM, Nitesh Narayan Lal, Randy Dunlap,
LKML, Palmer Dabbelt, Andrew Morton, linuxppc-dev, David S.Miller
In-Reply-To: <CADYN=9+=tCDmddTYGY44onvrzbg7yrbacMDSxd4hhD+=b=Yeiw@mail.gmail.com>
On 4/20/20 1:29 PM, Anders Roxell wrote:
> On Mon, 20 Apr 2020 at 20:23, Mike Kravetz <mike.kravetz@oracle.com> wrote:
>> On 4/20/20 8:34 AM, Qian Cai wrote:
>>>
>>> Reverted this series fixed many undefined behaviors on arm64 with the config,
>> While rearranging the code (patch 3 in series), I made the incorrect
>> assumption that CONT_XXX_SIZE == (1UL << CONT_XXX_SHIFT). However,
>> this is not the case. Does the following patch fix these issues?
>>
>> From b75cb4a0852e208bee8c4eb347dc076fcaa88859 Mon Sep 17 00:00:00 2001
>> From: Mike Kravetz <mike.kravetz@oracle.com>
>> Date: Mon, 20 Apr 2020 10:41:18 -0700
>> Subject: [PATCH] arm64/hugetlb: fix hugetlb initialization
>>
>> When calling hugetlb_add_hstate() to initialize a new hugetlb size,
>> be sure to use correct huge pages size order.
>>
>> Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
>> ---
>> arch/arm64/mm/hugetlbpage.c | 8 ++++----
>> 1 file changed, 4 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
>> index 9ca840527296..a02411a1f19a 100644
>> --- a/arch/arm64/mm/hugetlbpage.c
>> +++ b/arch/arm64/mm/hugetlbpage.c
>> @@ -453,11 +453,11 @@ void huge_ptep_clear_flush(struct vm_area_struct *vma,
>> static int __init hugetlbpage_init(void)
>> {
>> #ifdef CONFIG_ARM64_4K_PAGES
>> - hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
>> + hugetlb_add_hstate(ilog2(PUD_SIZE) - PAGE_SHIFT);
>> #endif
>> - hugetlb_add_hstate(CONT_PMD_SHIFT - PAGE_SHIFT);
>> - hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
>> - hugetlb_add_hstate(CONT_PTE_SHIFT - PAGE_SHIFT);
>> + hugetlb_add_hstate(ilog2(CONT_PMD_SIZE) - PAGE_SHIFT);
>> + hugetlb_add_hstate(ilog2(PMD_SIZE) - PAGE_SHIFT);
>> + hugetlb_add_hstate(ilog2(CONT_PTE_SIZE) - PAGE_SHIFT);
>>
>> return 0;
>> }
>
> I build this for an arm64 kernel and ran it in qemu and it worked.
Thanks for testing Anders!
Will, here is an updated version of the patch based on your suggestion.
I added the () for emphasis but that may just be noise for some. Also,
the naming differences and values for CONT_PTE may make some people
look twice. Not sure if being consistent here helps?
I have only built this. No testing.
From daf833ab6b806ecc0816d84d45dcbacc052a7eec Mon Sep 17 00:00:00 2001
From: Mike Kravetz <mike.kravetz@oracle.com>
Date: Mon, 20 Apr 2020 13:56:15 -0700
Subject: [PATCH] arm64/hugetlb: fix hugetlb initialization
When calling hugetlb_add_hstate() to initialize a new hugetlb size,
be sure to use correct huge pages size order.
Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
---
arch/arm64/mm/hugetlbpage.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index 9ca840527296..bed6dc7c4276 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -455,9 +455,9 @@ static int __init hugetlbpage_init(void)
#ifdef CONFIG_ARM64_4K_PAGES
hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
#endif
- hugetlb_add_hstate(CONT_PMD_SHIFT - PAGE_SHIFT);
+ hugetlb_add_hstate((CONT_PMD_SHIFT + PMD_SHIFT) - PAGE_SHIFT);
hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
- hugetlb_add_hstate(CONT_PTE_SHIFT - PAGE_SHIFT);
+ hugetlb_add_hstate((CONT_PTE_SHIFT + PAGE_SHIFT) - PAGE_SHIFT);
return 0;
}
--
2.25.2
^ permalink raw reply related
* Re: [PATCH v2 00/33] Documentation fixes for Kernel 5.8
From: Jonathan Corbet @ 2020-04-20 21:43 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: kvm, Linux Doc Mailing List, linux-pci, Linus Walleij, dri-devel,
linux-unionfs, linux-mm, netdev, linux-i2c, linux1394-devel,
kvmarm, linux-arch, Rob Herring, Geert Uytterhoeven, linux-rdma,
Kishon Vijay Abraham I, linux-rockchip, Matthias Kaehlcke,
Sandeep Maheswaram, linux-media, devicetree, linux-afs,
linux-arm-msm, ecryptfs, kvm-ppc, Stephen Boyd, Maxime Ripard,
linux-arm-kernel, linux-edac, Matthias Brugger, Yuti Amonkar,
linux-ide, linux-ntfs-dev, freedreno, linux-usb, linux-kernel,
linux-spi, linux-crypto, Sudeep Holla, linux-fsdevel,
linuxppc-dev, ocfs2-devel
In-Reply-To: <cover.1586881715.git.mchehab+huawei@kernel.org>
On Tue, 14 Apr 2020 18:48:26 +0200
Mauro Carvalho Chehab <mchehab+huawei@kernel.org> wrote:
> Patches 1 to 5 contain changes to the documentation toolset:
>
> - The first 3 patches help to reduce a lot the number of reported
> kernel-doc issues, by making the tool more smart.
>
> - Patches 4 and 5 are meant to partially address the PDF
> build, with now requires Sphinx version 2.4 or upper.
>
> The remaining patches fix broken references detected by
> this tool:
>
> ./scripts/documentation-file-ref-check
>
> and address other random errors due to tags being mis-interpreted
> or mis-used.
>
> They are independent each other, but some may depend on
> the kernel-doc improvements.
>
> PS.: Due to the large number of C/C, I opted to keep a smaller
> set of C/C at this first e-mail (only e-mails with "L:" tag from
> MAINTAINERS file).
OK, I've applied this set, minus #17 which was applied elsewhere.
Thanks,
jon
^ permalink raw reply
* [PATCH v2 0/2] Honoring Native AER/DPC Host Bridges
From: Jon Derrick @ 2020-04-20 21:37 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Kuppuswamy Sathyanarayanan, Rajat Jain, Rafael J. Wysocki,
Frederick Lawler, Sam Bobroff, linux-pci, Olof Johansson,
linuxppc-dev, linux-kernel, Bjorn Helgaas, Alex Williamson,
Patel, Mayurkumar, Oliver O'Halloran, Keith Busch,
Andy Shevchenko, Mika Westerberg, Jon Derrick
The two patches here force AER and DPC to honor the Host Bridge's Native
AER/DPC settings. This is under the assumption that when these bits are set,
that Firmware-First AER/DPC should not be in use for these ports. This
assumption seems to be true in ACPI, which explicitly clears these capability
settings in the host bridge if the service cannot be negotiated with _OSC.
This also fixes an issue I've seen in a few platforms whose BIOS and/or switch
firmware leaves DPC preconfigured. In these cases, the kernel DPC driver cannot
bind a handler to the interrupt and could result in unmanaged DPC link down
events.
Jon Derrick (2):
PCI/AER: Allow Native AER Host Bridges to use AER
PCI/DPC: Allow Native DPC Host Bridges to use DPC
drivers/pci/pcie/aer.c | 3 +++
drivers/pci/pcie/dpc.c | 3 ++-
drivers/pci/pcie/portdrv_core.c | 3 ++-
3 files changed, 7 insertions(+), 2 deletions(-)
--
1.8.3.1
^ permalink raw reply
* [PATCH v2 1/2] PCI/AER: Allow Native AER Host Bridges to use AER
From: Jon Derrick @ 2020-04-20 21:37 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Kuppuswamy Sathyanarayanan, Rajat Jain, Rafael J. Wysocki,
Frederick Lawler, Sam Bobroff, linux-pci, Olof Johansson,
linuxppc-dev, linux-kernel, Bjorn Helgaas, Alex Williamson,
Patel, Mayurkumar, Oliver O'Halloran, Keith Busch,
Andy Shevchenko, Mika Westerberg, Jon Derrick
In-Reply-To: <1587418630-13562-1-git-send-email-jonathan.derrick@intel.com>
Some platforms have a mix of ports whose capabilities can be negotiated
by _OSC, and some ports which are not described by ACPI and instead
managed by Native drivers. The existing Firmware-First HEST model can
incorrectly tag these Native, Non-ACPI ports as Firmware-First managed
ports by advertising the HEST Global Flag and matching the type and
class of the port (aer_hest_parse).
If the port requests Native AER through the Host Bridge's capability
settings, the AER driver should honor those settings and allow the port
to bind. This patch changes the definition of Firmware-First to exclude
ports whose Host Bridges request Native AER.
Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
---
drivers/pci/pcie/aer.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index f4274d3..30fbd1f 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -314,6 +314,9 @@ int pcie_aer_get_firmware_first(struct pci_dev *dev)
if (pcie_ports_native)
return 0;
+ if (pci_find_host_bridge(dev->bus)->native_aer)
+ return 0;
+
if (!dev->__aer_firmware_first_valid)
aer_set_firmware_first(dev);
return dev->__aer_firmware_first;
--
1.8.3.1
^ permalink raw reply related
* [PATCH v2 2/2] PCI/DPC: Allow Native DPC Host Bridges to use DPC
From: Jon Derrick @ 2020-04-20 21:37 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Kuppuswamy Sathyanarayanan, Rajat Jain, Rafael J. Wysocki,
Frederick Lawler, Sam Bobroff, linux-pci, Olof Johansson,
linuxppc-dev, linux-kernel, Bjorn Helgaas, Alex Williamson,
Patel, Mayurkumar, Oliver O'Halloran, Keith Busch,
Andy Shevchenko, Mika Westerberg, Jon Derrick
In-Reply-To: <1587418630-13562-1-git-send-email-jonathan.derrick@intel.com>
The existing portdrv model prevents DPC services without either OS
control (_OSC) granted to AER services, a Host Bridge requesting Native
AER, or using one of the 'pcie_ports=' parameters of 'native' or
'dpc-native'.
The DPC port service driver itself will also fail to probe if the kernel
assumes the port is using Firmware-First AER. It's a reasonable
expectation that a port using Firmware-First AER will also be using
Firmware-First DPC, however if a Host Bridge requests Native DPC, the
DPC driver should allow it and not fail to bind due to AER capability
settings.
Host Bridges which request Native DPC port services will also likely
request Native AER, however it shouldn't be a requirement. This patch
allows ports on those Host Bridges to have DPC port services.
This will avoid the unlikely situation where the port is Firmware-First
AER and Native DPC, and a BIOS or switch firmware preconfiguration of
the DPC trigger could result in unhandled DPC events.
Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
---
drivers/pci/pcie/dpc.c | 3 ++-
drivers/pci/pcie/portdrv_core.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 7621704..3f3106f 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -284,7 +284,8 @@ static int dpc_probe(struct pcie_device *dev)
int status;
u16 ctl, cap;
- if (pcie_aer_get_firmware_first(pdev) && !pcie_ports_dpc_native)
+ if (pcie_aer_get_firmware_first(pdev) && !pcie_ports_dpc_native &&
+ !pci_find_host_bridge(pdev->bus)->native_dpc)
return -ENOTSUPP;
status = devm_request_threaded_irq(device, dev->irq, dpc_irq,
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 50a9522..f2139a1 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -256,7 +256,8 @@ static int get_port_device_capability(struct pci_dev *dev)
*/
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_DPC) &&
pci_aer_available() &&
- (pcie_ports_dpc_native || (services & PCIE_PORT_SERVICE_AER)))
+ (pcie_ports_dpc_native || host->native_dpc ||
+ (services & PCIE_PORT_SERVICE_AER)))
services |= PCIE_PORT_SERVICE_DPC;
if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM ||
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH v5 0/5] Track and expose idle PURR and SPURR ticks
From: Tyrel Datwyler @ 2020-04-20 22:46 UTC (permalink / raw)
To: Gautham R. Shenoy, Nathan Lynch, Michael Ellerman,
Vaidyanathan Srinivasan, Kamalesh Babulal, Naveen N. Rao
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1586249263-14048-1-git-send-email-ego@linux.vnet.ibm.com>
On 4/7/20 1:47 AM, Gautham R. Shenoy wrote:
> From: "Gautham R. Shenoy" <ego@linux.vnet.ibm.com>
>
> Hi,
>
> This is the fifth version of the patches to track and expose idle PURR
> and SPURR ticks. These patches are required by tools such as lparstat
> to compute system utilization for capacity planning purposes.
>
> The previous versions can be found here:
> v4: https://lkml.org/lkml/2020/3/27/323
> v3: https://lkml.org/lkml/2020/3/11/331
> v2: https://lkml.org/lkml/2020/2/21/21
> v1: https://lore.kernel.org/patchwork/cover/1159341/
>
> They changes from v4 are:
>
> - As suggested by Naveen, moved the functions read_this_idle_purr()
> and read_this_idle_spurr() from Patch 2 and Patch 3 respectively
> to Patch 4 where it is invoked.
>
> - Dropped Patch 6 which cached the values of purr, spurr,
> idle_purr, idle_spurr in order to minimize the number of IPIs
> sent.
>
> - Updated the dates for the idle_purr, idle_spurr in the
> Documentation Patch 5.
>
> Motivation:
> ===========
> On PSeries LPARs, the data centers planners desire a more accurate
> view of system utilization per resource such as CPU to plan the system
> capacity requirements better. Such accuracy can be obtained by reading
> PURR/SPURR registers for CPU resource utilization.
>
> Tools such as lparstat which are used to compute the utilization need
> to know [S]PURR ticks when the cpu was busy or idle. The [S]PURR
> counters are already exposed through sysfs. We already account for
> PURR ticks when we go to idle so that we can update the VPA area. This
> patchset extends support to account for SPURR ticks when idle, and
> expose both via per-cpu sysfs files.
>
> These patches are required for enhancement to the lparstat utility
> that compute the CPU utilization based on PURR and SPURR which can be
> found here :
> https://groups.google.com/forum/#!topic/powerpc-utils-devel/fYRo69xO9r4
>
>
> With the patches, when lparstat is run on a LPAR running CPU-Hogs,
> =========================================================================
> sudo ./src/lparstat -E 1 3
>
> System Configuration
> type=Dedicated mode=Capped smt=8 lcpu=2 mem=4834112 kB cpus=0 ent=2.00
>
> ---Actual--- -Normalized-
> %busy %idle Frequency %busy %idle
> ------ ------ ------------- ------ ------
> 1 99.99 0.00 3.35GHz[111%] 110.99 0.00
> 2 100.00 0.00 3.35GHz[111%] 111.01 0.00
> 3 100.00 0.00 3.35GHz[111%] 111.00 0.00
>
> With patches, when lparstat is run on and idle LPAR
> =========================================================================
> System Configuration
> type=Dedicated mode=Capped smt=8 lcpu=2 mem=4834112 kB cpus=0 ent=2.00
> ---Actual--- -Normalized-
> %busy %idle Frequency %busy %idle
> ------ ------ ------------- ------ ------
> 1 0.15 99.84 2.17GHz[ 72%] 0.11 71.89
> 2 0.24 99.76 2.11GHz[ 70%] 0.18 69.82
> 3 0.24 99.75 2.11GHz[ 70%] 0.18 69.81
>
> Gautham R. Shenoy (5):
> powerpc: Move idle_loop_prolog()/epilog() functions to header file
> powerpc/idle: Store PURR snapshot in a per-cpu global variable
> powerpc/pseries: Account for SPURR ticks on idle CPUs
> powerpc/sysfs: Show idle_purr and idle_spurr for every CPU
> Documentation: Document sysfs interfaces purr, spurr, idle_purr,
> idle_spurr
>
> Documentation/ABI/testing/sysfs-devices-system-cpu | 39 +++++++++
> arch/powerpc/include/asm/idle.h | 93 ++++++++++++++++++++++
> arch/powerpc/kernel/sysfs.c | 82 ++++++++++++++++++-
> arch/powerpc/platforms/pseries/setup.c | 8 +-
> drivers/cpuidle/cpuidle-pseries.c | 39 ++-------
> 5 files changed, 224 insertions(+), 37 deletions(-)
> create mode 100644 arch/powerpc/include/asm/idle.h
>
Reviewed-by: Tyrel Datwyler <tyreld@linux.ibm.com>
Any chance this is going to be merged in the near future? There is a patchset to
update lparstat in the powerpc-utils package to calculate PURR/SPURR cpu
utilization that I would like to merge, but have been holding off to make sure
we are synced with this proposed patchset.
^ permalink raw reply
* Re: [PATCH v3 0/4] Clean up hugetlb boot command line processing
From: Anders Roxell @ 2020-04-20 22:53 UTC (permalink / raw)
To: Mike Kravetz
Cc: linux-doc, Dave Hansen, Heiko Carstens, Peter Xu, Linux-MM,
Paul Mackerras, sparclinux, linux-riscv, Will Deacon,
Mina Almasry, linux-s390, Jonathan Corbet, Christian Borntraeger,
Ingo Molnar, Catalin Marinas, Longpeng, Albert Ou, Vasily Gorbik,
Qian Cai, Paul Walmsley, Thomas Gleixner, Linux ARM,
Nitesh Narayan Lal, Randy Dunlap, LKML, Palmer Dabbelt,
Andrew Morton, linuxppc-dev, David S.Miller
In-Reply-To: <86333853-0648-393f-db96-d581ee114d2b@oracle.com>
On Mon, 20 Apr 2020 at 23:43, Mike Kravetz <mike.kravetz@oracle.com> wrote:
>
> On 4/20/20 1:29 PM, Anders Roxell wrote:
> > On Mon, 20 Apr 2020 at 20:23, Mike Kravetz <mike.kravetz@oracle.com> wrote:
> >> On 4/20/20 8:34 AM, Qian Cai wrote:
> >>>
> >>> Reverted this series fixed many undefined behaviors on arm64 with the config,
> >> While rearranging the code (patch 3 in series), I made the incorrect
> >> assumption that CONT_XXX_SIZE == (1UL << CONT_XXX_SHIFT). However,
> >> this is not the case. Does the following patch fix these issues?
> >>
> >> From b75cb4a0852e208bee8c4eb347dc076fcaa88859 Mon Sep 17 00:00:00 2001
> >> From: Mike Kravetz <mike.kravetz@oracle.com>
> >> Date: Mon, 20 Apr 2020 10:41:18 -0700
> >> Subject: [PATCH] arm64/hugetlb: fix hugetlb initialization
> >>
> >> When calling hugetlb_add_hstate() to initialize a new hugetlb size,
> >> be sure to use correct huge pages size order.
> >>
> >> Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
> >> ---
> >> arch/arm64/mm/hugetlbpage.c | 8 ++++----
> >> 1 file changed, 4 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> >> index 9ca840527296..a02411a1f19a 100644
> >> --- a/arch/arm64/mm/hugetlbpage.c
> >> +++ b/arch/arm64/mm/hugetlbpage.c
> >> @@ -453,11 +453,11 @@ void huge_ptep_clear_flush(struct vm_area_struct *vma,
> >> static int __init hugetlbpage_init(void)
> >> {
> >> #ifdef CONFIG_ARM64_4K_PAGES
> >> - hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
> >> + hugetlb_add_hstate(ilog2(PUD_SIZE) - PAGE_SHIFT);
> >> #endif
> >> - hugetlb_add_hstate(CONT_PMD_SHIFT - PAGE_SHIFT);
> >> - hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
> >> - hugetlb_add_hstate(CONT_PTE_SHIFT - PAGE_SHIFT);
> >> + hugetlb_add_hstate(ilog2(CONT_PMD_SIZE) - PAGE_SHIFT);
> >> + hugetlb_add_hstate(ilog2(PMD_SIZE) - PAGE_SHIFT);
> >> + hugetlb_add_hstate(ilog2(CONT_PTE_SIZE) - PAGE_SHIFT);
> >>
> >> return 0;
> >> }
> >
> > I build this for an arm64 kernel and ran it in qemu and it worked.
>
> Thanks for testing Anders!
>
> Will, here is an updated version of the patch based on your suggestion.
> I added the () for emphasis but that may just be noise for some. Also,
> the naming differences and values for CONT_PTE may make some people
> look twice. Not sure if being consistent here helps?
>
> I have only built this. No testing.
>
> From daf833ab6b806ecc0816d84d45dcbacc052a7eec Mon Sep 17 00:00:00 2001
> From: Mike Kravetz <mike.kravetz@oracle.com>
> Date: Mon, 20 Apr 2020 13:56:15 -0700
> Subject: [PATCH] arm64/hugetlb: fix hugetlb initialization
>
> When calling hugetlb_add_hstate() to initialize a new hugetlb size,
> be sure to use correct huge pages size order.
>
> Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
Tested-by: Anders Roxell <anders.roxell@linaro.org>
I tested this patch on qemu-aarch64.
Cheers,
Anders
> ---
> arch/arm64/mm/hugetlbpage.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
> index 9ca840527296..bed6dc7c4276 100644
> --- a/arch/arm64/mm/hugetlbpage.c
> +++ b/arch/arm64/mm/hugetlbpage.c
> @@ -455,9 +455,9 @@ static int __init hugetlbpage_init(void)
> #ifdef CONFIG_ARM64_4K_PAGES
> hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
> #endif
> - hugetlb_add_hstate(CONT_PMD_SHIFT - PAGE_SHIFT);
> + hugetlb_add_hstate((CONT_PMD_SHIFT + PMD_SHIFT) - PAGE_SHIFT);
> hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
> - hugetlb_add_hstate(CONT_PTE_SHIFT - PAGE_SHIFT);
> + hugetlb_add_hstate((CONT_PTE_SHIFT + PAGE_SHIFT) - PAGE_SHIFT);
>
> return 0;
> }
> --
> 2.25.2
>
^ permalink raw reply
* Re: [PATCH v3 02/13] powerpc/40x: Rework 40x PTE access and TLB miss
From: kbuild test robot @ 2020-04-21 0:47 UTC (permalink / raw)
To: Christophe Leroy, Benjamin Herrenschmidt, Paul Mackerras,
Michael Ellerman, michal.simek, arnd
Cc: linuxppc-dev, kbuild-all, linux-kernel
In-Reply-To: <9988528a455bb8c9962e2ea9e8df06ebca8cded1.1586852082.git.christophe.leroy@c-s.fr>
[-- Attachment #1: Type: text/plain, Size: 7571 bytes --]
Hi Christophe,
I love your patch! Yet something to improve:
[auto build test ERROR on powerpc/next]
[also build test ERROR on robh/for-next char-misc/char-misc-testing tip/locking/core linus/master v5.7-rc2 next-20200420]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Christophe-Leroy/Modernise-powerpc-40x/20200414-185156
base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-ppc40x_defconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 9.3.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day GCC_VERSION=9.3.0 make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
arch/powerpc/mm/nohash/40x.c: In function 'mmu_mapin_ram':
>> arch/powerpc/mm/nohash/40x.c:107:3: error: expected ',' or ';' before 'pmdp'
107 | pmdp = pmd_ptr_k(v);
| ^~~~
vim +107 arch/powerpc/mm/nohash/40x.c
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 90
14e609d693ef67 arch/powerpc/mm/40x_mmu.c Christophe Leroy 2019-02-21 91 unsigned long __init mmu_mapin_ram(unsigned long base, unsigned long top)
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 92 {
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 93 unsigned long v, s, mapped;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 94 phys_addr_t p;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 95
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 96 v = KERNELBASE;
99c62dd773797b arch/powerpc/mm/40x_mmu.c Kumar Gala 2008-04-16 97 p = 0;
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 98 s = total_lowmem;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 99
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 100 if (__map_without_ltlbs)
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 101 return 0;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 102
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 103 while (s >= LARGE_PAGE_SIZE_16M) {
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 104 pmd_t *pmdp;
682f715365c25b arch/powerpc/mm/nohash/40x.c Christophe Leroy 2020-04-14 105 unsigned long val = p | _PMD_SIZE_16M | _PAGE_EXEC | _PAGE_RW
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 106
0b1c524caaae24 arch/powerpc/mm/nohash/40x.c Christophe Leroy 2020-01-09 @107 pmdp = pmd_ptr_k(v);
f281b5d50c87ec arch/powerpc/mm/40x_mmu.c Aneesh Kumar K.V 2015-12-01 108 *pmdp++ = __pmd(val);
f281b5d50c87ec arch/powerpc/mm/40x_mmu.c Aneesh Kumar K.V 2015-12-01 109 *pmdp++ = __pmd(val);
f281b5d50c87ec arch/powerpc/mm/40x_mmu.c Aneesh Kumar K.V 2015-12-01 110 *pmdp++ = __pmd(val);
f281b5d50c87ec arch/powerpc/mm/40x_mmu.c Aneesh Kumar K.V 2015-12-01 111 *pmdp++ = __pmd(val);
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 112
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 113 v += LARGE_PAGE_SIZE_16M;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 114 p += LARGE_PAGE_SIZE_16M;
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 115 s -= LARGE_PAGE_SIZE_16M;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 116 }
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 117
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 118 while (s >= LARGE_PAGE_SIZE_4M) {
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 119 pmd_t *pmdp;
682f715365c25b arch/powerpc/mm/nohash/40x.c Christophe Leroy 2020-04-14 120 unsigned long val = p | _PMD_SIZE_4M | _PAGE_EXEC | _PAGE_RW;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 121
0b1c524caaae24 arch/powerpc/mm/nohash/40x.c Christophe Leroy 2020-01-09 122 pmdp = pmd_ptr_k(v);
f281b5d50c87ec arch/powerpc/mm/40x_mmu.c Aneesh Kumar K.V 2015-12-01 123 *pmdp = __pmd(val);
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 124
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 125 v += LARGE_PAGE_SIZE_4M;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 126 p += LARGE_PAGE_SIZE_4M;
bd942ba3db60d3 arch/powerpc/mm/40x_mmu.c Grant Likely 2007-10-31 127 s -= LARGE_PAGE_SIZE_4M;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 128 }
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 129
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 130 mapped = total_lowmem - s;
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 131
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 132 /* If the size of RAM is not an exact power of two, we may not
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 133 * have covered RAM in its entirety with 16 and 4 MiB
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 134 * pages. Consequently, restrict the top end of RAM currently
95f72d1ed41a66 arch/powerpc/mm/40x_mmu.c Yinghai Lu 2010-07-12 135 * allocable so that calls to the MEMBLOCK to allocate PTEs for "tail"
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 136 * coverage with normal-sized pages (or other reasons) do not
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 137 * attempt to allocate outside the allowed range.
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 138 */
cd3db0c4ca3d23 arch/powerpc/mm/40x_mmu.c Benjamin Herrenschmidt 2010-07-06 139 memblock_set_current_limit(mapped);
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 140
5907630ffc2b2d arch/powerpc/mm/40x_mmu.c Grant Erickson 2008-10-29 141 return mapped;
14cf11af6cf608 arch/powerpc/mm/4xx_mmu.c Paul Mackerras 2005-09-26 142 }
cd3db0c4ca3d23 arch/powerpc/mm/40x_mmu.c Benjamin Herrenschmidt 2010-07-06 143
:::::: The code at line 107 was first introduced by commit
:::::: 0b1c524caaae2428b20e714297243e5551251eb5 powerpc/32: refactor pmd_offset(pud_offset(pgd_offset...
:::::: TO: Christophe Leroy <christophe.leroy@c-s.fr>
:::::: CC: Michael Ellerman <mpe@ellerman.id.au>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 15348 bytes --]
^ permalink raw reply
* Re: [PATCH 1/5] drivers/powerpc: Replace _ALIGN_UP() by ALIGN()
From: Joel Stanley @ 2020-04-21 0:49 UTC (permalink / raw)
To: Christophe Leroy
Cc: alsa-devel, kvm, Linux Kernel Mailing List, dri-devel,
Paul Mackerras, linux-fbdev, linuxppc-dev
In-Reply-To: <a5945463f86c984151962a475a3ee56a2893e85d.1587407777.git.christophe.leroy@c-s.fr>
On Mon, 20 Apr 2020 at 18:37, Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> _ALIGN_UP() is specific to powerpc
> ALIGN() is generic and does the same
>
> Replace _ALIGN_UP() by ALIGN()
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
I was curious, so I expanded out the kernel one. Here's the diff:
- (((addr)+((size)-1))&(~((typeof(addr))(size)-1)))
+ (((addr)+((typeof(addr))(size) - 1))&~((typeof(addr))(size)-1))
So it adds a cast, but aside from that it's the same.
Reviewed-by: Joel Stanley <joel@jms.id.au>
> ---
> drivers/ps3/ps3-lpm.c | 6 +++---
> drivers/vfio/pci/vfio_pci_nvlink2.c | 2 +-
> drivers/video/fbdev/ps3fb.c | 4 ++--
> sound/ppc/snd_ps3.c | 2 +-
> 4 files changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c
> index 83c45659bc9d..064b5884ba13 100644
> --- a/drivers/ps3/ps3-lpm.c
> +++ b/drivers/ps3/ps3-lpm.c
> @@ -1096,8 +1096,8 @@ int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
> lpm_priv->tb_cache_internal = NULL;
> lpm_priv->tb_cache = NULL;
> } else if (tb_cache) {
> - if (tb_cache != (void *)_ALIGN_UP((unsigned long)tb_cache, 128)
> - || tb_cache_size != _ALIGN_UP(tb_cache_size, 128)) {
> + if (tb_cache != (void *)ALIGN((unsigned long)tb_cache, 128)
> + || tb_cache_size != ALIGN(tb_cache_size, 128)) {
> dev_err(sbd_core(), "%s:%u: unaligned tb_cache\n",
> __func__, __LINE__);
> result = -EINVAL;
> @@ -1116,7 +1116,7 @@ int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
> result = -ENOMEM;
> goto fail_malloc;
> }
> - lpm_priv->tb_cache = (void *)_ALIGN_UP(
> + lpm_priv->tb_cache = (void *)ALIGN(
> (unsigned long)lpm_priv->tb_cache_internal, 128);
> }
>
> diff --git a/drivers/vfio/pci/vfio_pci_nvlink2.c b/drivers/vfio/pci/vfio_pci_nvlink2.c
> index ed20d73cc27c..65c61710c0e9 100644
> --- a/drivers/vfio/pci/vfio_pci_nvlink2.c
> +++ b/drivers/vfio/pci/vfio_pci_nvlink2.c
> @@ -67,7 +67,7 @@ static size_t vfio_pci_nvgpu_rw(struct vfio_pci_device *vdev,
> *
> * This is not fast path anyway.
> */
> - sizealigned = _ALIGN_UP(posoff + count, PAGE_SIZE);
> + sizealigned = ALIGN(posoff + count, PAGE_SIZE);
> ptr = ioremap_cache(data->gpu_hpa + posaligned, sizealigned);
> if (!ptr)
> return -EFAULT;
> diff --git a/drivers/video/fbdev/ps3fb.c b/drivers/video/fbdev/ps3fb.c
> index 834f63edf700..9df78fb77267 100644
> --- a/drivers/video/fbdev/ps3fb.c
> +++ b/drivers/video/fbdev/ps3fb.c
> @@ -44,7 +44,7 @@
> #define GPU_CMD_BUF_SIZE (2 * 1024 * 1024)
> #define GPU_FB_START (64 * 1024)
> #define GPU_IOIF (0x0d000000UL)
> -#define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64)
> +#define GPU_ALIGN_UP(x) ALIGN((x), 64)
> #define GPU_MAX_LINE_LENGTH (65536 - 64)
>
> #define GPU_INTR_STATUS_VSYNC_0 0 /* vsync on head A */
> @@ -1015,7 +1015,7 @@ static int ps3fb_probe(struct ps3_system_bus_device *dev)
> }
> #endif
>
> - max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF;
> + max_ps3fb_size = ALIGN(GPU_IOIF, 256*1024*1024) - GPU_IOIF;
> if (ps3fb_videomemory.size > max_ps3fb_size) {
> dev_info(&dev->core, "Limiting ps3fb mem size to %lu bytes\n",
> max_ps3fb_size);
> diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
> index 6d2a33b8faa0..b8161a08f2ca 100644
> --- a/sound/ppc/snd_ps3.c
> +++ b/sound/ppc/snd_ps3.c
> @@ -926,7 +926,7 @@ static int snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
> PAGE_SHIFT, /* use system page size */
> 0, /* dma type; not used */
> NULL,
> - _ALIGN_UP(SND_PS3_DMA_REGION_SIZE, PAGE_SIZE));
> + ALIGN(SND_PS3_DMA_REGION_SIZE, PAGE_SIZE));
> dev->d_region->ioid = PS3_AUDIO_IOID;
>
> ret = ps3_dma_region_create(dev->d_region);
> --
> 2.25.0
>
^ permalink raw reply
* Re: [PATCH 2/5] powerpc: Replace _ALIGN_DOWN() by ALIGN_DOWN()
From: Joel Stanley @ 2020-04-21 1:04 UTC (permalink / raw)
To: Christophe Leroy
Cc: linux-fbdev, kvm, Linux Kernel Mailing List, dri-devel,
Paul Mackerras, alsa-devel, linuxppc-dev
In-Reply-To: <3911a86d6b5bfa7ad88cd7c82416fbe6bb47e793.1587407777.git.christophe.leroy@c-s.fr>
On Mon, 20 Apr 2020 at 18:38, Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> _ALIGN_DOWN() is specific to powerpc
> ALIGN_DOWN() is generic and does the same
>
> Replace _ALIGN_DOWN() by ALIGN_DOWN()
This one is a bit less obvious. It becomes (leaving the typeof's alone
for clarity):
-((addr)&(~((typeof(addr))(size)-1)))
+((((addr) - ((size) - 1)) + ((typeof(addr))(size) - 1)) &
~((typeof(addr))(size)-1))
Which I assume the compiler will sort out?
Reviewed-by: Joel Stanley <joel@jms.id.au>
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
> ---
> arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +-
> arch/powerpc/include/asm/nohash/32/pgtable.h | 2 +-
> arch/powerpc/kernel/pci_64.c | 2 +-
> arch/powerpc/kernel/prom.c | 6 +++---
> arch/powerpc/kernel/prom_init.c | 8 ++++----
> arch/powerpc/mm/book3s64/hash_tlb.c | 4 ++--
> arch/powerpc/mm/init_64.c | 4 ++--
> arch/powerpc/platforms/powernv/opal-fadump.c | 2 +-
> arch/powerpc/platforms/powernv/pci-ioda.c | 2 +-
> arch/powerpc/platforms/ps3/mm.c | 14 +++++++-------
> arch/powerpc/platforms/pseries/rtas-fadump.c | 2 +-
> 11 files changed, 24 insertions(+), 24 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
> index 7549393c4c43..53b5c93eaf5d 100644
> --- a/arch/powerpc/include/asm/book3s/32/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
> @@ -195,7 +195,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
> #endif
>
> #ifdef CONFIG_KASAN_VMALLOC
> -#define VMALLOC_END _ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
> +#define VMALLOC_END ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
> #else
> #define VMALLOC_END ioremap_bot
> #endif
> diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
> index b04ba257fddb..5b4d4c4297e1 100644
> --- a/arch/powerpc/include/asm/nohash/32/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
> @@ -116,7 +116,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
> #endif
>
> #ifdef CONFIG_KASAN_VMALLOC
> -#define VMALLOC_END _ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
> +#define VMALLOC_END ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
> #else
> #define VMALLOC_END ioremap_bot
> #endif
> diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
> index f83d1f69b1dd..e5d05af5a9af 100644
> --- a/arch/powerpc/kernel/pci_64.c
> +++ b/arch/powerpc/kernel/pci_64.c
> @@ -130,7 +130,7 @@ static int pcibios_map_phb_io_space(struct pci_controller *hose)
> unsigned long size_page;
> unsigned long io_virt_offset;
>
> - phys_page = _ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
> + phys_page = ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
> size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE);
>
> /* Make sure IO area address is clear */
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index 6620f37abe73..10b5d5eafd34 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -96,7 +96,7 @@ static inline int overlaps_initrd(unsigned long start, unsigned long size)
> if (!initrd_start)
> return 0;
>
> - return (start + size) > _ALIGN_DOWN(initrd_start, PAGE_SIZE) &&
> + return (start + size) > ALIGN_DOWN(initrd_start, PAGE_SIZE) &&
> start <= _ALIGN_UP(initrd_end, PAGE_SIZE);
> #else
> return 0;
> @@ -623,9 +623,9 @@ static void __init early_reserve_mem(void)
> #ifdef CONFIG_BLK_DEV_INITRD
> /* Then reserve the initrd, if any */
> if (initrd_start && (initrd_end > initrd_start)) {
> - memblock_reserve(_ALIGN_DOWN(__pa(initrd_start), PAGE_SIZE),
> + memblock_reserve(ALIGN_DOWN(__pa(initrd_start), PAGE_SIZE),
> _ALIGN_UP(initrd_end, PAGE_SIZE) -
> - _ALIGN_DOWN(initrd_start, PAGE_SIZE));
> + ALIGN_DOWN(initrd_start, PAGE_SIZE));
> }
> #endif /* CONFIG_BLK_DEV_INITRD */
>
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index 806be751c336..4cf5958eebd4 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -1500,7 +1500,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align,
>
> if (highmem) {
> /* Carve out storage for the TCE table. */
> - addr = _ALIGN_DOWN(alloc_top_high - size, align);
> + addr = ALIGN_DOWN(alloc_top_high - size, align);
> if (addr <= alloc_bottom)
> return 0;
> /* Will we bump into the RMO ? If yes, check out that we
> @@ -1518,9 +1518,9 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align,
> goto bail;
> }
>
> - base = _ALIGN_DOWN(alloc_top - size, align);
> + base = ALIGN_DOWN(alloc_top - size, align);
> for (; base > alloc_bottom;
> - base = _ALIGN_DOWN(base - 0x100000, align)) {
> + base = ALIGN_DOWN(base - 0x100000, align)) {
> prom_debug(" trying: 0x%lx\n\r", base);
> addr = (unsigned long)prom_claim(base, size, 0);
> if (addr != PROM_ERROR && addr != 0)
> @@ -1586,7 +1586,7 @@ static void __init reserve_mem(u64 base, u64 size)
> * have our terminator with "size" set to 0 since we are
> * dumb and just copy this entire array to the boot params
> */
> - base = _ALIGN_DOWN(base, PAGE_SIZE);
> + base = ALIGN_DOWN(base, PAGE_SIZE);
> top = _ALIGN_UP(top, PAGE_SIZE);
> size = top - base;
>
> diff --git a/arch/powerpc/mm/book3s64/hash_tlb.c b/arch/powerpc/mm/book3s64/hash_tlb.c
> index 4a70d8dd39cd..2242d022b620 100644
> --- a/arch/powerpc/mm/book3s64/hash_tlb.c
> +++ b/arch/powerpc/mm/book3s64/hash_tlb.c
> @@ -196,7 +196,7 @@ void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
> int hugepage_shift;
> unsigned long flags;
>
> - start = _ALIGN_DOWN(start, PAGE_SIZE);
> + start = ALIGN_DOWN(start, PAGE_SIZE);
> end = _ALIGN_UP(end, PAGE_SIZE);
>
> BUG_ON(!mm->pgd);
> @@ -238,7 +238,7 @@ void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd, unsigned long addr)
> pte_t *start_pte;
> unsigned long flags;
>
> - addr = _ALIGN_DOWN(addr, PMD_SIZE);
> + addr = ALIGN_DOWN(addr, PMD_SIZE);
> /*
> * Note: Normally, we should only ever use a batch within a
> * PTE locked section. This violates the rule, but will work
> diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
> index 4002ced3596f..c7ce4ec5060e 100644
> --- a/arch/powerpc/mm/init_64.c
> +++ b/arch/powerpc/mm/init_64.c
> @@ -203,7 +203,7 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
> unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
>
> /* Align to the page size of the linear mapping. */
> - start = _ALIGN_DOWN(start, page_size);
> + start = ALIGN_DOWN(start, page_size);
>
> pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node);
>
> @@ -292,7 +292,7 @@ void __ref vmemmap_free(unsigned long start, unsigned long end,
> unsigned long alt_start = ~0, alt_end = ~0;
> unsigned long base_pfn;
>
> - start = _ALIGN_DOWN(start, page_size);
> + start = ALIGN_DOWN(start, page_size);
> if (altmap) {
> alt_start = altmap->base_pfn;
> alt_end = altmap->base_pfn + altmap->reserve +
> diff --git a/arch/powerpc/platforms/powernv/opal-fadump.c b/arch/powerpc/platforms/powernv/opal-fadump.c
> index d361d37d975f..9a360ced663b 100644
> --- a/arch/powerpc/platforms/powernv/opal-fadump.c
> +++ b/arch/powerpc/platforms/powernv/opal-fadump.c
> @@ -671,7 +671,7 @@ void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
> * Firmware supports 32-bit field for size. Align it to PAGE_SIZE
> * and request firmware to copy multiple kernel boot memory regions.
> */
> - fadump_conf->max_copy_size = _ALIGN_DOWN(U32_MAX, PAGE_SIZE);
> + fadump_conf->max_copy_size = ALIGN_DOWN(U32_MAX, PAGE_SIZE);
>
> /*
> * Check if dump has been initiated on last reboot.
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
> index 57d3a6af1d52..276b011cd45d 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -264,7 +264,7 @@ static void pnv_ioda_reserve_dev_m64_pe(struct pci_dev *pdev,
> if (!r->parent || !pnv_pci_is_m64(phb, r))
> continue;
>
> - start = _ALIGN_DOWN(r->start - base, sgsz);
> + start = ALIGN_DOWN(r->start - base, sgsz);
> end = _ALIGN_UP(r->end - base, sgsz);
> for (segno = start / sgsz; segno < end / sgsz; segno++) {
> if (pe_bitmap)
> diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
> index 423be34f0f5f..71ed37f7f475 100644
> --- a/arch/powerpc/platforms/ps3/mm.c
> +++ b/arch/powerpc/platforms/ps3/mm.c
> @@ -263,7 +263,7 @@ static int ps3_mm_region_create(struct mem_region *r, unsigned long size)
> int result;
> u64 muid;
>
> - r->size = _ALIGN_DOWN(size, 1 << PAGE_SHIFT_16M);
> + r->size = ALIGN_DOWN(size, 1 << PAGE_SHIFT_16M);
>
> DBG("%s:%d requested %lxh\n", __func__, __LINE__, size);
> DBG("%s:%d actual %llxh\n", __func__, __LINE__, r->size);
> @@ -394,7 +394,7 @@ static struct dma_chunk * dma_find_chunk(struct ps3_dma_region *r,
> unsigned long bus_addr, unsigned long len)
> {
> struct dma_chunk *c;
> - unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size);
> + unsigned long aligned_bus = ALIGN_DOWN(bus_addr, 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len+bus_addr-aligned_bus,
> 1 << r->page_size);
>
> @@ -423,7 +423,7 @@ static struct dma_chunk *dma_find_chunk_lpar(struct ps3_dma_region *r,
> unsigned long lpar_addr, unsigned long len)
> {
> struct dma_chunk *c;
> - unsigned long aligned_lpar = _ALIGN_DOWN(lpar_addr, 1 << r->page_size);
> + unsigned long aligned_lpar = ALIGN_DOWN(lpar_addr, 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len + lpar_addr - aligned_lpar,
> 1 << r->page_size);
>
> @@ -775,7 +775,7 @@ static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
> struct dma_chunk *c;
> unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
> : virt_addr;
> - unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
> + unsigned long aligned_phys = ALIGN_DOWN(phys_addr, 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
> 1 << r->page_size);
> *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
> @@ -830,7 +830,7 @@ static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
> struct dma_chunk *c;
> unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
> : virt_addr;
> - unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
> + unsigned long aligned_phys = ALIGN_DOWN(phys_addr, 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
> 1 << r->page_size);
>
> @@ -889,7 +889,7 @@ static int dma_sb_unmap_area(struct ps3_dma_region *r, dma_addr_t bus_addr,
> c = dma_find_chunk(r, bus_addr, len);
>
> if (!c) {
> - unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
> + unsigned long aligned_bus = ALIGN_DOWN(bus_addr,
> 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len + bus_addr
> - aligned_bus, 1 << r->page_size);
> @@ -926,7 +926,7 @@ static int dma_ioc0_unmap_area(struct ps3_dma_region *r,
> c = dma_find_chunk(r, bus_addr, len);
>
> if (!c) {
> - unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
> + unsigned long aligned_bus = ALIGN_DOWN(bus_addr,
> 1 << r->page_size);
> unsigned long aligned_len = _ALIGN_UP(len + bus_addr
> - aligned_bus,
> diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.c b/arch/powerpc/platforms/pseries/rtas-fadump.c
> index 70c3013fdd07..81343908ed33 100644
> --- a/arch/powerpc/platforms/pseries/rtas-fadump.c
> +++ b/arch/powerpc/platforms/pseries/rtas-fadump.c
> @@ -506,7 +506,7 @@ void __init rtas_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
> fadump_conf->fadump_supported = 1;
>
> /* Firmware supports 64-bit value for size, align it to pagesize. */
> - fadump_conf->max_copy_size = _ALIGN_DOWN(U64_MAX, PAGE_SIZE);
> + fadump_conf->max_copy_size = ALIGN_DOWN(U64_MAX, PAGE_SIZE);
>
> /*
> * The 'ibm,kernel-dump' rtas node is present only if there is
> --
> 2.25.0
>
^ permalink raw reply
* Re: [PATCH 3/5] powerpc: Replace _ALIGN_UP() by ALIGN()
From: Joel Stanley @ 2020-04-21 1:04 UTC (permalink / raw)
To: Christophe Leroy
Cc: linux-fbdev, kvm, Linux Kernel Mailing List, dri-devel,
Paul Mackerras, alsa-devel, linuxppc-dev
In-Reply-To: <8a6d7e45f7904c73a0af539642d3962e2a3c7268.1587407777.git.christophe.leroy@c-s.fr>
On Mon, 20 Apr 2020 at 18:39, Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> _ALIGN_UP() is specific to powerpc
> ALIGN() is generic and does the same
>
> Replace _ALIGN_UP() by ALIGN()
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: Joel Stanley <joel@jms.id.au>
> ---
> arch/powerpc/include/asm/iommu.h | 4 ++--
> arch/powerpc/kernel/head_booke.h | 2 +-
> arch/powerpc/kernel/nvram_64.c | 4 ++--
> arch/powerpc/kernel/pci_64.c | 2 +-
> arch/powerpc/kernel/prom.c | 4 ++--
> arch/powerpc/kernel/prom_init.c | 8 ++++----
> arch/powerpc/kvm/book3s_64_vio_hv.c | 2 +-
> arch/powerpc/mm/book3s64/hash_tlb.c | 2 +-
> arch/powerpc/mm/book3s64/radix_pgtable.c | 2 +-
> arch/powerpc/mm/slice.c | 2 +-
> arch/powerpc/platforms/cell/iommu.c | 6 +++---
> arch/powerpc/platforms/powermac/bootx_init.c | 10 +++++-----
> arch/powerpc/platforms/powernv/pci-ioda.c | 8 ++++----
> arch/powerpc/platforms/ps3/mm.c | 16 ++++++++--------
> arch/powerpc/platforms/ps3/setup.c | 2 +-
> 15 files changed, 37 insertions(+), 37 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
> index 350101e11ddb..5032f1593299 100644
> --- a/arch/powerpc/include/asm/iommu.h
> +++ b/arch/powerpc/include/asm/iommu.h
> @@ -22,11 +22,11 @@
> #define IOMMU_PAGE_SHIFT_4K 12
> #define IOMMU_PAGE_SIZE_4K (ASM_CONST(1) << IOMMU_PAGE_SHIFT_4K)
> #define IOMMU_PAGE_MASK_4K (~((1 << IOMMU_PAGE_SHIFT_4K) - 1))
> -#define IOMMU_PAGE_ALIGN_4K(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE_4K)
> +#define IOMMU_PAGE_ALIGN_4K(addr) ALIGN(addr, IOMMU_PAGE_SIZE_4K)
>
> #define IOMMU_PAGE_SIZE(tblptr) (ASM_CONST(1) << (tblptr)->it_page_shift)
> #define IOMMU_PAGE_MASK(tblptr) (~((1 << (tblptr)->it_page_shift) - 1))
> -#define IOMMU_PAGE_ALIGN(addr, tblptr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE(tblptr))
> +#define IOMMU_PAGE_ALIGN(addr, tblptr) ALIGN(addr, IOMMU_PAGE_SIZE(tblptr))
>
> /* Boot time flags */
> extern int iommu_is_off;
> diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
> index bd2e5ed8dd50..18f87bf9e32b 100644
> --- a/arch/powerpc/kernel/head_booke.h
> +++ b/arch/powerpc/kernel/head_booke.h
> @@ -534,7 +534,7 @@ struct exception_regs {
> };
>
> /* ensure this structure is always sized to a multiple of the stack alignment */
> -#define STACK_EXC_LVL_FRAME_SIZE _ALIGN_UP(sizeof (struct exception_regs), 16)
> +#define STACK_EXC_LVL_FRAME_SIZE ALIGN(sizeof (struct exception_regs), 16)
>
> #endif /* __ASSEMBLY__ */
> #endif /* __HEAD_BOOKE_H__ */
> diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
> index fb4f61096613..314780e8ef78 100644
> --- a/arch/powerpc/kernel/nvram_64.c
> +++ b/arch/powerpc/kernel/nvram_64.c
> @@ -854,8 +854,8 @@ loff_t __init nvram_create_partition(const char *name, int sig,
> BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16);
>
> /* Convert sizes from bytes to blocks */
> - req_size = _ALIGN_UP(req_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
> - min_size = _ALIGN_UP(min_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
> + req_size = ALIGN(req_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
> + min_size = ALIGN(min_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN;
>
> /* If no minimum size specified, make it the same as the
> * requested size
> diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
> index e5d05af5a9af..ff8e3fbdf663 100644
> --- a/arch/powerpc/kernel/pci_64.c
> +++ b/arch/powerpc/kernel/pci_64.c
> @@ -131,7 +131,7 @@ static int pcibios_map_phb_io_space(struct pci_controller *hose)
> unsigned long io_virt_offset;
>
> phys_page = ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
> - size_page = _ALIGN_UP(hose->pci_io_size, PAGE_SIZE);
> + size_page = ALIGN(hose->pci_io_size, PAGE_SIZE);
>
> /* Make sure IO area address is clear */
> hose->io_base_alloc = NULL;
> diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
> index 10b5d5eafd34..1dcf0e214a22 100644
> --- a/arch/powerpc/kernel/prom.c
> +++ b/arch/powerpc/kernel/prom.c
> @@ -97,7 +97,7 @@ static inline int overlaps_initrd(unsigned long start, unsigned long size)
> return 0;
>
> return (start + size) > ALIGN_DOWN(initrd_start, PAGE_SIZE) &&
> - start <= _ALIGN_UP(initrd_end, PAGE_SIZE);
> + start <= ALIGN(initrd_end, PAGE_SIZE);
> #else
> return 0;
> #endif
> @@ -624,7 +624,7 @@ static void __init early_reserve_mem(void)
> /* Then reserve the initrd, if any */
> if (initrd_start && (initrd_end > initrd_start)) {
> memblock_reserve(ALIGN_DOWN(__pa(initrd_start), PAGE_SIZE),
> - _ALIGN_UP(initrd_end, PAGE_SIZE) -
> + ALIGN(initrd_end, PAGE_SIZE) -
> ALIGN_DOWN(initrd_start, PAGE_SIZE));
> }
> #endif /* CONFIG_BLK_DEV_INITRD */
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index 4cf5958eebd4..3a5a7db4564f 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -1449,18 +1449,18 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align)
> unsigned long addr = 0;
>
> if (align)
> - base = _ALIGN_UP(base, align);
> + base = ALIGN(base, align);
> prom_debug("%s(%lx, %lx)\n", __func__, size, align);
> if (ram_top == 0)
> prom_panic("alloc_up() called with mem not initialized\n");
>
> if (align)
> - base = _ALIGN_UP(alloc_bottom, align);
> + base = ALIGN(alloc_bottom, align);
> else
> base = alloc_bottom;
>
> for(; (base + size) <= alloc_top;
> - base = _ALIGN_UP(base + 0x100000, align)) {
> + base = ALIGN(base + 0x100000, align)) {
> prom_debug(" trying: 0x%lx\n\r", base);
> addr = (unsigned long)prom_claim(base, size, 0);
> if (addr != PROM_ERROR && addr != 0)
> @@ -1587,7 +1587,7 @@ static void __init reserve_mem(u64 base, u64 size)
> * dumb and just copy this entire array to the boot params
> */
> base = ALIGN_DOWN(base, PAGE_SIZE);
> - top = _ALIGN_UP(top, PAGE_SIZE);
> + top = ALIGN(top, PAGE_SIZE);
> size = top - base;
>
> if (cnt >= (MEM_RESERVE_MAP_SIZE - 1))
> diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
> index 6fcaf1fa8e02..2d231eb5884a 100644
> --- a/arch/powerpc/kvm/book3s_64_vio_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
> @@ -208,7 +208,7 @@ static long kvmppc_rm_ioba_validate(struct kvmppc_spapr_tce_table *stt,
>
> idx = (ioba >> stt->page_shift) - stt->offset;
> sttpage = idx / TCES_PER_PAGE;
> - sttpages = _ALIGN_UP(idx % TCES_PER_PAGE + npages, TCES_PER_PAGE) /
> + sttpages = ALIGN(idx % TCES_PER_PAGE + npages, TCES_PER_PAGE) /
> TCES_PER_PAGE;
> for (i = sttpage; i < sttpage + sttpages; ++i)
> if (!stt->pages[i])
> diff --git a/arch/powerpc/mm/book3s64/hash_tlb.c b/arch/powerpc/mm/book3s64/hash_tlb.c
> index 2242d022b620..081940b85e24 100644
> --- a/arch/powerpc/mm/book3s64/hash_tlb.c
> +++ b/arch/powerpc/mm/book3s64/hash_tlb.c
> @@ -197,7 +197,7 @@ void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
> unsigned long flags;
>
> start = ALIGN_DOWN(start, PAGE_SIZE);
> - end = _ALIGN_UP(end, PAGE_SIZE);
> + end = ALIGN(end, PAGE_SIZE);
>
> BUG_ON(!mm->pgd);
>
> diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c
> index 8f9edf07063a..4bdfc8dff87d 100644
> --- a/arch/powerpc/mm/book3s64/radix_pgtable.c
> +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c
> @@ -261,7 +261,7 @@ static int __meminit create_physical_mapping(unsigned long start,
> pgprot_t prot;
> int psize;
>
> - start = _ALIGN_UP(start, PAGE_SIZE);
> + start = ALIGN(start, PAGE_SIZE);
> for (addr = start; addr < end; addr += mapping_size) {
> unsigned long gap, previous_size;
> int rc;
> diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
> index dffe1a45b6ed..82b45b1cb973 100644
> --- a/arch/powerpc/mm/slice.c
> +++ b/arch/powerpc/mm/slice.c
> @@ -478,7 +478,7 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
>
> /* If hint, make sure it matches our alignment restrictions */
> if (!fixed && addr) {
> - addr = _ALIGN_UP(addr, page_size);
> + addr = ALIGN(addr, page_size);
> slice_dbg(" aligned addr=%lx\n", addr);
> /* Ignore hint if it's too large or overlaps a VMA */
> if (addr > high_limit - len || addr < mmap_min_addr ||
> diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
> index ca9ffc1c8685..2124831cf57c 100644
> --- a/arch/powerpc/platforms/cell/iommu.c
> +++ b/arch/powerpc/platforms/cell/iommu.c
> @@ -943,7 +943,7 @@ static int __init cell_iommu_fixed_mapping_init(void)
> fbase = max(fbase, dbase + dsize);
> }
>
> - fbase = _ALIGN_UP(fbase, 1 << IO_SEGMENT_SHIFT);
> + fbase = ALIGN(fbase, 1 << IO_SEGMENT_SHIFT);
> fsize = memblock_phys_mem_size();
>
> if ((fbase + fsize) <= 0x800000000ul)
> @@ -963,8 +963,8 @@ static int __init cell_iommu_fixed_mapping_init(void)
> hend = hbase + htab_size_bytes;
>
> /* The window must start and end on a segment boundary */
> - if ((hbase != _ALIGN_UP(hbase, 1 << IO_SEGMENT_SHIFT)) ||
> - (hend != _ALIGN_UP(hend, 1 << IO_SEGMENT_SHIFT))) {
> + if ((hbase != ALIGN(hbase, 1 << IO_SEGMENT_SHIFT)) ||
> + (hend != ALIGN(hend, 1 << IO_SEGMENT_SHIFT))) {
> pr_debug("iommu: hash window not segment aligned\n");
> return -1;
> }
> diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
> index af309ee99114..c3374a90952f 100644
> --- a/arch/powerpc/platforms/powermac/bootx_init.c
> +++ b/arch/powerpc/platforms/powermac/bootx_init.c
> @@ -108,7 +108,7 @@ static void * __init bootx_early_getprop(unsigned long base,
>
> #define dt_push_token(token, mem) \
> do { \
> - *(mem) = _ALIGN_UP(*(mem),4); \
> + *(mem) = ALIGN(*(mem),4); \
> *((u32 *)*(mem)) = token; \
> *(mem) += 4; \
> } while(0)
> @@ -150,7 +150,7 @@ static void __init bootx_dt_add_prop(char *name, void *data, int size,
> /* push property content */
> if (size && data) {
> memcpy((void *)*mem_end, data, size);
> - *mem_end = _ALIGN_UP(*mem_end + size, 4);
> + *mem_end = ALIGN(*mem_end + size, 4);
> }
> }
>
> @@ -303,7 +303,7 @@ static void __init bootx_scan_dt_build_struct(unsigned long base,
> *lp++ = *p;
> }
> *lp = 0;
> - *mem_end = _ALIGN_UP((unsigned long)lp + 1, 4);
> + *mem_end = ALIGN((unsigned long)lp + 1, 4);
>
> /* get and store all properties */
> while (*ppp) {
> @@ -356,11 +356,11 @@ static unsigned long __init bootx_flatten_dt(unsigned long start)
> /* Start using memory after the big blob passed by BootX, get
> * some space for the header
> */
> - mem_start = mem_end = _ALIGN_UP(((unsigned long)bi) + start, 4);
> + mem_start = mem_end = ALIGN(((unsigned long)bi) + start, 4);
> DBG("Boot params header at: %x\n", mem_start);
> hdr = (struct boot_param_header *)mem_start;
> mem_end += sizeof(struct boot_param_header);
> - rsvmap = (u64 *)(_ALIGN_UP(mem_end, 8));
> + rsvmap = (u64 *)(ALIGN(mem_end, 8));
> hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - mem_start;
> mem_end = ((unsigned long)rsvmap) + 8 * sizeof(u64);
>
> diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
> index 276b011cd45d..d1a16ebc31bb 100644
> --- a/arch/powerpc/platforms/powernv/pci-ioda.c
> +++ b/arch/powerpc/platforms/powernv/pci-ioda.c
> @@ -265,7 +265,7 @@ static void pnv_ioda_reserve_dev_m64_pe(struct pci_dev *pdev,
> continue;
>
> start = ALIGN_DOWN(r->start - base, sgsz);
> - end = _ALIGN_UP(r->end - base, sgsz);
> + end = ALIGN(r->end - base, sgsz);
> for (segno = start / sgsz; segno < end / sgsz; segno++) {
> if (pe_bitmap)
> set_bit(segno, pe_bitmap);
> @@ -361,7 +361,7 @@ static struct pnv_ioda_pe *pnv_ioda_pick_m64_pe(struct pci_bus *bus, bool all)
> return NULL;
>
> /* Allocate bitmap */
> - size = _ALIGN_UP(phb->ioda.total_pe_num / 8, sizeof(unsigned long));
> + size = ALIGN(phb->ioda.total_pe_num / 8, sizeof(unsigned long));
> pe_alloc = kzalloc(size, GFP_KERNEL);
> if (!pe_alloc) {
> pr_warn("%s: Out of memory !\n",
> @@ -2537,7 +2537,7 @@ unsigned long pnv_pci_ioda2_get_table_size(__u32 page_shift,
> direct_table_size = 1UL << table_shift;
>
> for ( ; levels; --levels) {
> - bytes += _ALIGN_UP(tce_table_size, direct_table_size);
> + bytes += ALIGN(tce_table_size, direct_table_size);
>
> tce_table_size /= direct_table_size;
> tce_table_size <<= 3;
> @@ -3863,7 +3863,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
> PNV_IODA1_DMA32_SEGSIZE;
>
> /* Allocate aux data & arrays. We don't have IO ports on PHB3 */
> - size = _ALIGN_UP(max_t(unsigned, phb->ioda.total_pe_num, 8) / 8,
> + size = ALIGN(max_t(unsigned, phb->ioda.total_pe_num, 8) / 8,
> sizeof(unsigned long));
> m64map_off = size;
> size += phb->ioda.total_pe_num * sizeof(phb->ioda.m64_segmap[0]);
> diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
> index 71ed37f7f475..b83f2c851b40 100644
> --- a/arch/powerpc/platforms/ps3/mm.c
> +++ b/arch/powerpc/platforms/ps3/mm.c
> @@ -395,7 +395,7 @@ static struct dma_chunk * dma_find_chunk(struct ps3_dma_region *r,
> {
> struct dma_chunk *c;
> unsigned long aligned_bus = ALIGN_DOWN(bus_addr, 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len+bus_addr-aligned_bus,
> + unsigned long aligned_len = ALIGN(len+bus_addr-aligned_bus,
> 1 << r->page_size);
>
> list_for_each_entry(c, &r->chunk_list.head, link) {
> @@ -424,7 +424,7 @@ static struct dma_chunk *dma_find_chunk_lpar(struct ps3_dma_region *r,
> {
> struct dma_chunk *c;
> unsigned long aligned_lpar = ALIGN_DOWN(lpar_addr, 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len + lpar_addr - aligned_lpar,
> + unsigned long aligned_len = ALIGN(len + lpar_addr - aligned_lpar,
> 1 << r->page_size);
>
> list_for_each_entry(c, &r->chunk_list.head, link) {
> @@ -776,7 +776,7 @@ static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
> unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
> : virt_addr;
> unsigned long aligned_phys = ALIGN_DOWN(phys_addr, 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
> + unsigned long aligned_len = ALIGN(len + phys_addr - aligned_phys,
> 1 << r->page_size);
> *bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
>
> @@ -831,7 +831,7 @@ static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
> unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
> : virt_addr;
> unsigned long aligned_phys = ALIGN_DOWN(phys_addr, 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
> + unsigned long aligned_len = ALIGN(len + phys_addr - aligned_phys,
> 1 << r->page_size);
>
> DBG(KERN_ERR "%s: vaddr=%#lx, len=%#lx\n", __func__,
> @@ -891,7 +891,7 @@ static int dma_sb_unmap_area(struct ps3_dma_region *r, dma_addr_t bus_addr,
> if (!c) {
> unsigned long aligned_bus = ALIGN_DOWN(bus_addr,
> 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len + bus_addr
> + unsigned long aligned_len = ALIGN(len + bus_addr
> - aligned_bus, 1 << r->page_size);
> DBG("%s:%d: not found: bus_addr %llxh\n",
> __func__, __LINE__, bus_addr);
> @@ -928,7 +928,7 @@ static int dma_ioc0_unmap_area(struct ps3_dma_region *r,
> if (!c) {
> unsigned long aligned_bus = ALIGN_DOWN(bus_addr,
> 1 << r->page_size);
> - unsigned long aligned_len = _ALIGN_UP(len + bus_addr
> + unsigned long aligned_len = ALIGN(len + bus_addr
> - aligned_bus,
> 1 << r->page_size);
> DBG("%s:%d: not found: bus_addr %llxh\n",
> @@ -974,7 +974,7 @@ static int dma_sb_region_create_linear(struct ps3_dma_region *r)
> pr_info("%s:%d: forcing 16M pages for linear map\n",
> __func__, __LINE__);
> r->page_size = PS3_DMA_16M;
> - r->len = _ALIGN_UP(r->len, 1 << r->page_size);
> + r->len = ALIGN(r->len, 1 << r->page_size);
> }
> }
>
> @@ -1125,7 +1125,7 @@ int ps3_dma_region_init(struct ps3_system_bus_device *dev,
> r->offset = lpar_addr;
> if (r->offset >= map.rm.size)
> r->offset -= map.r1.offset;
> - r->len = len ? len : _ALIGN_UP(map.total, 1 << r->page_size);
> + r->len = len ? len : ALIGN(map.total, 1 << r->page_size);
>
> switch (dev->dev_type) {
> case PS3_DEVICE_TYPE_SB:
> diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
> index b29368931c56..e9ae5dd03593 100644
> --- a/arch/powerpc/platforms/ps3/setup.c
> +++ b/arch/powerpc/platforms/ps3/setup.c
> @@ -138,7 +138,7 @@ static int __init early_parse_ps3fb(char *p)
> if (!p)
> return 1;
>
> - ps3fb_videomemory.size = _ALIGN_UP(memparse(p, &p),
> + ps3fb_videomemory.size = ALIGN(memparse(p, &p),
> ps3fb_videomemory.align);
> return 0;
> }
> --
> 2.25.0
>
^ permalink raw reply
* Re: [PATCH 5/5] powerpc: Remove _ALIGN_UP(), _ALIGN_DOWN() and _ALIGN()
From: Joel Stanley @ 2020-04-21 1:04 UTC (permalink / raw)
To: Christophe Leroy
Cc: linux-fbdev, kvm, Linux Kernel Mailing List, dri-devel,
Paul Mackerras, alsa-devel, linuxppc-dev
In-Reply-To: <bb0a6081f7b95ee64ca20f92483e5b9661cbacb2.1587407777.git.christophe.leroy@c-s.fr>
On Mon, 20 Apr 2020 at 18:39, Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> These three powerpc macros have been replaced by
> equivalent generic macros and are not used anymore.
>
> Remove them.
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Reviewed-By: Joel Stanley <joel@jms.id.au>
riscv has a copy of these too that could probably be removed:
arch/riscv/include/asm/page.h:#define _ALIGN_UP(addr, size)
(((addr)+((size)-1))&(~((size)-1)))
arch/riscv/include/asm/page.h:#define _ALIGN(addr, size)
_ALIGN_UP(addr, size)
> ---
> arch/powerpc/include/asm/page.h | 7 -------
> 1 file changed, 7 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
> index 3ee8df0f66e0..a63fe6f3a0ff 100644
> --- a/arch/powerpc/include/asm/page.h
> +++ b/arch/powerpc/include/asm/page.h
> @@ -249,13 +249,6 @@ static inline bool pfn_valid(unsigned long pfn)
> #include <asm/page_32.h>
> #endif
>
> -/* align addr on a size boundary - adjust address up/down if needed */
> -#define _ALIGN_UP(addr, size) __ALIGN_KERNEL(addr, size)
> -#define _ALIGN_DOWN(addr, size) ((addr)&(~((typeof(addr))(size)-1)))
> -
> -/* align addr on a size boundary - adjust address up if needed */
> -#define _ALIGN(addr,size) _ALIGN_UP(addr,size)
> -
> /*
> * Don't compare things with KERNELBASE or PAGE_OFFSET to test for
> * "kernelness", use is_kernel_addr() - it should do what you want.
> --
> 2.25.0
>
^ permalink raw reply
* Re: [PATCH 4/5] powerpc: Replace _ALIGN() by ALIGN()
From: Joel Stanley @ 2020-04-21 1:11 UTC (permalink / raw)
To: Christophe Leroy
Cc: linux-fbdev, kvm, Linux Kernel Mailing List, dri-devel,
Paul Mackerras, alsa-devel, linuxppc-dev
In-Reply-To: <4006d9c8e69f8eaccee954899f6b5fb76240d00b.1587407777.git.christophe.leroy@c-s.fr>
On Mon, 20 Apr 2020 at 18:39, Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> _ALIGN() is specific to powerpc
> ALIGN() is generic and does the same
>
> Replace _ALIGN() by ALIGN()
>
> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: Joel Stanley <joel@jms.id.au>
> ---
> arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +-
> arch/powerpc/include/asm/nohash/32/pgtable.h | 2 +-
> arch/powerpc/kernel/prom_init.c | 8 ++++----
> arch/powerpc/platforms/powermac/bootx_init.c | 4 ++--
> 4 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
> index 53b5c93eaf5d..0d4bccb4b9f2 100644
> --- a/arch/powerpc/include/asm/book3s/32/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
> @@ -188,7 +188,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
> * memory shall not share segments.
> */
> #if defined(CONFIG_STRICT_KERNEL_RWX) && defined(CONFIG_MODULES)
> -#define VMALLOC_START ((_ALIGN((long)high_memory, 256L << 20) + VMALLOC_OFFSET) & \
> +#define VMALLOC_START ((ALIGN((long)high_memory, 256L << 20) + VMALLOC_OFFSET) & \
> ~(VMALLOC_OFFSET - 1))
> #else
> #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
> diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
> index 5b4d4c4297e1..4315d40906a0 100644
> --- a/arch/powerpc/include/asm/nohash/32/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
> @@ -110,7 +110,7 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
> */
> #define VMALLOC_OFFSET (0x1000000) /* 16M */
> #ifdef PPC_PIN_SIZE
> -#define VMALLOC_START (((_ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
> +#define VMALLOC_START (((ALIGN((long)high_memory, PPC_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
Perhaps this once needed to be more flexiable, but now it always
aligns to 256M and then to 16MB.
> #else
> #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
This is an open coded align to VMALLOC_OFFSET.
> #endif
> diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
> index 3a5a7db4564f..e3a9fde51c4f 100644
> --- a/arch/powerpc/kernel/prom_init.c
> +++ b/arch/powerpc/kernel/prom_init.c
> @@ -2426,7 +2426,7 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end,
> {
> void *ret;
>
> - *mem_start = _ALIGN(*mem_start, align);
> + *mem_start = ALIGN(*mem_start, align);
> while ((*mem_start + needed) > *mem_end) {
> unsigned long room, chunk;
>
> @@ -2562,7 +2562,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
> *lp++ = *p;
> }
> *lp = 0;
> - *mem_start = _ALIGN((unsigned long)lp + 1, 4);
> + *mem_start = ALIGN((unsigned long)lp + 1, 4);
> }
>
> /* get it again for debugging */
> @@ -2608,7 +2608,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
> /* push property content */
> valp = make_room(mem_start, mem_end, l, 4);
> call_prom("getprop", 4, 1, node, pname, valp, l);
> - *mem_start = _ALIGN(*mem_start, 4);
> + *mem_start = ALIGN(*mem_start, 4);
>
> if (!prom_strcmp(pname, "phandle"))
> has_phandle = 1;
> @@ -2667,7 +2667,7 @@ static void __init flatten_device_tree(void)
> prom_panic ("couldn't get device tree root\n");
>
> /* Build header and make room for mem rsv map */
> - mem_start = _ALIGN(mem_start, 4);
> + mem_start = ALIGN(mem_start, 4);
> hdr = make_room(&mem_start, &mem_end,
> sizeof(struct boot_param_header), 4);
> dt_header_start = (unsigned long)hdr;
> diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
> index c3374a90952f..9d4ecd292255 100644
> --- a/arch/powerpc/platforms/powermac/bootx_init.c
> +++ b/arch/powerpc/platforms/powermac/bootx_init.c
> @@ -386,7 +386,7 @@ static unsigned long __init bootx_flatten_dt(unsigned long start)
> hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase;
>
> /* Build structure */
> - mem_end = _ALIGN(mem_end, 16);
> + mem_end = ALIGN(mem_end, 16);
> DBG("Building device tree structure at: %x\n", mem_end);
> hdr->off_dt_struct = mem_end - mem_start;
> bootx_scan_dt_build_struct(base, 4, &mem_end);
> @@ -404,7 +404,7 @@ static unsigned long __init bootx_flatten_dt(unsigned long start)
> * also bump mem_reserve_cnt to cause further reservations to
> * fail since it's too late.
> */
> - mem_end = _ALIGN(mem_end, PAGE_SIZE);
> + mem_end = ALIGN(mem_end, PAGE_SIZE);
> DBG("End of boot params: %x\n", mem_end);
> rsvmap[0] = mem_start;
> rsvmap[1] = mem_end;
> --
> 2.25.0
>
^ permalink raw reply
* Re: [PATCH 1/2] powerpc: Add base support for ISA v3.1
From: Alistair Popple @ 2020-04-21 1:30 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: mikey, linuxppc-dev, npiggin
In-Reply-To: <20200403153208.GI26902@gate.crashing.org>
On Saturday, 4 April 2020 2:32:08 AM AEST Segher Boessenkool wrote:
> Hi!
>
> On Fri, Apr 03, 2020 at 03:10:54PM +1100, Alistair Popple wrote:
> > +#define PCR_ARCH_300 0x10 /* Architecture 3.00 */
>
> It's called 3.0, not 3.00?
Thanks. I'll fix that up.
- Alistair
>
> Segher
^ permalink raw reply
* Re: [PATCH 1/2] powerpc: Add base support for ISA v3.1
From: Alistair Popple @ 2020-04-21 1:52 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: mikey, linuxppc-dev, npiggin
In-Reply-To: <2217912.fZQhC0vD34@townsend>
On Tuesday, 21 April 2020 11:30:52 AM AEST Alistair Popple wrote:
> On Saturday, 4 April 2020 2:32:08 AM AEST Segher Boessenkool wrote:
> > Hi!
> >
> > On Fri, Apr 03, 2020 at 03:10:54PM +1100, Alistair Popple wrote:
> > > +#define PCR_ARCH_300 0x10 /* Architecture 3.00 */
> >
> > It's called 3.0, not 3.00?
>
> Thanks. I'll fix that up.
Actually we have already defined it upstream as CPU_FTR_ARCH_300 in arch/
powerpc/include/asm/cputable.h and PVR_ARCH_300 in arch/powerpc/include/asm/
reg.h so for consistency we should make it the same here. So either we leave
this patch as is or we change it to PCR_ARCH_30 along with the existing
upstream #defines. Thoughts?
- Alistair
> - Alistair
>
> > Segher
^ permalink raw reply
* Re: [PATCH 1/2] powerpc: Add base support for ISA v3.1
From: Oliver O'Halloran @ 2020-04-21 1:58 UTC (permalink / raw)
To: Alistair Popple; +Cc: Michael Neuling, linuxppc-dev, Nicholas Piggin
In-Reply-To: <2992996.BaUphQCMZx@townsend>
On Tue, Apr 21, 2020 at 11:53 AM Alistair Popple <alistair@popple.id.au> wrote:
>
> On Tuesday, 21 April 2020 11:30:52 AM AEST Alistair Popple wrote:
> > On Saturday, 4 April 2020 2:32:08 AM AEST Segher Boessenkool wrote:
> > > Hi!
> > >
> > > On Fri, Apr 03, 2020 at 03:10:54PM +1100, Alistair Popple wrote:
> > > > +#define PCR_ARCH_300 0x10 /* Architecture 3.00 */
> > >
> > > It's called 3.0, not 3.00?
> >
> > Thanks. I'll fix that up.
>
> Actually we have already defined it upstream as CPU_FTR_ARCH_300 in arch/
> powerpc/include/asm/cputable.h and PVR_ARCH_300 in arch/powerpc/include/asm/
> reg.h so for consistency we should make it the same here. So either we leave
> this patch as is or we change it to PCR_ARCH_30 along with the existing
> upstream #defines. Thoughts?
I used 300 for consistency with the existing three digit definitions
when I added the CPU_FTR macro. It doesn't really matter since these
are all internal definitions, but I SAY THE BIKESHED SHOULD BE THREE
DIGITS LONG.
Oliver
^ permalink raw reply
* Re: [PATCH 01/21] mm: memblock: replace dereferences of memblock_region.nid with API calls
From: Baoquan He @ 2020-04-21 2:06 UTC (permalink / raw)
To: Mike Rapoport
Cc: Rich Felker, linux-ia64, linux-doc, Catalin Marinas,
Heiko Carstens, Michal Hocko, James E.J. Bottomley, Max Filippov,
Guo Ren, linux-csky, linux-parisc, sparclinux, linux-hexagon,
linux-riscv, Greg Ungerer, linux-arch, linux-s390, linux-snps-arc,
linux-c6x-dev, Brian Cain, Jonathan Corbet, linux-sh,
Helge Deller, x86, Russell King, Ley Foon Tan, Mike Rapoport,
Geert Uytterhoeven, linux-arm-kernel, Mark Salter, Matt Turner,
linux-mips, uclinux-h8-devel, linux-xtensa, linux-alpha, linux-um,
linux-m68k, Tony Luck, Greentime Hu, Paul Walmsley,
Stafford Horne, Guan Xuetao, Hoan Tran, Michal Simek,
Thomas Bogendoerfer, Yoshinori Sato, Nick Hu, linux-mm,
Vineet Gupta, linux-kernel, openrisc, Richard Weinberger,
Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <20200412194859.12663-2-rppt@kernel.org>
On 04/12/20 at 10:48pm, Mike Rapoport wrote:
> From: Mike Rapoport <rppt@linux.ibm.com>
>
> There are several places in the code that directly dereference
> memblock_region.nid despite this field being defined only when
> CONFIG_HAVE_MEMBLOCK_NODE_MAP=y.
>
> Replace these with calls to memblock_get_region_nid() to improve code
> robustness and to avoid possible breakage when
> CONFIG_HAVE_MEMBLOCK_NODE_MAP will be removed.
>
> Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
> ---
> arch/arm64/mm/numa.c | 9 ++++++---
> arch/x86/mm/numa.c | 6 ++++--
> mm/memblock.c | 8 +++++---
> mm/page_alloc.c | 4 ++--
> 4 files changed, 17 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c
> index 4decf1659700..aafcee3e3f7e 100644
> --- a/arch/arm64/mm/numa.c
> +++ b/arch/arm64/mm/numa.c
> @@ -350,13 +350,16 @@ static int __init numa_register_nodes(void)
> struct memblock_region *mblk;
>
> /* Check that valid nid is set to memblks */
> - for_each_memblock(memory, mblk)
> - if (mblk->nid == NUMA_NO_NODE || mblk->nid >= MAX_NUMNODES) {
> + for_each_memblock(memory, mblk) {
> + int mblk_nid = memblock_get_region_node(mblk);
> +
> + if (mblk_nid == NUMA_NO_NODE || mblk_nid >= MAX_NUMNODES) {
> pr_warn("Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
> - mblk->nid, mblk->base,
> + mblk_nid, mblk->base,
> mblk->base + mblk->size - 1);
> return -EINVAL;
> }
> + }
>
> /* Finally register nodes. */
> for_each_node_mask(nid, numa_nodes_parsed) {
> diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c
> index 59ba008504dc..fe024b2ac796 100644
> --- a/arch/x86/mm/numa.c
> +++ b/arch/x86/mm/numa.c
> @@ -517,8 +517,10 @@ static void __init numa_clear_kernel_node_hotplug(void)
> * reserve specific pages for Sandy Bridge graphics. ]
> */
> for_each_memblock(reserved, mb_region) {
> - if (mb_region->nid != MAX_NUMNODES)
> - node_set(mb_region->nid, reserved_nodemask);
> + int nid = memblock_get_region_node(mb_region);
> +
> + if (nid != MAX_NUMNODES)
> + node_set(nid, reserved_nodemask);
> }
>
> /*
> diff --git a/mm/memblock.c b/mm/memblock.c
> index c79ba6f9920c..43e2fd3006c1 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -1207,13 +1207,15 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid,
> {
> struct memblock_type *type = &memblock.memory;
> struct memblock_region *r;
> + int r_nid;
>
> while (++*idx < type->cnt) {
> r = &type->regions[*idx];
> + r_nid = memblock_get_region_node(r);
>
> if (PFN_UP(r->base) >= PFN_DOWN(r->base + r->size))
> continue;
> - if (nid == MAX_NUMNODES || nid == r->nid)
> + if (nid == MAX_NUMNODES || nid == r_nid)
> break;
> }
> if (*idx >= type->cnt) {
> @@ -1226,7 +1228,7 @@ void __init_memblock __next_mem_pfn_range(int *idx, int nid,
> if (out_end_pfn)
> *out_end_pfn = PFN_DOWN(r->base + r->size);
> if (out_nid)
> - *out_nid = r->nid;
> + *out_nid = r_nid;
> }
>
> /**
> @@ -1810,7 +1812,7 @@ int __init_memblock memblock_search_pfn_nid(unsigned long pfn,
> *start_pfn = PFN_DOWN(type->regions[mid].base);
> *end_pfn = PFN_DOWN(type->regions[mid].base + type->regions[mid].size);
>
> - return type->regions[mid].nid;
> + return memblock_get_region_node(&type->regions[mid]);
> }
> #endif
>
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 69827d4fa052..0d012eda1694 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -7208,7 +7208,7 @@ static void __init find_zone_movable_pfns_for_nodes(void)
> if (!memblock_is_hotpluggable(r))
> continue;
>
> - nid = r->nid;
> + nid = memblock_get_region_node(r);
>
> usable_startpfn = PFN_DOWN(r->base);
> zone_movable_pfn[nid] = zone_movable_pfn[nid] ?
> @@ -7229,7 +7229,7 @@ static void __init find_zone_movable_pfns_for_nodes(void)
> if (memblock_is_mirror(r))
> continue;
>
> - nid = r->nid;
> + nid = memblock_get_region_node(r);
>
> usable_startpfn = memblock_region_memory_base_pfn(r);
Looks good to me.
Reviewed-by: Baoquan He <bhe@redhat.com>
^ permalink raw reply
* [PATCH 0/4] powerpc: clean up pt_regs traps handling
From: Nicholas Piggin @ 2020-04-21 2:19 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Nicholas Piggin
scv support needs to test trap in some cases to distinguish sc from scv,
so it helps to have a few tidy-up patches to start with. This turned
into a slightly bigger job that we needed to do to clean up the double
restart logic that today zeroes traps which is ugly.
Thanks,
Nick
Nicholas Piggin (4):
powerpc/64s: Always has full regs, so remove remnant checks
powerpc: Use SET_TRAP and avoid open-coding trap masking
powerpc: TRAP_IS_SYSCALL helper to hide syscall trap number
powerpc: Use trap metadata to prevent double restart rather than
zeroing trap
arch/powerpc/include/asm/ptrace.h | 31 +++-
arch/powerpc/include/asm/syscall.h | 5 +-
arch/powerpc/kernel/process.c | 4 +-
arch/powerpc/kernel/ptrace/ptrace-tm.c | 2 +-
arch/powerpc/kernel/ptrace/ptrace-view.c | 2 +-
arch/powerpc/kernel/signal.c | 9 +-
arch/powerpc/kernel/signal_32.c | 2 +-
arch/powerpc/kernel/signal_64.c | 10 +-
arch/powerpc/xmon/xmon.c | 4 +-
.../testing/selftests/powerpc/signal/Makefile | 2 +-
.../powerpc/signal/sig_sc_double_restart.c | 174 ++++++++++++++++++
11 files changed, 220 insertions(+), 25 deletions(-)
create mode 100644 tools/testing/selftests/powerpc/signal/sig_sc_double_restart.c
--
2.23.0
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox