1
0
Fork 0

This is the 5.4.74 stable release

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAl+elYEACgkQONu9yGCS
 aT4DfQ/+OoCvKzPm/gxmJejGNUvagBhMLXxNw62jvmLwHnagWNchXMQEoplmwpIz
 D3FeSnH6VjBj8QfXCzxZJVazuPNaiSfxrwvaboakvVnvJw66rC0LgiXUJ5MuMhmr
 YVBJ9YfA73Lpv96ySrXWdqEO6QIMgYnlR95Ep+33IBUb5x2QuQB+8ho+qQ3h6I4r
 uoVAzFLaliCpRF/Hz9pwjZjSo3zDbyYx29XVFXYkrHn8cJWE6oBZtNo+K1cyY3wH
 dNY9CXPRh4oC5G+w579m5GvnW5Ac5hTHKONNURCu9NgsEJgHfpuXXiK+ve1yS7xa
 LFj1qFuYW90scgvmcx/YSKIWkNdCGCsqLlp3OJwVDm573touy6NZOag5GW2S35iD
 GcPRvJjWHay8NJSwKteKN9YH92xBxaSWJalrIQcY4Q4VAgJpXizIxZskGieWRdYv
 2XrSAOyXfSPP3nEsRXANEC2RY38Vp6zQt5G4a5duvztNU8knRjuQijMU7vvUbjvU
 V7D+kpamoqSiEkKmPYi3ViH80BkBNaxVrh54AMW9BQiFxUum5X/8sD7PDnKg+p8R
 tPPFsFHKAyVSQQe/7VlAfDq1D9xCfgfzA4TiMYqseyBBFs4UZ1dkLBQTL7Xza9ma
 H4NrA6SQibzYXH5F8OPWFqLPye1hmzAvojhskLk6ijeCw+koLk4=
 =zfx+
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEdQaENiSDAlGTDEbB7G51OISzHs0FAl+fFxUACgkQ7G51OISz
 Hs0X3hAAjgVqaYqcJyi3M+VOJSCknE4Yuf1PZaMyNwn62H0YdS+j4U7YoS3/68Oj
 hlS4wLq32cdhuTIr1WVw1I1f18YS1AMDdnjiorc/L4DvY8XWtytIBkxuw2yH0gFE
 tefAZdrF3wzhJ9eHiF0Oy/kvreZXD4ysitH648sg2X208lwy9HIMNAC+27WpG0gV
 p7xYkBcG55+/tmebD9xr7TVhGWupAsZK/wkWgojAY4+8NqsGI33QGbAf8WCxShj1
 /uBB7ZujIWTTRrluOltozGj/VtraBzA0m3PACR562wG2T/aJ+kG/n2VO3Qhga2Sk
 PaUx7aTCwM5BIbvM0tu+O6wCyrShS2dTgRQP/t07Y2BGmafWyDWLBd0yr6KvH9sf
 f8J5sv/2GFKYsip6kvJJets/XvctKNZ86y+LDeR5NnyufaWO3/7p+P1ZfG6cGnCK
 F9kOilDp/k2wj1GQB0w2iCjuw66jAC6Ib3uiebTN1MgfhoXZRI4TJOtDMnZuyJUZ
 HUO70wnP6qTWHpxUBu8JFf1nb3qsalk8lYgwjCzjeV1gVYXmy+PPdfcSEHprPj1H
 UaG7pdr3nFHGYLl45lpaQqhpuyDZsxD/EYeoohf6qsArrURzQFiHOUquppFZyzVD
 siIsFUFS4UeZPboFFsIzOEFMJONlOXRs701w9ZSXucNvDr5Nw8c=
 =ZiW5
 -----END PGP SIGNATURE-----

Merge tag 'v5.4.74' into 5.4-2.2.x-imx

This is the 5.4.74 stable release

Signed-off-by: Andrey Zhizhikin <andrey.zhizhikin@leica-geosystems.com>
5.4-rM2-2.2.x-imx-squashed
Andrey Zhizhikin 2020-11-01 20:14:07 +00:00
commit a2b777b0d2
53 changed files with 329 additions and 170 deletions

View File

@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0 # SPDX-License-Identifier: GPL-2.0
VERSION = 5 VERSION = 5
PATCHLEVEL = 4 PATCHLEVEL = 4
SUBLEVEL = 73 SUBLEVEL = 74
EXTRAVERSION = EXTRAVERSION =
NAME = Kleptomaniac Octopus NAME = Kleptomaniac Octopus

View File

@ -10,7 +10,7 @@
# #
# Copyright (C) 1995-2001 by Russell King # Copyright (C) 1995-2001 by Russell King
LDFLAGS_vmlinux :=--no-undefined -X LDFLAGS_vmlinux :=--no-undefined -X -z norelro
CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET) CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
GZFLAGS :=-9 GZFLAGS :=-9
@ -18,7 +18,7 @@ ifeq ($(CONFIG_RELOCATABLE), y)
# Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour
# for relative relocs, since this leads to better Image compression # for relative relocs, since this leads to better Image compression
# with the relocation offsets always being zero. # with the relocation offsets always being zero.
LDFLAGS_vmlinux += -shared -Bsymbolic -z notext -z norelro \ LDFLAGS_vmlinux += -shared -Bsymbolic -z notext \
$(call ld-option, --no-apply-dynamic-relocs) $(call ld-option, --no-apply-dynamic-relocs)
endif endif

View File

@ -492,6 +492,12 @@ out_printmsg:
return required; return required;
} }
static void cpu_enable_ssbd_mitigation(const struct arm64_cpu_capabilities *cap)
{
if (ssbd_state != ARM64_SSBD_FORCE_DISABLE)
cap->matches(cap, SCOPE_LOCAL_CPU);
}
/* known invulnerable cores */ /* known invulnerable cores */
static const struct midr_range arm64_ssb_cpus[] = { static const struct midr_range arm64_ssb_cpus[] = {
MIDR_ALL_VERSIONS(MIDR_CORTEX_A35), MIDR_ALL_VERSIONS(MIDR_CORTEX_A35),
@ -635,6 +641,12 @@ check_branch_predictor(const struct arm64_cpu_capabilities *entry, int scope)
return (need_wa > 0); return (need_wa > 0);
} }
static void
cpu_enable_branch_predictor_hardening(const struct arm64_cpu_capabilities *cap)
{
cap->matches(cap, SCOPE_LOCAL_CPU);
}
static const __maybe_unused struct midr_range tx2_family_cpus[] = { static const __maybe_unused struct midr_range tx2_family_cpus[] = {
MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN), MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2), MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2),
@ -894,9 +906,11 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
}, },
#endif #endif
{ {
.desc = "Branch predictor hardening",
.capability = ARM64_HARDEN_BRANCH_PREDICTOR, .capability = ARM64_HARDEN_BRANCH_PREDICTOR,
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
.matches = check_branch_predictor, .matches = check_branch_predictor,
.cpu_enable = cpu_enable_branch_predictor_hardening,
}, },
#ifdef CONFIG_HARDEN_EL2_VECTORS #ifdef CONFIG_HARDEN_EL2_VECTORS
{ {
@ -910,6 +924,7 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
.capability = ARM64_SSBD, .capability = ARM64_SSBD,
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM, .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
.matches = has_ssbd_mitigation, .matches = has_ssbd_mitigation,
.cpu_enable = cpu_enable_ssbd_mitigation,
.midr_range_list = arm64_ssb_cpus, .midr_range_list = arm64_ssb_cpus,
}, },
#ifdef CONFIG_ARM64_ERRATUM_1418040 #ifdef CONFIG_ARM64_ERRATUM_1418040

View File

