* [PATCH v2 1/5] pinctrl: imx: use struct imx_pinctrl_soc_info as a const
From: Gary Bisson @ 2018-01-08 16:48 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180106142553.15322-2-stefan@agner.ch>
Hi Stefan,
On Sat, Jan 06, 2018 at 03:25:49PM +0100, Stefan Agner wrote:
> For some SoCs the struct imx_pinctrl_soc_info is passed through
> of_device_id.data which is const. Most variables are already const
> or otherwise not written. However, some fields are modified at
> runtime. Move those fields to the dynamically allocated struct
> imx_pinctrl.
>
> Fixes: b3060044e495 ("pinctrl: freescale: imx7d: make of_device_ids const")
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Arvind Yadav <arvind.yadav.cs@gmail.com>
> Cc: Dong Aisheng <aisheng.dong@nxp.com>
> Cc: Gary Bisson <gary.bisson@boundarydevices.com>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
This is actually more or less a revert of a previous commit:
b28742be4709 pinctrl: imx: remove const qualifier of imx_pinctrl_soc_info
Note that the idea for this commit was to get dt-overlays working and
able to do pinctrl changes using configfs interface to load an overlay
(using Pantelis patch). Not sure where we stand on loading such overlay
from user-space, is it still something that will happen?
Regards,
Gary
^ permalink raw reply
* [PATCH 0/3] ARM branch predictor hardening
From: Tony Lindgren @ 2018-01-08 16:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180106120907.26701-1-marc.zyngier@arm.com>
* Marc Zyngier <marc.zyngier@arm.com> [180106 04:14]:
> This small series implements some basic BP hardening by invalidating
> the BTB on CPUs that are known to be susceptible to aliasing attacks.
>
> These patches are closely modelled against what we do on arm64,
> although simpler as we can rely on an architected instruction to
> perform the invalidation.
>
> The first patch reuses the Cortex-A8 BTB invalidation in switch_mm and
> generalises it to be used on all affected CPUs. The second perform the
> same invalidation on fatal signal delivery. The last one nukes it on
> guest exit, and results in some major surgery (kudos to Dimitris
> Papastamos who came up with the magic vector decoding sequence).
So if a Cortex-A8 has bootloder set the IBE bit, and kernel has
ARM_ERRATA_430973 enabled, is Cortex-A8 already hardened then?
Regards,
Tony
^ permalink raw reply
* [RFC] ARM: dts: sama5d2: qspi DMA fixes spi DMA
From: Nicolas Ferre @ 2018-01-08 16:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1514317960-27094-1-git-send-email-aford173@gmail.com>
On 26/12/2017 at 20:52, Adam Ford wrote:
> For some reason without this patch, using SPI0 with DMA yields the
> following message:
>
> atmel_spi f8000000.spi: DMA TX channel not available, SPI unable to use DMA
>
> With the patch, trying to use SPI0 yields the following:
>
> atmel_spi f8000000.spi: Using dma0chan0 (tx) and dma0chan1 (rx) for DMA transfers
It seems related to SPI interface, handled by drivers/spi/spi-atmel.c
driver. DMA properties are already set for this driver.
> The QSPI driver doesn't appear to me to be using the DMA but the
> datasheet seems indicate the DMA is supported. I am not sure why patch would
> fix the errors, so I'm posting it as RFC.
QSPI is a totally different IP and so driver:
drivers/mtd/spi-nor/atmel-quadspi.c
Actually what you modify hereunder is the QSPI DT and the DMA is
disabled for it because we miss a way to make sure that the buffer we
are handling are DMA capable (continuous for instance).
The support for a way to handle this is being discussed right now (by
Cyrille in copy). Once settled, we will be able to use DMA with QSPI in
this driver. DT binding is not determined yet BTW.
For now, your patch is not usable.
Thanks, best regards.
Nicolas
> Signed-off-by: Adam Ford <aford173@gmail.com>
>
> diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
> index 61f68e5..fd55e91 100644
> --- a/arch/arm/boot/dts/sama5d2.dtsi
> +++ b/arch/arm/boot/dts/sama5d2.dtsi
> @@ -999,6 +999,13 @@
> reg = <0xf0020000 0x100>, <0xd0000000 0x08000000>;
> reg-names = "qspi_base", "qspi_mmap";
> interrupts = <52 IRQ_TYPE_LEVEL_HIGH 7>;
> + dmas = <&dma0
> + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
> + AT91_XDMAC_DT_PERID(4))>,
> + <&dma0
> + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
> + AT91_XDMAC_DT_PERID(5))>;
> + dma-names = "tx", "rx";
> clocks = <&qspi0_clk>;
> #address-cells = <1>;
> #size-cells = <0>;
> @@ -1010,6 +1017,13 @@
> reg = <0xf0024000 0x100>, <0xd8000000 0x08000000>;
> reg-names = "qspi_base", "qspi_mmap";
> interrupts = <53 IRQ_TYPE_LEVEL_HIGH 7>;
> + dmas = <&dma1
> + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
> + AT91_XDMAC_DT_PERID(48))>,
> + <&dma0
> + (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
> + AT91_XDMAC_DT_PERID(49))>;
> + dma-names = "tx", "rx";
> clocks = <&qspi1_clk>;
> #address-cells = <1>;
> #size-cells = <0>;
>
--
Nicolas Ferre
^ permalink raw reply
* [PATCH 0/3] ARM branch predictor hardening
From: Marc Zyngier @ 2018-01-08 17:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180108165425.GR3875@atomide.com>
Hi Tony,
On 08/01/18 16:54, Tony Lindgren wrote:
> * Marc Zyngier <marc.zyngier@arm.com> [180106 04:14]:
>> This small series implements some basic BP hardening by invalidating
>> the BTB on CPUs that are known to be susceptible to aliasing attacks.
>>
>> These patches are closely modelled against what we do on arm64,
>> although simpler as we can rely on an architected instruction to
>> perform the invalidation.
>>
>> The first patch reuses the Cortex-A8 BTB invalidation in switch_mm and
>> generalises it to be used on all affected CPUs. The second perform the
>> same invalidation on fatal signal delivery. The last one nukes it on
>> guest exit, and results in some major surgery (kudos to Dimitris
>> Papastamos who came up with the magic vector decoding sequence).
>
> So if a Cortex-A8 has bootloder set the IBE bit, and kernel has
> ARM_ERRATA_430973 enabled, is Cortex-A8 already hardened then?
Almost. See the extra BTB invalidation in fault.c.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [v2,03/11] arm64: Take into account ID_AA64PFR0_EL1.CSV3
From: Will Deacon @ 2018-01-08 17:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180108072253.GA178830@jc-sabre>
On Sun, Jan 07, 2018 at 11:24:02PM -0800, Jayachandran C wrote:
> On Fri, Jan 05, 2018 at 01:12:33PM +0000, Will Deacon wrote:
> > For non-KASLR kernels where the KPTI behaviour has not been overridden
> > on the command line we can use ID_AA64PFR0_EL1.CSV3 to determine whether
> > or not we should unmap the kernel whilst running at EL0.
> >
> > Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > Signed-off-by: Will Deacon <will.deacon@arm.com>
> > ---
> > arch/arm64/include/asm/sysreg.h | 1 +
> > arch/arm64/kernel/cpufeature.c | 8 +++++++-
> > 2 files changed, 8 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> > index 08cc88574659..ae519bbd3f9e 100644
> > --- a/arch/arm64/include/asm/sysreg.h
> > +++ b/arch/arm64/include/asm/sysreg.h
> > @@ -437,6 +437,7 @@
> > #define ID_AA64ISAR1_DPB_SHIFT 0
> >
> > /* id_aa64pfr0 */
> > +#define ID_AA64PFR0_CSV3_SHIFT 60
> > #define ID_AA64PFR0_SVE_SHIFT 32
> > #define ID_AA64PFR0_GIC_SHIFT 24
> > #define ID_AA64PFR0_ASIMD_SHIFT 20
> > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > index 9f0545dfe497..d723fc071f39 100644
> > --- a/arch/arm64/kernel/cpufeature.c
> > +++ b/arch/arm64/kernel/cpufeature.c
> > @@ -145,6 +145,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
> > };
> >
> > static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
> > + ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_CSV3_SHIFT, 4, 0),
> > ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_SVE_SHIFT, 4, 0),
> > ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_GIC_SHIFT, 4, 0),
> > S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI),
> > @@ -851,6 +852,8 @@ static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
> > static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
> > int __unused)
> > {
> > + u64 pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
> > +
> > /* Forced on command line? */
> > if (__kpti_forced) {
> > pr_info_once("kernel page table isolation forced %s by command line option\n",
> > @@ -862,7 +865,9 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
> > if (IS_ENABLED(CONFIG_RANDOMIZE_BASE))
> > return true;
> >
> > - return false;
> > + /* Defer to CPU feature registers */
> > + return !cpuid_feature_extract_unsigned_field(pfr0,
> > + ID_AA64PFR0_CSV3_SHIFT);
>
> If I read this correctly, this enables KPTI on all processors without the CSV3
> set (which seems to be a future capability).
>
> Turning on KPTI has a small but significant overhead, so I think we should turn
> it off on processors that are not vulnerable to CVE-2017-5754. Can we add something
> like this:
>
> --->8
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 19ed09b..202b037 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -862,6 +862,13 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
> return __kpti_forced > 0;
> }
>
> + /* Don't force KPTI for CPUs that are not vulnerable */
> + switch (read_cpuid_id() & MIDR_CPU_MODEL_MASK) {
> + case MIDR_CAVIUM_THUNDERX2:
> + case MIDR_BRCM_VULCAN:
> + return false;
> + }
> +
KASLR aside (I agree with Marc on that), I did consider an MIDR whitelist,
but it gets nasty for big.LITTLE systems if maxcpus= is used and we see a
non-whitelisted CPU after we've booted. At this point, we can't actually
bring the thing online.
You could make the argument that if you're passing maxcpus= then you can just
easily pass kpti= as well, but I wasn't sure.
Will
^ permalink raw reply
* [PATCH v2 1/4] dmaengine: xilinx_dma: populate dma caps properly
From: Vinod Koul @ 2018-01-08 17:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CY1PR02MB1692EB7A4E66BA30A8E0DB45DC130@CY1PR02MB1692.namprd02.prod.outlook.com>
On Mon, Jan 08, 2018 at 10:52:01AM +0000, Appana Durga Kedareswara Rao wrote:
> Hi Vinod,
>
> Thanks for the review....
> <Snip>
> >> @@ -2398,6 +2398,7 @@ static int xilinx_dma_chan_probe(struct
> >xilinx_dma_device *xdev,
> >> chan->direction = DMA_MEM_TO_DEV;
> >> chan->id = chan_id;
> >> chan->tdest = chan_id;
> >> + xdev->common.directions = BIT(DMA_MEM_TO_DEV);
> >>
> >> chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
> >> if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) { @@ -
> >2415,6
> >> +2416,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
> >> chan->direction = DMA_DEV_TO_MEM;
> >> chan->id = chan_id;
> >> chan->tdest = chan_id - xdev->nr_channels;
> >> + xdev->common.directions |= BIT(DMA_DEV_TO_MEM);
> >>
> >> chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET;
> >> if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) { @@ -
> >2629,6
> >> +2631,8 @@ static int xilinx_dma_probe(struct platform_device *pdev)
> >> dma_cap_set(DMA_PRIVATE, xdev->common.cap_mask);
> >> }
> >>
> >> + xdev->common.dst_addr_widths = BIT(addr_width / 8);
> >> + xdev->common.src_addr_widths = BIT(addr_width / 8);
> >
> >Do you not support trf of 1byte, 2 bytes, or 4 bytes wide transfers? What is value
> >of addr_width here typically? Usually controllers can support different widths and
> >this is a surprise that you support only one value
>
> Controller supports address width of 32 and 64.
Then this should have both 32 and 64 values here
> addr_width typical values are 32-bit or 64-bit .
> Here addr_width is device-tree parameter...
> my understanding of src_addr_widths/dst_addr_widths is, it is a bit mask of the
> address with in bytes that DMA supports, please correct if my understanding is wrong.
>
> Regards,
> Kedar.
>
> >
> >--
> >~Vinod
--
~Vinod
^ permalink raw reply
* [PATCH] arm64: Implement branch predictor hardening for Falkor
From: Will Deacon @ 2018-01-08 17:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1515184139-23743-1-git-send-email-shankerd@codeaurora.org>
On Fri, Jan 05, 2018 at 02:28:59PM -0600, Shanker Donthineni wrote:
> Falkor is susceptible to branch predictor aliasing and can
> theoretically be attacked by malicious code. This patch
> implements a mitigation for these attacks, preventing any
> malicious entries from affecting other victim contexts.
Thanks, Shanker. I'll pick this up (fixing the typo pointed out by Drew).
One comment below.
> Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org>
> ---
> This patch has been verified using tip of
> https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=kpti
> and
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/arch/arm64?h=v4.15-rc6&id=c622cc013cece073722592cff1ac6643a33b1622
>
> arch/arm64/include/asm/cpucaps.h | 3 ++-
> arch/arm64/include/asm/kvm_asm.h | 2 ++
> arch/arm64/kernel/bpi.S | 8 +++++++
> arch/arm64/kernel/cpu_errata.c | 49 ++++++++++++++++++++++++++++++++++++++--
> arch/arm64/kvm/hyp/entry.S | 12 ++++++++++
> arch/arm64/kvm/hyp/switch.c | 10 ++++++++
> 6 files changed, 81 insertions(+), 3 deletions(-)
[...]
> diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
> index 12ee62d..9c45c6a 100644
> --- a/arch/arm64/kvm/hyp/entry.S
> +++ b/arch/arm64/kvm/hyp/entry.S
> @@ -196,3 +196,15 @@ alternative_endif
>
> eret
> ENDPROC(__fpsimd_guest_restore)
> +
> +ENTRY(__qcom_hyp_sanitize_btac_predictors)
> + /**
> + * Call SMC64 with Silicon provider serviceID 23<<8 (0xc2001700)
> + * 0xC2000000-0xC200FFFF: assigned to SiP Service Calls
> + * b15-b0: contains SiP functionID
> + */
> + movz x0, #0x1700
> + movk x0, #0xc200, lsl #16
> + smc #0
> + ret
As I mentioned to Jayachandran for the Cavium patches [1], using an
unallocated SMC number like this may cause a problem for some platforms,
such as qemu. Using the PSCI GET_VERSION call avoids this issue, so I'm
relying on you to handle any breakage reports that arise from this change
then.
FWIW: we're currently looking into extending PSCI/SMCCC so that a
standardised mechanism can be implemented without the overhead of the
current register stacking requirements.
Cheers,
Will
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-January/552511.html
^ permalink raw reply
* [PATCH net-next v5 2/2] net: thunderx: add timestamping support
From: Aleksey Makarov @ 2018-01-08 17:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171211233220.d72rys7nci4lqqd5@localhost>
On 12.12.2017 05:32, Richard Cochran wrote:
> On Mon, Dec 11, 2017 at 05:14:31PM +0300, Aleksey Makarov wrote:
>> diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
>> index 4a02e618e318..204b234beb9d 100644
>> --- a/drivers/net/ethernet/cavium/thunder/nic.h
>> +++ b/drivers/net/ethernet/cavium/thunder/nic.h
>> @@ -263,6 +263,8 @@ struct nicvf_drv_stats {
>> struct u64_stats_sync syncp;
>> };
>>
>> +struct cavium_ptp;
>> +
>> struct nicvf {
>> struct nicvf *pnicvf;
>> struct net_device *netdev;
>> @@ -312,6 +314,12 @@ struct nicvf {
>> struct tasklet_struct qs_err_task;
>> struct work_struct reset_task;
>>
>> + /* PTP timestamp */
>> + struct cavium_ptp *ptp_clock;
>> + bool hw_rx_tstamp;
>> + struct sk_buff *ptp_skb;
>> + atomic_t tx_ptp_skbs;
>
> It is disturbing that the above two fields are set in different
> places. Shouldn't they be unified into one logical lock?
No, they should not as they are not quite related.
`tx_ptp_skbs` is set when the hardware is sending a packet that requires
timestamping. Cavium hardware can not process more than one
such packet at once so this is set each time the driver submits
a packet that requires timestamping to the send queue and clears
each time it receives the entry on the completion queue saying
that such packet was sent.
So `tx_ptp_skbs` prevents driver from submitting more than one
packet that requires timestamping to the hardware for transmitting.
When that packet is sent, hardware inserts two entries to
the completion queue. First is the regular CQE_TYPE_SEND entry
that signals that the packet was sent. The second is CQE_TYPE_SEND_PTP
that contains the actual timestamp for that packet.
`ptp_skb` is initialized in the handler for the CQE_TYPE_SEND
entry and is used and zeroed in the handler for the CQE_TYPE_SEND_PTP
entry.
So `ptp_skb` is used to hold the pointer to the packet between
the calls to CQE_TYPE_SEND and CQE_TYPE_SEND_PTP handlers.
I am going to add those comments to the sources, fix other issues and
send v6 in short time.
Thank you
Aleksey Makarov
> Here you clear them together:
>
>> +static void nicvf_snd_ptp_handler(struct net_device *netdev,
>> + struct cqe_send_t *cqe_tx)
>> +{
>> + struct nicvf *nic = netdev_priv(netdev);
>> + struct skb_shared_hwtstamps ts;
>> + u64 ns;
>> +
>> + nic = nic->pnicvf;
>> +
>> + /* Sync for 'ptp_skb' */
>> + smp_rmb();
>> +
>> + /* New timestamp request can be queued now */
>> + atomic_set(&nic->tx_ptp_skbs, 0);
>> +
>> + /* Check for timestamp requested skb */
>> + if (!nic->ptp_skb)
>> + return;
>> +
>> + /* Check if timestamping is timedout, which is set to 10us */
>> + if (cqe_tx->send_status == CQ_TX_ERROP_TSTMP_TIMEOUT ||
>> + cqe_tx->send_status == CQ_TX_ERROP_TSTMP_CONFLICT)
>> + goto no_tstamp;
>> +
>> + /* Get the timestamp */
>> + memset(&ts, 0, sizeof(ts));
>> + ns = cavium_ptp_tstamp2time(nic->ptp_clock, cqe_tx->ptp_timestamp);
>> + ts.hwtstamp = ns_to_ktime(ns);
>> + skb_tstamp_tx(nic->ptp_skb, &ts);
>> +
>> +no_tstamp:
>> + /* Free the original skb */
>> + dev_kfree_skb_any(nic->ptp_skb);
>> + nic->ptp_skb = NULL;
>> + /* Sync 'ptp_skb' */
>> + smp_wmb();
>> +}
>> +
>
> but here you set the one:
>
>> @@ -657,7 +697,12 @@ static void nicvf_snd_pkt_handler(struct net_device *netdev,
>> prefetch(skb);
>> (*tx_pkts)++;
>> *tx_bytes += skb->len;
>> - napi_consume_skb(skb, budget);
>> + /* If timestamp is requested for this skb, don't free it */
>> + if (skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS &&
>> + !nic->pnicvf->ptp_skb)
>> + nic->pnicvf->ptp_skb = skb;
>> + else
>> + napi_consume_skb(skb, budget);
>> sq->skbuff[cqe_tx->sqe_ptr] = (u64)NULL;
>> } else {
>> /* In case of SW TSO on 88xx, only last segment will have
>
> here you clear one:
>
>> @@ -1319,12 +1382,28 @@ int nicvf_stop(struct net_device *netdev)
>>
>> nicvf_free_cq_poll(nic);
>>
>> + /* Free any pending SKB saved to receive timestamp */
>> + if (nic->ptp_skb) {
>> + dev_kfree_skb_any(nic->ptp_skb);
>> + nic->ptp_skb = NULL;
>> + }
>> +
>> /* Clear multiqset info */
>> nic->pnicvf = nic;
>>
>> return 0;
>> }
>
> here you clear both:
>
>> @@ -1394,6 +1473,12 @@ int nicvf_open(struct net_device *netdev)
>> if (nic->sqs_mode)
>> nicvf_get_primary_vf_struct(nic);
>>
>> + /* Configure PTP timestamp */
>> + if (nic->ptp_clock)
>> + nicvf_config_hw_rx_tstamp(nic, nic->hw_rx_tstamp);
>> + atomic_set(&nic->tx_ptp_skbs, 0);
>> + nic->ptp_skb = NULL;
>> +
>> /* Configure receive side scaling and MTU */
>> if (!nic->sqs_mode) {
>> nicvf_rss_init(nic);
>
> here you set the other:
>
>> @@ -1385,6 +1388,29 @@ nicvf_sq_add_hdr_subdesc(struct nicvf *nic, struct snd_queue *sq, int qentry,
>> hdr->inner_l3_offset = skb_network_offset(skb) - 2;
>> this_cpu_inc(nic->pnicvf->drv_stats->tx_tso);
>> }
>> +
>> + /* Check if timestamp is requested */
>> + if (!(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
>> + skb_tx_timestamp(skb);
>> + return;
>> + }
>> +
>> + /* Tx timestamping not supported along with TSO, so ignore request */
>> + if (skb_shinfo(skb)->gso_size)
>> + return;
>> +
>> + /* HW supports only a single outstanding packet to timestamp */
>> + if (!atomic_add_unless(&nic->pnicvf->tx_ptp_skbs, 1, 1))
>> + return;
>> +
>> + /* Mark the SKB for later reference */
>> + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
>> +
>> + /* Finally enable timestamp generation
>> + * Since 'post_cqe' is also set, two CQEs will be posted
>> + * for this packet i.e CQE_TYPE_SEND and CQE_TYPE_SEND_PTP.
>> + */
>> + hdr->tstmp = 1;
>> }
>
> and so it is completely non-obvious whether this is race free or not.
>
> Thanks,
> Richard
>
^ permalink raw reply
* [net-next: PATCH 0/8] Armada 7k/8k PP2 ACPI support
From: Marcin Wojtas @ 2018-01-08 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180108154243.GA30962@lunn.ch>
Hi Andrew,
2018-01-08 16:42 GMT+01:00 Andrew Lunn <andrew@lunn.ch>:
> w> I am not familiar with MDIO, but if its similar or a specific
>> implementation of a serial bus that does sound sane!
>
Thanks for digging, I will check if and how we can use
GenericSerialBus with MDIO.
Best regards,
Marcin
> It is a two wire serial bus. A good overview can be found here:
>
> https://www.totalphase.com/support/articles/200349206-MDIO-Background
>
^ permalink raw reply
* [PATCH 2/2] arm64: Branch predictor hardening for Cavium ThunderX2
From: Jayachandran C @ 2018-01-08 17:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180108164651.GQ25869@arm.com>
On Mon, Jan 08, 2018 at 04:46:52PM +0000, Will Deacon wrote:
> On Sun, Jan 07, 2018 at 10:53:36PM -0800, Jayachandran C wrote:
> > Use PSCI based mitigation for speculative execution attacks targeting
> > the branch predictor. The approach is similar to the one used for
> > Cortex-A CPUs, but in case of ThunderX2 we add another SMC call to
> > test if the firmware supports the capability.
> >
> > If the secure firmware has been updated with the mitigation code to
> > invalidate the branch target buffer, we use the PSCI version call to
> > invoke it.
> >
> > Signed-off-by: Jayachandran C <jnair@caviumnetworks.com>
> > ---
> > arch/arm64/kernel/cpu_errata.c | 38 ++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 38 insertions(+)
> >
> > diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> > index cb0fb37..abceb5d 100644
> > --- a/arch/arm64/kernel/cpu_errata.c
> > +++ b/arch/arm64/kernel/cpu_errata.c
> > @@ -124,6 +124,7 @@ static void install_bp_hardening_cb(const struct arm64_cpu_capabilities *entry,
> > __install_bp_hardening_cb(fn, hyp_vecs_start, hyp_vecs_end);
> > }
> >
> > +#include <linux/arm-smccc.h>
> > #include <linux/psci.h>
> >
> > static int enable_psci_bp_hardening(void *data)
> > @@ -138,6 +139,33 @@ static int enable_psci_bp_hardening(void *data)
> >
> > return 0;
> > }
> > +
> > +#define CAVIUM_TX2_SIP_SMC_CALL 0xC200FF00
> > +#define CAVIUM_TX2_BTB_HARDEN_CAP 0xB0A0
> > +
> > +static int enable_tx2_psci_bp_hardening(void *data)
> > +{
> > + const struct arm64_cpu_capabilities *entry = data;
> > + struct arm_smccc_res res;
> > +
> > + if (!entry->matches(entry, SCOPE_LOCAL_CPU))
> > + return;
> > +
> > + arm_smccc_smc(CAVIUM_TX2_SIP_SMC_CALL, CAVIUM_TX2_BTB_HARDEN_CAP, 0, 0, 0, 0, 0, 0, &res);
>
> One thing to be aware of here is that if somebody configures qemu to emulate
> a TX2, this may actually disappear into EL3 and not return. You're better
> off sticking with PSCI GET_VERSION in terms of portability, but it's your
> call -- I'd expect you to deal with any breakage reports on the list due
> to the SMC above. Fair?
I don't like having a custom SMC here either. But Overloading PSCI get version
is the problem as I wrote earlier - there is no way to check if the firmware
implements BTB hardening with overloading. There is a good chance that users
with old firmware will just fail without any warning.
Is there a reason for overloading PSCI get version? Allocating a new standard
SMC number would make checking for existance and usage much simpler.
I did not quite understand the possible issue in qemu, unimplemented SMC calls
are expected to return an error code. What am I missing here?
>
> > + if (res.a0 != 0) {
> > + pr_warn("Error: CONFIG_HARDEN_BRANCH_PREDICTOR enabled, but firmware does not support it\n");
> > + return 0;
> > + }
>
> Please don't print this here; see below.
>
> > + if (res.a1 == 1 && psci_ops.get_version) {
> > + pr_info("CPU%d: Branch predictor hardening enabled\n", smp_processor_id());
>
> If you want to print a message, please put it in the capability structure
> .desc field.
Thanks, will fix this in the next rev.
JC.
^ permalink raw reply
* [PATCH v6 11/16] firmware: arm_sdei: Add support for CPU and system power states
From: Lorenzo Pieralisi @ 2018-01-08 17:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180108153818.22743-12-james.morse@arm.com>
On Mon, Jan 08, 2018 at 03:38:13PM +0000, James Morse wrote:
[...]
> +/* When entering idle, mask/unmask events for this cpu */
Just mentioning (since I know you know), this notifier is called also
through syscore_ops so it is not just idle (CPUidle or Suspend-to-idle).
> +static int sdei_pm_notifier(struct notifier_block *nb, unsigned long action,
> + void *data)
> +{
> + int rv;
> +
> + switch (action) {
> + case CPU_PM_ENTER:
> + rv = sdei_mask_local_cpu();
> + break;
> + case CPU_PM_EXIT:
You should handle CPU_PM_ENTER_FAILED here for correctness,
in case the notifier chain fails.
Other than that:
Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> + rv = sdei_unmask_local_cpu();
> + break;
> + default:
> + return NOTIFY_DONE;
> + }
> +
> + if (rv)
> + return notifier_from_errno(rv);
> +
> + return NOTIFY_OK;
> +}
> +
> +static struct notifier_block sdei_pm_nb = {
> + .notifier_call = sdei_pm_notifier,
> +};
> +
> +static int sdei_device_suspend(struct device *dev)
> +{
> + on_each_cpu(_ipi_mask_cpu, NULL, true);
> +
> + return 0;
> +}
> +
> +static int sdei_device_resume(struct device *dev)
> +{
> + on_each_cpu(_ipi_unmask_cpu, NULL, true);
> +
> + return 0;
> +}
> +
> +/*
> + * We need all events to be reregistered when we resume from hibernate.
> + *
> + * The sequence is freeze->thaw. Reboot. freeze->restore. We unregister
> + * events during freeze, then re-register and re-enable them during thaw
> + * and restore.
> + */
> +static int sdei_device_freeze(struct device *dev)
> +{
> + int err;
> +
> + cpuhp_remove_state(CPUHP_AP_ARM_SDEI_STARTING);
> +
> + err = sdei_unregister_shared();
> + if (err)
> + return err;
> +
> + return 0;
> +}
> +
> +static int sdei_device_thaw(struct device *dev)
> +{
> + int err;
> +
> + /* re-register shared events */
> + err = sdei_reregister_shared();
> + if (err) {
> + pr_warn("Failed to re-register shared events...\n");
> + sdei_mark_interface_broken();
> + return err;
> + }
> +
> + err = cpuhp_setup_state(CPUHP_AP_ARM_SDEI_STARTING, "SDEI",
> + &sdei_cpuhp_up, &sdei_cpuhp_down);
> + if (err)
> + pr_warn("Failed to re-register CPU hotplug notifier...\n");
> +
> + return err;
> +}
> +
> +static int sdei_device_restore(struct device *dev)
> +{
> + int err;
> +
> + err = sdei_platform_reset();
> + if (err)
> + return err;
> +
> + return sdei_device_thaw(dev);
> +}
> +
> +static const struct dev_pm_ops sdei_pm_ops = {
> + .suspend = sdei_device_suspend,
> + .resume = sdei_device_resume,
> + .freeze = sdei_device_freeze,
> + .thaw = sdei_device_thaw,
> + .restore = sdei_device_restore,
> +};
> +
> +/*
> + * Mask all CPUs and unregister all events on panic, reboot or kexec.
> + */
> +static int sdei_reboot_notifier(struct notifier_block *nb, unsigned long action,
> + void *data)
> +{
> + /*
> + * We are going to reset the interface, after this there is no point
> + * doing work when we take CPUs offline.
> + */
> + cpuhp_remove_state(CPUHP_AP_ARM_SDEI_STARTING);
> +
> + sdei_platform_reset();
> +
> + return NOTIFY_OK;
> +}
> +
> +static struct notifier_block sdei_reboot_nb = {
> + .notifier_call = sdei_reboot_notifier,
> +};
> +
> static void sdei_smccc_smc(unsigned long function_id,
> unsigned long arg0, unsigned long arg1,
> unsigned long arg2, unsigned long arg3,
> @@ -547,9 +772,36 @@ static int sdei_probe(struct platform_device *pdev)
> return 0;
> }
>
> - on_each_cpu(&_ipi_unmask_cpu, NULL, false);
> + err = cpu_pm_register_notifier(&sdei_pm_nb);
> + if (err) {
> + pr_warn("Failed to register CPU PM notifier...\n");
> + goto error;
> + }
> +
> + err = register_reboot_notifier(&sdei_reboot_nb);
> + if (err) {
> + pr_warn("Failed to register reboot notifier...\n");
> + goto remove_cpupm;
> + }
> +
> + err = cpuhp_setup_state(CPUHP_AP_ARM_SDEI_STARTING, "SDEI",
> + &sdei_cpuhp_up, &sdei_cpuhp_down);
> + if (err) {
> + pr_warn("Failed to register CPU hotplug notifier...\n");
> + goto remove_reboot;
> + }
>
> return 0;
> +
> +remove_reboot:
> + unregister_reboot_notifier(&sdei_reboot_nb);
> +
> +remove_cpupm:
> + cpu_pm_unregister_notifier(&sdei_pm_nb);
> +
> +error:
> + sdei_mark_interface_broken();
> + return err;
> }
>
> static const struct of_device_id sdei_of_match[] = {
> @@ -560,6 +812,7 @@ static const struct of_device_id sdei_of_match[] = {
> static struct platform_driver sdei_driver = {
> .driver = {
> .name = "sdei",
> + .pm = &sdei_pm_ops,
> .of_match_table = sdei_of_match,
> },
> .probe = sdei_probe,
> diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
> index 201ab7267986..87b505a48a94 100644
> --- a/include/linux/cpuhotplug.h
> +++ b/include/linux/cpuhotplug.h
> @@ -109,6 +109,7 @@ enum cpuhp_state {
> CPUHP_AP_PERF_XTENSA_STARTING,
> CPUHP_AP_PERF_METAG_STARTING,
> CPUHP_AP_MIPS_OP_LOONGSON3_STARTING,
> + CPUHP_AP_ARM_SDEI_STARTING,
> CPUHP_AP_ARM_VFP_STARTING,
> CPUHP_AP_ARM64_DEBUG_MONITORS_STARTING,
> CPUHP_AP_PERF_ARM_HW_BREAKPOINT_STARTING,
> --
> 2.15.0
>
^ permalink raw reply
* [PATCH] arm64: Implement branch predictor hardening for Falkor
From: Shanker Donthineni @ 2018-01-08 17:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180108092849.alfqtsmaf2dqakkr@kamzik.brq.redhat.com>
Hi Andrew,
On 01/08/2018 03:28 AM, Andrew Jones wrote:
> Hi Shanker,
>
> On Fri, Jan 05, 2018 at 02:28:59PM -0600, Shanker Donthineni wrote:
> ...
>> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
>> index cb0fb37..daf53a5 100644
>> --- a/arch/arm64/kernel/cpu_errata.c
>> +++ b/arch/arm64/kernel/cpu_errata.c
>> @@ -54,6 +54,8 @@ static int cpu_enable_trap_ctr_access(void *__unused)
>>
>> #ifdef CONFIG_KVM
>> extern char __psci_hyp_bp_inval_start[], __psci_hyp_bp_inval_end[];
>> +extern char __qcom_hyp_sanitize_link_stack_start[];
>> +extern char __qcom_hyp_sanitize_link_stack_end[];
>>
>> static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
>> const char *hyp_vecs_end)
>> @@ -96,8 +98,10 @@ static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
>> spin_unlock(&bp_lock);
>> }
>> #else
>> -#define __psci_hyp_bp_inval_start NULL
>> -#define __psci_hyp_bp_inval_end NULL
>> +#define __psci_hyp_bp_inval_start NULL
>> +#define __psci_hyp_bp_inval_end NULL
>> +#define __qcom_hyp_sanitize_link_stack_start NULL
>> +#define __qcom_hyp_sanitize_link_stack_start NULL
> ^^ copy+paste error here
Thanks for catching typo, I'll fix in v2 patch.
>
> Thanks,
> drew
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
--
Shanker Donthineni
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* [PATCH 2/2] arm64: Branch predictor hardening for Cavium ThunderX2
From: Will Deacon @ 2018-01-08 17:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180108171943.GA180149@jc-sabre>
On Mon, Jan 08, 2018 at 09:19:43AM -0800, Jayachandran C wrote:
> On Mon, Jan 08, 2018 at 04:46:52PM +0000, Will Deacon wrote:
> > On Sun, Jan 07, 2018 at 10:53:36PM -0800, Jayachandran C wrote:
> > > Use PSCI based mitigation for speculative execution attacks targeting
> > > the branch predictor. The approach is similar to the one used for
> > > Cortex-A CPUs, but in case of ThunderX2 we add another SMC call to
> > > test if the firmware supports the capability.
> > >
> > > If the secure firmware has been updated with the mitigation code to
> > > invalidate the branch target buffer, we use the PSCI version call to
> > > invoke it.
> > >
> > > Signed-off-by: Jayachandran C <jnair@caviumnetworks.com>
> > > ---
> > > arch/arm64/kernel/cpu_errata.c | 38 ++++++++++++++++++++++++++++++++++++++
> > > 1 file changed, 38 insertions(+)
> > >
> > > diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> > > index cb0fb37..abceb5d 100644
> > > --- a/arch/arm64/kernel/cpu_errata.c
> > > +++ b/arch/arm64/kernel/cpu_errata.c
> > > @@ -124,6 +124,7 @@ static void install_bp_hardening_cb(const struct arm64_cpu_capabilities *entry,
> > > __install_bp_hardening_cb(fn, hyp_vecs_start, hyp_vecs_end);
> > > }
> > >
> > > +#include <linux/arm-smccc.h>
> > > #include <linux/psci.h>
> > >
> > > static int enable_psci_bp_hardening(void *data)
> > > @@ -138,6 +139,33 @@ static int enable_psci_bp_hardening(void *data)
> > >
> > > return 0;
> > > }
> > > +
> > > +#define CAVIUM_TX2_SIP_SMC_CALL 0xC200FF00
> > > +#define CAVIUM_TX2_BTB_HARDEN_CAP 0xB0A0
> > > +
> > > +static int enable_tx2_psci_bp_hardening(void *data)
> > > +{
> > > + const struct arm64_cpu_capabilities *entry = data;
> > > + struct arm_smccc_res res;
> > > +
> > > + if (!entry->matches(entry, SCOPE_LOCAL_CPU))
> > > + return;
> > > +
> > > + arm_smccc_smc(CAVIUM_TX2_SIP_SMC_CALL, CAVIUM_TX2_BTB_HARDEN_CAP, 0, 0, 0, 0, 0, 0, &res);
> >
> > One thing to be aware of here is that if somebody configures qemu to emulate
> > a TX2, this may actually disappear into EL3 and not return. You're better
> > off sticking with PSCI GET_VERSION in terms of portability, but it's your
> > call -- I'd expect you to deal with any breakage reports on the list due
> > to the SMC above. Fair?
>
> I don't like having a custom SMC here either. But Overloading PSCI get version
> is the problem as I wrote earlier - there is no way to check if the firmware
> implements BTB hardening with overloading. There is a good chance that users
> with old firmware will just fail without any warning.
That's true, but there is precedent for this elsewhere. For example, CPU
errata that require a firmware change are often not probable. Also, your SMC
call won't always work (see the qemu comment below). Note that I'm not
saying I won't take this code, just that you need to be aware of what
you're doing.
> Is there a reason for overloading PSCI get version? Allocating a new standard
> SMC number would make checking for existance and usage much simpler.
PSCI get version is what we have today. We're working on extending PSCI to
allocate a new standard SMC number, but we need something that can be used
with existing firmware too and standardisation doesn't happen overnight.
> I did not quite understand the possible issue in qemu, unimplemented SMC calls
> are expected to return an error code. What am I missing here?
Qemu will inject them into EL3, and there might not be anything there.
Will
^ permalink raw reply
* [PATCH 0/3] ARM branch predictor hardening
From: Tony Lindgren @ 2018-01-08 17:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <0d7ac442-1112-33e9-1f1f-cd600c3e326d@arm.com>
* Marc Zyngier <marc.zyngier@arm.com> [180108 17:05]:
> Hi Tony,
>
> On 08/01/18 16:54, Tony Lindgren wrote:
> > * Marc Zyngier <marc.zyngier@arm.com> [180106 04:14]:
> >> This small series implements some basic BP hardening by invalidating
> >> the BTB on CPUs that are known to be susceptible to aliasing attacks.
> >>
> >> These patches are closely modelled against what we do on arm64,
> >> although simpler as we can rely on an architected instruction to
> >> perform the invalidation.
> >>
> >> The first patch reuses the Cortex-A8 BTB invalidation in switch_mm and
> >> generalises it to be used on all affected CPUs. The second perform the
> >> same invalidation on fatal signal delivery. The last one nukes it on
> >> guest exit, and results in some major surgery (kudos to Dimitris
> >> Papastamos who came up with the magic vector decoding sequence).
> >
> > So if a Cortex-A8 has bootloder set the IBE bit, and kernel has
> > ARM_ERRATA_430973 enabled, is Cortex-A8 already hardened then?
>
> Almost. See the extra BTB invalidation in fault.c.
OK thanks. So for Cortex-A8, only patch "[PATCH 2/3] arm: Invalidate
BTB on fatal signal for Cortex A8, A9, A12, A15 and A17" is needed
if I read that right.
Regards,
Tony
^ permalink raw reply
* [PATCH v2 1/4] dmaengine: xilinx_dma: populate dma caps properly
From: Appana Durga Kedareswara Rao @ 2018-01-08 17:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180108170655.GJ18649@localhost>
Hi,
<Snip>
>> >> + xdev->common.dst_addr_widths = BIT(addr_width / 8);
>> >> + xdev->common.src_addr_widths = BIT(addr_width / 8);
>> >
>> >Do you not support trf of 1byte, 2 bytes, or 4 bytes wide transfers?
>> >What is value of addr_width here typically? Usually controllers can
>> >support different widths and this is a surprise that you support only
>> >one value
>>
>> Controller supports address width of 32 and 64.
>
>Then this should have both 32 and 64 values here
Address width is configurable parameter at the h/w level.
Since this IP is a soft IP user can create a design with either
32-bit or 64-bit address configuration.
Currently we are reading this configuration through device-tree (xlnx, addr-width property)
https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/slave-dma.git/tree/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt#n19
Based on the h/w configuration setting the dst_addr_widths/src_addr_widths variables in this patch.
Please let me know if you are still not clear with my explanation will explain in detail...
Regards,
Kedar.
>
>> addr_width typical values are 32-bit or 64-bit .
>> Here addr_width is device-tree parameter...
>> my understanding of src_addr_widths/dst_addr_widths is, it is a bit
>> mask of the address with in bytes that DMA supports, please correct if my
>understanding is wrong.
>>
>> Regards,
>> Kedar.
>>
>> >
>> >--
>> >~Vinod
>
>--
>~Vinod
^ permalink raw reply
* mt76: fix memcpy to potential null pointer on failed allocation
From: Kalle Valo @ 2018-01-08 17:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20171214101322.10178-1-colin.king@canonical.com>
Colin Ian King <colin.king@canonical.com> wrote:
> From: Colin Ian King <colin.king@canonical.com>
>
> Currently if the allocation of skb fails and returns NULL then the
> call to skb_put will cause a null pointer dereference. Fix this by
> checking for a null skb and returning NULL. Note that calls to
> function mt76x2_mcu_msg_alloc don't directly check the null return
> but instead pass the NULL pointer to mt76x2_mcu_msg_send which
> checks for the NULL and returns ENOMEM in this case.
>
> Detected by CoverityScan, CID#1462624 ("Dereference null return value")
>
> Fixes: 7bc04215a66b ("mt76: add driver code for MT76x2e")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> Acked-by: Felix Fietkau <nbd@nbd.name>
Patch applied to wireless-drivers-next.git, thanks.
364bea50dbea mt76: fix memcpy to potential null pointer on failed allocation
--
https://patchwork.kernel.org/patch/10111747/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* [PATCH 0/3] ARM branch predictor hardening
From: Marc Zyngier @ 2018-01-08 17:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180108172435.GS3875@atomide.com>
On 08/01/18 17:24, Tony Lindgren wrote:
> * Marc Zyngier <marc.zyngier@arm.com> [180108 17:05]:
>> Hi Tony,
>>
>> On 08/01/18 16:54, Tony Lindgren wrote:
>>> * Marc Zyngier <marc.zyngier@arm.com> [180106 04:14]:
>>>> This small series implements some basic BP hardening by invalidating
>>>> the BTB on CPUs that are known to be susceptible to aliasing attacks.
>>>>
>>>> These patches are closely modelled against what we do on arm64,
>>>> although simpler as we can rely on an architected instruction to
>>>> perform the invalidation.
>>>>
>>>> The first patch reuses the Cortex-A8 BTB invalidation in switch_mm and
>>>> generalises it to be used on all affected CPUs. The second perform the
>>>> same invalidation on fatal signal delivery. The last one nukes it on
>>>> guest exit, and results in some major surgery (kudos to Dimitris
>>>> Papastamos who came up with the magic vector decoding sequence).
>>>
>>> So if a Cortex-A8 has bootloder set the IBE bit, and kernel has
>>> ARM_ERRATA_430973 enabled, is Cortex-A8 already hardened then?
>>
>> Almost. See the extra BTB invalidation in fault.c.
>
> OK thanks. So for Cortex-A8, only patch "[PATCH 2/3] arm: Invalidate
> BTB on fatal signal for Cortex A8, A9, A12, A15 and A17" is needed
> if I read that right.
That's the idea. Although I'm about to change that patch as it's been
pointed out to me that I'm doing that in a preemptible context, which
makes it a bit dodgy.
I should have something to post later today, once I'm done with fixing
the Thumb2 build (which completely breaks on patch #3)...
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH v3 00/13] arm64 kpti hardening and variant 2 workarounds
From: Will Deacon @ 2018-01-08 17:32 UTC (permalink / raw)
To: linux-arm-kernel
Hi all,
This is version three of the patches previously posted here:
v1: http://lists.infradead.org/pipermail/linux-arm-kernel/2018-January/551838.html
v2: http://lists.infradead.org/pipermail/linux-arm-kernel/2018-January/552085.html
Changes since v2:
* Fix typo in comment
* Include Falkor hardening from Shanker
* Add ThunderX2 MIDRs (subsequent patches under review)
* Avoid applying hardening from preemtible context
* Fix stack offsets in hyp SMC call
Cheers,
Will
--->8
Jayachandran C (1):
arm64: cputype: Add MIDR values for Cavium ThunderX2 CPUs
Marc Zyngier (3):
arm64: Move post_ttbr_update_workaround to C code
arm64: KVM: Use per-CPU vector when BP hardening is enabled
arm64: KVM: Make PSCI_VERSION a fast path
Shanker Donthineni (1):
arm64: Implement branch predictor hardening for Falkor
Will Deacon (8):
arm64: use RET instruction for exiting the trampoline
arm64: Kconfig: Reword UNMAP_KERNEL_AT_EL0 kconfig entry
arm64: Take into account ID_AA64PFR0_EL1.CSV3
arm64: cpufeature: Pass capability structure to ->enable callback
drivers/firmware: Expose psci_get_version through psci_ops structure
arm64: Add skeleton to harden the branch predictor against aliasing
attacks
arm64: cputype: Add missing MIDR values for Cortex-A72 and Cortex-A75
arm64: Implement branch predictor hardening for affected Cortex-A CPUs
arch/arm/include/asm/kvm_mmu.h | 10 +++
arch/arm64/Kconfig | 30 +++++--
arch/arm64/include/asm/assembler.h | 13 ---
arch/arm64/include/asm/cpucaps.h | 4 +-
arch/arm64/include/asm/cputype.h | 7 ++
arch/arm64/include/asm/kvm_asm.h | 2 +
arch/arm64/include/asm/kvm_mmu.h | 38 +++++++++
arch/arm64/include/asm/mmu.h | 37 +++++++++
arch/arm64/include/asm/sysreg.h | 2 +
arch/arm64/kernel/Makefile | 4 +
arch/arm64/kernel/bpi.S | 87 ++++++++++++++++++++
arch/arm64/kernel/cpu_errata.c | 161 +++++++++++++++++++++++++++++++++++++
arch/arm64/kernel/cpufeature.c | 13 ++-
arch/arm64/kernel/entry.S | 19 ++++-
arch/arm64/kvm/hyp/entry.S | 12 +++
arch/arm64/kvm/hyp/switch.c | 25 +++++-
arch/arm64/mm/context.c | 11 +++
arch/arm64/mm/fault.c | 17 ++++
arch/arm64/mm/proc.S | 3 +-
drivers/firmware/psci.c | 2 +
include/linux/psci.h | 1 +
virt/kvm/arm/arm.c | 8 +-
22 files changed, 474 insertions(+), 32 deletions(-)
create mode 100644 arch/arm64/kernel/bpi.S
--
2.1.4
^ permalink raw reply
* [PATCH v3 01/13] arm64: use RET instruction for exiting the trampoline
From: Will Deacon @ 2018-01-08 17:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1515432758-26440-1-git-send-email-will.deacon@arm.com>
Speculation attacks against the entry trampoline can potentially resteer
the speculative instruction stream through the indirect branch and into
arbitrary gadgets within the kernel.
This patch defends against these attacks by forcing a misprediction
through the return stack: a dummy BL instruction loads an entry into
the stack, so that the predicted program flow of the subsequent RET
instruction is to a branch-to-self instruction which is finally resolved
as a branch to the kernel vectors with speculation suppressed.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/kernel/entry.S | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 031392ee5f47..6ceed4877daf 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -1029,6 +1029,14 @@ alternative_else_nop_endif
.if \regsize == 64
msr tpidrro_el0, x30 // Restored in kernel_ventry
.endif
+ /*
+ * Defend against branch aliasing attacks by pushing a dummy
+ * entry onto the return stack and using a RET instruction to
+ * enter the full-fat kernel vectors.
+ */
+ bl 2f
+ b .
+2:
tramp_map_kernel x30
#ifdef CONFIG_RANDOMIZE_BASE
adr x30, tramp_vectors + PAGE_SIZE
@@ -1041,7 +1049,7 @@ alternative_insn isb, nop, ARM64_WORKAROUND_QCOM_FALKOR_E1003
msr vbar_el1, x30
add x30, x30, #(1b - tramp_vectors)
isb
- br x30
+ ret
.endm
.macro tramp_exit, regsize = 64
--
2.1.4
^ permalink raw reply related
* [PATCH v3 02/13] arm64: Kconfig: Reword UNMAP_KERNEL_AT_EL0 kconfig entry
From: Will Deacon @ 2018-01-08 17:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1515432758-26440-1-git-send-email-will.deacon@arm.com>
Although CONFIG_UNMAP_KERNEL_AT_EL0 does make KASLR more robust, it's
actually more useful as a mitigation against speculation attacks that
can leak arbitrary kernel data to userspace through speculation.
Reword the Kconfig help message to reflect this, and make the option
depend on EXPERT so that it is on by default for the majority of users.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/Kconfig | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3af1657fcac3..efaaa3a66b95 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -834,15 +834,14 @@ config FORCE_MAX_ZONEORDER
4M allocations matching the default size used by generic code.
config UNMAP_KERNEL_AT_EL0
- bool "Unmap kernel when running in userspace (aka \"KAISER\")"
+ bool "Unmap kernel when running in userspace (aka \"KAISER\")" if EXPERT
default y
help
- Some attacks against KASLR make use of the timing difference between
- a permission fault which could arise from a page table entry that is
- present in the TLB, and a translation fault which always requires a
- page table walk. This option defends against these attacks by unmapping
- the kernel whilst running in userspace, therefore forcing translation
- faults for all of kernel space.
+ Speculation attacks against some high-performance processors can
+ be used to bypass MMU permission checks and leak kernel data to
+ userspace. This can be defended against by unmapping the kernel
+ when running in userspace, mapping it back in on exception entry
+ via a trampoline page in the vector table.
If unsure, say Y.
--
2.1.4
^ permalink raw reply related
* [PATCH v3 03/13] arm64: Take into account ID_AA64PFR0_EL1.CSV3
From: Will Deacon @ 2018-01-08 17:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1515432758-26440-1-git-send-email-will.deacon@arm.com>
For non-KASLR kernels where the KPTI behaviour has not been overridden
on the command line we can use ID_AA64PFR0_EL1.CSV3 to determine whether
or not we should unmap the kernel whilst running at EL0.
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/sysreg.h | 1 +
arch/arm64/kernel/cpufeature.c | 8 +++++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 08cc88574659..ae519bbd3f9e 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -437,6 +437,7 @@
#define ID_AA64ISAR1_DPB_SHIFT 0
/* id_aa64pfr0 */
+#define ID_AA64PFR0_CSV3_SHIFT 60
#define ID_AA64PFR0_SVE_SHIFT 32
#define ID_AA64PFR0_GIC_SHIFT 24
#define ID_AA64PFR0_ASIMD_SHIFT 20
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 9f0545dfe497..d723fc071f39 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -145,6 +145,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
};
static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_CSV3_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_SVE_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_GIC_SHIFT, 4, 0),
S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI),
@@ -851,6 +852,8 @@ static int __kpti_forced; /* 0: not forced, >0: forced on, <0: forced off */
static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
int __unused)
{
+ u64 pfr0 = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+
/* Forced on command line? */
if (__kpti_forced) {
pr_info_once("kernel page table isolation forced %s by command line option\n",
@@ -862,7 +865,9 @@ static bool unmap_kernel_at_el0(const struct arm64_cpu_capabilities *entry,
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE))
return true;
- return false;
+ /* Defer to CPU feature registers */
+ return !cpuid_feature_extract_unsigned_field(pfr0,
+ ID_AA64PFR0_CSV3_SHIFT);
}
static int __init parse_kpti(char *str)
@@ -967,6 +972,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
},
#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
{
+ .desc = "Kernel page table isolation (KPTI)",
.capability = ARM64_UNMAP_KERNEL_AT_EL0,
.def_scope = SCOPE_SYSTEM,
.matches = unmap_kernel_at_el0,
--
2.1.4
^ permalink raw reply related
* [PATCH v3 04/13] arm64: cpufeature: Pass capability structure to ->enable callback
From: Will Deacon @ 2018-01-08 17:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1515432758-26440-1-git-send-email-will.deacon@arm.com>
In order to invoke the CPU capability ->matches callback from the ->enable
callback for applying local-CPU workarounds, we need a handle on the
capability structure.
This patch passes a pointer to the capability structure to the ->enable
callback.
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/kernel/cpufeature.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index d723fc071f39..55712ab4e3bf 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1152,7 +1152,7 @@ void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
* uses an IPI, giving us a PSTATE that disappears when
* we return.
*/
- stop_machine(caps->enable, NULL, cpu_online_mask);
+ stop_machine(caps->enable, (void *)caps, cpu_online_mask);
}
}
}
@@ -1195,7 +1195,7 @@ verify_local_cpu_features(const struct arm64_cpu_capabilities *caps)
cpu_die_early();
}
if (caps->enable)
- caps->enable(NULL);
+ caps->enable((void *)caps);
}
}
--
2.1.4
^ permalink raw reply related
* [PATCH v3 05/13] drivers/firmware: Expose psci_get_version through psci_ops structure
From: Will Deacon @ 2018-01-08 17:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1515432758-26440-1-git-send-email-will.deacon@arm.com>
Entry into recent versions of ARM Trusted Firmware will invalidate the CPU
branch predictor state in order to protect against aliasing attacks.
This patch exposes the PSCI "VERSION" function via psci_ops, so that it
can be invoked outside of the PSCI driver where necessary.
Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
drivers/firmware/psci.c | 2 ++
include/linux/psci.h | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index d687ca3d5049..8b25d31e8401 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -496,6 +496,8 @@ static void __init psci_init_migrate(void)
static void __init psci_0_2_set_functions(void)
{
pr_info("Using standard PSCI v0.2 function IDs\n");
+ psci_ops.get_version = psci_get_version;
+
psci_function_id[PSCI_FN_CPU_SUSPEND] =
PSCI_FN_NATIVE(0_2, CPU_SUSPEND);
psci_ops.cpu_suspend = psci_cpu_suspend;
diff --git a/include/linux/psci.h b/include/linux/psci.h
index bdea1cb5e1db..6306ab10af18 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -26,6 +26,7 @@ int psci_cpu_init_idle(unsigned int cpu);
int psci_cpu_suspend_enter(unsigned long index);
struct psci_operations {
+ u32 (*get_version)(void);
int (*cpu_suspend)(u32 state, unsigned long entry_point);
int (*cpu_off)(u32 state);
int (*cpu_on)(unsigned long cpuid, unsigned long entry_point);
--
2.1.4
^ permalink raw reply related
* [PATCH v3 06/13] arm64: Move post_ttbr_update_workaround to C code
From: Will Deacon @ 2018-01-08 17:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1515432758-26440-1-git-send-email-will.deacon@arm.com>
From: Marc Zyngier <marc.zyngier@arm.com>
We will soon need to invoke a CPU-specific function pointer after changing
page tables, so move post_ttbr_update_workaround out into C code to make
this possible.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/include/asm/assembler.h | 13 -------------
arch/arm64/kernel/entry.S | 2 +-
arch/arm64/mm/context.c | 9 +++++++++
arch/arm64/mm/proc.S | 3 +--
4 files changed, 11 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index c45bc94f15d0..cee60ce0da52 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -476,17 +476,4 @@ alternative_endif
mrs \rd, sp_el0
.endm
-/*
- * Errata workaround post TTBRx_EL1 update.
- */
- .macro post_ttbr_update_workaround
-#ifdef CONFIG_CAVIUM_ERRATUM_27456
-alternative_if ARM64_WORKAROUND_CAVIUM_27456
- ic iallu
- dsb nsh
- isb
-alternative_else_nop_endif
-#endif
- .endm
-
#endif /* __ASM_ASSEMBLER_H */
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 6ceed4877daf..80b539845da6 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -277,7 +277,7 @@ alternative_else_nop_endif
* Cavium erratum 27456 (broadcast TLBI instructions may cause I-cache
* corruption).
*/
- post_ttbr_update_workaround
+ bl post_ttbr_update_workaround
.endif
1:
.if \el != 0
diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
index 1cb3bc92ae5c..5f7097d0cd12 100644
--- a/arch/arm64/mm/context.c
+++ b/arch/arm64/mm/context.c
@@ -239,6 +239,15 @@ void check_and_switch_context(struct mm_struct *mm, unsigned int cpu)
cpu_switch_mm(mm->pgd, mm);
}
+/* Errata workaround post TTBRx_EL1 update. */
+asmlinkage void post_ttbr_update_workaround(void)
+{
+ asm(ALTERNATIVE("nop; nop; nop",
+ "ic iallu; dsb nsh; isb",
+ ARM64_WORKAROUND_CAVIUM_27456,
+ CONFIG_CAVIUM_ERRATUM_27456));
+}
+
static int asids_init(void)
{
asid_bits = get_cpu_asid_bits();
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 3146dc96f05b..6affb68a9a14 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -145,8 +145,7 @@ ENTRY(cpu_do_switch_mm)
isb
msr ttbr0_el1, x0 // now update TTBR0
isb
- post_ttbr_update_workaround
- ret
+ b post_ttbr_update_workaround // Back to C code...
ENDPROC(cpu_do_switch_mm)
.pushsection ".idmap.text", "ax"
--
2.1.4
^ permalink raw reply related
* [PATCH v3 07/13] arm64: Add skeleton to harden the branch predictor against aliasing attacks
From: Will Deacon @ 2018-01-08 17:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1515432758-26440-1-git-send-email-will.deacon@arm.com>
Aliasing attacks against CPU branch predictors can allow an attacker to
redirect speculative control flow on some CPUs and potentially divulge
information from one context to another.
This patch adds initial skeleton code behind a new Kconfig option to
enable implementation-specific mitigations against these attacks for
CPUs that are affected.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm64/Kconfig | 17 +++++++++
arch/arm64/include/asm/cpucaps.h | 3 +-
arch/arm64/include/asm/mmu.h | 37 ++++++++++++++++++++
arch/arm64/include/asm/sysreg.h | 1 +
arch/arm64/kernel/Makefile | 4 +++
arch/arm64/kernel/bpi.S | 55 +++++++++++++++++++++++++++++
arch/arm64/kernel/cpu_errata.c | 74 ++++++++++++++++++++++++++++++++++++++++
arch/arm64/kernel/cpufeature.c | 1 +
arch/arm64/kernel/entry.S | 7 ++--
arch/arm64/mm/context.c | 2 ++
arch/arm64/mm/fault.c | 17 +++++++++
11 files changed, 215 insertions(+), 3 deletions(-)
create mode 100644 arch/arm64/kernel/bpi.S
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index efaaa3a66b95..cea44b95187c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -845,6 +845,23 @@ config UNMAP_KERNEL_AT_EL0
If unsure, say Y.
+config HARDEN_BRANCH_PREDICTOR
+ bool "Harden the branch predictor against aliasing attacks" if EXPERT
+ default y
+ help
+ Speculation attacks against some high-performance processors rely on
+ being able to manipulate the branch predictor for a victim context by
+ executing aliasing branches in the attacker context. Such attacks
+ can be partially mitigated against by clearing internal branch
+ predictor state and limiting the prediction logic in some situations.
+
+ This config option will take CPU-specific actions to harden the
+ branch predictor against aliasing attacks and may rely on specific
+ instruction sequences or control bits being set by the system
+ firmware.
+
+ If unsure, say Y.
+
menuconfig ARMV8_DEPRECATED
bool "Emulate deprecated/obsolete ARMv8 instructions"
depends on COMPAT
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index b4537ffd1018..51616e77fe6b 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -42,7 +42,8 @@
#define ARM64_HAS_DCPOP 21
#define ARM64_SVE 22
#define ARM64_UNMAP_KERNEL_AT_EL0 23
+#define ARM64_HARDEN_BRANCH_PREDICTOR 24
-#define ARM64_NCAPS 24
+#define ARM64_NCAPS 25
#endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h
index 6f7bdb89817f..6dd83d75b82a 100644
--- a/arch/arm64/include/asm/mmu.h
+++ b/arch/arm64/include/asm/mmu.h
@@ -41,6 +41,43 @@ static inline bool arm64_kernel_unmapped_at_el0(void)
cpus_have_const_cap(ARM64_UNMAP_KERNEL_AT_EL0);
}
+typedef void (*bp_hardening_cb_t)(void);
+
+struct bp_hardening_data {
+ int hyp_vectors_slot;
+ bp_hardening_cb_t fn;
+};
+
+#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
+extern char __bp_harden_hyp_vecs_start[], __bp_harden_hyp_vecs_end[];
+
+DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);
+
+static inline struct bp_hardening_data *arm64_get_bp_hardening_data(void)
+{
+ return this_cpu_ptr(&bp_hardening_data);
+}
+
+static inline void arm64_apply_bp_hardening(void)
+{
+ struct bp_hardening_data *d;
+
+ if (!cpus_have_const_cap(ARM64_HARDEN_BRANCH_PREDICTOR))
+ return;
+
+ d = arm64_get_bp_hardening_data();
+ if (d->fn)
+ d->fn();
+}
+#else
+static inline struct bp_hardening_data *arm64_get_bp_hardening_data(void)
+{
+ return NULL;
+}
+
+static inline void arm64_apply_bp_hardening(void) { }
+#endif /* CONFIG_HARDEN_BRANCH_PREDICTOR */
+
extern void paging_init(void);
extern void bootmem_init(void);
extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt);
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index ae519bbd3f9e..871744973ece 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -438,6 +438,7 @@
/* id_aa64pfr0 */
#define ID_AA64PFR0_CSV3_SHIFT 60
+#define ID_AA64PFR0_CSV2_SHIFT 56
#define ID_AA64PFR0_SVE_SHIFT 32
#define ID_AA64PFR0_GIC_SHIFT 24
#define ID_AA64PFR0_ASIMD_SHIFT 20
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 067baace74a0..0c760db04858 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -53,6 +53,10 @@ arm64-obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o
arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
+ifeq ($(CONFIG_KVM),y)
+arm64-obj-$(CONFIG_HARDEN_BRANCH_PREDICTOR) += bpi.o
+endif
+
obj-y += $(arm64-obj-y) vdso/ probes/
obj-m += $(arm64-obj-m)
head-y := head.o
diff --git a/arch/arm64/kernel/bpi.S b/arch/arm64/kernel/bpi.S
new file mode 100644
index 000000000000..06a931eb2673
--- /dev/null
+++ b/arch/arm64/kernel/bpi.S
@@ -0,0 +1,55 @@
+/*
+ * Contains CPU specific branch predictor invalidation sequences
+ *
+ * Copyright (C) 2018 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+
+.macro ventry target
+ .rept 31
+ nop
+ .endr
+ b \target
+.endm
+
+.macro vectors target
+ ventry \target + 0x000
+ ventry \target + 0x080
+ ventry \target + 0x100
+ ventry \target + 0x180
+
+ ventry \target + 0x200
+ ventry \target + 0x280
+ ventry \target + 0x300
+ ventry \target + 0x380
+
+ ventry \target + 0x400
+ ventry \target + 0x480
+ ventry \target + 0x500
+ ventry \target + 0x580
+
+ ventry \target + 0x600
+ ventry \target + 0x680
+ ventry \target + 0x700
+ ventry \target + 0x780
+.endm
+
+ .align 11
+ENTRY(__bp_harden_hyp_vecs_start)
+ .rept 4
+ vectors __kvm_hyp_vector
+ .endr
+ENTRY(__bp_harden_hyp_vecs_end)
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 0e27f86ee709..16ea5c6f314e 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -46,6 +46,80 @@ static int cpu_enable_trap_ctr_access(void *__unused)
return 0;
}
+#ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
+#include <asm/mmu_context.h>
+#include <asm/cacheflush.h>
+
+DEFINE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);
+
+#ifdef CONFIG_KVM
+static void __copy_hyp_vect_bpi(int slot, const char *hyp_vecs_start,
+ const char *hyp_vecs_end)
+{
+ void *dst = lm_alias(__bp_harden_hyp_vecs_start + slot * SZ_2K);
+ int i;
+
+ for (i = 0; i < SZ_2K; i += 0x80)
+ memcpy(dst + i, hyp_vecs_start, hyp_vecs_end - hyp_vecs_start);
+
+ flush_icache_range((uintptr_t)dst, (uintptr_t)dst + SZ_2K);
+}
+
+static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
+ const char *hyp_vecs_start,
+ const char *hyp_vecs_end)
+{
+ static int last_slot = -1;
+ static DEFINE_SPINLOCK(bp_lock);
+ int cpu, slot = -1;
+
+ spin_lock(&bp_lock);
+ for_each_possible_cpu(cpu) {
+ if (per_cpu(bp_hardening_data.fn, cpu) == fn) {
+ slot = per_cpu(bp_hardening_data.hyp_vectors_slot, cpu);
+ break;
+ }
+ }
+
+ if (slot == -1) {
+ last_slot++;
+ BUG_ON(((__bp_harden_hyp_vecs_end - __bp_harden_hyp_vecs_start)
+ / SZ_2K) <= last_slot);
+ slot = last_slot;
+ __copy_hyp_vect_bpi(slot, hyp_vecs_start, hyp_vecs_end);
+ }
+
+ __this_cpu_write(bp_hardening_data.hyp_vectors_slot, slot);
+ __this_cpu_write(bp_hardening_data.fn, fn);
+ spin_unlock(&bp_lock);
+}
+#else
+static void __install_bp_hardening_cb(bp_hardening_cb_t fn,
+ const char *hyp_vecs_start,
+ const char *hyp_vecs_end)
+{
+ __this_cpu_write(bp_hardening_data.fn, fn);
+}
+#endif /* CONFIG_KVM */
+
+static void install_bp_hardening_cb(const struct arm64_cpu_capabilities *entry,
+ bp_hardening_cb_t fn,
+ const char *hyp_vecs_start,
+ const char *hyp_vecs_end)
+{
+ u64 pfr0;
+
+ if (!entry->matches(entry, SCOPE_LOCAL_CPU))
+ return;
+
+ pfr0 = read_cpuid(ID_AA64PFR0_EL1);
+ if (cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_CSV2_SHIFT))
+ return;
+
+ __install_bp_hardening_cb(fn, hyp_vecs_start, hyp_vecs_end);
+}
+#endif /* CONFIG_HARDEN_BRANCH_PREDICTOR */
+
#define MIDR_RANGE(model, min, max) \
.def_scope = SCOPE_LOCAL_CPU, \
.matches = is_affected_midr_range, \
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 55712ab4e3bf..9d4d82c11528 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -146,6 +146,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_CSV3_SHIFT, 4, 0),
+ ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64PFR0_CSV2_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_SVE_SHIFT, 4, 0),
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_GIC_SHIFT, 4, 0),
S_ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR0_ASIMD_SHIFT, 4, ID_AA64PFR0_ASIMD_NI),
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 80b539845da6..07a7d4db8ec4 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -721,12 +721,15 @@ el0_ia:
* Instruction abort handling
*/
mrs x26, far_el1
- enable_daif
+ enable_da_f
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl trace_hardirqs_off
+#endif
ct_user_exit
mov x0, x26
mov x1, x25
mov x2, sp
- bl do_mem_abort
+ bl do_el0_ia_bp_hardening
b ret_to_user
el0_fpsimd_acc:
/*
diff --git a/arch/arm64/mm/context.c b/arch/arm64/mm/context.c
index 5f7097d0cd12..d99b36555a16 100644
--- a/arch/arm64/mm/context.c
+++ b/arch/arm64/mm/context.c
@@ -246,6 +246,8 @@ asmlinkage void post_ttbr_update_workaround(void)
"ic iallu; dsb nsh; isb",
ARM64_WORKAROUND_CAVIUM_27456,
CONFIG_CAVIUM_ERRATUM_27456));
+
+ arm64_apply_bp_hardening();
}
static int asids_init(void)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 22168cd0dde7..0e671ddf4855 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -708,6 +708,23 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr,
arm64_notify_die("", regs, &info, esr);
}
+asmlinkage void __exception do_el0_ia_bp_hardening(unsigned long addr,
+ unsigned int esr,
+ struct pt_regs *regs)
+{
+ /*
+ * We've taken an instruction abort from userspace and not yet
+ * re-enabled IRQs. If the address is a kernel address, apply
+ * BP hardening prior to enabling IRQs and pre-emption.
+ */
+ if (addr > TASK_SIZE)
+ arm64_apply_bp_hardening();
+
+ local_irq_enable();
+ do_mem_abort(addr, esr, regs);
+}
+
+
asmlinkage void __exception do_sp_pc_abort(unsigned long addr,
unsigned int esr,
struct pt_regs *regs)
--
2.1.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox