* [PATCH v8 12/12] tests/vm: Add workaround to consume console
From: Robert Foley @ 2020-05-29 20:34 UTC (permalink / raw)
To: qemu-devel; +Cc: Fam Zheng, philmd, alex.bennee, robert.foley, peter.puhov
In-Reply-To: <20200529203458.1038-1-robert.foley@linaro.org>
This adds support to basevm.py so that we always
drain the console chars. This makes use of
support added in an earlier commit that allows
QEMUMachine to use the ConsoleSocket.
This is a workaround we found was needed since
there is a known issue where QEMU will hang waiting
for console characters to be consumed.
We also added the option of logging the console to a file.
LOG_CONSOLE=1 will now log the output to a file.
Signed-off-by: Robert Foley <robert.foley@linaro.org>
Reviewed-by: Peter Puhov <peter.puhov@linaro.org>
Acked-by: Alex Bennée <alex.bennee@linaro.org>
---
tests/vm/Makefile.include | 4 ++++
tests/vm/basevm.py | 17 +++++++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/tests/vm/Makefile.include b/tests/vm/Makefile.include
index 8cccfaf95d..ad35c6e7a1 100644
--- a/tests/vm/Makefile.include
+++ b/tests/vm/Makefile.include
@@ -49,6 +49,7 @@ endif
@echo ' EXTRA_CONFIGURE_OPTS="..."'
@echo " J=[0..9]* - Override the -jN parameter for make commands"
@echo " DEBUG=1 - Enable verbose output on host and interactive debugging"
+ @echo " LOG_CONSOLE=1 - Log console to file in: ~/.cache/qemu-vm "
@echo " V=1 - Enable verbose ouput on host and guest commands"
@echo " QEMU_LOCAL=1 - Use QEMU binary local to this build."
@echo " QEMU=/path/to/qemu - Change path to QEMU binary"
@@ -75,6 +76,7 @@ $(IMAGES_DIR)/%.img: $(SRC_PATH)/tests/vm/% \
$(if $(GENISOIMAGE),--genisoimage $(GENISOIMAGE)) \
$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
+ $(if $(LOG_CONSOLE),--log-console) \
--image "$@" \
--force \
--build-image $@, \
@@ -91,6 +93,7 @@ vm-build-%: $(IMAGES_DIR)/%.img
$(if $(V),--verbose) \
$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
+ $(if $(LOG_CONSOLE),--log-console) \
--image "$<" \
$(if $(BUILD_TARGET),--build-target $(BUILD_TARGET)) \
--snapshot \
@@ -114,6 +117,7 @@ vm-boot-ssh-%: $(IMAGES_DIR)/%.img
$(if $(V)$(DEBUG), --debug) \
$(if $(QEMU_LOCAL),--build-path $(BUILD_DIR)) \
$(if $(EFI_AARCH64),--efi-aarch64 $(EFI_AARCH64)) \
+ $(if $(LOG_CONSOLE),--log-console) \
--image "$<" \
--interactive \
false, \
diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py
index b9d828423b..64dbe64326 100644
--- a/tests/vm/basevm.py
+++ b/tests/vm/basevm.py
@@ -117,6 +117,11 @@ class BaseVM(object):
"w").write(self._config['ssh_pub_key'])
self.debug = args.debug
+ self._console_log_path = None
+ if args.log_console:
+ self._console_log_path = \
+ os.path.join(os.path.expanduser("~/.cache/qemu-vm"),
+ "{}.install.log".format(self.name))
self._stderr = sys.stderr
self._devnull = open(os.devnull, "w")
if self.debug:
@@ -271,7 +276,9 @@ class BaseVM(object):
args += self._data_args + extra_args + self._config['extra_args']
logging.debug("QEMU args: %s", " ".join(args))
qemu_path = get_qemu_path(self.arch, self._build_path)
- guest = QEMUMachine(binary=qemu_path, args=args)
+ guest = QEMUMachine(binary=qemu_path, args=args,
+ console_log=self._console_log_path,
+ drain_console=True)
guest.set_machine(self._config['machine'])
guest.set_console()
try:
@@ -285,6 +292,8 @@ class BaseVM(object):
raise
atexit.register(self.shutdown)
self._guest = guest
+ # Init console so we can start consuming the chars.
+ self.console_init()
usernet_info = guest.qmp("human-monitor-command",
command_line="info usernet")
self.ssh_port = None
@@ -296,7 +305,9 @@ class BaseVM(object):
raise Exception("Cannot find ssh port from 'info usernet':\n%s" % \
usernet_info)
- def console_init(self, timeout = 120):
+ def console_init(self, timeout = None):
+ if timeout == None:
+ timeout = self.socket_timeout
vm = self._guest
vm.console_socket.settimeout(timeout)
self.console_raw_path = os.path.join(vm._temp_dir,
@@ -578,6 +589,8 @@ def parse_args(vmcls):
parser.add_option("--efi-aarch64",
default="/usr/share/qemu-efi-aarch64/QEMU_EFI.fd",
help="Path to efi image for aarch64 VMs.")
+ parser.add_option("--log-console", action="store_true",
+ help="Log console to file.")
parser.disable_interspersed_args()
return parser.parse_args()
--
2.17.1
^ permalink raw reply related
* Re: [PATCH] spi: spi-fsl-dspi: fix native data copy
From: Vladimir Oltean @ 2020-05-29 20:55 UTC (permalink / raw)
To: Angelo Dureghello; +Cc: Mark Brown, linux-spi, Vladimir Oltean
In-Reply-To: <20200529195756.184677-1-angelo.dureghello@timesys.com>
Hi Angelo,
On Fri, 29 May 2020 at 22:53, Angelo Dureghello
<angelo.dureghello@timesys.com> wrote:
>
> ColdFire is a big-endian cpu with a big-endian dspi hw module,
> so, it uses native access, but memcpy breaks the endianness.
>
> So, if i understand properly, by native copy we would mean
> be(cpu)->be(dspi) or le(cpu)->le(dspi) accesses, so my fix
> shouldn't break anything, but i couldn't test it on LS family,
> so every test is really appreciated.
>
> Signed-off-by: Angelo Dureghello <angelo.dureghello@timesys.com>
> ---
Honestly I was expecting more breakage than that on Coldfire :)
I looked at this patch for a while before I figured out what's going on.
Let there be the program below:
#include <linux/types.h>
#include <string.h>
#include <stdio.h>
struct fsl_dspi {
__u8 *tx;
int oper_word_size;
};
static void dspi_native_host_to_dev_v1(struct fsl_dspi *dspi, __u32 *txdata)
{
memcpy(txdata, dspi->tx, dspi->oper_word_size);
dspi->tx += dspi->oper_word_size;
}
static void dspi_native_host_to_dev_v2(struct fsl_dspi *dspi, __u32 *txdata)
{
switch (dspi->oper_word_size) {
case 1:
*txdata = *(__u8 *)dspi->tx;
break;
case 2:
*txdata = *(__u16 *)dspi->tx;
break;
case 4:
*txdata = *(__u32 *)dspi->tx;
break;
}
dspi->tx += dspi->oper_word_size;
}
int main()
{
struct fsl_dspi dspi;
__u8 tx_buf[] = {
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
};
__u32 txdata;
dspi.tx = tx_buf;
dspi.oper_word_size = 2;
txdata = 0xdeadbeef;
dspi_native_host_to_dev_v1(&dspi, &txdata);
printf("txdata v1: 0x%08x\n", txdata);
txdata = 0xdeadbeef;
dspi_native_host_to_dev_v2(&dspi, &txdata);
printf("txdata v2: 0x%08x\n", txdata);
return 0;
}
On little endian, it prints:
txdata v1: 0xdead0100
txdata v2: 0x00000302
On big endian, it prints:
txdata v1: 0x0001beef
txdata v2: 0x00000203
So yeah, in your case, 0xbeef (uninitialized data) would get sent on
the wire. Your patch is correct.
Fixes: 53fadb4d90c7 ("spi: spi-fsl-dspi: Simplify bytes_per_word gymnastics")
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> drivers/spi/spi-fsl-dspi.c | 24 ++++++++++++++++++++++--
> 1 file changed, 22 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
> index 50e41f66a2d7..2e9f9adc5900 100644
> --- a/drivers/spi/spi-fsl-dspi.c
> +++ b/drivers/spi/spi-fsl-dspi.c
> @@ -246,13 +246,33 @@ struct fsl_dspi {
>
> static void dspi_native_host_to_dev(struct fsl_dspi *dspi, u32 *txdata)
> {
> - memcpy(txdata, dspi->tx, dspi->oper_word_size);
> + switch (dspi->oper_word_size) {
> + case 1:
> + *txdata = *(u8 *)dspi->tx;
> + break;
> + case 2:
> + *txdata = *(u16 *)dspi->tx;
> + break;
> + case 4:
> + *txdata = *(u32 *)dspi->tx;
> + break;
> + }
> dspi->tx += dspi->oper_word_size;
> }
>
> static void dspi_native_dev_to_host(struct fsl_dspi *dspi, u32 rxdata)
> {
> - memcpy(dspi->rx, &rxdata, dspi->oper_word_size);
> + switch (dspi->oper_word_size) {
> + case 1:
> + *(u8 *)dspi->rx = rxdata;
> + break;
> + case 2:
> + *(u16 *)dspi->rx = rxdata;
> + break;
> + case 4:
> + *(u32 *)dspi->rx = rxdata;
> + break;
> + }
> dspi->rx += dspi->oper_word_size;
> }
>
> --
> 2.26.2
>
Thanks,
-Vladimir
^ permalink raw reply
* [Buildroot] Buildroot 2020.05-rc3 released
From: Peter Korsgaard @ 2020-05-29 20:56 UTC (permalink / raw)
To: buildroot
Hi,
Buildroot 2020.05-rc3 is released - Go download it at:
http://buildroot.net/downloads/buildroot-2020.05-rc3.tar.gz
or
http://buildroot.net/downloads/buildroot-2020.05-rc3.tar.bz2
Or get it from Git:
git://git.buildroot.net/buildroot
Another week, another release candidate.
Please give it a spin and report any problems to the mailing list or
bug tracker. Many thanks to the people contributing to this release:
git shortlog -sn 2020.05-rc2..
9 Fabrice Fontaine
4 Heiko Thiery
4 Thomas Petazzoni
4 Yann E. MORIN
3 Peter Korsgaard
3 Romain Naour
2 James Hilliard
1 Bernd Kuhls
1 Fabio Estevam
1 Joachim Nilsson
1 J?r?my Rosen
1 Stefan Ott
1 Yegor Yefremov
For more details, see the CHANGES file:
http://git.buildroot.net/buildroot/plain/CHANGES?id=2020.05-rc3
Expect the final 2020.05 release early next week.
--
Bye, Peter Korsgaard
^ permalink raw reply
* Re: [dpdk-dev] mlx5 & pdump: convert HW timestamps to nanoseconds
From: PATRICK KEROULAS @ 2020-05-29 20:56 UTC (permalink / raw)
To: Slava Ovsiienko
Cc: dev@dpdk.org, Vivien Didelot, Shahaf Shuler, Raslan Darawsheh,
Matan Azrad
In-Reply-To: <AM4PR05MB3265F9A5814408F1E961ECDED2B00@AM4PR05MB3265.eurprd05.prod.outlook.com>
On Tue, May 26, 2020 at 12:00 PM Slava Ovsiienko <viacheslavo@mellanox.com>
wrote:
>> Hi, Patrick
>
> ConnectX HW timestamp is the captured value of internal 64-bit counter
running at the frequency,
> reported in the device_frequency_khz field of struct
mlx5_ifc_cmd_hca_cap_bits{}.
> This structure is queried in mlx5_devx_cmd_query_hca_attr() routine.
> So, with known frequency it is possible to recalculate timestamp ticks to
desired units.
Hello Slava,
Assuming that the NIC clock is already synced thanks to a PTP client,
does the bit counter give an absolute time value (0 => 1 January 1970
00:00:00)? Or do I need to calculate a time duration from the process
start time?
I just want to validate the path from mlx5 eth dev(Rx) to eth pcap (Tx) :
- query the oscillator frequency at the mlx5_eth_dev init step
(mlx5_devx_cmd_query_hca_attr())
- store the freq with other hca_attr, carried by dev config which should
be shared with the secondary process
- in eth_pcap_tx_dumper(), retrieve the freq from the dev given by
mbuf->port
- convert all the incoming mbuf->timestamp using this freq whose
variation should be negligible over the capture duration
Last question: what is your opinion about this other method?
https://github.com/linux-rdma/rdma-core/blob/7af01c79e00555207dee6132d72e7bfc1bb5485e/providers/mlx5/mlx5dv.h#L1201
Thanks a lot!
^ permalink raw reply
* Re: [PATCH v3 1/2] avrcp: Fix always requesting player settings for category 1
From: Andrey Semashev @ 2020-05-29 20:56 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
In-Reply-To: <CABBYNZ+RQooYxKUYLd6TPL-o7vN6Xzeq0RN3E-ii_wbTfPyQtg@mail.gmail.com>
On 2020-05-29 23:29, Luiz Augusto von Dentz wrote:
> Hi,
>
> On Thu, May 28, 2020 at 2:53 PM Luiz Augusto von Dentz
> <luiz.dentz@gmail.com> wrote:
>>
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> Player Application settings is not mandatory for category 1 so instead
>> of always listing the settings the code now checks if
>> AVRCP_FEATURE_PLAYER_SETTINGS is enabled.
>> ---
>> profiles/audio/avrcp.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
>> index 773ccdb60..75811bf98 100644
>> --- a/profiles/audio/avrcp.c
>> +++ b/profiles/audio/avrcp.c
>> @@ -3814,7 +3814,8 @@ static gboolean avrcp_get_capabilities_resp(struct avctp *conn, uint8_t code,
>> if (!session->controller || !session->controller->player)
>> return FALSE;
>>
>> - if (!(events & (1 << AVRCP_EVENT_SETTINGS_CHANGED)))
>> + if ((session->controller->features & AVRCP_FEATURE_PLAYER_SETTINGS) &&
>> + !(events & (1 << AVRCP_EVENT_SETTINGS_CHANGED)))
>> avrcp_list_player_attributes(session);
>>
>> if (!(events & (1 << AVRCP_EVENT_STATUS_CHANGED)))
>> --
>> 2.25.3
>>
>
> Applied.
>
Thanks. You may want to close
https://bugzilla.kernel.org/show_bug.cgi?id=207625.
^ permalink raw reply
* Re: [PATCH v8 42/62] target/riscv: vector floating-point merge instructions
From: Alistair Francis @ 2020-05-29 20:36 UTC (permalink / raw)
To: LIU Zhiwei
Cc: open list:RISC-V, Richard Henderson,
qemu-devel@nongnu.org Developers, wxy194768, wenmeng_zhang,
Alistair Francis, Palmer Dabbelt
In-Reply-To: <20200521094413.10425-43-zhiwei_liu@c-sky.com>
On Thu, May 21, 2020 at 4:09 AM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/helper.h | 4 +++
> target/riscv/insn32.decode | 2 ++
> target/riscv/insn_trans/trans_rvv.inc.c | 38 +++++++++++++++++++++++++
> target/riscv/vector_helper.c | 24 ++++++++++++++++
> 4 files changed, 68 insertions(+)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 23b268df90..21054cc957 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -994,3 +994,7 @@ DEF_HELPER_6(vmford_vf_d, void, ptr, ptr, i64, ptr, env, i32)
> DEF_HELPER_5(vfclass_v_h, void, ptr, ptr, ptr, env, i32)
> DEF_HELPER_5(vfclass_v_w, void, ptr, ptr, ptr, env, i32)
> DEF_HELPER_5(vfclass_v_d, void, ptr, ptr, ptr, env, i32)
> +
> +DEF_HELPER_6(vfmerge_vfm_h, void, ptr, ptr, i64, ptr, env, i32)
> +DEF_HELPER_6(vfmerge_vfm_w, void, ptr, ptr, i64, ptr, env, i32)
> +DEF_HELPER_6(vfmerge_vfm_d, void, ptr, ptr, i64, ptr, env, i32)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index 23e80fe954..14cb4e2e66 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -513,6 +513,8 @@ vmfge_vf 011111 . ..... ..... 101 ..... 1010111 @r_vm
> vmford_vv 011010 . ..... ..... 001 ..... 1010111 @r_vm
> vmford_vf 011010 . ..... ..... 101 ..... 1010111 @r_vm
> vfclass_v 100011 . ..... 10000 001 ..... 1010111 @r2_vm
> +vfmerge_vfm 010111 0 ..... ..... 101 ..... 1010111 @r_vm_0
> +vfmv_v_f 010111 1 00000 ..... 101 ..... 1010111 @r2
>
> vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm
> vsetvl 1000000 ..... ..... 111 ..... 1010111 @r
> diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c
> index 621220e5ff..dfa2177331 100644
> --- a/target/riscv/insn_trans/trans_rvv.inc.c
> +++ b/target/riscv/insn_trans/trans_rvv.inc.c
> @@ -2177,3 +2177,41 @@ GEN_OPFVF_TRANS(vmford_vf, opfvf_cmp_check)
>
> /* Vector Floating-Point Classify Instruction */
> GEN_OPFV_TRANS(vfclass_v, opfv_check)
> +
> +/* Vector Floating-Point Merge Instruction */
> +GEN_OPFVF_TRANS(vfmerge_vfm, opfvf_check)
> +
> +static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
> +{
> + if (vext_check_isa_ill(s) &&
> + vext_check_reg(s, a->rd, false) &&
> + (s->sew != 0)) {
> +
> + if (s->vl_eq_vlmax) {
> + tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
> + MAXSZ(s), MAXSZ(s), cpu_fpr[a->rs1]);
> + } else {
> + TCGv_ptr dest;
> + TCGv_i32 desc;
> + uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
> + static gen_helper_vmv_vx * const fns[3] = {
> + gen_helper_vmv_v_x_h,
> + gen_helper_vmv_v_x_w,
> + gen_helper_vmv_v_x_d,
> + };
> + TCGLabel *over = gen_new_label();
> + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
> +
> + dest = tcg_temp_new_ptr();
> + desc = tcg_const_i32(simd_desc(0, s->vlen / 8, data));
> + tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
> + fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc);
> +
> + tcg_temp_free_ptr(dest);
> + tcg_temp_free_i32(desc);
> + gen_set_label(over);
> + }
> + return true;
> + }
> + return false;
> +}
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 63d8873c0a..018293570d 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -4193,3 +4193,27 @@ RVVCALL(OPIVV1, vfclass_v_d, OP_UU_D, H8, H8, fclass_d)
> GEN_VEXT_V(vfclass_v_h, 2, 2, clearh)
> GEN_VEXT_V(vfclass_v_w, 4, 4, clearl)
> GEN_VEXT_V(vfclass_v_d, 8, 8, clearq)
> +
> +/* Vector Floating-Point Merge Instruction */
> +#define GEN_VFMERGE_VF(NAME, ETYPE, H, CLEAR_FN) \
> +void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void *vs2, \
> + CPURISCVState *env, uint32_t desc) \
> +{ \
> + uint32_t mlen = vext_mlen(desc); \
> + uint32_t vm = vext_vm(desc); \
> + uint32_t vl = env->vl; \
> + uint32_t esz = sizeof(ETYPE); \
> + uint32_t vlmax = vext_maxsz(desc) / esz; \
> + uint32_t i; \
> + \
> + for (i = 0; i < vl; i++) { \
> + ETYPE s2 = *((ETYPE *)vs2 + H(i)); \
> + *((ETYPE *)vd + H(i)) \
> + = (!vm && !vext_elem_mask(v0, mlen, i) ? s2 : s1); \
> + } \
> + CLEAR_FN(vd, vl, vl * esz, vlmax * esz); \
> +}
> +
> +GEN_VFMERGE_VF(vfmerge_vfm_h, int16_t, H2, clearh)
> +GEN_VFMERGE_VF(vfmerge_vfm_w, int32_t, H4, clearl)
> +GEN_VFMERGE_VF(vfmerge_vfm_d, int64_t, H8, clearq)
> --
> 2.23.0
>
>
^ permalink raw reply
* Re: [PATCH v3 7/7] zram: Use local lock to protect per-CPU data
From: Minchan Kim @ 2020-05-29 20:57 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: linux-kernel, Peter Zijlstra, Ingo Molnar, Steven Rostedt,
Will Deacon, Thomas Gleixner, Paul E . McKenney, Linus Torvalds,
Matthew Wilcox, Mike Galbraith, Nitin Gupta, Sergey Senozhatsky
In-Reply-To: <20200527201119.1692513-8-bigeasy@linutronix.de>
On Wed, May 27, 2020 at 10:11:19PM +0200, Sebastian Andrzej Siewior wrote:
> From: Mike Galbraith <umgwanakikbuti@gmail.com>
>
> The zcomp driver uses per-CPU compression. The per-CPU data pointer is
> acquired with get_cpu_ptr() which implicitly disables preemption.
> It allocates memory inside the preempt disabled region which conflicts
> with the PREEMPT_RT semantics.
>
> Replace the implicit preemption control with an explicit local lock.
> This allows RT kernels to substitute it with a real per CPU lock, which
> serializes the access but keeps the code section preemptible. On non RT
> kernels this maps to preempt_disable() as before, i.e. no functional
> change.
>
> [bigeasy: Use local_lock(), description, drop reordering]
>
> Cc: Minchan Kim <minchan@kernel.org>
> Cc: Nitin Gupta <ngupta@vflare.org>
> Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
> Signed-off-by: Mike Galbraith <umgwanakikbuti@gmail.com>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Acked-by: Minchan Kim <minchan@kernel.org>
^ permalink raw reply
* Re: [PATCH 2/2] dlmfs: convert dlmfs_file_read() to copy_to_user()
From: Linus Torvalds @ 2020-05-29 20:57 UTC (permalink / raw)
To: Al Viro; +Cc: Linux Kernel Mailing List, linux-fsdevel
In-Reply-To: <20200529204628.GI23230@ZenIV.linux.org.uk>
On Fri, May 29, 2020 at 1:46 PM Al Viro <viro@zeniv.linux.org.uk> wrote:
>
> Umm... I'd been concerned about code generation, but it actually gets
> split into a pair of scalars just fine...
We actually have depended on that for a long time: our 'pte_t' etc on
32-bit kernels were very much about "structs of two words are handled
fairly well by gcc".
IIrc, we (for a while) had a config option to switch between "long
long" and the struct, but passing and returning two-word structs ends
up working fine even when it's a function call, and when it's all
inlined it ends up generating pretty good code on just two registers
instead.
> Al, trying to resist the temptation to call those struct bad_idea and
> struct bad_idea_32...
I'm sure you can contain yourself.
> All jokes aside, when had we (or anybody else, really) _not_ gotten
> into trouble when passing structs across the kernel boundary? Sure,
> sometimes you have to (stat, for example), but just look at the amount
> of PITA stat() has spawned...
I'd rather see the struct than some ugly manual address calculations
and casts...
Because that's fundamentally what a struct _is_, after all.
Linus
^ permalink raw reply
* Re: [PATCH v8 44/62] target/riscv: widening floating-point/integer type-convert instructions
From: Alistair Francis @ 2020-05-29 20:43 UTC (permalink / raw)
To: LIU Zhiwei
Cc: open list:RISC-V, Richard Henderson,
qemu-devel@nongnu.org Developers, wxy194768, wenmeng_zhang,
Alistair Francis, Palmer Dabbelt
In-Reply-To: <20200521094413.10425-45-zhiwei_liu@c-sky.com>
On Thu, May 21, 2020 at 4:13 AM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/helper.h | 11 ++++++
> target/riscv/insn32.decode | 5 +++
> target/riscv/insn_trans/trans_rvv.inc.c | 47 +++++++++++++++++++++++++
> target/riscv/vector_helper.c | 42 ++++++++++++++++++++++
> 4 files changed, 105 insertions(+)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 05f8fb5ffc..e59dcc5a7c 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -1011,3 +1011,14 @@ DEF_HELPER_5(vfcvt_f_xu_v_d, void, ptr, ptr, ptr, env, i32)
> DEF_HELPER_5(vfcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
> DEF_HELPER_5(vfcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
> DEF_HELPER_5(vfcvt_f_x_v_d, void, ptr, ptr, ptr, env, i32)
> +
> +DEF_HELPER_5(vfwcvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfwcvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfwcvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfwcvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfwcvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfwcvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfwcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index 53562c6663..e0efc63ec2 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -519,6 +519,11 @@ vfcvt_xu_f_v 100010 . ..... 00000 001 ..... 1010111 @r2_vm
> vfcvt_x_f_v 100010 . ..... 00001 001 ..... 1010111 @r2_vm
> vfcvt_f_xu_v 100010 . ..... 00010 001 ..... 1010111 @r2_vm
> vfcvt_f_x_v 100010 . ..... 00011 001 ..... 1010111 @r2_vm
> +vfwcvt_xu_f_v 100010 . ..... 01000 001 ..... 1010111 @r2_vm
> +vfwcvt_x_f_v 100010 . ..... 01001 001 ..... 1010111 @r2_vm
> +vfwcvt_f_xu_v 100010 . ..... 01010 001 ..... 1010111 @r2_vm
> +vfwcvt_f_x_v 100010 . ..... 01011 001 ..... 1010111 @r2_vm
> +vfwcvt_f_f_v 100010 . ..... 01100 001 ..... 1010111 @r2_vm
>
> vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm
> vsetvl 1000000 ..... ..... 111 ..... 1010111 @r
> diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c
> index 6db460177d..44505027c1 100644
> --- a/target/riscv/insn_trans/trans_rvv.inc.c
> +++ b/target/riscv/insn_trans/trans_rvv.inc.c
> @@ -2221,3 +2221,50 @@ GEN_OPFV_TRANS(vfcvt_xu_f_v, opfv_check)
> GEN_OPFV_TRANS(vfcvt_x_f_v, opfv_check)
> GEN_OPFV_TRANS(vfcvt_f_xu_v, opfv_check)
> GEN_OPFV_TRANS(vfcvt_f_x_v, opfv_check)
> +
> +/* Widening Floating-Point/Integer Type-Convert Instructions */
> +
> +/*
> + * If the current SEW does not correspond to a supported IEEE floating-point
> + * type, an illegal instruction exception is raised
> + */
> +static bool opfv_widen_check(DisasContext *s, arg_rmr *a)
> +{
> + return (vext_check_isa_ill(s) &&
> + vext_check_overlap_mask(s, a->rd, a->vm, true) &&
> + vext_check_reg(s, a->rd, true) &&
> + vext_check_reg(s, a->rs2, false) &&
> + vext_check_overlap_group(a->rd, 2 << s->lmul, a->rs2,
> + 1 << s->lmul) &&
> + (s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0));
> +}
> +
> +#define GEN_OPFV_WIDEN_TRANS(NAME) \
> +static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
> +{ \
> + if (opfv_widen_check(s, a)) { \
> + uint32_t data = 0; \
> + static gen_helper_gvec_3_ptr * const fns[2] = { \
> + gen_helper_##NAME##_h, \
> + gen_helper_##NAME##_w, \
> + }; \
> + TCGLabel *over = gen_new_label(); \
> + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
> + \
> + data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \
> + data = FIELD_DP32(data, VDATA, VM, a->vm); \
> + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
> + tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
> + vreg_ofs(s, a->rs2), cpu_env, 0, \
> + s->vlen / 8, data, fns[s->sew - 1]); \
> + gen_set_label(over); \
> + return true; \
> + } \
> + return false; \
> +}
> +
> +GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v)
> +GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v)
> +GEN_OPFV_WIDEN_TRANS(vfwcvt_f_xu_v)
> +GEN_OPFV_WIDEN_TRANS(vfwcvt_f_x_v)
> +GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v)
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index 34b21c8deb..ea6a5853f3 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -4250,3 +4250,45 @@ RVVCALL(OPFVV1, vfcvt_f_x_v_d, OP_UU_D, H8, H8, int64_to_float64)
> GEN_VEXT_V_ENV(vfcvt_f_x_v_h, 2, 2, clearh)
> GEN_VEXT_V_ENV(vfcvt_f_x_v_w, 4, 4, clearl)
> GEN_VEXT_V_ENV(vfcvt_f_x_v_d, 8, 8, clearq)
> +
> +/* Widening Floating-Point/Integer Type-Convert Instructions */
> +/* (TD, T2, TX2) */
> +#define WOP_UU_H uint32_t, uint16_t, uint16_t
> +#define WOP_UU_W uint64_t, uint32_t, uint32_t
> +/* vfwcvt.xu.f.v vd, vs2, vm # Convert float to double-width unsigned integer.*/
> +RVVCALL(OPFVV1, vfwcvt_xu_f_v_h, WOP_UU_H, H4, H2, float16_to_uint32)
> +RVVCALL(OPFVV1, vfwcvt_xu_f_v_w, WOP_UU_W, H8, H4, float32_to_uint64)
> +GEN_VEXT_V_ENV(vfwcvt_xu_f_v_h, 2, 4, clearl)
> +GEN_VEXT_V_ENV(vfwcvt_xu_f_v_w, 4, 8, clearq)
> +
> +/* vfwcvt.x.f.v vd, vs2, vm # Convert float to double-width signed integer. */
> +RVVCALL(OPFVV1, vfwcvt_x_f_v_h, WOP_UU_H, H4, H2, float16_to_int32)
> +RVVCALL(OPFVV1, vfwcvt_x_f_v_w, WOP_UU_W, H8, H4, float32_to_int64)
> +GEN_VEXT_V_ENV(vfwcvt_x_f_v_h, 2, 4, clearl)
> +GEN_VEXT_V_ENV(vfwcvt_x_f_v_w, 4, 8, clearq)
> +
> +/* vfwcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to double-width float */
> +RVVCALL(OPFVV1, vfwcvt_f_xu_v_h, WOP_UU_H, H4, H2, uint16_to_float32)
> +RVVCALL(OPFVV1, vfwcvt_f_xu_v_w, WOP_UU_W, H8, H4, uint32_to_float64)
> +GEN_VEXT_V_ENV(vfwcvt_f_xu_v_h, 2, 4, clearl)
> +GEN_VEXT_V_ENV(vfwcvt_f_xu_v_w, 4, 8, clearq)
> +
> +/* vfwcvt.f.x.v vd, vs2, vm # Convert integer to double-width float. */
> +RVVCALL(OPFVV1, vfwcvt_f_x_v_h, WOP_UU_H, H4, H2, int16_to_float32)
> +RVVCALL(OPFVV1, vfwcvt_f_x_v_w, WOP_UU_W, H8, H4, int32_to_float64)
> +GEN_VEXT_V_ENV(vfwcvt_f_x_v_h, 2, 4, clearl)
> +GEN_VEXT_V_ENV(vfwcvt_f_x_v_w, 4, 8, clearq)
> +
> +/*
> + * vfwcvt.f.f.v vd, vs2, vm #
> + * Convert single-width float to double-width float.
> + */
> +static uint32_t vfwcvtffv16(uint16_t a, float_status *s)
> +{
> + return float16_to_float32(a, true, s);
> +}
> +
> +RVVCALL(OPFVV1, vfwcvt_f_f_v_h, WOP_UU_H, H4, H2, vfwcvtffv16)
> +RVVCALL(OPFVV1, vfwcvt_f_f_v_w, WOP_UU_W, H8, H4, float32_to_float64)
> +GEN_VEXT_V_ENV(vfwcvt_f_f_v_h, 2, 4, clearl)
> +GEN_VEXT_V_ENV(vfwcvt_f_f_v_w, 4, 8, clearq)
> --
> 2.23.0
>
>
^ permalink raw reply
* Re: [PATCH net-next v4 1/4] dt-bindings: net: Add tx and rx internal delays
From: Rob Herring @ 2020-05-29 20:58 UTC (permalink / raw)
To: Dan Murphy
Cc: Andrew Lunn, Florian Fainelli, Heiner Kallweit, David Miller,
netdev, linux-kernel@vger.kernel.org, devicetree
In-Reply-To: <b8a0b1e8-c7fb-d38b-5c43-c6c4116a3349@ti.com>
On Fri, May 29, 2020 at 1:24 PM Dan Murphy <dmurphy@ti.com> wrote:
>
> Rob
>
> On 5/29/20 1:25 PM, Rob Herring wrote:
> > On Wed, May 27, 2020 at 11:49:31AM -0500, Dan Murphy wrote:
> >> tx-internal-delays and rx-internal-delays are a common setting for RGMII
> >> capable devices.
> >>
> >> These properties are used when the phy-mode or phy-controller is set to
> >> rgmii-id, rgmii-rxid or rgmii-txid. These modes indicate to the
> >> controller that the PHY will add the internal delay for the connection.
> >>
> >> Signed-off-by: Dan Murphy <dmurphy@ti.com>
> >> ---
> >> .../bindings/net/ethernet-controller.yaml | 14 ++++++++++++++
> >> 1 file changed, 14 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/net/ethernet-controller.yaml b/Documentation/devicetree/bindings/net/ethernet-controller.yaml
> >> index ac471b60ed6a..70702a4ef5e8 100644
> >> --- a/Documentation/devicetree/bindings/net/ethernet-controller.yaml
> >> +++ b/Documentation/devicetree/bindings/net/ethernet-controller.yaml
> >> @@ -143,6 +143,20 @@ properties:
> >> Specifies the PHY management type. If auto is set and fixed-link
> >> is not specified, it uses MDIO for management.
> >>
> >> + rx-internal-delay-ps:
> >> + $ref: /schemas/types.yaml#definitions/uint32
> >> + description: |
> >> + RGMII Receive PHY Clock Delay defined in pico seconds. This is used for
> >> + PHY's that have configurable RX internal delays. This property is only
> >> + used when the phy-mode or phy-connection-type is rgmii-id or rgmii-rxid.
> > Isn't this a property of the phy (this is the controller schema)? Looks
> > like we have similar properties already and they go in phy nodes. Would
> > be good to have a standard property, but let's be clear where it goes.
> >
> > We need to add '-ps' as a standard unit suffix (in dt-schema) and then a
> > type is not needed here.
>
> This is a PHY specific property.
>
> I will move them.
>
> Dumb question but you can just point me to the manual about how and
> where to add the '-ps' to the dt-schema
Here[1], but looks like I already added it. I'd checked the old kernel
version (property-units.txt) which didn't have it.
Rob
[1] https://github.com/devicetree-org/dt-schema/blob/master/schemas/property-units.yaml#L48
^ permalink raw reply
* [Buildroot] [git commit branch/2020.02.x] package/rpi-firmware: select BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT when needed
From: Peter Korsgaard @ 2020-05-29 20:59 UTC (permalink / raw)
To: buildroot
commit: https://git.buildroot.net/buildroot/commit/?id=37c425cf2ceeec6b28efbc1120c52a43d3212bb3
branch: https://git.buildroot.net/buildroot/commit/?id=refs/heads/2020.02.x
When BR2_PACKAGE_RPI_FIRMWARE_INSTALL_DTB_OVERLAYS is enabled, and the
DTBs are built by Linux (i.e BR2_LINUX_KERNEL_DTS_SUPPORT is enabled),
these DTBs should be built with the -@ Device Tree compiler option, so
that they can be used together with DTB overlays. So let's select
BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT in this situation.
Fixes:
https://bugs.busybox.net/show_bug.cgi?id=12831
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
(cherry picked from commit 9fd1d4fec1c88f9f3f4e41f9b6dc8a740538217b)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
---
package/rpi-firmware/Config.in | 2 ++
1 file changed, 2 insertions(+)
diff --git a/package/rpi-firmware/Config.in b/package/rpi-firmware/Config.in
index 7cebc5e7ca..cced53f017 100644
--- a/package/rpi-firmware/Config.in
+++ b/package/rpi-firmware/Config.in
@@ -85,6 +85,8 @@ config BR2_PACKAGE_RPI_FIRMWARE_INSTALL_DTB_OVERLAYS
default y
depends on BR2_PACKAGE_RPI_FIRMWARE_INSTALL_DTBS \
|| BR2_LINUX_KERNEL_DTS_SUPPORT
+ select BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT \
+ if BR2_LINUX_KERNEL_DTS_SUPPORT
help
Say 'y' here if you need to load one or more of the DTB
overlays, to support HATs (Hardware Attached on Top, add-on
^ permalink raw reply related
* [Buildroot] [git commit branch/2020.02.x] configs/raspberrypi{3, 4}_64: enabling BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT no longer needed
From: Peter Korsgaard @ 2020-05-29 20:59 UTC (permalink / raw)
To: buildroot
commit: https://git.buildroot.net/buildroot/commit/?id=9f6504fc5912386ecb07a95b2c90f8a88b4a8b3f
branch: https://git.buildroot.net/buildroot/commit/?id=refs/heads/2020.02.x
BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT is now forcefully selected by
BR2_PACKAGE_RPI_FIRMWARE_INSTALL_DTB_OVERLAYS when the kernel is in
charge of building DTBs (BR2_LINUX_KERNEL_DTS_SUPPORT=y). So enabling
BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT is no longer needed in the 64-bit
defconfigs for Raspberry Pi 3 and 4.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
(cherry picked from commit 562e602442ebe1db832d1673cda7a1261f24bd9c)
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
---
configs/raspberrypi3_64_defconfig | 1 -
configs/raspberrypi4_64_defconfig | 1 -
2 files changed, 2 deletions(-)
diff --git a/configs/raspberrypi3_64_defconfig b/configs/raspberrypi3_64_defconfig
index 148769e9db..1f27957c69 100644
--- a/configs/raspberrypi3_64_defconfig
+++ b/configs/raspberrypi3_64_defconfig
@@ -17,7 +17,6 @@ BR2_LINUX_KERNEL_DEFCONFIG="bcmrpi3"
# Build the DTB from the kernel sources
BR2_LINUX_KERNEL_DTS_SUPPORT=y
BR2_LINUX_KERNEL_INTREE_DTS_NAME="broadcom/bcm2710-rpi-3-b broadcom/bcm2710-rpi-3-b-plus broadcom/bcm2837-rpi-3-b"
-BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT=y
BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y
diff --git a/configs/raspberrypi4_64_defconfig b/configs/raspberrypi4_64_defconfig
index 056b89cecd..b14c66d227 100644
--- a/configs/raspberrypi4_64_defconfig
+++ b/configs/raspberrypi4_64_defconfig
@@ -17,7 +17,6 @@ BR2_LINUX_KERNEL_DEFCONFIG="bcm2711"
# Build the DTB from the kernel sources
BR2_LINUX_KERNEL_DTS_SUPPORT=y
BR2_LINUX_KERNEL_INTREE_DTS_NAME="broadcom/bcm2711-rpi-4-b"
-BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT=y
BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y
^ permalink raw reply related
* Re: CFLAGS overridden by distribution build system
From: William Roberts @ 2020-05-29 20:59 UTC (permalink / raw)
To: Stephen Smalley; +Cc: Laurent Bigonville, SElinux list
In-Reply-To: <CAEjxPJ5N8Htq0uEekR7M7mt17_h7rRSzHU=kRBU_F02JfxO4ew@mail.gmail.com>
On Fri, May 29, 2020 at 1:18 PM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
>
> On Fri, May 29, 2020 at 1:15 PM William Roberts
> <bill.c.roberts@gmail.com> wrote:
> >
> > On Fri, May 29, 2020 at 11:40 AM Stephen Smalley
> > <stephen.smalley.work@gmail.com> wrote:
> > >
> > > On Fri, May 29, 2020 at 12:05 PM William Roberts
> > > <bill.c.roberts@gmail.com> wrote:
> > > >
> > > > On Fri, May 29, 2020 at 8:31 AM Stephen Smalley
> > > > <stephen.smalley.work@gmail.com> wrote:
> > > > >
> > > > > On Sat, May 23, 2020 at 11:59 AM William Roberts
> > > > > <bill.c.roberts@gmail.com> wrote:
> > > > > >
> > > > > > On Sat, May 23, 2020 at 5:57 AM Laurent Bigonville <bigon@debian.org> wrote:
> > > > > > >
> > > > > > > Hello,
> > > > > > >
> > > > > > > The current build system of the userspace is setting a lot of CFLAGS,
> > > > > > > but most of these are overridden by the distributions when building.
> > > > > > >
> > > > > > > Today I received a bug report[0] from Christian Göttsche asking me to
> > > > > > > set -fno-semantic-interposition again in libsepol. I see also the same
> > > > > > > flag and also a lot of others set in libselinux and libsemanage build
> > > > > > > system.
> > > > > >
> > > > > > Why would it be again? The old DSO design made that option impotent.
> > > > > > Clang does it by default.
> > > > > >
> > > > > > >
> > > > > > > For what I understand some of these are just needed for code quality
> > > > > > > (-W) and could be controlled by distributions but others might actually
> > > > > > > need to be always set (-f?).
> > > > > >
> > > > > > If you look at the Makefiles overall in all the projects, you'll see hardening
> > > > > > flags, etc. Libsepol has a pretty minimal set compared to say libselinux, but
> > > > > > they all get overridden by build time CFLAGS if you want.
> > > > > >
> > > > > > >
> > > > > > > Shouldn't the flags that always need to be set (which ones?) be moved to
> > > > > > > a "override CFLAGS" directive to avoid these to be unset by distributions?
> > > > > >
> > > > > > If you we're cleaver with CFLAGS before, you could acually circumvent
> > > > > > the buildtime
> > > > > > DSO stuff. While i'm not opposed to adding it to immutable flag, if
> > > > > > you're setting
> > > > > > CFLAGS, you're on your own. At least with the current design.
> > > > > >
> > > > > > I have no issues with adding it to override, but we would have to
> > > > > > overhaul a bunch
> > > > > > of them and make them consistent.
> > > > >
> > > > > I'm inclined to agree with Laurent here - we should always set this
> > > > > flag in order to preserve the same behavior prior to the patches that
> > > > > removed hidden_def/hidden_proto and switched to relying on this
> > > > > instead.
> > > >
> > > > Theirs a lot of features that rely on particular cflags, consider hardening
> > > > options. A lot of the warnings/error stuff is not just a code hygiene, but also
> > > > spotting potential issues that could arise as security issues. If one starts
> > > > tinkering with cflags, you can really change the code quite a bit. This is why
> > > > some places only approve sanctioned builds of crypto libraries.
> > >
> > > I think the difference here is that we made a change in the source
> > > code (hidden_def/hidden_proto removal) that requires use of
> > > -fno-semantic-interposition to preserve existing behavior.
> > >
> > > > But one of the things to consider is that for clang builds, clang
> > > > doesn't support
> > > > this option, so we would need to move the compiler checking code into each
> > > > projects root makefile and ensure any consuming subordinate leafs add a
> > > > default, or move it to the global makefile and make sure each leaf that needs it
> > > > has a default.
> > >
> > > I think clang does support it now? https://reviews.llvm.org/D72724
> >
> > Yeah but that bug is all 2020 stuff. It is in the clang-10 release. I
> > verified that
> > with a local build from here:
> > - https://apt.llvm.org/
> > So anything sub clang-10 won't support it, do you want to tie us to that
> > new of a clang?
>
> No, I guess not. So I guess our options are to leave it alone and
> just make sure it is well documented or complicate the Makefiles.
Pretty much, which is why I go back to, "If your setting CFLAGS, you better
make sure you get em right". There are so many options and so many things
that can affect the build output, you really need to get em right.
This is the one area autoconf/automake is nice (I have a hate/hate
relationship with it),
but it does give one easy-peasy feature test macros, so this problem
is simple to fix.
The problem with documentation is no one reads it :-p. We could do something
like issue a warning, compiler agnostic, from make if we don't detect the
-fsemantic-interposition option (easy). That would be simple, or I can
work up the
gcc/clang split patches (slightly harder).
Or we can just say, if your messing with CFLAGS do it right and you should
probably add -fsemantic-interposition if your using gcc documentation (easiest).
If they didn't change the CFLAGS for their build, they wouldn't have this issue.
Which brings up the question, "can they add the flags they need to the
Makefile?"
or "What do they need added/removed/changed in CFLAGS overall?"
I'd like to start with why they need to change CFLAGS, and can we just
make that the default?
^ permalink raw reply
* [Buildroot] [PATCH 1/2] package/rpi-firmware: select BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT when needed
From: Peter Korsgaard @ 2020-05-29 20:59 UTC (permalink / raw)
To: buildroot
In-Reply-To: <20200516140221.1464063-1-thomas.petazzoni@bootlin.com>
>>>>> "Thomas" == Thomas Petazzoni <thomas.petazzoni@bootlin.com> writes:
> When BR2_PACKAGE_RPI_FIRMWARE_INSTALL_DTB_OVERLAYS is enabled, and the
> DTBs are built by Linux (i.e BR2_LINUX_KERNEL_DTS_SUPPORT is enabled),
> these DTBs should be built with the -@ Device Tree compiler option, so
> that they can be used together with DTB overlays. So let's select
> BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT in this situation.
> Fixes:
> https://bugs.busybox.net/show_bug.cgi?id=12831
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Committed to 2020.02.x, thanks.
--
Bye, Peter Korsgaard
^ permalink raw reply
* [Buildroot] [PATCH 2/2] configs/raspberrypi{3, 4}_64: enabling BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT no longer needed
From: Peter Korsgaard @ 2020-05-29 20:59 UTC (permalink / raw)
To: buildroot
In-Reply-To: <20200516140221.1464063-2-thomas.petazzoni@bootlin.com>
>>>>> "Thomas" == Thomas Petazzoni <thomas.petazzoni@bootlin.com> writes:
> BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT is now forcefully selected by
> BR2_PACKAGE_RPI_FIRMWARE_INSTALL_DTB_OVERLAYS when the kernel is in
> charge of building DTBs (BR2_LINUX_KERNEL_DTS_SUPPORT=y). So enabling
> BR2_LINUX_KERNEL_DTB_OVERLAY_SUPPORT is no longer needed in the 64-bit
> defconfigs for Raspberry Pi 3 and 4.
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Committed to 2020.02.x, thanks.
--
Bye, Peter Korsgaard
^ permalink raw reply
* fs/xfs/libxfs/xfs_btree_staging.c:144 xfs_btree_stage_afakeroot() error: potential null dereference 'nops'. (kmem_alloc returns null)
From: kbuild test robot @ 2020-05-29 21:00 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 1998 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 75caf310d16cc5e2f851c048cd597f5437013368
commit: e06536a692e032470130af5b2136b519595809da xfs: introduce fake roots for ag-rooted btrees
date: 2 months ago
config: i386-randconfig-m021-20200529 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-13) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>
smatch warnings:
fs/xfs/libxfs/xfs_btree_staging.c:144 xfs_btree_stage_afakeroot() error: potential null dereference 'nops'. (kmem_alloc returns null)
vim +/nops +144 fs/xfs/libxfs/xfs_btree_staging.c
125
126 /*
127 * Initialize a AG-rooted btree cursor with the given AG btree fake root.
128 * The btree cursor's bc_ops will be overridden as needed to make the staging
129 * functionality work.
130 */
131 void
132 xfs_btree_stage_afakeroot(
133 struct xfs_btree_cur *cur,
134 struct xbtree_afakeroot *afake)
135 {
136 struct xfs_btree_ops *nops;
137
138 ASSERT(!(cur->bc_flags & XFS_BTREE_STAGING));
139 ASSERT(!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE));
140 ASSERT(cur->bc_tp == NULL);
141
142 nops = kmem_alloc(sizeof(struct xfs_btree_ops), KM_NOFS);
143 memcpy(nops, cur->bc_ops, sizeof(struct xfs_btree_ops));
> 144 nops->alloc_block = xfs_btree_fakeroot_alloc_block;
145 nops->free_block = xfs_btree_fakeroot_free_block;
146 nops->init_ptr_from_cur = xfs_btree_fakeroot_init_ptr_from_cur;
147 nops->set_root = xfs_btree_afakeroot_set_root;
148 nops->dup_cursor = xfs_btree_fakeroot_dup_cursor;
149
150 cur->bc_ag.afake = afake;
151 cur->bc_nlevels = afake->af_levels;
152 cur->bc_ops = nops;
153 cur->bc_flags |= XFS_BTREE_STAGING;
154 }
155
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 38946 bytes --]
^ permalink raw reply
* [PATCH v2 4/4] check-block: enable iotests with SafeStack
From: Daniele Buono @ 2020-05-29 20:51 UTC (permalink / raw)
To: qemu-devel
Cc: Kevin Wolf, Daniel P . Berrangé, Stefan Hajnoczi,
Paolo Bonzini, Philippe Mathieu-Daudé, dbuono
In-Reply-To: <20200529205122.714-1-dbuono@linux.vnet.ibm.com>
SafeStack is a stack protection technique implemented in llvm. It is
enabled with a -fsanitize flag.
iotests are currently disabled when any -fsanitize option is used,
because such options tend to produce additional warnings and false
positives.
While common -fsanitize options are used to verify the code and not
added in production, SafeStack's main use is in production environments
to protect against stack smashing.
Since SafeStack does not print any warning or false positive, enable
iotests when SafeStack is the only -fsanitize option used.
This is likely going to be a production binary and we want to make sure
it works correctly.
Signed-off-by: Daniele Buono <dbuono@linux.vnet.ibm.com>
---
tests/check-block.sh | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/tests/check-block.sh b/tests/check-block.sh
index ad320c21ba..8e29c868e5 100755
--- a/tests/check-block.sh
+++ b/tests/check-block.sh
@@ -21,7 +21,17 @@ if grep -q "CONFIG_GPROF=y" config-host.mak 2>/dev/null ; then
exit 0
fi
-if grep -q "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null ; then
+# Disable tests with any sanitizer except for SafeStack
+CFLAGS=$( grep "CFLAGS.*-fsanitize" config-host.mak 2>/dev/null )
+SANITIZE_FLAGS=""
+#Remove all occurrencies of -fsanitize=safe-stack
+for i in ${CFLAGS}; do
+ if [ "${i}" != "-fsanitize=safe-stack" ]; then
+ SANITIZE_FLAGS="${SANITIZE_FLAGS} ${i}"
+ fi
+done
+if echo ${SANITIZE_FLAGS} | grep -q "\-fsanitize" 2>/dev/null; then
+ # Have a sanitize flag that is not allowed, stop
echo "Sanitizers are enabled ==> Not running the qemu-iotests."
exit 0
fi
--
2.26.2
^ permalink raw reply related
* drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c:49:1: warning: no previous prototype for 'lsb_header_tail_dump'
From: kbuild test robot @ 2020-05-29 21:00 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 2489 bytes --]
Hi Ben,
FYI, the error/warning still remains.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 75caf310d16cc5e2f851c048cd597f5437013368
commit: 22dcda45a3d1dfe6eeb4ab0a3b9aaa2333cb649d drm/nouveau/acr: implement new subdev to replace "secure boot"
date: 5 months ago
config: arm64-sof-customedconfig-sst-defconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout 22dcda45a3d1dfe6eeb4ab0a3b9aaa2333cb649d
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>
All warnings (new ones prefixed by >>, old ones prefixed by <<):
>> drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c:49:1: warning: no previous prototype for 'lsb_header_tail_dump' [-Wmissing-prototypes]
49 | lsb_header_tail_dump(struct nvkm_subdev *subdev,
| ^~~~~~~~~~~~~~~~~~~~
vim +/lsb_header_tail_dump +49 drivers/gpu/drm/nouveau/nvkm/nvfw/acr.c
47
48 void
> 49 lsb_header_tail_dump(struct nvkm_subdev *subdev,
50 struct lsb_header_tail *hdr)
51 {
52 nvkm_debug(subdev, "lsbHeader\n");
53 nvkm_debug(subdev, "\tucodeOff : 0x%x\n", hdr->ucode_off);
54 nvkm_debug(subdev, "\tucodeSize : 0x%x\n", hdr->ucode_size);
55 nvkm_debug(subdev, "\tdataSize : 0x%x\n", hdr->data_size);
56 nvkm_debug(subdev, "\tblCodeSize : 0x%x\n", hdr->bl_code_size);
57 nvkm_debug(subdev, "\tblImemOff : 0x%x\n", hdr->bl_imem_off);
58 nvkm_debug(subdev, "\tblDataOff : 0x%x\n", hdr->bl_data_off);
59 nvkm_debug(subdev, "\tblDataSize : 0x%x\n", hdr->bl_data_size);
60 nvkm_debug(subdev, "\tappCodeOff : 0x%x\n", hdr->app_code_off);
61 nvkm_debug(subdev, "\tappCodeSize : 0x%x\n", hdr->app_code_size);
62 nvkm_debug(subdev, "\tappDataOff : 0x%x\n", hdr->app_data_off);
63 nvkm_debug(subdev, "\tappDataSize : 0x%x\n", hdr->app_data_size);
64 nvkm_debug(subdev, "\tflags : 0x%x\n", hdr->flags);
65 }
66
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 41446 bytes --]
^ permalink raw reply
* Re: [RFC PATCH 1/1] drm/mm: add ig_frag selftest
From: Nirmoy @ 2020-05-29 21:01 UTC (permalink / raw)
To: Chris Wilson, Nirmoy Das, dri-devel
Cc: intel-gfx, Nirmoy Das, christian.koenig
In-Reply-To: <159076753114.8851.15594151673471255964@build.alporthouse.com>
On 5/29/20 5:52 PM, Chris Wilson wrote:
> Quoting Nirmoy (2020-05-29 16:40:53)
>> This works correctly most of the times but sometimes
I have to take my word back. In another machine, 20k insertions in
best mode takes 6-9 times more than 10k insertions, all most all the time.
evict, bottom-up and top-down modes remains in 2-5 times range.
If I reduce the insertions to 1k and 2k then scaling factor for best
mode stays below 4 most of the time.
evict, bottom-up and top-down modes remains in 2-3 times range.
I wonder if it makes sense to test with only 1k and 2k insertions and
tolerate more than error if the mode == best.
Regards,
Nirmoy
>>
>> 20k insertions can take more than 8 times of 10k insertion time.
> The pressure is on to improve then :)
>
>> Regards,
>>
>> Nirmoy
>>
>> On 5/29/20 6:33 PM, Nirmoy Das wrote:
>>> This patch introduces fragmentation in the address range
>>> and measures time taken by 10k and 20k insertions. ig_frag()
>>> will fail if time taken by 20k insertions takes more than 4 times
>>> of 10k insertions as we know that insertions scale quadratically.
>>> Also tolerate 10% error because of kernel scheduler's jitters.
>>>
>>> Output:
>>> <snip>
>>> [ 8092.653518] drm_mm: Testing DRM range manger (struct drm_mm), with random_seed=0x9bfb4117 max_iterations=8192 max_prime=128
>>> [ 8092.653520] drm_mm: igt_sanitycheck - ok!
>>> [ 8092.653525] igt_debug 0x0000000000000000-0x0000000000000200: 512: free
>>> [ 8092.653526] igt_debug 0x0000000000000200-0x0000000000000600: 1024: used
>>> [ 8092.653527] igt_debug 0x0000000000000600-0x0000000000000a00: 1024: free
>>> [ 8092.653528] igt_debug 0x0000000000000a00-0x0000000000000e00: 1024: used
>>> [ 8092.653529] igt_debug 0x0000000000000e00-0x0000000000001000: 512: free
>>> [ 8092.653529] igt_debug total: 4096, used 2048 free 2048
>>> [ 8112.569813] drm_mm: best fragmented insert of 10000 and 20000 insertions took 504 and 1996 msecs
>>> [ 8112.723254] drm_mm: bottom-up fragmented insert of 10000 and 20000 insertions took 44 and 108 msecs
>>> [ 8112.813212] drm_mm: top-down fragmented insert of 10000 and 20000 insertions took 40 and 44 msecs
>>> [ 8112.847733] drm_mm: evict fragmented insert of 10000 and 20000 insertions took 8 and 20 msecs
>>> <snip>
>>>
>>> Signed-off-by: Nirmoy Das <nirmoy.das@amd.com>
>>> ---
>>> drivers/gpu/drm/selftests/drm_mm_selftests.h | 1 +
>>> drivers/gpu/drm/selftests/test-drm_mm.c | 73 ++++++++++++++++++++
>>> 2 files changed, 74 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/selftests/drm_mm_selftests.h b/drivers/gpu/drm/selftests/drm_mm_selftests.h
>>> index 6b943ea1c57d..8c87c964176b 100644
>>> --- a/drivers/gpu/drm/selftests/drm_mm_selftests.h
>>> +++ b/drivers/gpu/drm/selftests/drm_mm_selftests.h
>>> @@ -14,6 +14,7 @@ selftest(insert, igt_insert)
>>> selftest(replace, igt_replace)
>>> selftest(insert_range, igt_insert_range)
>>> selftest(align, igt_align)
>>> +selftest(frag, igt_frag)
>>> selftest(align32, igt_align32)
>>> selftest(align64, igt_align64)
>>> selftest(evict, igt_evict)
>>> diff --git a/drivers/gpu/drm/selftests/test-drm_mm.c b/drivers/gpu/drm/selftests/test-drm_mm.c
>>> index 9aabe82dcd3a..05d8f3659b4d 100644
>>> --- a/drivers/gpu/drm/selftests/test-drm_mm.c
>>> +++ b/drivers/gpu/drm/selftests/test-drm_mm.c
>>> @@ -1033,6 +1033,79 @@ static int igt_insert_range(void *ignored)
>>> return 0;
>>> }
>>>
>>> +static int get_insert_time(unsigned int num_insert,
>>> + const struct insert_mode *mode)
>>> +{
>>> + struct drm_mm mm;
>>> + struct drm_mm_node *nodes, *node, *next;
>>> + unsigned int size = 4096, align = 8192;
>>> + unsigned long start;
>>> + unsigned int i;
>>> + int ret = -EINVAL;
>>> +
>>> + drm_mm_init(&mm, 1, U64_MAX - 2);
>>> + nodes = vzalloc(array_size(num_insert, sizeof(*nodes)));
>>> + if (!nodes)
>>> + goto err;
>>> +
>>> + start = jiffies;
> Use ktime_t start = ktime_now();
>
>>> + for (i = 0; i < num_insert; i++) {
>>> + if (!expect_insert(&mm, &nodes[i], size, align, i, mode)) {
>>> + pr_err("%s insert failed\n", mode->name);
>>> + goto out;
>>> + }
>>> + }
>>> +
>>> + ret = jiffies_to_msecs(jiffies - start);
> ret = ktime_sub(ktime_now(), start);
>
> The downside to using ktime is remembering it is s64 and so requires care
> and attention in doing math.
>
>>> +out:
>>> + drm_mm_for_each_node_safe(node, next, &mm)
>>> + drm_mm_remove_node(node);
>>> + drm_mm_takedown(&mm);
>>> + vfree(nodes);
>>> +err:
>>> + return ret;
>>> +
>>> +}
>>> +
>>> +static int igt_frag(void *ignored)
>>> +{
>>> + const struct insert_mode *mode;
>>> + unsigned int insert_time1, insert_time2;
>>> + unsigned int insert_size = 10000;
>>> + unsigned int scale_factor = 4;
>>> + /* tolerate 10% excess insertion duration */
>>> + unsigned int error_factor = 110;
>>> + int ret = -EINVAL;
>>> +
>>> + for (mode = insert_modes; mode->name; mode++) {
>>> + unsigned int expected_time;
>>> +
>>> + insert_time1 = get_insert_time(insert_size, mode);
>>> + if (insert_time1 < 0)
>>> + goto err;
> Ah, can you propagate the actual error. I see you are returning EINVAL
> for ENOMEM errors. Just wait until it hits and you have to debug why :)
>
>>> + insert_time2 = get_insert_time((insert_size * 2), mode);
>>> + if (insert_time2 < 0)
>>> + goto err;
>>> +
>>> + expected_time = (scale_factor * insert_time1 *
>>> + error_factor)/100;
>>> + if (insert_time2 > expected_time) {
>>> + pr_err("%s fragmented insert took more %u msecs\n",
>>> + mode->name, insert_time2 - expected_time);
>>> + goto err;
>>> + }
>>> +
>>> + pr_info("%s fragmented insert of %u and %u insertions took %u and %u msecs\n",
>>> + mode->name, insert_size, insert_size * 2, insert_time1,
>>> + insert_time2);
> Put the info first before the error. We always want the full details,
> with the error message explaining why it's unhappy.
> -Chris
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Fdri-devel&data=02%7C01%7Cnirmoy.das%40amd.com%7C5c7df129b9cf44b3ae4008d803e84445%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637263643415833767&sdata=PrCQse4nhN0ZITT9OniuHhF7A5uxJD6ehk0PMjm7WMU%3D&reserved=0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH v8 45/62] target/riscv: narrowing floating-point/integer type-convert instructions
From: Alistair Francis @ 2020-05-29 20:51 UTC (permalink / raw)
To: LIU Zhiwei
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Richard Henderson, wxy194768, wenmeng_zhang, Alistair Francis,
Palmer Dabbelt
In-Reply-To: <20200521094413.10425-46-zhiwei_liu@c-sky.com>
On Thu, May 21, 2020 at 4:15 AM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/helper.h | 11 ++++++
> target/riscv/insn32.decode | 5 +++
> target/riscv/insn_trans/trans_rvv.inc.c | 47 +++++++++++++++++++++++++
> target/riscv/vector_helper.c | 39 ++++++++++++++++++++
> 4 files changed, 102 insertions(+)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index e59dcc5a7c..82c5d1129e 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -1022,3 +1022,14 @@ DEF_HELPER_5(vfwcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
> DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
> DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
> DEF_HELPER_5(vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
> +
> +DEF_HELPER_5(vfncvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index e0efc63ec2..57ac4de1c2 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -524,6 +524,11 @@ vfwcvt_x_f_v 100010 . ..... 01001 001 ..... 1010111 @r2_vm
> vfwcvt_f_xu_v 100010 . ..... 01010 001 ..... 1010111 @r2_vm
> vfwcvt_f_x_v 100010 . ..... 01011 001 ..... 1010111 @r2_vm
> vfwcvt_f_f_v 100010 . ..... 01100 001 ..... 1010111 @r2_vm
> +vfncvt_xu_f_v 100010 . ..... 10000 001 ..... 1010111 @r2_vm
> +vfncvt_x_f_v 100010 . ..... 10001 001 ..... 1010111 @r2_vm
> +vfncvt_f_xu_v 100010 . ..... 10010 001 ..... 1010111 @r2_vm
> +vfncvt_f_x_v 100010 . ..... 10011 001 ..... 1010111 @r2_vm
> +vfncvt_f_f_v 100010 . ..... 10100 001 ..... 1010111 @r2_vm
>
> vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm
> vsetvl 1000000 ..... ..... 111 ..... 1010111 @r
> diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c
> index 44505027c1..e63b88a4cc 100644
> --- a/target/riscv/insn_trans/trans_rvv.inc.c
> +++ b/target/riscv/insn_trans/trans_rvv.inc.c
> @@ -2268,3 +2268,50 @@ GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v)
> GEN_OPFV_WIDEN_TRANS(vfwcvt_f_xu_v)
> GEN_OPFV_WIDEN_TRANS(vfwcvt_f_x_v)
> GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v)
> +
> +/* Narrowing Floating-Point/Integer Type-Convert Instructions */
> +
> +/*
> + * If the current SEW does not correspond to a supported IEEE floating-point
> + * type, an illegal instruction exception is raised
> + */
> +static bool opfv_narrow_check(DisasContext *s, arg_rmr *a)
> +{
> + return (vext_check_isa_ill(s) &&
> + vext_check_overlap_mask(s, a->rd, a->vm, false) &&
> + vext_check_reg(s, a->rd, false) &&
> + vext_check_reg(s, a->rs2, true) &&
> + vext_check_overlap_group(a->rd, 1 << s->lmul, a->rs2,
> + 2 << s->lmul) &&
> + (s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0));
> +}
> +
> +#define GEN_OPFV_NARROW_TRANS(NAME) \
> +static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
> +{ \
> + if (opfv_narrow_check(s, a)) { \
> + uint32_t data = 0; \
> + static gen_helper_gvec_3_ptr * const fns[2] = { \
> + gen_helper_##NAME##_h, \
> + gen_helper_##NAME##_w, \
> + }; \
> + TCGLabel *over = gen_new_label(); \
> + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
> + \
> + data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \
> + data = FIELD_DP32(data, VDATA, VM, a->vm); \
> + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
> + tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
> + vreg_ofs(s, a->rs2), cpu_env, 0, \
> + s->vlen / 8, data, fns[s->sew - 1]); \
> + gen_set_label(over); \
> + return true; \
> + } \
> + return false; \
> +}
> +
> +GEN_OPFV_NARROW_TRANS(vfncvt_xu_f_v)
> +GEN_OPFV_NARROW_TRANS(vfncvt_x_f_v)
> +GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_v)
> +GEN_OPFV_NARROW_TRANS(vfncvt_f_x_v)
> +GEN_OPFV_NARROW_TRANS(vfncvt_f_f_v)
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index ea6a5853f3..8e525720d1 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -4292,3 +4292,42 @@ RVVCALL(OPFVV1, vfwcvt_f_f_v_h, WOP_UU_H, H4, H2, vfwcvtffv16)
> RVVCALL(OPFVV1, vfwcvt_f_f_v_w, WOP_UU_W, H8, H4, float32_to_float64)
> GEN_VEXT_V_ENV(vfwcvt_f_f_v_h, 2, 4, clearl)
> GEN_VEXT_V_ENV(vfwcvt_f_f_v_w, 4, 8, clearq)
> +
> +/* Narrowing Floating-Point/Integer Type-Convert Instructions */
> +/* (TD, T2, TX2) */
> +#define NOP_UU_H uint16_t, uint32_t, uint32_t
> +#define NOP_UU_W uint32_t, uint64_t, uint64_t
> +/* vfncvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer. */
> +RVVCALL(OPFVV1, vfncvt_xu_f_v_h, NOP_UU_H, H2, H4, float32_to_uint16)
> +RVVCALL(OPFVV1, vfncvt_xu_f_v_w, NOP_UU_W, H4, H8, float64_to_uint32)
> +GEN_VEXT_V_ENV(vfncvt_xu_f_v_h, 2, 2, clearh)
> +GEN_VEXT_V_ENV(vfncvt_xu_f_v_w, 4, 4, clearl)
> +
> +/* vfncvt.x.f.v vd, vs2, vm # Convert double-width float to signed integer. */
> +RVVCALL(OPFVV1, vfncvt_x_f_v_h, NOP_UU_H, H2, H4, float32_to_int16)
> +RVVCALL(OPFVV1, vfncvt_x_f_v_w, NOP_UU_W, H4, H8, float64_to_int32)
> +GEN_VEXT_V_ENV(vfncvt_x_f_v_h, 2, 2, clearh)
> +GEN_VEXT_V_ENV(vfncvt_x_f_v_w, 4, 4, clearl)
> +
> +/* vfncvt.f.xu.v vd, vs2, vm # Convert double-width unsigned integer to float */
> +RVVCALL(OPFVV1, vfncvt_f_xu_v_h, NOP_UU_H, H2, H4, uint32_to_float16)
> +RVVCALL(OPFVV1, vfncvt_f_xu_v_w, NOP_UU_W, H4, H8, uint64_to_float32)
> +GEN_VEXT_V_ENV(vfncvt_f_xu_v_h, 2, 2, clearh)
> +GEN_VEXT_V_ENV(vfncvt_f_xu_v_w, 4, 4, clearl)
> +
> +/* vfncvt.f.x.v vd, vs2, vm # Convert double-width integer to float. */
> +RVVCALL(OPFVV1, vfncvt_f_x_v_h, NOP_UU_H, H2, H4, int32_to_float16)
> +RVVCALL(OPFVV1, vfncvt_f_x_v_w, NOP_UU_W, H4, H8, int64_to_float32)
> +GEN_VEXT_V_ENV(vfncvt_f_x_v_h, 2, 2, clearh)
> +GEN_VEXT_V_ENV(vfncvt_f_x_v_w, 4, 4, clearl)
> +
> +/* vfncvt.f.f.v vd, vs2, vm # Convert double float to single-width float. */
> +static uint16_t vfncvtffv16(uint32_t a, float_status *s)
> +{
> + return float32_to_float16(a, true, s);
> +}
> +
> +RVVCALL(OPFVV1, vfncvt_f_f_v_h, NOP_UU_H, H2, H4, vfncvtffv16)
> +RVVCALL(OPFVV1, vfncvt_f_f_v_w, NOP_UU_W, H4, H8, float64_to_float32)
> +GEN_VEXT_V_ENV(vfncvt_f_f_v_h, 2, 2, clearh)
> +GEN_VEXT_V_ENV(vfncvt_f_f_v_w, 4, 4, clearl)
> --
> 2.23.0
>
>
^ permalink raw reply
* [PATCH 0/2] objtool: Support implicit addend relocations
From: Matt Helsley @ 2020-05-29 21:01 UTC (permalink / raw)
To: linux-kernel
Cc: Josh Poimboeuf, Peter Zijlstra, Steven Rostedt, Julien Thierry,
Matt Helsley
Future tools that use objtool to process ELF object files may require
reading or even modifying relocations with implicit addends. This
series cleans up the naming of the relocation struct in objtool,
variable names, and function names to be consistent with a more
generic use rather than being specific to those applying explicit
addends.
Changes since RFC [1]:
* Dropped the second patch and rebased on tip objtool/core with
patch[2] from Sami Tolvanen [Josh Poimboeuf]
* Remade the rename patch with a sed script and added script to
the commit message to aid backports. [Josh]
* Removed function pointers from last patch. [Josh]
* Added relocation type parameter to elf_create_reloc_section()
to match pattern with relocation section rebuilding.
[1] https://lore.kernel.org/lkml/cover.1590597288.git.mhelsley@vmware.com
[2] https://lore.kernel.org/lkml/20200421182501.149101-1-samitolvanen@google.com/
Matt Helsley (2):
objtool: Rename rela to reloc
objtool: Add support for relocations without addends
tools/objtool/arch.h | 2 +-
tools/objtool/arch/x86/decode.c | 2 +-
tools/objtool/check.c | 190 +++++++++++------------
tools/objtool/check.h | 2 +-
tools/objtool/elf.c | 262 +++++++++++++++++++++++---------
tools/objtool/elf.h | 27 ++--
tools/objtool/orc_gen.c | 44 +++---
tools/objtool/special.c | 22 +--
8 files changed, 333 insertions(+), 218 deletions(-)
base-commit: 0decf1f8de919782b152daf9c991967a2bac54f0
prerequisite-patch-id: 83ac956b6b4a769cafcdc4abaea4a3bcc3136d6d
--
2.20.1
^ permalink raw reply
* [PATCH 2/2] objtool: Add support for relocations without addends
From: Matt Helsley @ 2020-05-29 21:01 UTC (permalink / raw)
To: linux-kernel
Cc: Josh Poimboeuf, Peter Zijlstra, Steven Rostedt, Julien Thierry,
Matt Helsley
In-Reply-To: <cover.1590785960.git.mhelsley@vmware.com>
Currently objtool only collects information about relocations with
addends. In recordmcount, which we are about to merge into objtool,
some supported architectures do not use rela relocations.
Signed-off-by: Matt Helsley <mhelsley@vmware.com>
---
tools/objtool/elf.c | 146 +++++++++++++++++++++++++++++++++++-----
tools/objtool/elf.h | 7 +-
tools/objtool/orc_gen.c | 2 +-
3 files changed, 135 insertions(+), 20 deletions(-)
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index c21e8417637b..5034918494b6 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -490,6 +490,32 @@ void elf_add_reloc(struct elf *elf, struct reloc *reloc)
elf_hash_add(elf->reloc_hash, &reloc->hash, reloc_hash(reloc));
}
+static int read_rel_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx)
+{
+ if (!gelf_getrel(sec->data, i, &reloc->rel)) {
+ WARN_ELF("gelf_getrel");
+ return -1;
+ }
+ reloc->type = GELF_R_TYPE(reloc->rel.r_info);
+ reloc->addend = 0;
+ reloc->offset = reloc->rel.r_offset;
+ *symndx = GELF_R_SYM(reloc->rel.r_info);
+ return 0;
+}
+
+static int read_rela_reloc(struct section *sec, int i, struct reloc *reloc, unsigned int *symndx)
+{
+ if (!gelf_getrela(sec->data, i, &reloc->rela)) {
+ WARN_ELF("gelf_getrela");
+ return -1;
+ }
+ reloc->type = GELF_R_TYPE(reloc->rela.r_info);
+ reloc->addend = reloc->rela.r_addend;
+ reloc->offset = reloc->rela.r_offset;
+ *symndx = GELF_R_SYM(reloc->rela.r_info);
+ return 0;
+}
+
static int read_relocs(struct elf *elf)
{
struct section *sec;
@@ -499,7 +525,8 @@ static int read_relocs(struct elf *elf)
unsigned long nr_reloc, max_reloc = 0, tot_reloc = 0;
list_for_each_entry(sec, &elf->sections, list) {
- if (sec->sh.sh_type != SHT_RELA)
+ if ((sec->sh.sh_type != SHT_RELA) &&
+ (sec->sh.sh_type != SHT_REL))
continue;
sec->base = find_section_by_index(elf, sec->sh.sh_info);
@@ -519,16 +546,17 @@ static int read_relocs(struct elf *elf)
return -1;
}
memset(reloc, 0, sizeof(*reloc));
-
- if (!gelf_getrela(sec->data, i, &reloc->rela)) {
- WARN_ELF("gelf_getrela");
- return -1;
+ switch(sec->sh.sh_type) {
+ case SHT_REL:
+ if (read_rel_reloc(sec, i, reloc, &symndx))
+ return -1;
+ break;
+ case SHT_RELA:
+ if (read_rela_reloc(sec, i, reloc, &symndx))
+ return -1;
+ break;
+ default: return -1;
}
-
- reloc->type = GELF_R_TYPE(reloc->rela.r_info);
- reloc->addend = reloc->rela.r_addend;
- reloc->offset = reloc->rela.r_offset;
- symndx = GELF_R_SYM(reloc->rela.r_info);
reloc->sym = find_symbol_by_index(elf, symndx);
reloc->sec = sec;
if (!reloc->sym) {
@@ -716,7 +744,38 @@ struct section *elf_create_section(struct elf *elf, const char *name,
return sec;
}
-struct section *elf_create_reloc_section(struct elf *elf, struct section *base)
+static struct section *elf_create_rel_reloc_section(struct elf *elf, struct section *base)
+{
+ char *relocname;
+ struct section *sec;
+
+ relocname = malloc(strlen(base->name) + strlen(".rel") + 1);
+ if (!relocname) {
+ perror("malloc");
+ return NULL;
+ }
+ strcpy(relocname, ".rel");
+ strcat(relocname, base->name);
+
+ sec = elf_create_section(elf, relocname, sizeof(GElf_Rel), 0);
+ free(relocname);
+ if (!sec)
+ return NULL;
+
+ base->reloc = sec;
+ sec->base = base;
+
+ sec->sh.sh_type = SHT_REL;
+ sec->sh.sh_addralign = 8;
+ sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx;
+ sec->sh.sh_info = base->idx;
+ sec->sh.sh_flags = SHF_INFO_LINK;
+
+ return sec;
+}
+
+
+static struct section *elf_create_rela_reloc_section(struct elf *elf, struct section *base)
{
char *relocname;
struct section *sec;
@@ -746,16 +805,53 @@ struct section *elf_create_reloc_section(struct elf *elf, struct section *base)
return sec;
}
-int elf_rebuild_reloc_section(struct section *sec)
+struct section *elf_create_reloc_section(struct elf *elf,
+ struct section *base,
+ int reltype)
+{
+ switch(reltype) {
+ case SHT_REL: return elf_create_rel_reloc_section(elf, base);
+ case SHT_RELA: return elf_create_rela_reloc_section(elf, base);
+ default: return NULL;
+ }
+}
+
+static int elf_rebuild_rel_reloc_section(struct section *sec, int nr)
{
struct reloc *reloc;
- int nr, idx = 0, size;
- GElf_Rela *relocs;
+ int idx = 0, size;
+ GElf_Rel *relocs;
- nr = 0;
- list_for_each_entry(reloc, &sec->reloc_list, list)
- nr++;
+ /* Allocate a buffer for relocations */
+ size = nr * sizeof(*relocs);
+ relocs = malloc(size);
+ if (!relocs) {
+ perror("malloc");
+ return -1;
+ }
+
+ sec->data->d_buf = relocs;
+ sec->data->d_size = size;
+ sec->sh.sh_size = size;
+
+ idx = 0;
+ list_for_each_entry(reloc, &sec->reloc_list, list) {
+ relocs[idx].r_offset = reloc->offset;
+ relocs[idx].r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
+ idx++;
+ }
+
+ return 0;
+}
+
+static int elf_rebuild_rela_reloc_section(struct section *sec, int nr)
+{
+ struct reloc *reloc;
+ int idx = 0, size;
+ GElf_Rela *relocs;
+
+ /* Allocate a buffer for relocations with addends */
size = nr * sizeof(*relocs);
relocs = malloc(size);
if (!relocs) {
@@ -779,6 +875,22 @@ int elf_rebuild_reloc_section(struct section *sec)
return 0;
}
+int elf_rebuild_reloc_section(struct section *sec)
+{
+ struct reloc *reloc;
+ int nr;
+
+ nr = 0;
+ list_for_each_entry(reloc, &sec->reloc_list, list)
+ nr++;
+
+ switch(sec->sh.sh_type) {
+ case SHT_REL: return elf_rebuild_rel_reloc_section(sec, nr);
+ case SHT_RELA: return elf_rebuild_rela_reloc_section(sec, nr);
+ default: return -1;
+ }
+}
+
int elf_write(const struct elf *elf)
{
struct section *sec;
diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
index 6ad759fd778e..78a2db23b8b6 100644
--- a/tools/objtool/elf.h
+++ b/tools/objtool/elf.h
@@ -61,7 +61,10 @@ struct symbol {
struct reloc {
struct list_head list;
struct hlist_node hash;
- GElf_Rela rela;
+ union {
+ GElf_Rela rela;
+ GElf_Rel rel;
+ };
struct section *sec;
struct symbol *sym;
unsigned int type;
@@ -116,7 +119,7 @@ static inline u32 reloc_hash(struct reloc *reloc)
struct elf *elf_open_read(const char *name, int flags);
struct section *elf_create_section(struct elf *elf, const char *name, size_t entsize, int nr);
-struct section *elf_create_reloc_section(struct elf *elf, struct section *base);
+struct section *elf_create_reloc_section(struct elf *elf, struct section *base, int reltype);
void elf_add_reloc(struct elf *elf, struct reloc *reloc);
int elf_write(const struct elf *elf);
void elf_close(struct elf *elf);
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
index b538a0408cde..47875e83598b 100644
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -181,7 +181,7 @@ int create_orc_sections(struct objtool_file *file)
if (!sec)
return -1;
- ip_relocsec = elf_create_reloc_section(file->elf, sec);
+ ip_relocsec = elf_create_reloc_section(file->elf, sec, SHT_RELA);
if (!ip_relocsec)
return -1;
--
2.20.1
^ permalink raw reply related
* [PATCH 1/2] objtool: Rename rela to reloc
From: Matt Helsley @ 2020-05-29 21:01 UTC (permalink / raw)
To: linux-kernel
Cc: Josh Poimboeuf, Peter Zijlstra, Steven Rostedt, Julien Thierry,
Matt Helsley
In-Reply-To: <cover.1590785960.git.mhelsley@vmware.com>
Before supporting additional relocation types rename the relevant
types and functions from "rela" to "reloc". This work be done with
the following regex:
sed -i -e 's/struct rela/struct reloc/g' \
-e 's/\([_\*]\)rela\(s\{0,1\}\)/\1reloc\2/g' \
-e 's/tmprela\(s\{0,1\}\)/tmpreloc\1/g' \
-e 's/relasec/relocsec/g' \
-e 's/rela_list/reloc_list/g' \
-e 's/rela_hash/reloc_hash/g' \
-e 's/add_rela/add_reloc/g' \
-e 's/rela->/reloc->/g' \
-e '/rela[,\.]/{ s/\([^\.>]\)rela\([\.,]\)/\1reloc\2/g ; }' \
-e 's/rela =/reloc =/g' \
-e 's/relas =/relocs =/g' \
-e 's/relas\[/relocs[/g' \
-e 's/relaname =/relocname =/g' \
-e 's/= rela\;/= reloc\;/g' \
-e 's/= relas\;/= relocs\;/g' \
-e 's/= relaname\;/= relocname\;/g' \
-e 's/, rela)/, reloc)/g' \
-e 's/, relaname/, relocname/g' \
-e 's/sec->rela/sec->reloc/g' \
-e 's/(\(!\{0,1\}\)rela/(\1reloc/g' \
arch.h \
arch/x86/decode.c \
check.c \
check.h \
elf.c \
elf.h \
orc_gen.c \
special.c \
Notable exceptions which complicate the regex include gelf_*
library calls and standard/expected section names which still use
"rela" because they encode the type of relocation expected. Also, keep
"rela" in the struct because it encodes a specific type of relocation
we currently expect.
It will eventually turn into a member of an anonymous union when a
susequent patch adds implicit addend, or "rel", relocation support.
Signed-off-by: Matt Helsley <mhelsley@vmware.com>
---
tools/objtool/arch.h | 2 +-
tools/objtool/arch/x86/decode.c | 2 +-
tools/objtool/check.c | 190 ++++++++++++++++----------------
tools/objtool/check.h | 2 +-
tools/objtool/elf.c | 134 +++++++++++-----------
tools/objtool/elf.h | 22 ++--
tools/objtool/orc_gen.c | 44 ++++----
tools/objtool/special.c | 22 ++--
8 files changed, 209 insertions(+), 209 deletions(-)
diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h
index eda15a5a285e..d0969a9328c2 100644
--- a/tools/objtool/arch.h
+++ b/tools/objtool/arch.h
@@ -82,6 +82,6 @@ bool arch_callee_saved_reg(unsigned char reg);
unsigned long arch_jump_destination(struct instruction *insn);
-unsigned long arch_dest_rela_offset(int addend);
+unsigned long arch_dest_reloc_offset(int addend);
#endif /* _ARCH_H */
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 4b504fc90bbb..fe83d4c92825 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -67,7 +67,7 @@ bool arch_callee_saved_reg(unsigned char reg)
}
}
-unsigned long arch_dest_rela_offset(int addend)
+unsigned long arch_dest_reloc_offset(int addend)
{
return addend + 4;
}
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 63d65a702900..4c39734b29ed 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -352,7 +352,7 @@ static struct instruction *find_last_insn(struct objtool_file *file,
static int add_dead_ends(struct objtool_file *file)
{
struct section *sec;
- struct rela *rela;
+ struct reloc *reloc;
struct instruction *insn;
/*
@@ -370,24 +370,24 @@ static int add_dead_ends(struct objtool_file *file)
if (!sec)
goto reachable;
- list_for_each_entry(rela, &sec->rela_list, list) {
- if (rela->sym->type != STT_SECTION) {
+ list_for_each_entry(reloc, &sec->reloc_list, list) {
+ if (reloc->sym->type != STT_SECTION) {
WARN("unexpected relocation symbol type in %s", sec->name);
return -1;
}
- insn = find_insn(file, rela->sym->sec, rela->addend);
+ insn = find_insn(file, reloc->sym->sec, reloc->addend);
if (insn)
insn = list_prev_entry(insn, list);
- else if (rela->addend == rela->sym->sec->len) {
- insn = find_last_insn(file, rela->sym->sec);
+ else if (reloc->addend == reloc->sym->sec->len) {
+ insn = find_last_insn(file, reloc->sym->sec);
if (!insn) {
WARN("can't find unreachable insn at %s+0x%x",
- rela->sym->sec->name, rela->addend);
+ reloc->sym->sec->name, reloc->addend);
return -1;
}
} else {
WARN("can't find unreachable insn at %s+0x%x",
- rela->sym->sec->name, rela->addend);
+ reloc->sym->sec->name, reloc->addend);
return -1;
}
@@ -405,24 +405,24 @@ static int add_dead_ends(struct objtool_file *file)
if (!sec)
return 0;
- list_for_each_entry(rela, &sec->rela_list, list) {
- if (rela->sym->type != STT_SECTION) {
+ list_for_each_entry(reloc, &sec->reloc_list, list) {
+ if (reloc->sym->type != STT_SECTION) {
WARN("unexpected relocation symbol type in %s", sec->name);
return -1;
}
- insn = find_insn(file, rela->sym->sec, rela->addend);
+ insn = find_insn(file, reloc->sym->sec, reloc->addend);
if (insn)
insn = list_prev_entry(insn, list);
- else if (rela->addend == rela->sym->sec->len) {
- insn = find_last_insn(file, rela->sym->sec);
+ else if (reloc->addend == reloc->sym->sec->len) {
+ insn = find_last_insn(file, reloc->sym->sec);
if (!insn) {
WARN("can't find reachable insn at %s+0x%x",
- rela->sym->sec->name, rela->addend);
+ reloc->sym->sec->name, reloc->addend);
return -1;
}
} else {
WARN("can't find reachable insn at %s+0x%x",
- rela->sym->sec->name, rela->addend);
+ reloc->sym->sec->name, reloc->addend);
return -1;
}
@@ -440,26 +440,26 @@ static void add_ignores(struct objtool_file *file)
struct instruction *insn;
struct section *sec;
struct symbol *func;
- struct rela *rela;
+ struct reloc *reloc;
sec = find_section_by_name(file->elf, ".rela.discard.func_stack_frame_non_standard");
if (!sec)
return;
- list_for_each_entry(rela, &sec->rela_list, list) {
- switch (rela->sym->type) {
+ list_for_each_entry(reloc, &sec->reloc_list, list) {
+ switch (reloc->sym->type) {
case STT_FUNC:
- func = rela->sym;
+ func = reloc->sym;
break;
case STT_SECTION:
- func = find_func_by_offset(rela->sym->sec, rela->addend);
+ func = find_func_by_offset(reloc->sym->sec, reloc->addend);
if (!func)
continue;
break;
default:
- WARN("unexpected relocation symbol type in %s: %d", sec->name, rela->sym->type);
+ WARN("unexpected relocation symbol type in %s: %d", sec->name, reloc->sym->type);
continue;
}
@@ -557,20 +557,20 @@ static void add_uaccess_safe(struct objtool_file *file)
static int add_ignore_alternatives(struct objtool_file *file)
{
struct section *sec;
- struct rela *rela;
+ struct reloc *reloc;
struct instruction *insn;
sec = find_section_by_name(file->elf, ".rela.discard.ignore_alts");
if (!sec)
return 0;
- list_for_each_entry(rela, &sec->rela_list, list) {
- if (rela->sym->type != STT_SECTION) {
+ list_for_each_entry(reloc, &sec->reloc_list, list) {
+ if (reloc->sym->type != STT_SECTION) {
WARN("unexpected relocation symbol type in %s", sec->name);
return -1;
}
- insn = find_insn(file, rela->sym->sec, rela->addend);
+ insn = find_insn(file, reloc->sym->sec, reloc->addend);
if (!insn) {
WARN("bad .discard.ignore_alts entry");
return -1;
@@ -588,7 +588,7 @@ static int add_ignore_alternatives(struct objtool_file *file)
static int add_jump_destinations(struct objtool_file *file)
{
struct instruction *insn;
- struct rela *rela;
+ struct reloc *reloc;
struct section *dest_sec;
unsigned long dest_off;
@@ -599,19 +599,19 @@ static int add_jump_destinations(struct objtool_file *file)
if (insn->ignore || insn->offset == FAKE_JUMP_OFFSET)
continue;
- rela = find_rela_by_dest_range(file->elf, insn->sec,
+ reloc = find_reloc_by_dest_range(file->elf, insn->sec,
insn->offset, insn->len);
- if (!rela) {
+ if (!reloc) {
dest_sec = insn->sec;
dest_off = arch_jump_destination(insn);
- } else if (rela->sym->type == STT_SECTION) {
- dest_sec = rela->sym->sec;
- dest_off = arch_dest_rela_offset(rela->addend);
- } else if (rela->sym->sec->idx) {
- dest_sec = rela->sym->sec;
- dest_off = rela->sym->sym.st_value +
- arch_dest_rela_offset(rela->addend);
- } else if (strstr(rela->sym->name, "_indirect_thunk_")) {
+ } else if (reloc->sym->type == STT_SECTION) {
+ dest_sec = reloc->sym->sec;
+ dest_off = arch_dest_reloc_offset(reloc->addend);
+ } else if (reloc->sym->sec->idx) {
+ dest_sec = reloc->sym->sec;
+ dest_off = reloc->sym->sym.st_value +
+ arch_dest_reloc_offset(reloc->addend);
+ } else if (strstr(reloc->sym->name, "_indirect_thunk_")) {
/*
* Retpoline jumps are really dynamic jumps in
* disguise, so convert them accordingly.
@@ -625,7 +625,7 @@ static int add_jump_destinations(struct objtool_file *file)
continue;
} else {
/* external sibling call */
- insn->call_dest = rela->sym;
+ insn->call_dest = reloc->sym;
continue;
}
@@ -701,15 +701,15 @@ static int add_call_destinations(struct objtool_file *file)
{
struct instruction *insn;
unsigned long dest_off;
- struct rela *rela;
+ struct reloc *reloc;
for_each_insn(file, insn) {
if (insn->type != INSN_CALL)
continue;
- rela = find_rela_by_dest_range(file->elf, insn->sec,
+ reloc = find_reloc_by_dest_range(file->elf, insn->sec,
insn->offset, insn->len);
- if (!rela) {
+ if (!reloc) {
dest_off = arch_jump_destination(insn);
insn->call_dest = find_func_by_offset(insn->sec, dest_off);
if (!insn->call_dest)
@@ -729,19 +729,19 @@ static int add_call_destinations(struct objtool_file *file)
return -1;
}
- } else if (rela->sym->type == STT_SECTION) {
- dest_off = arch_dest_rela_offset(rela->addend);
- insn->call_dest = find_func_by_offset(rela->sym->sec,
+ } else if (reloc->sym->type == STT_SECTION) {
+ dest_off = arch_dest_reloc_offset(reloc->addend);
+ insn->call_dest = find_func_by_offset(reloc->sym->sec,
dest_off);
if (!insn->call_dest) {
WARN_FUNC("can't find call dest symbol at %s+0x%lx",
insn->sec, insn->offset,
- rela->sym->sec->name,
+ reloc->sym->sec->name,
dest_off);
return -1;
}
} else
- insn->call_dest = rela->sym;
+ insn->call_dest = reloc->sym;
/*
* Whatever stack impact regular CALLs have, should be undone
@@ -849,7 +849,7 @@ static int handle_group_alt(struct objtool_file *file,
*/
if ((insn->offset != special_alt->new_off ||
(insn->type != INSN_CALL && !is_static_jump(insn))) &&
- find_rela_by_dest_range(file->elf, insn->sec, insn->offset, insn->len)) {
+ find_reloc_by_dest_range(file->elf, insn->sec, insn->offset, insn->len)) {
WARN_FUNC("unsupported relocation in alternatives section",
insn->sec, insn->offset);
@@ -995,9 +995,9 @@ static int add_special_section_alts(struct objtool_file *file)
}
static int add_jump_table(struct objtool_file *file, struct instruction *insn,
- struct rela *table)
+ struct reloc *table)
{
- struct rela *rela = table;
+ struct reloc *reloc = table;
struct instruction *dest_insn;
struct alternative *alt;
struct symbol *pfunc = insn->func->pfunc;
@@ -1007,22 +1007,22 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
* Each @rela is a switch table relocation which points to the target
* instruction.
*/
- list_for_each_entry_from(rela, &table->sec->rela_list, list) {
+ list_for_each_entry_from(reloc, &table->sec->reloc_list, list) {
/* Check for the end of the table: */
- if (rela != table && rela->jump_table_start)
+ if (reloc != table && reloc->jump_table_start)
break;
/* Make sure the table entries are consecutive: */
- if (prev_offset && rela->offset != prev_offset + 8)
+ if (prev_offset && reloc->offset != prev_offset + 8)
break;
/* Detect function pointers from contiguous objects: */
- if (rela->sym->sec == pfunc->sec &&
- rela->addend == pfunc->offset)
+ if (reloc->sym->sec == pfunc->sec &&
+ reloc->addend == pfunc->offset)
break;
- dest_insn = find_insn(file, rela->sym->sec, rela->addend);
+ dest_insn = find_insn(file, reloc->sym->sec, reloc->addend);
if (!dest_insn)
break;
@@ -1038,7 +1038,7 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
alt->insn = dest_insn;
list_add_tail(&alt->list, &insn->alts);
- prev_offset = rela->offset;
+ prev_offset = reloc->offset;
}
if (!prev_offset) {
@@ -1093,11 +1093,11 @@ static int add_jump_table(struct objtool_file *file, struct instruction *insn,
*
* NOTE: RETPOLINE made it harder still to decode dynamic jumps.
*/
-static struct rela *find_jump_table(struct objtool_file *file,
+static struct reloc *find_jump_table(struct objtool_file *file,
struct symbol *func,
struct instruction *insn)
{
- struct rela *text_rela, *table_rela;
+ struct reloc *text_reloc, *table_reloc;
struct instruction *dest_insn, *orig_insn = insn;
struct section *table_sec;
unsigned long table_offset;
@@ -1122,16 +1122,16 @@ static struct rela *find_jump_table(struct objtool_file *file,
break;
/* look for a relocation which references .rodata */
- text_rela = find_rela_by_dest_range(file->elf, insn->sec,
+ text_reloc = find_reloc_by_dest_range(file->elf, insn->sec,
insn->offset, insn->len);
- if (!text_rela || text_rela->sym->type != STT_SECTION ||
- !text_rela->sym->sec->rodata)
+ if (!text_reloc || text_reloc->sym->type != STT_SECTION ||
+ !text_reloc->sym->sec->rodata)
continue;
- table_offset = text_rela->addend;
- table_sec = text_rela->sym->sec;
+ table_offset = text_reloc->addend;
+ table_sec = text_reloc->sym->sec;
- if (text_rela->type == R_X86_64_PC32)
+ if (text_reloc->type == R_X86_64_PC32)
table_offset += 4;
/*
@@ -1152,10 +1152,10 @@ static struct rela *find_jump_table(struct objtool_file *file,
* should reference text in the same function as the original
* instruction.
*/
- table_rela = find_rela_by_dest(file->elf, table_sec, table_offset);
- if (!table_rela)
+ table_reloc = find_reloc_by_dest(file->elf, table_sec, table_offset);
+ if (!table_reloc)
continue;
- dest_insn = find_insn(file, table_rela->sym->sec, table_rela->addend);
+ dest_insn = find_insn(file, table_reloc->sym->sec, table_reloc->addend);
if (!dest_insn || !dest_insn->func || dest_insn->func->pfunc != func)
continue;
@@ -1164,10 +1164,10 @@ static struct rela *find_jump_table(struct objtool_file *file,
* indicates a rare GCC quirk/bug which can leave dead code
* behind.
*/
- if (text_rela->type == R_X86_64_PC32)
+ if (text_reloc->type == R_X86_64_PC32)
file->ignore_unreachables = true;
- return table_rela;
+ return table_reloc;
}
return NULL;
@@ -1181,7 +1181,7 @@ static void mark_func_jump_tables(struct objtool_file *file,
struct symbol *func)
{
struct instruction *insn, *last = NULL;
- struct rela *rela;
+ struct reloc *reloc;
func_for_each_insn(file, func, insn) {
if (!last)
@@ -1204,10 +1204,10 @@ static void mark_func_jump_tables(struct objtool_file *file,
if (insn->type != INSN_JUMP_DYNAMIC)
continue;
- rela = find_jump_table(file, func, insn);
- if (rela) {
- rela->jump_table_start = true;
- insn->jump_table = rela;
+ reloc = find_jump_table(file, func, insn);
+ if (reloc) {
+ reloc->jump_table_start = true;
+ insn->jump_table = reloc;
}
}
}
@@ -1261,8 +1261,8 @@ static int add_jump_table_alts(struct objtool_file *file)
static int read_unwind_hints(struct objtool_file *file)
{
- struct section *sec, *relasec;
- struct rela *rela;
+ struct section *sec, *relocsec;
+ struct reloc *reloc;
struct unwind_hint *hint;
struct instruction *insn;
struct cfi_reg *cfa;
@@ -1272,8 +1272,8 @@ static int read_unwind_hints(struct objtool_file *file)
if (!sec)
return 0;
- relasec = sec->rela;
- if (!relasec) {
+ relocsec = sec->reloc;
+ if (!relocsec) {
WARN("missing .rela.discard.unwind_hints section");
return -1;
}
@@ -1288,13 +1288,13 @@ static int read_unwind_hints(struct objtool_file *file)
for (i = 0; i < sec->len / sizeof(struct unwind_hint); i++) {
hint = (struct unwind_hint *)sec->data->d_buf + i;
- rela = find_rela_by_dest(file->elf, sec, i * sizeof(*hint));
- if (!rela) {
+ reloc = find_reloc_by_dest(file->elf, sec, i * sizeof(*hint));
+ if (!reloc) {
WARN("can't find rela for unwind_hints[%d]", i);
return -1;
}
- insn = find_insn(file, rela->sym->sec, rela->addend);
+ insn = find_insn(file, reloc->sym->sec, reloc->addend);
if (!insn) {
WARN("can't find insn for unwind_hints[%d]", i);
return -1;
@@ -1352,19 +1352,19 @@ static int read_retpoline_hints(struct objtool_file *file)
{
struct section *sec;
struct instruction *insn;
- struct rela *rela;
+ struct reloc *reloc;
sec = find_section_by_name(file->elf, ".rela.discard.retpoline_safe");
if (!sec)
return 0;
- list_for_each_entry(rela, &sec->rela_list, list) {
- if (rela->sym->type != STT_SECTION) {
+ list_for_each_entry(reloc, &sec->reloc_list, list) {
+ if (reloc->sym->type != STT_SECTION) {
WARN("unexpected relocation symbol type in %s", sec->name);
return -1;
}
- insn = find_insn(file, rela->sym->sec, rela->addend);
+ insn = find_insn(file, reloc->sym->sec, reloc->addend);
if (!insn) {
WARN("bad .discard.retpoline_safe entry");
return -1;
@@ -1387,19 +1387,19 @@ static int read_instr_hints(struct objtool_file *file)
{
struct section *sec;
struct instruction *insn;
- struct rela *rela;
+ struct reloc *reloc;
sec = find_section_by_name(file->elf, ".rela.discard.instr_end");
if (!sec)
return 0;
- list_for_each_entry(rela, &sec->rela_list, list) {
- if (rela->sym->type != STT_SECTION) {
+ list_for_each_entry(reloc, &sec->reloc_list, list) {
+ if (reloc->sym->type != STT_SECTION) {
WARN("unexpected relocation symbol type in %s", sec->name);
return -1;
}
- insn = find_insn(file, rela->sym->sec, rela->addend);
+ insn = find_insn(file, reloc->sym->sec, reloc->addend);
if (!insn) {
WARN("bad .discard.instr_end entry");
return -1;
@@ -1412,13 +1412,13 @@ static int read_instr_hints(struct objtool_file *file)
if (!sec)
return 0;
- list_for_each_entry(rela, &sec->rela_list, list) {
- if (rela->sym->type != STT_SECTION) {
+ list_for_each_entry(reloc, &sec->reloc_list, list) {
+ if (reloc->sym->type != STT_SECTION) {
WARN("unexpected relocation symbol type in %s", sec->name);
return -1;
}
- insn = find_insn(file, rela->sym->sec, rela->addend);
+ insn = find_insn(file, reloc->sym->sec, reloc->addend);
if (!insn) {
WARN("bad .discard.instr_begin entry");
return -1;
@@ -1434,22 +1434,22 @@ static int read_intra_function_calls(struct objtool_file *file)
{
struct instruction *insn;
struct section *sec;
- struct rela *rela;
+ struct reloc *reloc;
sec = find_section_by_name(file->elf, ".rela.discard.intra_function_calls");
if (!sec)
return 0;
- list_for_each_entry(rela, &sec->rela_list, list) {
+ list_for_each_entry(reloc, &sec->reloc_list, list) {
unsigned long dest_off;
- if (rela->sym->type != STT_SECTION) {
+ if (reloc->sym->type != STT_SECTION) {
WARN("unexpected relocation symbol type in %s",
sec->name);
return -1;
}
- insn = find_insn(file, rela->sym->sec, rela->addend);
+ insn = find_insn(file, reloc->sym->sec, reloc->addend);
if (!insn) {
WARN("bad .discard.intra_function_call entry");
return -1;
diff --git a/tools/objtool/check.h b/tools/objtool/check.h
index 906b5210f7ca..061aa96e15d3 100644
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -37,7 +37,7 @@ struct instruction {
struct symbol *call_dest;
struct instruction *jump_dest;
struct instruction *first_jump_src;
- struct rela *jump_table;
+ struct reloc *jump_table;
struct list_head alts;
struct symbol *func;
struct list_head stack_ops;
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index c1ba92abaa03..c21e8417637b 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -228,26 +228,26 @@ struct symbol *find_symbol_by_name(const struct elf *elf, const char *name)
return NULL;
}
-struct rela *find_rela_by_dest_range(const struct elf *elf, struct section *sec,
+struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
unsigned long offset, unsigned int len)
{
- struct rela *rela, *r = NULL;
+ struct reloc *reloc, *r = NULL;
unsigned long o;
- if (!sec->rela)
+ if (!sec->reloc)
return NULL;
- sec = sec->rela;
+ sec = sec->reloc;
for_offset_range(o, offset, offset + len) {
- elf_hash_for_each_possible(elf->rela_hash, rela, hash,
+ elf_hash_for_each_possible(elf->reloc_hash, reloc, hash,
sec_offset_hash(sec, o)) {
- if (rela->sec != sec)
+ if (reloc->sec != sec)
continue;
- if (rela->offset >= offset && rela->offset < offset + len) {
- if (!r || rela->offset < r->offset)
- r = rela;
+ if (reloc->offset >= offset && reloc->offset < offset + len) {
+ if (!r || reloc->offset < r->offset)
+ r = reloc;
}
}
if (r)
@@ -257,9 +257,9 @@ struct rela *find_rela_by_dest_range(const struct elf *elf, struct section *sec,
return NULL;
}
-struct rela *find_rela_by_dest(const struct elf *elf, struct section *sec, unsigned long offset)
+struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset)
{
- return find_rela_by_dest_range(elf, sec, offset, 1);
+ return find_reloc_by_dest_range(elf, sec, offset, 1);
}
static int read_sections(struct elf *elf)
@@ -288,7 +288,7 @@ static int read_sections(struct elf *elf)
memset(sec, 0, sizeof(*sec));
INIT_LIST_HEAD(&sec->symbol_list);
- INIT_LIST_HEAD(&sec->rela_list);
+ INIT_LIST_HEAD(&sec->reloc_list);
s = elf_getscn(elf->elf, i);
if (!s) {
@@ -482,21 +482,21 @@ static int read_symbols(struct elf *elf)
return -1;
}
-void elf_add_rela(struct elf *elf, struct rela *rela)
+void elf_add_reloc(struct elf *elf, struct reloc *reloc)
{
- struct section *sec = rela->sec;
+ struct section *sec = reloc->sec;
- list_add_tail(&rela->list, &sec->rela_list);
- elf_hash_add(elf->rela_hash, &rela->hash, rela_hash(rela));
+ list_add_tail(&reloc->list, &sec->reloc_list);
+ elf_hash_add(elf->reloc_hash, &reloc->hash, reloc_hash(reloc));
}
-static int read_relas(struct elf *elf)
+static int read_relocs(struct elf *elf)
{
struct section *sec;
- struct rela *rela;
+ struct reloc *reloc;
int i;
unsigned int symndx;
- unsigned long nr_rela, max_rela = 0, tot_rela = 0;
+ unsigned long nr_reloc, max_reloc = 0, tot_reloc = 0;
list_for_each_entry(sec, &elf->sections, list) {
if (sec->sh.sh_type != SHT_RELA)
@@ -509,44 +509,44 @@ static int read_relas(struct elf *elf)
return -1;
}
- sec->base->rela = sec;
+ sec->base->reloc = sec;
- nr_rela = 0;
+ nr_reloc = 0;
for (i = 0; i < sec->sh.sh_size / sec->sh.sh_entsize; i++) {
- rela = malloc(sizeof(*rela));
- if (!rela) {
+ reloc = malloc(sizeof(*reloc));
+ if (!reloc) {
perror("malloc");
return -1;
}
- memset(rela, 0, sizeof(*rela));
+ memset(reloc, 0, sizeof(*reloc));
- if (!gelf_getrela(sec->data, i, &rela->rela)) {
+ if (!gelf_getrela(sec->data, i, &reloc->rela)) {
WARN_ELF("gelf_getrela");
return -1;
}
- rela->type = GELF_R_TYPE(rela->rela.r_info);
- rela->addend = rela->rela.r_addend;
- rela->offset = rela->rela.r_offset;
- symndx = GELF_R_SYM(rela->rela.r_info);
- rela->sym = find_symbol_by_index(elf, symndx);
- rela->sec = sec;
- if (!rela->sym) {
+ reloc->type = GELF_R_TYPE(reloc->rela.r_info);
+ reloc->addend = reloc->rela.r_addend;
+ reloc->offset = reloc->rela.r_offset;
+ symndx = GELF_R_SYM(reloc->rela.r_info);
+ reloc->sym = find_symbol_by_index(elf, symndx);
+ reloc->sec = sec;
+ if (!reloc->sym) {
WARN("can't find rela entry symbol %d for %s",
symndx, sec->name);
return -1;
}
- elf_add_rela(elf, rela);
- nr_rela++;
+ elf_add_reloc(elf, reloc);
+ nr_reloc++;
}
- max_rela = max(max_rela, nr_rela);
- tot_rela += nr_rela;
+ max_reloc = max(max_reloc, nr_reloc);
+ tot_reloc += nr_reloc;
}
if (stats) {
- printf("max_rela: %lu\n", max_rela);
- printf("tot_rela: %lu\n", tot_rela);
+ printf("max_reloc: %lu\n", max_reloc);
+ printf("tot_reloc: %lu\n", tot_reloc);
}
return 0;
@@ -572,7 +572,7 @@ struct elf *elf_open_read(const char *name, int flags)
elf_hash_init(elf->symbol_name_hash);
elf_hash_init(elf->section_hash);
elf_hash_init(elf->section_name_hash);
- elf_hash_init(elf->rela_hash);
+ elf_hash_init(elf->reloc_hash);
elf->fd = open(name, flags);
if (elf->fd == -1) {
@@ -605,7 +605,7 @@ struct elf *elf_open_read(const char *name, int flags)
if (read_symbols(elf))
goto err;
- if (read_relas(elf))
+ if (read_relocs(elf))
goto err;
return elf;
@@ -631,7 +631,7 @@ struct section *elf_create_section(struct elf *elf, const char *name,
memset(sec, 0, sizeof(*sec));
INIT_LIST_HEAD(&sec->symbol_list);
- INIT_LIST_HEAD(&sec->rela_list);
+ INIT_LIST_HEAD(&sec->reloc_list);
s = elf_newscn(elf->elf);
if (!s) {
@@ -716,25 +716,25 @@ struct section *elf_create_section(struct elf *elf, const char *name,
return sec;
}
-struct section *elf_create_rela_section(struct elf *elf, struct section *base)
+struct section *elf_create_reloc_section(struct elf *elf, struct section *base)
{
- char *relaname;
+ char *relocname;
struct section *sec;
- relaname = malloc(strlen(base->name) + strlen(".rela") + 1);
- if (!relaname) {
+ relocname = malloc(strlen(base->name) + strlen(".rela") + 1);
+ if (!relocname) {
perror("malloc");
return NULL;
}
- strcpy(relaname, ".rela");
- strcat(relaname, base->name);
+ strcpy(relocname, ".rela");
+ strcat(relocname, base->name);
- sec = elf_create_section(elf, relaname, sizeof(GElf_Rela), 0);
- free(relaname);
+ sec = elf_create_section(elf, relocname, sizeof(GElf_Rela), 0);
+ free(relocname);
if (!sec)
return NULL;
- base->rela = sec;
+ base->reloc = sec;
sec->base = base;
sec->sh.sh_type = SHT_RELA;
@@ -746,33 +746,33 @@ struct section *elf_create_rela_section(struct elf *elf, struct section *base)
return sec;
}
-int elf_rebuild_rela_section(struct section *sec)
+int elf_rebuild_reloc_section(struct section *sec)
{
- struct rela *rela;
+ struct reloc *reloc;
int nr, idx = 0, size;
- GElf_Rela *relas;
+ GElf_Rela *relocs;
nr = 0;
- list_for_each_entry(rela, &sec->rela_list, list)
+ list_for_each_entry(reloc, &sec->reloc_list, list)
nr++;
- size = nr * sizeof(*relas);
- relas = malloc(size);
- if (!relas) {
+ size = nr * sizeof(*relocs);
+ relocs = malloc(size);
+ if (!relocs) {
perror("malloc");
return -1;
}
- sec->data->d_buf = relas;
+ sec->data->d_buf = relocs;
sec->data->d_size = size;
sec->sh.sh_size = size;
idx = 0;
- list_for_each_entry(rela, &sec->rela_list, list) {
- relas[idx].r_offset = rela->offset;
- relas[idx].r_addend = rela->addend;
- relas[idx].r_info = GELF_R_INFO(rela->sym->idx, rela->type);
+ list_for_each_entry(reloc, &sec->reloc_list, list) {
+ relocs[idx].r_offset = reloc->offset;
+ relocs[idx].r_addend = reloc->addend;
+ relocs[idx].r_info = GELF_R_INFO(reloc->sym->idx, reloc->type);
idx++;
}
@@ -815,7 +815,7 @@ void elf_close(struct elf *elf)
{
struct section *sec, *tmpsec;
struct symbol *sym, *tmpsym;
- struct rela *rela, *tmprela;
+ struct reloc *reloc, *tmpreloc;
if (elf->elf)
elf_end(elf->elf);
@@ -829,10 +829,10 @@ void elf_close(struct elf *elf)
hash_del(&sym->hash);
free(sym);
}
- list_for_each_entry_safe(rela, tmprela, &sec->rela_list, list) {
- list_del(&rela->list);
- hash_del(&rela->hash);
- free(rela);
+ list_for_each_entry_safe(reloc, tmpreloc, &sec->reloc_list, list) {
+ list_del(&reloc->list);
+ hash_del(&reloc->hash);
+ free(reloc);
}
list_del(&sec->list);
free(sec);
diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
index f4fe1d6ea392..6ad759fd778e 100644
--- a/tools/objtool/elf.h
+++ b/tools/objtool/elf.h
@@ -32,8 +32,8 @@ struct section {
GElf_Shdr sh;
struct rb_root symbol_tree;
struct list_head symbol_list;
- struct list_head rela_list;
- struct section *base, *rela;
+ struct list_head reloc_list;
+ struct section *base, *reloc;
struct symbol *sym;
Elf_Data *data;
char *name;
@@ -58,7 +58,7 @@ struct symbol {
bool uaccess_safe;
};
-struct rela {
+struct reloc {
struct list_head list;
struct hlist_node hash;
GElf_Rela rela;
@@ -82,7 +82,7 @@ struct elf {
DECLARE_HASHTABLE(symbol_name_hash, ELF_HASH_BITS);
DECLARE_HASHTABLE(section_hash, ELF_HASH_BITS);
DECLARE_HASHTABLE(section_name_hash, ELF_HASH_BITS);
- DECLARE_HASHTABLE(rela_hash, ELF_HASH_BITS);
+ DECLARE_HASHTABLE(reloc_hash, ELF_HASH_BITS);
};
#define OFFSET_STRIDE_BITS 4
@@ -109,15 +109,15 @@ static inline u32 sec_offset_hash(struct section *sec, unsigned long offset)
return ol;
}
-static inline u32 rela_hash(struct rela *rela)
+static inline u32 reloc_hash(struct reloc *reloc)
{
- return sec_offset_hash(rela->sec, rela->offset);
+ return sec_offset_hash(reloc->sec, reloc->offset);
}
struct elf *elf_open_read(const char *name, int flags);
struct section *elf_create_section(struct elf *elf, const char *name, size_t entsize, int nr);
-struct section *elf_create_rela_section(struct elf *elf, struct section *base);
-void elf_add_rela(struct elf *elf, struct rela *rela);
+struct section *elf_create_reloc_section(struct elf *elf, struct section *base);
+void elf_add_reloc(struct elf *elf, struct reloc *reloc);
int elf_write(const struct elf *elf);
void elf_close(struct elf *elf);
@@ -126,11 +126,11 @@ struct symbol *find_func_by_offset(struct section *sec, unsigned long offset);
struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
struct symbol *find_symbol_by_name(const struct elf *elf, const char *name);
struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset);
-struct rela *find_rela_by_dest(const struct elf *elf, struct section *sec, unsigned long offset);
-struct rela *find_rela_by_dest_range(const struct elf *elf, struct section *sec,
+struct reloc *find_reloc_by_dest(const struct elf *elf, struct section *sec, unsigned long offset);
+struct reloc *find_reloc_by_dest_range(const struct elf *elf, struct section *sec,
unsigned long offset, unsigned int len);
struct symbol *find_func_containing(struct section *sec, unsigned long offset);
-int elf_rebuild_rela_section(struct section *sec);
+int elf_rebuild_reloc_section(struct section *sec);
#define for_each_sec(file, sec) \
list_for_each_entry(sec, &file->elf->sections, list)
diff --git a/tools/objtool/orc_gen.c b/tools/objtool/orc_gen.c
index c9549988121a..b538a0408cde 100644
--- a/tools/objtool/orc_gen.c
+++ b/tools/objtool/orc_gen.c
@@ -80,56 +80,56 @@ int create_orc(struct objtool_file *file)
return 0;
}
-static int create_orc_entry(struct elf *elf, struct section *u_sec, struct section *ip_relasec,
+static int create_orc_entry(struct elf *elf, struct section *u_sec, struct section *ip_relocsec,
unsigned int idx, struct section *insn_sec,
unsigned long insn_off, struct orc_entry *o)
{
struct orc_entry *orc;
- struct rela *rela;
+ struct reloc *reloc;
/* populate ORC data */
orc = (struct orc_entry *)u_sec->data->d_buf + idx;
memcpy(orc, o, sizeof(*orc));
/* populate rela for ip */
- rela = malloc(sizeof(*rela));
- if (!rela) {
+ reloc = malloc(sizeof(*reloc));
+ if (!reloc) {
perror("malloc");
return -1;
}
- memset(rela, 0, sizeof(*rela));
+ memset(reloc, 0, sizeof(*reloc));
if (insn_sec->sym) {
- rela->sym = insn_sec->sym;
- rela->addend = insn_off;
+ reloc->sym = insn_sec->sym;
+ reloc->addend = insn_off;
} else {
/*
* The Clang assembler doesn't produce section symbols, so we
* have to reference the function symbol instead:
*/
- rela->sym = find_symbol_containing(insn_sec, insn_off);
- if (!rela->sym) {
+ reloc->sym = find_symbol_containing(insn_sec, insn_off);
+ if (!reloc->sym) {
/*
* Hack alert. This happens when we need to reference
* the NOP pad insn immediately after the function.
*/
- rela->sym = find_symbol_containing(insn_sec,
+ reloc->sym = find_symbol_containing(insn_sec,
insn_off - 1);
}
- if (!rela->sym) {
+ if (!reloc->sym) {
WARN("missing symbol for insn at offset 0x%lx\n",
insn_off);
return -1;
}
- rela->addend = insn_off - rela->sym->offset;
+ reloc->addend = insn_off - reloc->sym->offset;
}
- rela->type = R_X86_64_PC32;
- rela->offset = idx * sizeof(int);
- rela->sec = ip_relasec;
+ reloc->type = R_X86_64_PC32;
+ reloc->offset = idx * sizeof(int);
+ reloc->sec = ip_relocsec;
- elf_add_rela(elf, rela);
+ elf_add_reloc(elf, reloc);
return 0;
}
@@ -137,7 +137,7 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
int create_orc_sections(struct objtool_file *file)
{
struct instruction *insn, *prev_insn;
- struct section *sec, *u_sec, *ip_relasec;
+ struct section *sec, *u_sec, *ip_relocsec;
unsigned int idx;
struct orc_entry empty = {
@@ -181,8 +181,8 @@ int create_orc_sections(struct objtool_file *file)
if (!sec)
return -1;
- ip_relasec = elf_create_rela_section(file->elf, sec);
- if (!ip_relasec)
+ ip_relocsec = elf_create_reloc_section(file->elf, sec);
+ if (!ip_relocsec)
return -1;
/* create .orc_unwind section */
@@ -200,7 +200,7 @@ int create_orc_sections(struct objtool_file *file)
if (!prev_insn || memcmp(&insn->orc, &prev_insn->orc,
sizeof(struct orc_entry))) {
- if (create_orc_entry(file->elf, u_sec, ip_relasec, idx,
+ if (create_orc_entry(file->elf, u_sec, ip_relocsec, idx,
insn->sec, insn->offset,
&insn->orc))
return -1;
@@ -212,7 +212,7 @@ int create_orc_sections(struct objtool_file *file)
/* section terminator */
if (prev_insn) {
- if (create_orc_entry(file->elf, u_sec, ip_relasec, idx,
+ if (create_orc_entry(file->elf, u_sec, ip_relocsec, idx,
prev_insn->sec,
prev_insn->offset + prev_insn->len,
&empty))
@@ -222,7 +222,7 @@ int create_orc_sections(struct objtool_file *file)
}
}
- if (elf_rebuild_rela_section(ip_relasec))
+ if (elf_rebuild_reloc_section(ip_relocsec))
return -1;
return 0;
diff --git a/tools/objtool/special.c b/tools/objtool/special.c
index e74e0189de22..7facd5f659d6 100644
--- a/tools/objtool/special.c
+++ b/tools/objtool/special.c
@@ -72,7 +72,7 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
struct section *sec, int idx,
struct special_alt *alt)
{
- struct rela *orig_rela, *new_rela;
+ struct reloc *orig_reloc, *new_reloc;
unsigned long offset;
offset = idx * entry->size;
@@ -118,30 +118,30 @@ static int get_alt_entry(struct elf *elf, struct special_entry *entry,
}
}
- orig_rela = find_rela_by_dest(elf, sec, offset + entry->orig);
- if (!orig_rela) {
+ orig_reloc = find_reloc_by_dest(elf, sec, offset + entry->orig);
+ if (!orig_reloc) {
WARN_FUNC("can't find orig rela", sec, offset + entry->orig);
return -1;
}
- if (orig_rela->sym->type != STT_SECTION) {
+ if (orig_reloc->sym->type != STT_SECTION) {
WARN_FUNC("don't know how to handle non-section rela symbol %s",
- sec, offset + entry->orig, orig_rela->sym->name);
+ sec, offset + entry->orig, orig_reloc->sym->name);
return -1;
}
- alt->orig_sec = orig_rela->sym->sec;
- alt->orig_off = orig_rela->addend;
+ alt->orig_sec = orig_reloc->sym->sec;
+ alt->orig_off = orig_reloc->addend;
if (!entry->group || alt->new_len) {
- new_rela = find_rela_by_dest(elf, sec, offset + entry->new);
- if (!new_rela) {
+ new_reloc = find_reloc_by_dest(elf, sec, offset + entry->new);
+ if (!new_reloc) {
WARN_FUNC("can't find new rela",
sec, offset + entry->new);
return -1;
}
- alt->new_sec = new_rela->sym->sec;
- alt->new_off = (unsigned int)new_rela->addend;
+ alt->new_sec = new_reloc->sym->sec;
+ alt->new_off = (unsigned int)new_reloc->addend;
/* _ASM_EXTABLE_EX hack */
if (alt->new_off >= 0x7ffffff0)
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v8 45/62] target/riscv: narrowing floating-point/integer type-convert instructions
From: Alistair Francis @ 2020-05-29 20:51 UTC (permalink / raw)
To: LIU Zhiwei
Cc: open list:RISC-V, Richard Henderson,
qemu-devel@nongnu.org Developers, wxy194768, wenmeng_zhang,
Alistair Francis, Palmer Dabbelt
In-Reply-To: <20200521094413.10425-46-zhiwei_liu@c-sky.com>
On Thu, May 21, 2020 at 4:15 AM LIU Zhiwei <zhiwei_liu@c-sky.com> wrote:
>
> Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> target/riscv/helper.h | 11 ++++++
> target/riscv/insn32.decode | 5 +++
> target/riscv/insn_trans/trans_rvv.inc.c | 47 +++++++++++++++++++++++++
> target/riscv/vector_helper.c | 39 ++++++++++++++++++++
> 4 files changed, 102 insertions(+)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index e59dcc5a7c..82c5d1129e 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -1022,3 +1022,14 @@ DEF_HELPER_5(vfwcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
> DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
> DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
> DEF_HELPER_5(vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
> +
> +DEF_HELPER_5(vfncvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
> +DEF_HELPER_5(vfncvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index e0efc63ec2..57ac4de1c2 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -524,6 +524,11 @@ vfwcvt_x_f_v 100010 . ..... 01001 001 ..... 1010111 @r2_vm
> vfwcvt_f_xu_v 100010 . ..... 01010 001 ..... 1010111 @r2_vm
> vfwcvt_f_x_v 100010 . ..... 01011 001 ..... 1010111 @r2_vm
> vfwcvt_f_f_v 100010 . ..... 01100 001 ..... 1010111 @r2_vm
> +vfncvt_xu_f_v 100010 . ..... 10000 001 ..... 1010111 @r2_vm
> +vfncvt_x_f_v 100010 . ..... 10001 001 ..... 1010111 @r2_vm
> +vfncvt_f_xu_v 100010 . ..... 10010 001 ..... 1010111 @r2_vm
> +vfncvt_f_x_v 100010 . ..... 10011 001 ..... 1010111 @r2_vm
> +vfncvt_f_f_v 100010 . ..... 10100 001 ..... 1010111 @r2_vm
>
> vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm
> vsetvl 1000000 ..... ..... 111 ..... 1010111 @r
> diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c
> index 44505027c1..e63b88a4cc 100644
> --- a/target/riscv/insn_trans/trans_rvv.inc.c
> +++ b/target/riscv/insn_trans/trans_rvv.inc.c
> @@ -2268,3 +2268,50 @@ GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v)
> GEN_OPFV_WIDEN_TRANS(vfwcvt_f_xu_v)
> GEN_OPFV_WIDEN_TRANS(vfwcvt_f_x_v)
> GEN_OPFV_WIDEN_TRANS(vfwcvt_f_f_v)
> +
> +/* Narrowing Floating-Point/Integer Type-Convert Instructions */
> +
> +/*
> + * If the current SEW does not correspond to a supported IEEE floating-point
> + * type, an illegal instruction exception is raised
> + */
> +static bool opfv_narrow_check(DisasContext *s, arg_rmr *a)
> +{
> + return (vext_check_isa_ill(s) &&
> + vext_check_overlap_mask(s, a->rd, a->vm, false) &&
> + vext_check_reg(s, a->rd, false) &&
> + vext_check_reg(s, a->rs2, true) &&
> + vext_check_overlap_group(a->rd, 1 << s->lmul, a->rs2,
> + 2 << s->lmul) &&
> + (s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0));
> +}
> +
> +#define GEN_OPFV_NARROW_TRANS(NAME) \
> +static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
> +{ \
> + if (opfv_narrow_check(s, a)) { \
> + uint32_t data = 0; \
> + static gen_helper_gvec_3_ptr * const fns[2] = { \
> + gen_helper_##NAME##_h, \
> + gen_helper_##NAME##_w, \
> + }; \
> + TCGLabel *over = gen_new_label(); \
> + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over); \
> + \
> + data = FIELD_DP32(data, VDATA, MLEN, s->mlen); \
> + data = FIELD_DP32(data, VDATA, VM, a->vm); \
> + data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
> + tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
> + vreg_ofs(s, a->rs2), cpu_env, 0, \
> + s->vlen / 8, data, fns[s->sew - 1]); \
> + gen_set_label(over); \
> + return true; \
> + } \
> + return false; \
> +}
> +
> +GEN_OPFV_NARROW_TRANS(vfncvt_xu_f_v)
> +GEN_OPFV_NARROW_TRANS(vfncvt_x_f_v)
> +GEN_OPFV_NARROW_TRANS(vfncvt_f_xu_v)
> +GEN_OPFV_NARROW_TRANS(vfncvt_f_x_v)
> +GEN_OPFV_NARROW_TRANS(vfncvt_f_f_v)
> diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
> index ea6a5853f3..8e525720d1 100644
> --- a/target/riscv/vector_helper.c
> +++ b/target/riscv/vector_helper.c
> @@ -4292,3 +4292,42 @@ RVVCALL(OPFVV1, vfwcvt_f_f_v_h, WOP_UU_H, H4, H2, vfwcvtffv16)
> RVVCALL(OPFVV1, vfwcvt_f_f_v_w, WOP_UU_W, H8, H4, float32_to_float64)
> GEN_VEXT_V_ENV(vfwcvt_f_f_v_h, 2, 4, clearl)
> GEN_VEXT_V_ENV(vfwcvt_f_f_v_w, 4, 8, clearq)
> +
> +/* Narrowing Floating-Point/Integer Type-Convert Instructions */
> +/* (TD, T2, TX2) */
> +#define NOP_UU_H uint16_t, uint32_t, uint32_t
> +#define NOP_UU_W uint32_t, uint64_t, uint64_t
> +/* vfncvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer. */
> +RVVCALL(OPFVV1, vfncvt_xu_f_v_h, NOP_UU_H, H2, H4, float32_to_uint16)
> +RVVCALL(OPFVV1, vfncvt_xu_f_v_w, NOP_UU_W, H4, H8, float64_to_uint32)
> +GEN_VEXT_V_ENV(vfncvt_xu_f_v_h, 2, 2, clearh)
> +GEN_VEXT_V_ENV(vfncvt_xu_f_v_w, 4, 4, clearl)
> +
> +/* vfncvt.x.f.v vd, vs2, vm # Convert double-width float to signed integer. */
> +RVVCALL(OPFVV1, vfncvt_x_f_v_h, NOP_UU_H, H2, H4, float32_to_int16)
> +RVVCALL(OPFVV1, vfncvt_x_f_v_w, NOP_UU_W, H4, H8, float64_to_int32)
> +GEN_VEXT_V_ENV(vfncvt_x_f_v_h, 2, 2, clearh)
> +GEN_VEXT_V_ENV(vfncvt_x_f_v_w, 4, 4, clearl)
> +
> +/* vfncvt.f.xu.v vd, vs2, vm # Convert double-width unsigned integer to float */
> +RVVCALL(OPFVV1, vfncvt_f_xu_v_h, NOP_UU_H, H2, H4, uint32_to_float16)
> +RVVCALL(OPFVV1, vfncvt_f_xu_v_w, NOP_UU_W, H4, H8, uint64_to_float32)
> +GEN_VEXT_V_ENV(vfncvt_f_xu_v_h, 2, 2, clearh)
> +GEN_VEXT_V_ENV(vfncvt_f_xu_v_w, 4, 4, clearl)
> +
> +/* vfncvt.f.x.v vd, vs2, vm # Convert double-width integer to float. */
> +RVVCALL(OPFVV1, vfncvt_f_x_v_h, NOP_UU_H, H2, H4, int32_to_float16)
> +RVVCALL(OPFVV1, vfncvt_f_x_v_w, NOP_UU_W, H4, H8, int64_to_float32)
> +GEN_VEXT_V_ENV(vfncvt_f_x_v_h, 2, 2, clearh)
> +GEN_VEXT_V_ENV(vfncvt_f_x_v_w, 4, 4, clearl)
> +
> +/* vfncvt.f.f.v vd, vs2, vm # Convert double float to single-width float. */
> +static uint16_t vfncvtffv16(uint32_t a, float_status *s)
> +{
> + return float32_to_float16(a, true, s);
> +}
> +
> +RVVCALL(OPFVV1, vfncvt_f_f_v_h, NOP_UU_H, H2, H4, vfncvtffv16)
> +RVVCALL(OPFVV1, vfncvt_f_f_v_w, NOP_UU_W, H4, H8, float64_to_float32)
> +GEN_VEXT_V_ENV(vfncvt_f_f_v_h, 2, 2, clearh)
> +GEN_VEXT_V_ENV(vfncvt_f_f_v_w, 4, 4, clearl)
> --
> 2.23.0
>
>
^ permalink raw reply
* Re: [PATCH 1/9] xfs_repair: port the online repair newbt structure
From: Darrick J. Wong @ 2020-05-29 21:01 UTC (permalink / raw)
To: Brian Foster; +Cc: sandeen, linux-xfs
In-Reply-To: <20200528150836.GA17794@bfoster>
On Thu, May 28, 2020 at 11:08:36AM -0400, Brian Foster wrote:
> On Wed, May 27, 2020 at 03:34:24PM -0700, Darrick J. Wong wrote:
> > On Wed, May 27, 2020 at 08:15:31AM -0400, Brian Foster wrote:
> > > On Tue, May 19, 2020 at 06:50:49PM -0700, Darrick J. Wong wrote:
> > > > From: Darrick J. Wong <darrick.wong@oracle.com>
> > > >
> > > > Port the new btree staging context and related block reservation helper
> > > > code from the kernel to repair. We'll use this in subsequent patches to
> > > > implement btree bulk loading.
> > > >
> > > > Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
> > > > ---
> > > > include/libxfs.h | 1
> > > > libxfs/libxfs_api_defs.h | 2
> > > > repair/Makefile | 4 -
> > > > repair/bload.c | 303 ++++++++++++++++++++++++++++++++++++++++++++++
> > > > repair/bload.h | 77 ++++++++++++
> > > > repair/xfs_repair.c | 17 +++
> > > > 6 files changed, 402 insertions(+), 2 deletions(-)
> > > > create mode 100644 repair/bload.c
> > > > create mode 100644 repair/bload.h
> > > >
> > > >
> > > ...
> > > > diff --git a/repair/bload.c b/repair/bload.c
> > > > new file mode 100644
> > > > index 00000000..9bc17468
> > > > --- /dev/null
> > > > +++ b/repair/bload.c
> > > > @@ -0,0 +1,303 @@
> > > > +// SPDX-License-Identifier: GPL-2.0-or-later
> > > > +/*
> > > > + * Copyright (C) 2020 Oracle. All Rights Reserved.
> > > > + * Author: Darrick J. Wong <darrick.wong@oracle.com>
> > > > + */
> > > > +#include <libxfs.h>
> > > > +#include "bload.h"
> > > > +
> > > > +#define trace_xrep_newbt_claim_block(...) ((void) 0)
> > > > +#define trace_xrep_newbt_free_blocks(...) ((void) 0)
> > > > +
> > > > +int bload_leaf_slack = -1;
> > > > +int bload_node_slack = -1;
> > > > +
> > > > +/* Ported routines from fs/xfs/scrub/repair.c */
> > > > +
> > >
> > > Looks mostly straightforward, but I'll have to come back to this as I
> > > get to the code that uses it later in the series. In the meantime, I see
> > > some of these helpers in scrub/repair.c while not others. Are there
> > > references to other routines that are intended to be copies from kernel
> > > code?
> >
> > Hm. I might not understand the question, but in general the code should
> > be fairly similar to the kernel functions. The biggest differences are
> > (a) that whole libxfs error code mess, (b) the much simpler repair_ctx
> > structure, and (c) the fact that repair doesn't bother with EFIs to
> > automatically reap blocks.
> >
> > So... the ten functions you see here do the same things as their kernel
> > counterparts, but they get to do it in the much simpler userspace
> > environment.
> >
>
> Right.. I was able to find the first function (xrep_roll_ag_trans())
> easily in the kernel because it has the same name. The next one or two
> (i.e., xrep_newbt_*()) I couldn't find and then gave up. Are they
> renamed? Unmerged?
Ahh, silly me, the rest are as yet unmerged components of the online
repair code. Maybe it makes more sense to drop the "Ported routines
from XXXX" comment, particularly since it probably will be easier to
merge the xfs_repair series first, which is /much/ smaller in scope.
> > The other functions in scrub/repair.c that didn't get ported are either
> > for other types of repairs or exist to support the in-kernel code and
> > aren't needed here.
> >
>
> Sure, I'm just curious how to identify the source of the ones that are.
https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/tree/fs/xfs/scrub/repair.c?h=djwong-wtf
Is a fairly recent snapshot of what the kernel version looks like.
--D
>
> Brian
>
> > --D
> >
> > > Brian
> > >
> > > > +/*
> > > > + * Roll a transaction, keeping the AG headers locked and reinitializing
> > > > + * the btree cursors.
> > > > + */
> > > > +int
> > > > +xrep_roll_ag_trans(
> > > > + struct repair_ctx *sc)
> > > > +{
> > > > + int error;
> > > > +
> > > > + /* Keep the AG header buffers locked so we can keep going. */
> > > > + if (sc->agi_bp)
> > > > + libxfs_trans_bhold(sc->tp, sc->agi_bp);
> > > > + if (sc->agf_bp)
> > > > + libxfs_trans_bhold(sc->tp, sc->agf_bp);
> > > > + if (sc->agfl_bp)
> > > > + libxfs_trans_bhold(sc->tp, sc->agfl_bp);
> > > > +
> > > > + /*
> > > > + * Roll the transaction. We still own the buffer and the buffer lock
> > > > + * regardless of whether or not the roll succeeds. If the roll fails,
> > > > + * the buffers will be released during teardown on our way out of the
> > > > + * kernel. If it succeeds, we join them to the new transaction and
> > > > + * move on.
> > > > + */
> > > > + error = -libxfs_trans_roll(&sc->tp);
> > > > + if (error)
> > > > + return error;
> > > > +
> > > > + /* Join AG headers to the new transaction. */
> > > > + if (sc->agi_bp)
> > > > + libxfs_trans_bjoin(sc->tp, sc->agi_bp);
> > > > + if (sc->agf_bp)
> > > > + libxfs_trans_bjoin(sc->tp, sc->agf_bp);
> > > > + if (sc->agfl_bp)
> > > > + libxfs_trans_bjoin(sc->tp, sc->agfl_bp);
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +/* Initialize accounting resources for staging a new AG btree. */
> > > > +void
> > > > +xrep_newbt_init_ag(
> > > > + struct xrep_newbt *xnr,
> > > > + struct repair_ctx *sc,
> > > > + const struct xfs_owner_info *oinfo,
> > > > + xfs_fsblock_t alloc_hint,
> > > > + enum xfs_ag_resv_type resv)
> > > > +{
> > > > + memset(xnr, 0, sizeof(struct xrep_newbt));
> > > > + xnr->sc = sc;
> > > > + xnr->oinfo = *oinfo; /* structure copy */
> > > > + xnr->alloc_hint = alloc_hint;
> > > > + xnr->resv = resv;
> > > > + INIT_LIST_HEAD(&xnr->resv_list);
> > > > +}
> > > > +
> > > > +/* Initialize accounting resources for staging a new inode fork btree. */
> > > > +void
> > > > +xrep_newbt_init_inode(
> > > > + struct xrep_newbt *xnr,
> > > > + struct repair_ctx *sc,
> > > > + int whichfork,
> > > > + const struct xfs_owner_info *oinfo)
> > > > +{
> > > > + xrep_newbt_init_ag(xnr, sc, oinfo,
> > > > + XFS_INO_TO_FSB(sc->mp, sc->ip->i_ino),
> > > > + XFS_AG_RESV_NONE);
> > > > + xnr->ifake.if_fork = kmem_zone_zalloc(xfs_ifork_zone, 0);
> > > > + xnr->ifake.if_fork_size = XFS_IFORK_SIZE(sc->ip, whichfork);
> > > > +}
> > > > +
> > > > +/*
> > > > + * Initialize accounting resources for staging a new btree. Callers are
> > > > + * expected to add their own reservations (and clean them up) manually.
> > > > + */
> > > > +void
> > > > +xrep_newbt_init_bare(
> > > > + struct xrep_newbt *xnr,
> > > > + struct repair_ctx *sc)
> > > > +{
> > > > + xrep_newbt_init_ag(xnr, sc, &XFS_RMAP_OINFO_ANY_OWNER, NULLFSBLOCK,
> > > > + XFS_AG_RESV_NONE);
> > > > +}
> > > > +
> > > > +/* Designate specific blocks to be used to build our new btree. */
> > > > +int
> > > > +xrep_newbt_add_blocks(
> > > > + struct xrep_newbt *xnr,
> > > > + xfs_fsblock_t fsbno,
> > > > + xfs_extlen_t len)
> > > > +{
> > > > + struct xrep_newbt_resv *resv;
> > > > +
> > > > + resv = kmem_alloc(sizeof(struct xrep_newbt_resv), KM_MAYFAIL);
> > > > + if (!resv)
> > > > + return ENOMEM;
> > > > +
> > > > + INIT_LIST_HEAD(&resv->list);
> > > > + resv->fsbno = fsbno;
> > > > + resv->len = len;
> > > > + resv->used = 0;
> > > > + list_add_tail(&resv->list, &xnr->resv_list);
> > > > + return 0;
> > > > +}
> > > > +
> > > > +/* Reserve disk space for our new btree. */
> > > > +int
> > > > +xrep_newbt_alloc_blocks(
> > > > + struct xrep_newbt *xnr,
> > > > + uint64_t nr_blocks)
> > > > +{
> > > > + struct repair_ctx *sc = xnr->sc;
> > > > + xfs_alloctype_t type;
> > > > + xfs_fsblock_t alloc_hint = xnr->alloc_hint;
> > > > + int error = 0;
> > > > +
> > > > + type = sc->ip ? XFS_ALLOCTYPE_START_BNO : XFS_ALLOCTYPE_NEAR_BNO;
> > > > +
> > > > + while (nr_blocks > 0 && !error) {
> > > > + struct xfs_alloc_arg args = {
> > > > + .tp = sc->tp,
> > > > + .mp = sc->mp,
> > > > + .type = type,
> > > > + .fsbno = alloc_hint,
> > > > + .oinfo = xnr->oinfo,
> > > > + .minlen = 1,
> > > > + .maxlen = nr_blocks,
> > > > + .prod = 1,
> > > > + .resv = xnr->resv,
> > > > + };
> > > > +
> > > > + error = -libxfs_alloc_vextent(&args);
> > > > + if (error)
> > > > + return error;
> > > > + if (args.fsbno == NULLFSBLOCK)
> > > > + return ENOSPC;
> > > > +
> > > > + /* We don't have real EFIs here so skip that. */
> > > > +
> > > > + error = xrep_newbt_add_blocks(xnr, args.fsbno, args.len);
> > > > + if (error)
> > > > + break;
> > > > +
> > > > + nr_blocks -= args.len;
> > > > + alloc_hint = args.fsbno + args.len - 1;
> > > > +
> > > > + if (sc->ip)
> > > > + error = -libxfs_trans_roll_inode(&sc->tp, sc->ip);
> > > > + else
> > > > + error = xrep_roll_ag_trans(sc);
> > > > + }
> > > > +
> > > > + return error;
> > > > +}
> > > > +
> > > > +/*
> > > > + * Release blocks that were reserved for a btree repair. If the repair
> > > > + * succeeded then we log deferred frees for unused blocks. Otherwise, we try
> > > > + * to free the extents immediately to roll the filesystem back to where it was
> > > > + * before we started.
> > > > + */
> > > > +static inline int
> > > > +xrep_newbt_destroy_reservation(
> > > > + struct xrep_newbt *xnr,
> > > > + struct xrep_newbt_resv *resv,
> > > > + bool cancel_repair)
> > > > +{
> > > > + struct repair_ctx *sc = xnr->sc;
> > > > +
> > > > + if (cancel_repair) {
> > > > + int error;
> > > > +
> > > > + /* Free the extent then roll the transaction. */
> > > > + error = -libxfs_free_extent(sc->tp, resv->fsbno, resv->len,
> > > > + &xnr->oinfo, xnr->resv);
> > > > + if (error)
> > > > + return error;
> > > > +
> > > > + if (sc->ip)
> > > > + return -libxfs_trans_roll_inode(&sc->tp, sc->ip);
> > > > + return xrep_roll_ag_trans(sc);
> > > > + }
> > > > +
> > > > + /* We don't have EFIs here so skip the EFD. */
> > > > +
> > > > + /*
> > > > + * Use the deferred freeing mechanism to schedule for deletion any
> > > > + * blocks we didn't use to rebuild the tree. This enables us to log
> > > > + * them all in the same transaction as the root change.
> > > > + */
> > > > + resv->fsbno += resv->used;
> > > > + resv->len -= resv->used;
> > > > + resv->used = 0;
> > > > +
> > > > + if (resv->len == 0)
> > > > + return 0;
> > > > +
> > > > + trace_xrep_newbt_free_blocks(sc->mp,
> > > > + XFS_FSB_TO_AGNO(sc->mp, resv->fsbno),
> > > > + XFS_FSB_TO_AGBNO(sc->mp, resv->fsbno),
> > > > + resv->len, xnr->oinfo.oi_owner);
> > > > +
> > > > + __xfs_bmap_add_free(sc->tp, resv->fsbno, resv->len, &xnr->oinfo, true);
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +/* Free all the accounting info and disk space we reserved for a new btree. */
> > > > +void
> > > > +xrep_newbt_destroy(
> > > > + struct xrep_newbt *xnr,
> > > > + int error)
> > > > +{
> > > > + struct repair_ctx *sc = xnr->sc;
> > > > + struct xrep_newbt_resv *resv, *n;
> > > > + int err2;
> > > > +
> > > > + list_for_each_entry_safe(resv, n, &xnr->resv_list, list) {
> > > > + err2 = xrep_newbt_destroy_reservation(xnr, resv, error != 0);
> > > > + if (err2)
> > > > + goto junkit;
> > > > +
> > > > + list_del(&resv->list);
> > > > + kmem_free(resv);
> > > > + }
> > > > +
> > > > +junkit:
> > > > + /*
> > > > + * If we still have reservations attached to @newbt, cleanup must have
> > > > + * failed and the filesystem is about to go down. Clean up the incore
> > > > + * reservations.
> > > > + */
> > > > + list_for_each_entry_safe(resv, n, &xnr->resv_list, list) {
> > > > + list_del(&resv->list);
> > > > + kmem_free(resv);
> > > > + }
> > > > +
> > > > + if (sc->ip) {
> > > > + kmem_cache_free(xfs_ifork_zone, xnr->ifake.if_fork);
> > > > + xnr->ifake.if_fork = NULL;
> > > > + }
> > > > +}
> > > > +
> > > > +/* Feed one of the reserved btree blocks to the bulk loader. */
> > > > +int
> > > > +xrep_newbt_claim_block(
> > > > + struct xfs_btree_cur *cur,
> > > > + struct xrep_newbt *xnr,
> > > > + union xfs_btree_ptr *ptr)
> > > > +{
> > > > + struct xrep_newbt_resv *resv;
> > > > + xfs_fsblock_t fsb;
> > > > +
> > > > + /*
> > > > + * The first item in the list should always have a free block unless
> > > > + * we're completely out.
> > > > + */
> > > > + resv = list_first_entry(&xnr->resv_list, struct xrep_newbt_resv, list);
> > > > + if (resv->used == resv->len)
> > > > + return ENOSPC;
> > > > +
> > > > + /*
> > > > + * Peel off a block from the start of the reservation. We allocate
> > > > + * blocks in order to place blocks on disk in increasing record or key
> > > > + * order. The block reservations tend to end up on the list in
> > > > + * decreasing order, which hopefully results in leaf blocks ending up
> > > > + * together.
> > > > + */
> > > > + fsb = resv->fsbno + resv->used;
> > > > + resv->used++;
> > > > +
> > > > + /* If we used all the blocks in this reservation, move it to the end. */
> > > > + if (resv->used == resv->len)
> > > > + list_move_tail(&resv->list, &xnr->resv_list);
> > > > +
> > > > + trace_xrep_newbt_claim_block(cur->bc_mp,
> > > > + XFS_FSB_TO_AGNO(cur->bc_mp, fsb),
> > > > + XFS_FSB_TO_AGBNO(cur->bc_mp, fsb),
> > > > + 1, xnr->oinfo.oi_owner);
> > > > +
> > > > + if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
> > > > + ptr->l = cpu_to_be64(fsb);
> > > > + else
> > > > + ptr->s = cpu_to_be32(XFS_FSB_TO_AGBNO(cur->bc_mp, fsb));
> > > > + return 0;
> > > > +}
> > > > diff --git a/repair/bload.h b/repair/bload.h
> > > > new file mode 100644
> > > > index 00000000..020c4834
> > > > --- /dev/null
> > > > +++ b/repair/bload.h
> > > > @@ -0,0 +1,77 @@
> > > > +// SPDX-License-Identifier: GPL-2.0-or-later
> > > > +/*
> > > > + * Copyright (C) 2020 Oracle. All Rights Reserved.
> > > > + * Author: Darrick J. Wong <darrick.wong@oracle.com>
> > > > + */
> > > > +#ifndef __XFS_REPAIR_BLOAD_H__
> > > > +#define __XFS_REPAIR_BLOAD_H__
> > > > +
> > > > +extern int bload_leaf_slack;
> > > > +extern int bload_node_slack;
> > > > +
> > > > +struct repair_ctx {
> > > > + struct xfs_mount *mp;
> > > > + struct xfs_inode *ip;
> > > > + struct xfs_trans *tp;
> > > > +
> > > > + struct xfs_buf *agi_bp;
> > > > + struct xfs_buf *agf_bp;
> > > > + struct xfs_buf *agfl_bp;
> > > > +};
> > > > +
> > > > +struct xrep_newbt_resv {
> > > > + /* Link to list of extents that we've reserved. */
> > > > + struct list_head list;
> > > > +
> > > > + /* FSB of the block we reserved. */
> > > > + xfs_fsblock_t fsbno;
> > > > +
> > > > + /* Length of the reservation. */
> > > > + xfs_extlen_t len;
> > > > +
> > > > + /* How much of this reservation we've used. */
> > > > + xfs_extlen_t used;
> > > > +};
> > > > +
> > > > +struct xrep_newbt {
> > > > + struct repair_ctx *sc;
> > > > +
> > > > + /* List of extents that we've reserved. */
> > > > + struct list_head resv_list;
> > > > +
> > > > + /* Fake root for new btree. */
> > > > + union {
> > > > + struct xbtree_afakeroot afake;
> > > > + struct xbtree_ifakeroot ifake;
> > > > + };
> > > > +
> > > > + /* rmap owner of these blocks */
> > > > + struct xfs_owner_info oinfo;
> > > > +
> > > > + /* The last reservation we allocated from. */
> > > > + struct xrep_newbt_resv *last_resv;
> > > > +
> > > > + /* Allocation hint */
> > > > + xfs_fsblock_t alloc_hint;
> > > > +
> > > > + /* per-ag reservation type */
> > > > + enum xfs_ag_resv_type resv;
> > > > +};
> > > > +
> > > > +#define for_each_xrep_newbt_reservation(xnr, resv, n) \
> > > > + list_for_each_entry_safe((resv), (n), &(xnr)->resv_list, list)
> > > > +
> > > > +void xrep_newbt_init_bare(struct xrep_newbt *xnr, struct repair_ctx *sc);
> > > > +void xrep_newbt_init_ag(struct xrep_newbt *xnr, struct repair_ctx *sc,
> > > > + const struct xfs_owner_info *oinfo, xfs_fsblock_t alloc_hint,
> > > > + enum xfs_ag_resv_type resv);
> > > > +void xrep_newbt_init_inode(struct xrep_newbt *xnr, struct repair_ctx *sc,
> > > > + int whichfork, const struct xfs_owner_info *oinfo);
> > > > +int xrep_newbt_add_blocks(struct xrep_newbt *xnr, xfs_fsblock_t fsbno,
> > > > + xfs_extlen_t len);
> > > > +int xrep_newbt_alloc_blocks(struct xrep_newbt *xnr, uint64_t nr_blocks);
> > > > +void xrep_newbt_destroy(struct xrep_newbt *xnr, int error);
> > > > +int xrep_newbt_claim_block(struct xfs_btree_cur *cur, struct xrep_newbt *xnr,
> > > > + union xfs_btree_ptr *ptr);
> > > > +
> > > > +#endif /* __XFS_REPAIR_BLOAD_H__ */
> > > > diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c
> > > > index 9d72fa8e..8fbd3649 100644
> > > > --- a/repair/xfs_repair.c
> > > > +++ b/repair/xfs_repair.c
> > > > @@ -24,6 +24,7 @@
> > > > #include "rmap.h"
> > > > #include "libfrog/fsgeom.h"
> > > > #include "libfrog/platform.h"
> > > > +#include "bload.h"
> > > >
> > > > /*
> > > > * option tables for getsubopt calls
> > > > @@ -39,6 +40,8 @@ enum o_opt_nums {
> > > > AG_STRIDE,
> > > > FORCE_GEO,
> > > > PHASE2_THREADS,
> > > > + BLOAD_LEAF_SLACK,
> > > > + BLOAD_NODE_SLACK,
> > > > O_MAX_OPTS,
> > > > };
> > > >
> > > > @@ -49,6 +52,8 @@ static char *o_opts[] = {
> > > > [AG_STRIDE] = "ag_stride",
> > > > [FORCE_GEO] = "force_geometry",
> > > > [PHASE2_THREADS] = "phase2_threads",
> > > > + [BLOAD_LEAF_SLACK] = "debug_bload_leaf_slack",
> > > > + [BLOAD_NODE_SLACK] = "debug_bload_node_slack",
> > > > [O_MAX_OPTS] = NULL,
> > > > };
> > > >
> > > > @@ -260,6 +265,18 @@ process_args(int argc, char **argv)
> > > > _("-o phase2_threads requires a parameter\n"));
> > > > phase2_threads = (int)strtol(val, NULL, 0);
> > > > break;
> > > > + case BLOAD_LEAF_SLACK:
> > > > + if (!val)
> > > > + do_abort(
> > > > + _("-o debug_bload_leaf_slack requires a parameter\n"));
> > > > + bload_leaf_slack = (int)strtol(val, NULL, 0);
> > > > + break;
> > > > + case BLOAD_NODE_SLACK:
> > > > + if (!val)
> > > > + do_abort(
> > > > + _("-o debug_bload_node_slack requires a parameter\n"));
> > > > + bload_node_slack = (int)strtol(val, NULL, 0);
> > > > + break;
> > > > default:
> > > > unknown('o', val);
> > > > break;
> > > >
> > >
> >
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.