@ -164,19 +164,19 @@ struct __large_struct {
#define __get_user_nocheck(x, ptr, size) \ #define __get_user_nocheck(x, ptr, size) \
({ \ ({ \
long __gu_err, __gu_val; \ long __gu_err; \
__get_user_size(__gu_val, (ptr), (size), __gu_err); \ __get_user_size((x), (ptr), (size), __gu_err); \
(x) = (__force __typeof__(*(ptr)))__gu_val; \
__gu_err; \ __gu_err; \
}) })
#define __get_user_check(x, ptr, size) \ #define __get_user_check(x, ptr, size) \
({ \ ({ \
long __gu_err = -EFAULT, __gu_val = 0; \ long __gu_err = -EFAULT; \
const __typeof__(*(ptr)) * __gu_addr = (ptr); \ const __typeof__(*(ptr)) *__gu_addr = (ptr); \
if (access_ok(__gu_addr, size)) \ if (access_ok(__gu_addr, size)) \
__get_user_size(__gu_val, __gu_addr, (size), __gu_err); \ __get_user_size((x), __gu_addr, (size), __gu_err); \
(x) = (__force __typeof__(*(ptr)))__gu_val; \ else \
(x) = (__typeof__(*(ptr))) 0; \
__gu_err; \ __gu_err; \
}) })
@ -190,11 +190,13 @@ do { \
case 2: __get_user_asm(x, ptr, retval, "l.lhz"); break; \ case 2: __get_user_asm(x, ptr, retval, "l.lhz"); break; \
case 4: __get_user_asm(x, ptr, retval, "l.lwz"); break; \ case 4: __get_user_asm(x, ptr, retval, "l.lwz"); break; \
case 8: __get_user_asm2(x, ptr, retval); break; \ case 8: __get_user_asm2(x, ptr, retval); break; \
default: (x) = __get_user_bad(); \ default: (x) = (__typeof__(*(ptr)))__get_user_bad(); \
} \ } \
} while (0) } while (0)
#define __get_user_asm(x, addr, err, op) \ #define __get_user_asm(x, addr, err, op) \
{ \
unsigned long __gu_tmp; \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: "op" %1,0(%2)\n" \ "1: "op" %1,0(%2)\n" \
"2:\n" \ "2:\n" \
@ -208,10 +210,14 @@ do { \
" .align 2\n" \ " .align 2\n" \
" .long 1b,3b\n" \ " .long 1b,3b\n" \
".previous" \ ".previous" \
: "=r"(err), "=r"(x) \ : "=r"(err), "=r"(__gu_tmp) \
: "r"(addr), "i"(-EFAULT), "0"(err)) : "r"(addr), "i"(-EFAULT), "0"(err)); \
(x) = (__typeof__(*(addr)))__gu_tmp; \
}
#define __get_user_asm2(x, addr, err) \ #define __get_user_asm2(x, addr, err) \
{ \
unsigned long long __gu_tmp; \
__asm__ __volatile__( \ __asm__ __volatile__( \
"1: l.lwz %1,0(%2)\n" \ "1: l.lwz %1,0(%2)\n" \
"2: l.lwz %H1,4(%2)\n" \ "2: l.lwz %H1,4(%2)\n" \
@ -228,8 +234,11 @@ do { \
" .long 1b,4b\n" \ " .long 1b,4b\n" \
" .long 2b,4b\n" \ " .long 2b,4b\n" \
".previous" \ ".previous" \
: "=r"(err), "=&r"(x) \ : "=r"(err), "=&r"(__gu_tmp) \
: "r"(addr), "i"(-EFAULT), "0"(err)) : "r"(addr), "i"(-EFAULT), "0"(err)); \
(x) = (__typeof__(*(addr)))( \
(__typeof__((x)-(x)))__gu_tmp); \
}
/* more complex routines */ /* more complex routines */

View File

@ -170,7 +170,7 @@ continue_block:
## branch into array ## branch into array
lea jump_table(%rip), bufp lea jump_table(%rip), bufp
movzxw (bufp, %rax, 2), len movzwq (bufp, %rax, 2), len
lea crc_array(%rip), bufp lea crc_array(%rip), bufp
lea (bufp, len, 1), bufp lea (bufp, len, 1), bufp
JMP_NOSPEC bufp JMP_NOSPEC bufp

View File

@ -89,6 +89,7 @@ struct perf_ibs {
u64 max_period; u64 max_period;
unsigned long offset_mask[1]; unsigned long offset_mask[1];
int offset_max; int offset_max;
unsigned int fetch_count_reset_broken : 1;
struct cpu_perf_ibs __percpu *pcpu; struct cpu_perf_ibs __percpu *pcpu;
struct attribute **format_attrs; struct attribute **format_attrs;
@ -363,7 +364,12 @@ perf_ibs_event_update(struct perf_ibs *perf_ibs, struct perf_event *event,
static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs, static inline void perf_ibs_enable_event(struct perf_ibs *perf_ibs,
struct hw_perf_event *hwc, u64 config) struct hw_perf_event *hwc, u64 config)
{ {
wrmsrl(hwc->config_base, hwc->config | config | perf_ibs->enable_mask); u64 tmp = hwc->config | config;
if (perf_ibs->fetch_count_reset_broken)
wrmsrl(hwc->config_base, tmp & ~perf_ibs->enable_mask);
wrmsrl(hwc->config_base, tmp | perf_ibs->enable_mask);
} }
/* /*
@ -733,6 +739,13 @@ static __init void perf_event_ibs_init(void)
{ {
struct attribute **attr = ibs_op_format_attrs; struct attribute **attr = ibs_op_format_attrs;
/*
* Some chips fail to reset the fetch count when it is written; instead
* they need a 0-1 transition of IbsFetchEn.
*/
if (boot_cpu_data.x86 >= 0x16 && boot_cpu_data.x86 <= 0x18)
perf_ibs_fetch.fetch_count_reset_broken = 1;
perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch"); perf_ibs_pmu_init(&perf_ibs_fetch, "ibs_fetch");
if (ibs_caps & IBS_CAPS_OPCNT) { if (ibs_caps & IBS_CAPS_OPCNT) {

View File

@ -33,6 +33,7 @@
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
#include <asm/io_apic.h> #include <asm/io_apic.h>
#include <asm/intel-mid.h> #include <asm/intel-mid.h>
#include <asm/acpi.h>
#define PCIE_CAP_OFFSET 0x100 #define PCIE_CAP_OFFSET 0x100

View File

@ -1382,6 +1382,15 @@ asmlinkage __visible void __init xen_start_kernel(void)
x86_init.mpparse.get_smp_config = x86_init_uint_noop; x86_init.mpparse.get_smp_config = x86_init_uint_noop;
xen_boot_params_init_edd(); xen_boot_params_init_edd();
#ifdef CONFIG_ACPI
/*
* Disable selecting "Firmware First mode" for correctable
* memory errors, as this is the duty of the hypervisor to
* decide.
*/
acpi_disable_cmcff = 1;
#endif
} }
if (!boot_params.screen_info.orig_video_isVGA) if (!boot_params.screen_info.orig_video_isVGA)

View File

@ -240,6 +240,8 @@ enum {
as default lpm_policy */ as default lpm_policy */
AHCI_HFLAG_SUSPEND_PHYS = (1 << 26), /* handle PHYs during AHCI_HFLAG_SUSPEND_PHYS = (1 << 26), /* handle PHYs during
suspend/resume */ suspend/resume */
AHCI_HFLAG_IGN_NOTSUPP_POWER_ON = (1 << 27), /* ignore -EOPNOTSUPP
from phy_power_on() */
/* ap->flags bits */ /* ap->flags bits */

View File

@ -227,7 +227,7 @@ static const struct ahci_mvebu_plat_data ahci_mvebu_armada_380_plat_data = {
static const struct ahci_mvebu_plat_data ahci_mvebu_armada_3700_plat_data = { static const struct ahci_mvebu_plat_data ahci_mvebu_armada_3700_plat_data = {
.plat_config = ahci_mvebu_armada_3700_config, .plat_config = ahci_mvebu_armada_3700_config,
.flags = AHCI_HFLAG_SUSPEND_PHYS, .flags = AHCI_HFLAG_SUSPEND_PHYS | AHCI_HFLAG_IGN_NOTSUPP_POWER_ON,
}; };
static const struct of_device_id ahci_mvebu_of_match[] = { static const struct of_device_id ahci_mvebu_of_match[] = {

View File

@ -59,7 +59,7 @@ int ahci_platform_enable_phys(struct ahci_host_priv *hpriv)
} }
rc = phy_power_on(hpriv->phys[i]); rc = phy_power_on(hpriv->phys[i]);
if (rc) { if (rc && !(rc == -EOPNOTSUPP && (hpriv->flags & AHCI_HFLAG_IGN_NOTSUPP_POWER_ON))) {
phy_exit(hpriv->phys[i]); phy_exit(hpriv->phys[i]);
goto disable_phys; goto disable_phys;
} }

View File

@ -120,7 +120,7 @@
/* Descriptor table word 0 bit (when DTA32M = 1) */ /* Descriptor table word 0 bit (when DTA32M = 1) */
#define SATA_RCAR_DTEND BIT(0) #define SATA_RCAR_DTEND BIT(0)
#define SATA_RCAR_DMA_BOUNDARY 0x1FFFFFFEUL #define SATA_RCAR_DMA_BOUNDARY 0x1FFFFFFFUL
/* Gen2 Physical Layer Control Registers */ /* Gen2 Physical Layer Control Registers */
#define RCAR_GEN2_PHY_CTL1_REG 0x1704 #define RCAR_GEN2_PHY_CTL1_REG 0x1704

View File

@ -692,14 +692,13 @@ static int chtls_pass_open_rpl(struct chtls_dev *cdev, struct sk_buff *skb)
if (rpl->status != CPL_ERR_NONE) { if (rpl->status != CPL_ERR_NONE) {
pr_info("Unexpected PASS_OPEN_RPL status %u for STID %u\n", pr_info("Unexpected PASS_OPEN_RPL status %u for STID %u\n",
rpl->status, stid); rpl->status, stid);
return CPL_RET_BUF_DONE; } else {
cxgb4_free_stid(cdev->tids, stid, listen_ctx->lsk->sk_family);
sock_put(listen_ctx->lsk);
kfree(listen_ctx);
module_put(THIS_MODULE);
} }
cxgb4_free_stid(cdev->tids, stid, listen_ctx->lsk->sk_family); return CPL_RET_BUF_DONE;
sock_put(listen_ctx->lsk);
kfree(listen_ctx);
module_put(THIS_MODULE);
return 0;
} }
static int chtls_close_listsrv_rpl(struct chtls_dev *cdev, struct sk_buff *skb) static int chtls_close_listsrv_rpl(struct chtls_dev *cdev, struct sk_buff *skb)
@ -716,15 +715,13 @@ static int chtls_close_listsrv_rpl(struct chtls_dev *cdev, struct sk_buff *skb)
if (rpl->status != CPL_ERR_NONE) { if (rpl->status != CPL_ERR_NONE) {
pr_info("Unexpected CLOSE_LISTSRV_RPL status %u for STID %u\n", pr_info("Unexpected CLOSE_LISTSRV_RPL status %u for STID %u\n",
rpl->status, stid); rpl->status, stid);
return CPL_RET_BUF_DONE; } else {
cxgb4_free_stid(cdev->tids, stid, listen_ctx->lsk->sk_family);
sock_put(listen_ctx->lsk);
kfree(listen_ctx);
module_put(THIS_MODULE);
} }
return CPL_RET_BUF_DONE;
cxgb4_free_stid(cdev->tids, stid, listen_ctx->lsk->sk_family);
sock_put(listen_ctx->lsk);
kfree(listen_ctx);
module_put(THIS_MODULE);
return 0;
} }
static void chtls_purge_wr_queue(struct sock *sk) static void chtls_purge_wr_queue(struct sock *sk)
@ -1369,7 +1366,6 @@ static void add_to_reap_list(struct sock *sk)
struct chtls_sock *csk = sk->sk_user_data; struct chtls_sock *csk = sk->sk_user_data;
local_bh_disable(); local_bh_disable();
bh_lock_sock(sk);
release_tcp_port(sk); /* release the port immediately */ release_tcp_port(sk); /* release the port immediately */
spin_lock(&reap_list_lock); spin_lock(&reap_list_lock);
@ -1378,7 +1374,6 @@ static void add_to_reap_list(struct sock *sk)
if (!csk->passive_reap_next) if (!csk->passive_reap_next)
schedule_work(&reap_task); schedule_work(&reap_task);
spin_unlock(&reap_list_lock); spin_unlock(&reap_list_lock);
bh_unlock_sock(sk);
local_bh_enable(); local_bh_enable();
} }

View File

@ -1537,6 +1537,7 @@ skip_copy:
tp->urg_data = 0; tp->urg_data = 0;
if ((avail + offset) >= skb->len) { if ((avail + offset) >= skb->len) {
struct sk_buff *next_skb;
if (ULP_SKB_CB(skb)->flags & ULPCB_FLAG_TLS_HDR) { if (ULP_SKB_CB(skb)->flags & ULPCB_FLAG_TLS_HDR) {
tp->copied_seq += skb->len; tp->copied_seq += skb->len;
hws->rcvpld = skb->hdr_len; hws->rcvpld = skb->hdr_len;
@ -1546,8 +1547,10 @@ skip_copy:
chtls_free_skb(sk, skb); chtls_free_skb(sk, skb);
buffers_freed++; buffers_freed++;
hws->copied_seq = 0; hws->copied_seq = 0;
if (copied >= target && next_skb = skb_peek(&sk->sk_receive_queue);
!skb_peek(&sk->sk_receive_queue)) if (copied >= target && !next_skb)
break;
if (ULP_SKB_CB(next_skb)->flags & ULPCB_FLAG_TLS_HDR)
break; break;
} }
} while (len > 0); } while (len > 0);

View File

@ -645,13 +645,12 @@ static void process_one_req(struct work_struct *_work)
req->callback = NULL; req->callback = NULL;
spin_lock_bh(&lock); spin_lock_bh(&lock);
/*
* Although the work will normally have been canceled by the workqueue,
* it can still be requeued as long as it is on the req_list.
*/
cancel_delayed_work(&req->work);
if (!list_empty(&req->list)) { if (!list_empty(&req->list)) {
/*
* Although the work will normally have been canceled by the
* workqueue, it can still be requeued as long as it is on the
* req_list.
*/
cancel_delayed_work(&req->work);
list_del_init(&req->list); list_del_init(&req->list);
kfree(req); kfree(req);
} }

View File

@ -1189,10 +1189,6 @@ void rtsx_pci_init_ocp(struct rtsx_pcr *pcr)
rtsx_pci_write_register(pcr, REG_OCPGLITCH, rtsx_pci_write_register(pcr, REG_OCPGLITCH,
SD_OCP_GLITCH_MASK, pcr->hw_param.ocp_glitch); SD_OCP_GLITCH_MASK, pcr->hw_param.ocp_glitch);
rtsx_pci_enable_ocp(pcr); rtsx_pci_enable_ocp(pcr);
} else {
/* OC power down */
rtsx_pci_write_register(pcr, FPDCTL, OC_POWER_DOWN,
OC_POWER_DOWN);
} }
} }
} }

View File

@ -393,8 +393,8 @@ int cxl_calc_capp_routing(struct pci_dev *dev, u64 *chipid,
*capp_unit_id = get_capp_unit_id(np, *phb_index); *capp_unit_id = get_capp_unit_id(np, *phb_index);
of_node_put(np); of_node_put(np);
if (!*capp_unit_id) { if (!*capp_unit_id) {
pr_err("cxl: invalid capp unit id (phb_index: %d)\n", pr_err("cxl: No capp unit found for PHB[%lld,%d]. Make sure the adapter is on a capi-compatible slot\n",
*phb_index); *chipid, *phb_index);
return -ENODEV; return -ENODEV;
} }

View File

@ -1160,16 +1160,6 @@ static void bnxt_queue_sp_work(struct bnxt *bp)
schedule_work(&bp->sp_task); schedule_work(&bp->sp_task);
} }
static void bnxt_cancel_sp_work(struct bnxt *bp)
{
if (BNXT_PF(bp)) {
flush_workqueue(bnxt_pf_wq);
} else {
cancel_work_sync(&bp->sp_task);
cancel_delayed_work_sync(&bp->fw_reset_task);
}
}
static void bnxt_sched_reset(struct bnxt *bp, struct bnxt_rx_ring_info *rxr) static void bnxt_sched_reset(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
{ {
if (!rxr->bnapi->in_reset) { if (!rxr->bnapi->in_reset) {
@ -4204,7 +4194,8 @@ static int bnxt_hwrm_do_send_msg(struct bnxt *bp, void *msg, u32 msg_len,
u32 bar_offset = BNXT_GRCPF_REG_CHIMP_COMM; u32 bar_offset = BNXT_GRCPF_REG_CHIMP_COMM;
u16 dst = BNXT_HWRM_CHNL_CHIMP; u16 dst = BNXT_HWRM_CHNL_CHIMP;
if (BNXT_NO_FW_ACCESS(bp)) if (BNXT_NO_FW_ACCESS(bp) &&
le16_to_cpu(req->req_type) != HWRM_FUNC_RESET)
return -EBUSY; return -EBUSY;
if (msg_len > BNXT_HWRM_MAX_REQ_LEN) { if (msg_len > BNXT_HWRM_MAX_REQ_LEN) {
@ -9193,7 +9184,10 @@ int bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
{ {
int rc = 0; int rc = 0;
rc = __bnxt_open_nic(bp, irq_re_init, link_re_init); if (test_bit(BNXT_STATE_ABORT_ERR, &bp->state))
rc = -EIO;
if (!rc)
rc = __bnxt_open_nic(bp, irq_re_init, link_re_init);
if (rc) { if (rc) {
netdev_err(bp->dev, "nic open fail (rc: %x)\n", rc); netdev_err(bp->dev, "nic open fail (rc: %x)\n", rc);
dev_close(bp->dev); dev_close(bp->dev);
@ -11392,13 +11386,15 @@ static void bnxt_remove_one(struct pci_dev *pdev)
if (BNXT_PF(bp)) if (BNXT_PF(bp))
bnxt_sriov_disable(bp); bnxt_sriov_disable(bp);
pci_disable_pcie_error_reporting(pdev);
unregister_netdev(dev);
clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
bnxt_cancel_sp_work(bp); /* Flush any pending tasks */
cancel_work_sync(&bp->sp_task);
cancel_delayed_work_sync(&bp->fw_reset_task);
bp->sp_event = 0; bp->sp_event = 0;
bnxt_dl_fw_reporters_destroy(bp, true); bnxt_dl_fw_reporters_destroy(bp, true);
pci_disable_pcie_error_reporting(pdev);
unregister_netdev(dev);
bnxt_dl_unregister(bp); bnxt_dl_unregister(bp);
bnxt_shutdown_tc(bp); bnxt_shutdown_tc(bp);
@ -12045,6 +12041,9 @@ static pci_ers_result_t bnxt_io_error_detected(struct pci_dev *pdev,
return PCI_ERS_RESULT_DISCONNECT; return PCI_ERS_RESULT_DISCONNECT;
} }
if (state == pci_channel_io_frozen)
set_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN, &bp->state);
if (netif_running(netdev)) if (netif_running(netdev))
bnxt_close(netdev); bnxt_close(netdev);
@ -12068,7 +12067,7 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
{ {
struct net_device *netdev = pci_get_drvdata(pdev); struct net_device *netdev = pci_get_drvdata(pdev);
struct bnxt *bp = netdev_priv(netdev); struct bnxt *bp = netdev_priv(netdev);
int err = 0; int err = 0, off;
pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT; pci_ers_result_t result = PCI_ERS_RESULT_DISCONNECT;
netdev_info(bp->dev, "PCI Slot Reset\n"); netdev_info(bp->dev, "PCI Slot Reset\n");
@ -12080,6 +12079,20 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
"Cannot re-enable PCI device after reset.\n"); "Cannot re-enable PCI device after reset.\n");
} else { } else {
pci_set_master(pdev); pci_set_master(pdev);
/* Upon fatal error, our device internal logic that latches to
* BAR value is getting reset and will restore only upon
* rewritting the BARs.
*
* As pci_restore_state() does not re-write the BARs if the
* value is same as saved value earlier, driver needs to
* write the BARs to 0 to force restore, in case of fatal error.
*/
if (test_and_clear_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN,
&bp->state)) {
for (off = PCI_BASE_ADDRESS_0;
off <= PCI_BASE_ADDRESS_5; off += 4)
pci_write_config_dword(bp->pdev, off, 0);
}
pci_restore_state(pdev); pci_restore_state(pdev);
pci_save_state(pdev); pci_save_state(pdev);

View File

@ -1627,6 +1627,7 @@ struct bnxt {
#define BNXT_STATE_IN_FW_RESET 4 #define BNXT_STATE_IN_FW_RESET 4
#define BNXT_STATE_ABORT_ERR 5 #define BNXT_STATE_ABORT_ERR 5
#define BNXT_STATE_FW_FATAL_COND 6 #define BNXT_STATE_FW_FATAL_COND 6
#define BNXT_STATE_PCI_CHANNEL_IO_FROZEN 8
#define BNXT_NO_FW_ACCESS(bp) \ #define BNXT_NO_FW_ACCESS(bp) \
(test_bit(BNXT_STATE_FW_FATAL_COND, &(bp)->state) || \ (test_bit(BNXT_STATE_FW_FATAL_COND, &(bp)->state) || \

View File

@ -145,13 +145,13 @@ static int configure_filter_smac(struct adapter *adap, struct filter_entry *f)
int err; int err;
/* do a set-tcb for smac-sel and CWR bit.. */ /* do a set-tcb for smac-sel and CWR bit.. */
err = set_tcb_tflag(adap, f, f->tid, TF_CCTRL_CWR_S, 1, 1);
if (err)
goto smac_err;
err = set_tcb_field(adap, f, f->tid, TCB_SMAC_SEL_W, err = set_tcb_field(adap, f, f->tid, TCB_SMAC_SEL_W,
TCB_SMAC_SEL_V(TCB_SMAC_SEL_M), TCB_SMAC_SEL_V(TCB_SMAC_SEL_M),
TCB_SMAC_SEL_V(f->smt->idx), 1); TCB_SMAC_SEL_V(f->smt->idx), 1);
if (err)
goto smac_err;
err = set_tcb_tflag(adap, f, f->tid, TF_CCTRL_CWR_S, 1, 1);
if (!err) if (!err)
return 0; return 0;
@ -612,6 +612,7 @@ int set_filter_wr(struct adapter *adapter, int fidx)
FW_FILTER_WR_DIRSTEERHASH_V(f->fs.dirsteerhash) | FW_FILTER_WR_DIRSTEERHASH_V(f->fs.dirsteerhash) |
FW_FILTER_WR_LPBK_V(f->fs.action == FILTER_SWITCH) | FW_FILTER_WR_LPBK_V(f->fs.action == FILTER_SWITCH) |
FW_FILTER_WR_DMAC_V(f->fs.newdmac) | FW_FILTER_WR_DMAC_V(f->fs.newdmac) |
FW_FILTER_WR_SMAC_V(f->fs.newsmac) |
FW_FILTER_WR_INSVLAN_V(f->fs.newvlan == VLAN_INSERT || FW_FILTER_WR_INSVLAN_V(f->fs.newvlan == VLAN_INSERT ||
f->fs.newvlan == VLAN_REWRITE) | f->fs.newvlan == VLAN_REWRITE) |
FW_FILTER_WR_RMVLAN_V(f->fs.newvlan == VLAN_REMOVE || FW_FILTER_WR_RMVLAN_V(f->fs.newvlan == VLAN_REMOVE ||
@ -629,7 +630,7 @@ int set_filter_wr(struct adapter *adapter, int fidx)
FW_FILTER_WR_OVLAN_VLD_V(f->fs.val.ovlan_vld) | FW_FILTER_WR_OVLAN_VLD_V(f->fs.val.ovlan_vld) |
FW_FILTER_WR_IVLAN_VLDM_V(f->fs.mask.ivlan_vld) | FW_FILTER_WR_IVLAN_VLDM_V(f->fs.mask.ivlan_vld) |
FW_FILTER_WR_OVLAN_VLDM_V(f->fs.mask.ovlan_vld)); FW_FILTER_WR_OVLAN_VLDM_V(f->fs.mask.ovlan_vld));
fwr->smac_sel = 0; fwr->smac_sel = f->smt->idx;
fwr->rx_chan_rx_rpl_iq = fwr->rx_chan_rx_rpl_iq =
htons(FW_FILTER_WR_RX_CHAN_V(0) | htons(FW_FILTER_WR_RX_CHAN_V(0) |
FW_FILTER_WR_RX_RPL_IQ_V(adapter->sge.fw_evtq.abs_id)); FW_FILTER_WR_RX_RPL_IQ_V(adapter->sge.fw_evtq.abs_id));
@ -1048,11 +1049,8 @@ static void mk_act_open_req6(struct filter_entry *f, struct sk_buff *skb,
TX_QUEUE_V(f->fs.nat_mode) | TX_QUEUE_V(f->fs.nat_mode) |
T5_OPT_2_VALID_F | T5_OPT_2_VALID_F |
RX_CHANNEL_V(cxgb4_port_e2cchan(f->dev)) | RX_CHANNEL_V(cxgb4_port_e2cchan(f->dev)) |
CONG_CNTRL_V((f->fs.action == FILTER_DROP) |
(f->fs.dirsteer << 1)) |
PACE_V((f->fs.maskhash) | PACE_V((f->fs.maskhash) |
((f->fs.dirsteerhash) << 1)) | ((f->fs.dirsteerhash) << 1)));
CCTRL_ECN_V(f->fs.action == FILTER_SWITCH));
} }
static void mk_act_open_req(struct filter_entry *f, struct sk_buff *skb, static void mk_act_open_req(struct filter_entry *f, struct sk_buff *skb,
@ -1088,11 +1086,8 @@ static void mk_act_open_req(struct filter_entry *f, struct sk_buff *skb,
TX_QUEUE_V(f->fs.nat_mode) | TX_QUEUE_V(f->fs.nat_mode) |
T5_OPT_2_VALID_F | T5_OPT_2_VALID_F |
RX_CHANNEL_V(cxgb4_port_e2cchan(f->dev)) | RX_CHANNEL_V(cxgb4_port_e2cchan(f->dev)) |
CONG_CNTRL_V((f->fs.action == FILTER_DROP) |
(f->fs.dirsteer << 1)) |
PACE_V((f->fs.maskhash) | PACE_V((f->fs.maskhash) |
((f->fs.dirsteerhash) << 1)) | ((f->fs.dirsteerhash) << 1)));
CCTRL_ECN_V(f->fs.action == FILTER_SWITCH));
} }
static int cxgb4_set_hash_filter(struct net_device *dev, static int cxgb4_set_hash_filter(struct net_device *dev,
@ -1748,6 +1743,20 @@ void hash_filter_rpl(struct adapter *adap, const struct cpl_act_open_rpl *rpl)
} }
return; return;
} }
switch (f->fs.action) {
case FILTER_PASS:
if (f->fs.dirsteer)
set_tcb_tflag(adap, f, tid,
TF_DIRECT_STEER_S, 1, 1);
break;
case FILTER_DROP:
set_tcb_tflag(adap, f, tid, TF_DROP_S, 1, 1);
break;
case FILTER_SWITCH:
set_tcb_tflag(adap, f, tid, TF_LPBK_S, 1, 1);
break;
}
break; break;
default: default:
@ -1808,22 +1817,11 @@ void filter_rpl(struct adapter *adap, const struct cpl_set_tcb_rpl *rpl)
if (ctx) if (ctx)
ctx->result = 0; ctx->result = 0;
} else if (ret == FW_FILTER_WR_FLT_ADDED) { } else if (ret == FW_FILTER_WR_FLT_ADDED) {
int err = 0; f->pending = 0; /* async setup completed */
f->valid = 1;
if (f->fs.newsmac) if (ctx) {
err = configure_filter_smac(adap, f); ctx->result = 0;
ctx->tid = idx;
if (!err) {
f->pending = 0; /* async setup completed */
f->valid = 1;
if (ctx) {
ctx->result = 0;
ctx->tid = idx;
}
} else {
clear_filter(adap, f);
if (ctx)
ctx->result = err;
} }
} else { } else {
/* Something went wrong. Issue a warning about the /* Something went wrong. Issue a warning about the

View File

@ -50,6 +50,10 @@
#define TCB_RQ_START_M 0x3ffffffULL #define TCB_RQ_START_M 0x3ffffffULL
#define TCB_RQ_START_V(x) ((x) << TCB_RQ_START_S) #define TCB_RQ_START_V(x) ((x) << TCB_RQ_START_S)
#define TF_DROP_S 22
#define TF_DIRECT_STEER_S 23
#define TF_LPBK_S 59
#define TF_CCTRL_ECE_S 60 #define TF_CCTRL_ECE_S 60
#define TF_CCTRL_CWR_S 61 #define TF_CCTRL_CWR_S 61
#define TF_CCTRL_RFR_S 62 #define TF_CCTRL_RFR_S 62

View File

@ -2782,8 +2782,8 @@ static void hclgevf_uninit_hdev(struct hclgevf_dev *hdev)
hclgevf_uninit_msi(hdev); hclgevf_uninit_msi(hdev);
} }
hclgevf_pci_uninit(hdev);
hclgevf_cmd_uninit(hdev); hclgevf_cmd_uninit(hdev);
hclgevf_pci_uninit(hdev);
} }
static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev) static int hclgevf_init_ae_dev(struct hnae3_ae_dev *ae_dev)

View File

@ -1735,9 +1735,13 @@ static int ibmvnic_set_mac(struct net_device *netdev, void *p)
int rc; int rc;
rc = 0; rc = 0;
ether_addr_copy(adapter->mac_addr, addr->sa_data); if (!is_valid_ether_addr(addr->sa_data))
if (adapter->state != VNIC_PROBED) return -EADDRNOTAVAIL;
if (adapter->state != VNIC_PROBED) {
ether_addr_copy(adapter->mac_addr, addr->sa_data);
rc = __ibmvnic_set_mac(netdev, addr->sa_data); rc = __ibmvnic_set_mac(netdev, addr->sa_data);
}
return rc; return rc;
} }

View File

@ -1281,6 +1281,8 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
if (!reload) if (!reload)
devlink_resources_unregister(devlink, NULL); devlink_resources_unregister(devlink, NULL);
mlxsw_core->bus->fini(mlxsw_core->bus_priv); mlxsw_core->bus->fini(mlxsw_core->bus_priv);
if (!reload)
devlink_free(devlink);
return; return;

View File

@ -6264,7 +6264,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
} }
rtl_irq_disable(tp); rtl_irq_disable(tp);
napi_schedule_irqoff(&tp->napi); napi_schedule(&tp->napi);
out: out:
rtl_ack_events(tp, status); rtl_ack_events(tp, status);
@ -6470,7 +6470,7 @@ static int rtl_open(struct net_device *dev)
rtl_request_firmware(tp); rtl_request_firmware(tp);
retval = request_irq(pci_irq_vector(pdev, 0), rtl8169_interrupt, retval = request_irq(pci_irq_vector(pdev, 0), rtl8169_interrupt,
IRQF_NO_THREAD | IRQF_SHARED, dev->name, tp); IRQF_SHARED, dev->name, tp);
if (retval < 0) if (retval < 0)
goto err_release_fw_2; goto err_release_fw_2;

View File

@ -1741,12 +1741,16 @@ static int ravb_hwtstamp_get(struct net_device *ndev, struct ifreq *req)
config.flags = 0; config.flags = 0;
config.tx_type = priv->tstamp_tx_ctrl ? HWTSTAMP_TX_ON : config.tx_type = priv->tstamp_tx_ctrl ? HWTSTAMP_TX_ON :
HWTSTAMP_TX_OFF; HWTSTAMP_TX_OFF;
if (priv->tstamp_rx_ctrl & RAVB_RXTSTAMP_TYPE_V2_L2_EVENT) switch (priv->tstamp_rx_ctrl & RAVB_RXTSTAMP_TYPE) {
case RAVB_RXTSTAMP_TYPE_V2_L2_EVENT:
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
else if (priv->tstamp_rx_ctrl & RAVB_RXTSTAMP_TYPE_ALL) break;
case RAVB_RXTSTAMP_TYPE_ALL:
config.rx_filter = HWTSTAMP_FILTER_ALL; config.rx_filter = HWTSTAMP_FILTER_ALL;
else break;
default:
config.rx_filter = HWTSTAMP_FILTER_NONE; config.rx_filter = HWTSTAMP_FILTER_NONE;
}
return copy_to_user(req->ifr_data, &config, sizeof(config)) ? return copy_to_user(req->ifr_data, &config, sizeof(config)) ?
-EFAULT : 0; -EFAULT : 0;

View File

@ -663,10 +663,6 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
gtp = netdev_priv(dev); gtp = netdev_priv(dev);
err = gtp_encap_enable(gtp, data);
if (err < 0)
return err;
if (!data[IFLA_GTP_PDP_HASHSIZE]) { if (!data[IFLA_GTP_PDP_HASHSIZE]) {
hashsize = 1024; hashsize = 1024;
} else { } else {
@ -677,12 +673,16 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
err = gtp_hashtable_new(gtp, hashsize); err = gtp_hashtable_new(gtp, hashsize);
if (err < 0) if (err < 0)
goto out_encap; return err;
err = gtp_encap_enable(gtp, data);
if (err < 0)
goto out_hashtable;
err = register_netdevice(dev); err = register_netdevice(dev);
if (err < 0) { if (err < 0) {
netdev_dbg(dev, "failed to register new netdev %d\n", err); netdev_dbg(dev, "failed to register new netdev %d\n", err);
goto out_hashtable; goto out_encap;
} }
gn = net_generic(dev_net(dev), gtp_net_id); gn = net_generic(dev_net(dev), gtp_net_id);
@ -693,11 +693,11 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev,
return 0; return 0;
out_encap:
gtp_encap_disable(gtp);
out_hashtable: out_hashtable:
kfree(gtp->addr_hash); kfree(gtp->addr_hash);
kfree(gtp->tid_hash); kfree(gtp->tid_hash);
out_encap:
gtp_encap_disable(gtp);
return err; return err;
} }

View File

@ -329,10 +329,12 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
struct p54p_desc *desc; struct p54p_desc *desc;
dma_addr_t mapping; dma_addr_t mapping;
u32 idx, i; u32 idx, i;
__le32 device_addr;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
idx = le32_to_cpu(ring_control->host_idx[1]); idx = le32_to_cpu(ring_control->host_idx[1]);
i = idx % ARRAY_SIZE(ring_control->tx_data); i = idx % ARRAY_SIZE(ring_control->tx_data);
device_addr = ((struct p54_hdr *)skb->data)->req_id;
mapping = pci_map_single(priv->pdev, skb->data, skb->len, mapping = pci_map_single(priv->pdev, skb->data, skb->len,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
@ -346,7 +348,7 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
desc = &ring_control->tx_data[i]; desc = &ring_control->tx_data[i];
desc->host_addr = cpu_to_le32(mapping); desc->host_addr = cpu_to_le32(mapping);
desc->device_addr = ((struct p54_hdr *)skb->data)->req_id; desc->device_addr = device_addr;
desc->len = cpu_to_le16(skb->len); desc->len = cpu_to_le16(skb->len);
desc->flags = 0; desc->flags = 0;

View File

@ -26,7 +26,6 @@
#define COMPHY_SIP_POWER_ON 0x82000001 #define COMPHY_SIP_POWER_ON 0x82000001
#define COMPHY_SIP_POWER_OFF 0x82000002 #define COMPHY_SIP_POWER_OFF 0x82000002
#define COMPHY_SIP_PLL_LOCK 0x82000003 #define COMPHY_SIP_PLL_LOCK 0x82000003
#define COMPHY_FW_NOT_SUPPORTED (-1)
#define COMPHY_FW_MODE_SATA 0x1 #define COMPHY_FW_MODE_SATA 0x1
#define COMPHY_FW_MODE_SGMII 0x2 #define COMPHY_FW_MODE_SGMII 0x2
@ -112,10 +111,19 @@ static int mvebu_a3700_comphy_smc(unsigned long function, unsigned long lane,
unsigned long mode) unsigned long mode)
{ {
struct arm_smccc_res res; struct arm_smccc_res res;
s32 ret;
arm_smccc_smc(function, lane, mode, 0, 0, 0, 0, 0, &res); arm_smccc_smc(function, lane, mode, 0, 0, 0, 0, 0, &res);
ret = res.a0;
return res.a0; switch (ret) {
case SMCCC_RET_SUCCESS:
return 0;
case SMCCC_RET_NOT_SUPPORTED:
return -EOPNOTSUPP;
default:
return -EINVAL;
}
} }
static int mvebu_a3700_comphy_get_fw_mode(int lane, int port, static int mvebu_a3700_comphy_get_fw_mode(int lane, int port,
@ -220,7 +228,7 @@ static int mvebu_a3700_comphy_power_on(struct phy *phy)
} }
ret = mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_ON, lane->id, fw_param); ret = mvebu_a3700_comphy_smc(COMPHY_SIP_POWER_ON, lane->id, fw_param);
if (ret == COMPHY_FW_NOT_SUPPORTED) if (ret == -EOPNOTSUPP)
dev_err(lane->dev, dev_err(lane->dev,
"unsupported SMC call, try updating your firmware\n"); "unsupported SMC call, try updating your firmware\n");

View File

@ -123,7 +123,6 @@
#define COMPHY_SIP_POWER_ON 0x82000001 #define COMPHY_SIP_POWER_ON 0x82000001
#define COMPHY_SIP_POWER_OFF 0x82000002 #define COMPHY_SIP_POWER_OFF 0x82000002
#define COMPHY_FW_NOT_SUPPORTED (-1)
/* /*
* A lane is described by the following bitfields: * A lane is described by the following bitfields:
@ -273,10 +272,19 @@ static int mvebu_comphy_smc(unsigned long function, unsigned long phys,
unsigned long lane, unsigned long mode) unsigned long lane, unsigned long mode)
{ {
struct arm_smccc_res res; struct arm_smccc_res res;
s32 ret;
arm_smccc_smc(function, phys, lane, mode, 0, 0, 0, 0, &res); arm_smccc_smc(function, phys, lane, mode, 0, 0, 0, 0, &res);
ret = res.a0;
return res.a0; switch (ret) {
case SMCCC_RET_SUCCESS:
return 0;
case SMCCC_RET_NOT_SUPPORTED:
return -EOPNOTSUPP;
default:
return -EINVAL;
}
} }
static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port, static int mvebu_comphy_get_mode(bool fw_mode, int lane, int port,
@ -819,7 +827,7 @@ static int mvebu_comphy_power_on(struct phy *phy)
if (!ret) if (!ret)
return ret; return ret;
if (ret == COMPHY_FW_NOT_SUPPORTED) if (ret == -EOPNOTSUPP)
dev_err(priv->dev, dev_err(priv->dev,
"unsupported SMC call, try updating your firmware\n"); "unsupported SMC call, try updating your firmware\n");

View File

@ -313,8 +313,9 @@ static void pl011_write(unsigned int val, const struct uart_amba_port *uap,
*/ */
static int pl011_fifo_to_tty(struct uart_amba_port *uap) static int pl011_fifo_to_tty(struct uart_amba_port *uap)
{ {
u16 status;
unsigned int ch, flag, fifotaken; unsigned int ch, flag, fifotaken;
int sysrq;
u16 status;
for (fifotaken = 0; fifotaken != 256; fifotaken++) { for (fifotaken = 0; fifotaken != 256; fifotaken++) {
status = pl011_read(uap, REG_FR); status = pl011_read(uap, REG_FR);
@ -349,10 +350,12 @@ static int pl011_fifo_to_tty(struct uart_amba_port *uap)
flag = TTY_FRAME; flag = TTY_FRAME;
} }
if (uart_handle_sysrq_char(&uap->port, ch & 255)) spin_unlock(&uap->port.lock);
continue; sysrq = uart_handle_sysrq_char(&uap->port, ch & 255);
spin_lock(&uap->port.lock);
uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); if (!sysrq)
uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
} }
return fifotaken; return fifotaken;

View File

@ -970,7 +970,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
sampling_rate = UART_OVERSAMPLING; sampling_rate = UART_OVERSAMPLING;
/* Sampling rate is halved for IP versions >= 2.5 */ /* Sampling rate is halved for IP versions >= 2.5 */
ver = geni_se_get_qup_hw_version(&port->se); ver = geni_se_get_qup_hw_version(&port->se);
if (GENI_SE_VERSION_MAJOR(ver) >= 2 && GENI_SE_VERSION_MINOR(ver) >= 5) if (ver >= QUP_SE_VERSION_2_5)
sampling_rate /= 2; sampling_rate /= 2;
clk_rate = get_clk_div_rate(baud, sampling_rate, &clk_div); clk_rate = get_clk_div_rate(baud, sampling_rate, &clk_div);

View File

@ -831,17 +831,18 @@ struct gntdev_copy_batch {
s16 __user *status[GNTDEV_COPY_BATCH]; s16 __user *status[GNTDEV_COPY_BATCH];
unsigned int nr_ops; unsigned int nr_ops;
unsigned int nr_pages; unsigned int nr_pages;
bool writeable;
}; };
static int gntdev_get_page(struct gntdev_copy_batch *batch, void __user *virt, static int gntdev_get_page(struct gntdev_copy_batch *batch, void __user *virt,
bool writeable, unsigned long *gfn) unsigned long *gfn)
{ {
unsigned long addr = (unsigned long)virt; unsigned long addr = (unsigned long)virt;
struct page *page; struct page *page;
unsigned long xen_pfn; unsigned long xen_pfn;
int ret; int ret;
ret = get_user_pages_fast(addr, 1, writeable ? FOLL_WRITE : 0, &page); ret = get_user_pages_fast(addr, 1, batch->writeable ? FOLL_WRITE : 0, &page);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -857,9 +858,13 @@ static void gntdev_put_pages(struct gntdev_copy_batch *batch)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < batch->nr_pages; i++) for (i = 0; i < batch->nr_pages; i++) {
if (batch->writeable && !PageDirty(batch->pages[i]))
set_page_dirty_lock(batch->pages[i]);
put_page(batch->pages[i]); put_page(batch->pages[i]);
}
batch->nr_pages = 0; batch->nr_pages = 0;
batch->writeable = false;
} }
static int gntdev_copy(struct gntdev_copy_batch *batch) static int gntdev_copy(struct gntdev_copy_batch *batch)
@ -948,8 +953,9 @@ static int gntdev_grant_copy_seg(struct gntdev_copy_batch *batch,
virt = seg->source.virt + copied; virt = seg->source.virt + copied;
off = (unsigned long)virt & ~XEN_PAGE_MASK; off = (unsigned long)virt & ~XEN_PAGE_MASK;
len = min(len, (size_t)XEN_PAGE_SIZE - off); len = min(len, (size_t)XEN_PAGE_SIZE - off);
batch->writeable = false;
ret = gntdev_get_page(batch, virt, false, &gfn); ret = gntdev_get_page(batch, virt, &gfn);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -967,8 +973,9 @@ static int gntdev_grant_copy_seg(struct gntdev_copy_batch *batch,
virt = seg->dest.virt + copied; virt = seg->dest.virt + copied;
off = (unsigned long)virt & ~XEN_PAGE_MASK; off = (unsigned long)virt & ~XEN_PAGE_MASK;
len = min(len, (size_t)XEN_PAGE_SIZE - off); len = min(len, (size_t)XEN_PAGE_SIZE - off);
batch->writeable = true;
ret = gntdev_get_page(batch, virt, true, &gfn); ret = gntdev_get_page(batch, virt, &gfn);
if (ret < 0) if (ret < 0)
return ret; return ret;

View File

@ -141,6 +141,9 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor,
name[len + EFI_VARIABLE_GUID_LEN+1] = '\0'; name[len + EFI_VARIABLE_GUID_LEN+1] = '\0';
/* replace invalid slashes like kobject_set_name_vargs does for /sys/firmware/efi/vars. */
strreplace(name, '/', '!');
inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | 0644, 0, inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | 0644, 0,
is_removable); is_removable);
if (!inode) if (!inode)

View File

@ -473,8 +473,6 @@ static int erofs_xattr_generic_get(const struct xattr_handler *handler,
return -EOPNOTSUPP; return -EOPNOTSUPP;
break; break;
case EROFS_XATTR_INDEX_TRUSTED: case EROFS_XATTR_INDEX_TRUSTED:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
break; break;
case EROFS_XATTR_INDEX_SECURITY: case EROFS_XATTR_INDEX_SECURITY:
break; break;

View File

@ -786,15 +786,16 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
struct page *newpage; struct page *newpage;
struct pipe_buffer *buf = cs->pipebufs; struct pipe_buffer *buf = cs->pipebufs;
get_page(oldpage);
err = unlock_request(cs->req); err = unlock_request(cs->req);
if (err) if (err)
return err; goto out_put_old;
fuse_copy_finish(cs); fuse_copy_finish(cs);
err = pipe_buf_confirm(cs->pipe, buf); err = pipe_buf_confirm(cs->pipe, buf);
if (err) if (err)
return err; goto out_put_old;
BUG_ON(!cs->nr_segs); BUG_ON(!cs->nr_segs);
cs->currbuf = buf; cs->currbuf = buf;
@ -834,7 +835,7 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL); err = replace_page_cache_page(oldpage, newpage, GFP_KERNEL);
if (err) { if (err) {
unlock_page(newpage); unlock_page(newpage);
return err; goto out_put_old;
} }
get_page(newpage); get_page(newpage);
@ -853,14 +854,19 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
if (err) { if (err) {
unlock_page(newpage); unlock_page(newpage);
put_page(newpage); put_page(newpage);
return err; goto out_put_old;
} }
unlock_page(oldpage); unlock_page(oldpage);
/* Drop ref for ap->pages[] array */
put_page(oldpage); put_page(oldpage);
cs->len = 0; cs->len = 0;
return 0; err = 0;
out_put_old:
/* Drop ref obtained in this function */
put_page(oldpage);
return err;
out_fallback_unlock: out_fallback_unlock:
unlock_page(newpage); unlock_page(newpage);
@ -869,10 +875,10 @@ out_fallback:
cs->offset = buf->offset; cs->offset = buf->offset;
err = lock_request(cs->req); err = lock_request(cs->req);
if (err) if (!err)
return err; err = 1;
return 1; goto out_put_old;
} }
static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page, static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
@ -884,14 +890,16 @@ static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
if (cs->nr_segs == cs->pipe->buffers) if (cs->nr_segs == cs->pipe->buffers)
return -EIO; return -EIO;
get_page(page);
err = unlock_request(cs->req); err = unlock_request(cs->req);
if (err) if (err) {
put_page(page);
return err; return err;
}
fuse_copy_finish(cs); fuse_copy_finish(cs);
buf = cs->pipebufs; buf = cs->pipebufs;
get_page(page);
buf->page = page; buf->page = page;
buf->offset = offset; buf->offset = offset;
buf->len = count; buf->len = count;

View File

@ -128,7 +128,7 @@ static inline void print_drs_error(unsigned dsr)
if (!(dsr & DSR_AVAILABLE)) if (!(dsr & DSR_AVAILABLE))
printk(KERN_NOTICE"DSR.15: (0) Device not Available\n"); printk(KERN_NOTICE"DSR.15: (0) Device not Available\n");
if (prog_status & 0x03) if ((prog_status & 0x03) == 0x03)
printk(KERN_NOTICE"DSR.9,8: (11) Attempt to program invalid " printk(KERN_NOTICE"DSR.9,8: (11) Attempt to program invalid "
"half with 41h command\n"); "half with 41h command\n");
else if (prog_status & 0x02) else if (prog_status & 0x02)

View File

@ -598,7 +598,7 @@ struct dev_pm_info {
#endif #endif
#ifdef CONFIG_PM #ifdef CONFIG_PM
struct hrtimer suspend_timer; struct hrtimer suspend_timer;
unsigned long timer_expires; u64 timer_expires;
struct work_struct work; struct work_struct work;
wait_queue_head_t wait_queue; wait_queue_head_t wait_queue;
struct wake_irq *wakeirq; struct wake_irq *wakeirq;

View File

@ -229,6 +229,9 @@ struct geni_se {
#define GENI_SE_VERSION_MINOR(ver) ((ver & HW_VER_MINOR_MASK) >> HW_VER_MINOR_SHFT) #define GENI_SE_VERSION_MINOR(ver) ((ver & HW_VER_MINOR_MASK) >> HW_VER_MINOR_SHFT)
#define GENI_SE_VERSION_STEP(ver) (ver & HW_VER_STEP_MASK) #define GENI_SE_VERSION_STEP(ver) (ver & HW_VER_STEP_MASK)
/* QUP SE VERSION value for major number 2 and minor number 5 */
#define QUP_SE_VERSION_2_5 0x20050000
#if IS_ENABLED(CONFIG_QCOM_GENI_SE) #if IS_ENABLED(CONFIG_QCOM_GENI_SE)
u32 geni_se_get_qup_hw_version(struct geni_se *se); u32 geni_se_get_qup_hw_version(struct geni_se *se);

View File

@ -872,6 +872,12 @@ static inline struct nft_expr *nft_expr_last(const struct nft_rule *rule)
return (struct nft_expr *)&rule->data[rule->dlen]; return (struct nft_expr *)&rule->data[rule->dlen];
} }
static inline bool nft_expr_more(const struct nft_rule *rule,
const struct nft_expr *expr)
{
return expr != nft_expr_last(rule) && expr->ops;
}
static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule) static inline struct nft_userdata *nft_userdata(const struct nft_rule *rule)
{ {
return (void *)&rule->data[rule->dlen]; return (void *)&rule->data[rule->dlen];

View File

@ -1294,8 +1294,8 @@ union bpf_attr {
* Return * Return
* The return value depends on the result of the test, and can be: * The return value depends on the result of the test, and can be:
* *
* * 0, if the *skb* task belongs to the cgroup2. * * 0, if current task belongs to the cgroup2.
* * 1, if the *skb* task does not belong to the cgroup2. * * 1, if current task does not belong to the cgroup2.
* * A negative error code, if an error occurred. * * A negative error code, if an error occurred.
* *
* int bpf_skb_change_tail(struct sk_buff *skb, u32 len, u64 flags) * int bpf_skb_change_tail(struct sk_buff *skb, u32 len, u64 flags)

View File

@ -923,7 +923,6 @@ set_rcvbuf:
} else { } else {
sock_reset_flag(sk, SOCK_RCVTSTAMP); sock_reset_flag(sk, SOCK_RCVTSTAMP);
sock_reset_flag(sk, SOCK_RCVTSTAMPNS); sock_reset_flag(sk, SOCK_RCVTSTAMPNS);
sock_reset_flag(sk, SOCK_TSTAMP_NEW);
} }
break; break;

View File

@ -484,6 +484,8 @@ static inline bool tcp_stream_is_readable(const struct tcp_sock *tp,
return true; return true;
if (tcp_rmem_pressure(sk)) if (tcp_rmem_pressure(sk))
return true; return true;
if (tcp_receive_window(tp) <= inet_csk(sk)->icsk_ack.rcv_mss)
return true;
} }
if (sk->sk_prot->stream_memory_read) if (sk->sk_prot->stream_memory_read)
return sk->sk_prot->stream_memory_read(sk); return sk->sk_prot->stream_memory_read(sk);

View File

@ -4774,7 +4774,8 @@ void tcp_data_ready(struct sock *sk)
int avail = tp->rcv_nxt - tp->copied_seq; int avail = tp->rcv_nxt - tp->copied_seq;
if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) && if (avail < sk->sk_rcvlowat && !tcp_rmem_pressure(sk) &&
!sock_flag(sk, SOCK_DONE)) !sock_flag(sk, SOCK_DONE) &&
tcp_receive_window(tp) > inet_csk(sk)->icsk_ack.rcv_mss)
return; return;
sk->sk_data_ready(sk); sk->sk_data_ready(sk);

View File

@ -254,7 +254,7 @@ static void nft_rule_expr_activate(const struct nft_ctx *ctx,
struct nft_expr *expr; struct nft_expr *expr;
expr = nft_expr_first(rule); expr = nft_expr_first(rule);
while (expr != nft_expr_last(rule) && expr->ops) { while (nft_expr_more(rule, expr)) {
if (expr->ops->activate) if (expr->ops->activate)
expr->ops->activate(ctx, expr); expr->ops->activate(ctx, expr);
@ -269,7 +269,7 @@ static void nft_rule_expr_deactivate(const struct nft_ctx *ctx,
struct nft_expr *expr; struct nft_expr *expr;
expr = nft_expr_first(rule); expr = nft_expr_first(rule);
while (expr != nft_expr_last(rule) && expr->ops) { while (nft_expr_more(rule, expr)) {
if (expr->ops->deactivate) if (expr->ops->deactivate)
expr->ops->deactivate(ctx, expr, phase); expr->ops->deactivate(ctx, expr, phase);
@ -2642,7 +2642,7 @@ static void nf_tables_rule_destroy(const struct nft_ctx *ctx,
* is called on error from nf_tables_newrule(). * is called on error from nf_tables_newrule().
*/ */
expr = nft_expr_first(rule); expr = nft_expr_first(rule);
while (expr != nft_expr_last(rule) && expr->ops) { while (nft_expr_more(rule, expr)) {
next = nft_expr_next(expr); next = nft_expr_next(expr);
nf_tables_expr_destroy(ctx, expr); nf_tables_expr_destroy(ctx, expr);
expr = next; expr = next;

View File

@ -37,7 +37,7 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net,
struct nft_expr *expr; struct nft_expr *expr;
expr = nft_expr_first(rule); expr = nft_expr_first(rule);
while (expr->ops && expr != nft_expr_last(rule)) { while (nft_expr_more(rule, expr)) {
if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION) if (expr->ops->offload_flags & NFT_OFFLOAD_F_ACTION)
num_actions++; num_actions++;
@ -61,7 +61,7 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net,
ctx->net = net; ctx->net = net;
ctx->dep.type = NFT_OFFLOAD_DEP_UNSPEC; ctx->dep.type = NFT_OFFLOAD_DEP_UNSPEC;
while (expr->ops && expr != nft_expr_last(rule)) { while (nft_expr_more(rule, expr)) {
if (!expr->ops->offload) { if (!expr->ops->offload) {
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto err_out; goto err_out;

View File

@ -408,6 +408,7 @@ static void __exit mpls_cleanup_module(void)
module_init(mpls_init_module); module_init(mpls_init_module);
module_exit(mpls_cleanup_module); module_exit(mpls_cleanup_module);
MODULE_SOFTDEP("post: mpls_gso");
MODULE_AUTHOR("Netronome Systems <oss-drivers@netronome.com>"); MODULE_AUTHOR("Netronome Systems <oss-drivers@netronome.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MPLS manipulation actions"); MODULE_DESCRIPTION("MPLS manipulation actions");

View File

@ -330,7 +330,7 @@ static s64 tabledist(s64 mu, s32 sigma,
/* default uniform distribution */ /* default uniform distribution */
if (dist == NULL) if (dist == NULL)
return ((rnd % (2 * sigma)) + mu) - sigma; return ((rnd % (2 * (u32)sigma)) + mu) - sigma;
t = dist->table[rnd % dist->size]; t = dist->table[rnd % dist->size];
x = (sigma % NETEM_DIST_SCALE) * t; x = (sigma % NETEM_DIST_SCALE) * t;
@ -812,6 +812,10 @@ static void get_slot(struct netem_sched_data *q, const struct nlattr *attr)
q->slot_config.max_packets = INT_MAX; q->slot_config.max_packets = INT_MAX;
if (q->slot_config.max_bytes == 0) if (q->slot_config.max_bytes == 0)
q->slot_config.max_bytes = INT_MAX; q->slot_config.max_bytes = INT_MAX;
/* capping dist_jitter to the range acceptable by tabledist() */
q->slot_config.dist_jitter = min_t(__s64, INT_MAX, abs(q->slot_config.dist_jitter));
q->slot.packets_left = q->slot_config.max_packets; q->slot.packets_left = q->slot_config.max_packets;
q->slot.bytes_left = q->slot_config.max_bytes; q->slot.bytes_left = q->slot_config.max_bytes;
if (q->slot_config.min_delay | q->slot_config.max_delay | if (q->slot_config.min_delay | q->slot_config.max_delay |
@ -1037,6 +1041,9 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt,
if (tb[TCA_NETEM_SLOT]) if (tb[TCA_NETEM_SLOT])
get_slot(q, tb[TCA_NETEM_SLOT]); get_slot(q, tb[TCA_NETEM_SLOT]);
/* capping jitter to the range acceptable by tabledist() */
q->jitter = min_t(s64, abs(q->jitter), INT_MAX);
return ret; return ret;
get_table_failure: get_table_failure:

View File

@ -140,12 +140,11 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
if (fragid == FIRST_FRAGMENT) { if (fragid == FIRST_FRAGMENT) {
if (unlikely(head)) if (unlikely(head))
goto err; goto err;
if (skb_cloned(frag)) *buf = NULL;
frag = skb_copy(frag, GFP_ATOMIC); frag = skb_unshare(frag, GFP_ATOMIC);
if (unlikely(!frag)) if (unlikely(!frag))
goto err; goto err;
head = *headbuf = frag; head = *headbuf = frag;
*buf = NULL;
TIPC_SKB_CB(head)->tail = NULL; TIPC_SKB_CB(head)->tail = NULL;
if (skb_is_nonlinear(head)) { if (skb_is_nonlinear(head)) {
skb_walk_frags(head, tail) { skb_walk_frags(head, tail) {

View File

@ -45,7 +45,7 @@ scm_version()
# Check for git and a git repo. # Check for git and a git repo.
if test -z "$(git rev-parse --show-cdup 2>/dev/null)" && if test -z "$(git rev-parse --show-cdup 2>/dev/null)" &&
head=`git rev-parse --verify --short HEAD 2>/dev/null`; then head=$(git rev-parse --verify HEAD 2>/dev/null); then
# If we are at a tagged commit (like "v2.6.30-rc6"), we ignore # If we are at a tagged commit (like "v2.6.30-rc6"), we ignore
# it, because this version is defined in the top level Makefile. # it, because this version is defined in the top level Makefile.
@ -59,11 +59,22 @@ scm_version()
fi fi
# If we are past a tagged commit (like # If we are past a tagged commit (like
# "v2.6.30-rc5-302-g72357d5"), we pretty print it. # "v2.6.30-rc5-302-g72357d5"), we pretty print it.
if atag="`git describe 2>/dev/null`"; then #
echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),$(NF))}' # Ensure the abbreviated sha1 has exactly 12
# hex characters, to make the output
# independent of git version, local
# core.abbrev settings and/or total number of
# objects in the current repository - passing
# --abbrev=12 ensures a minimum of 12, and the
# awk substr() then picks the 'g' and first 12
# hex chars.
if atag="$(git describe --abbrev=12 2>/dev/null)"; then
echo "$atag" | awk -F- '{printf("-%05d-%s", $(NF-1),substr($(NF),0,13))}'
# If we don't have a tag at all we print -g{commitish}. # If we don't have a tag at all we print -g{commitish},
# again using exactly 12 hex chars.
else else
head="$(echo $head | cut -c1-12)"
printf '%s%s' -g $head printf '%s%s' -g $head
fi fi
fi fi

View File

@ -183,6 +183,12 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
break; break;
case EVM_IMA_XATTR_DIGSIG: case EVM_IMA_XATTR_DIGSIG:
case EVM_XATTR_PORTABLE_DIGSIG: case EVM_XATTR_PORTABLE_DIGSIG:
/* accept xattr with non-empty signature field */
if (xattr_len <= sizeof(struct signature_v2_hdr)) {
evm_status = INTEGRITY_FAIL;
goto out;
}
hdr = (struct signature_v2_hdr *)xattr_data; hdr = (struct signature_v2_hdr *)xattr_data;
digest.hdr.algo = hdr->hash_algo; digest.hdr.algo = hdr->hash_algo;
rc = evm_calc_hash(dentry, xattr_name, xattr_value, rc = evm_calc_hash(dentry, xattr_name, xattr_value,

View File

@ -1294,8 +1294,8 @@ union bpf_attr {
* Return * Return
* The return value depends on the result of the test, and can be: * The return value depends on the result of the test, and can be:
* *
* * 0, if the *skb* task belongs to the cgroup2. * * 0, if current task belongs to the cgroup2.
* * 1, if the *skb* task does not belong to the cgroup2. * * 1, if current task does not belong to the cgroup2.
* * A negative error code, if an error occurred. * * A negative error code, if an error occurred.
* *
* int bpf_skb_change_tail(struct sk_buff *skb, u32 len, u64 flags) * int bpf_skb_change_tail(struct sk_buff *skb, u32 len, u64 flags)

View File

@ -88,11 +88,6 @@ static int create_orc_entry(struct section *u_sec, struct section *ip_relasec,
struct orc_entry *orc; struct orc_entry *orc;
struct rela *rela; struct rela *rela;
if (!insn_sec->sym) {
WARN("missing symbol for section %s", insn_sec->name);
return -1;
}
/* populate ORC data */ /* populate ORC data */
orc = (struct orc_entry *)u_sec->data->d_buf + idx; orc = (struct orc_entry *)u_sec->data->d_buf + idx;
memcpy(orc, o, sizeof(*orc)); memcpy(orc, o, sizeof(*orc));
@ -105,8 +100,32 @@ static int create_orc_entry(struct section *u_sec, struct section *ip_relasec,
} }
memset(rela, 0, sizeof(*rela)); memset(rela, 0, sizeof(*rela));
rela->sym = insn_sec->sym; if (insn_sec->sym) {
rela->addend = insn_off; rela->sym = insn_sec->sym;
rela->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) {
/*
* Hack alert. This happens when we need to reference
* the NOP pad insn immediately after the function.
*/
rela->sym = find_symbol_containing(insn_sec,
insn_off - 1);
}
if (!rela->sym) {
WARN("missing symbol for insn at offset 0x%lx\n",
insn_off);
return -1;
}
rela->addend = insn_off - rela->sym->offset;
}
rela->type = R_X86_64_PC32; rela->type = R_X86_64_PC32;
rela->offset = idx * sizeof(int); rela->offset = idx * sizeof(int);