* [PATCH 4/5] input: touchscreen: support Allwinner SoCs' touchscreen
From: Jonathan Cameron @ 2016-09-27 19:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <db3ab94a-9dbb-3bd6-fe43-e530b42c9246@free-electrons.com>
On 25/09/16 20:44, Quentin Schulz wrote:
> On 24/07/2016 13:24, Jonathan Cameron wrote:
>> On 20/07/16 09:29, Quentin Schulz wrote:
>>> This adds support for Allwinner SoCs' (A10, A13 and A31) resistive
>>> touchscreen. This driver is probed by the MFD sunxi-gpadc-mfd.
>>>
>>> This driver uses ADC channels exposed through the IIO framework by
>>> sunxi-gpadc-iio to get its data. When opening this input device, it will
>>> start buffering in the ADC driver and enable a TP_UP_PENDING irq. The ADC
>>> driver will fill in a buffer with all data and call the callback the input
>>> device associated with this buffer. The input device will then read the
>>> buffer two by two and send X and Y coordinates to the input framework based
>>> on what it received from the ADC's buffer. When closing this input device,
>>> the buffering is stopped.
>>>
>>> Note that locations in the first received buffer after an TP_UP_PENDING irq
>>> occurred are unreliable, thus dropped.
>>>
>> I think I now understand what you are doing.
>>
>> The channel grab is grabbing 4 channels, when there are only two real
>> ones (x and y) then you are abusing the callback interface from IIO.
>
> Actually, I need an IIO channel only for registering the callback from
> the consumer but I never use the IIO channel in an other way from
> consumer side (everything's done in the provider by reading the FIFO
> register and sending data to the callback via iio_buffer).
Whilst it 'would work' to just hook in and deal with the data if it
came through a single channel with enough space, that would be an
abuse of the interface which is very much designed to ship 'scans'
(e.g. sets of data taken at the same time ish).
There is a demux unit in the path which is designed to pull out
only the channels wanted by the consumer. If the combination
of available_scan_masks in the provider and the channels requested
by the consumer (via the map) are right then you'll only 'get'
the data you want and the rest will disappear into thin air ;)
>
>> That transmits only one scan (e.g. here (x,y)) per call. Because you
>> have added a sideband route for the buffer size what you have wil work.
>>
>> However, it is not how the interface should be used. Please fix that.
>> Using it correctly is not a big issue.
>>
>> On the channels front, I'd be tempted to do this as follows:
>>
>> 6 Channels, not 4.
>>
>> First 4 are standard ADC channels
>> Next 2 are the touch screen channels with appropriate descriptions
>> (guessing these are actually differential channels across the various
>> wires of the first two?)
>>
>
> Yes they are differential channels.
>
> However, I think there is actually no sense in using several channels
> for the touchscreen as everything is handled by the hardware. You only
> select the touchscreen mode by setting a register and then X and Y
> coordinates will be added to the FIFO register when touching the
> touchscreen. I would not mind not having IIO channel at all since we do
> not read from the consumer. But I need a way to register a callback to
> get data from the provider. I don't know if I make myself clear enough?
If you want to do it another way (I'd rather you didn't!) then you'll
need to create an mfd style base driver and register the touch screen
on that with custom callback registration etc.
>
>> Then you set the map up to apply to the last two channels only.
>> By setting available_scan_masks to the relevant options in the IIO driver
>> you'll be able to automatically lock the device when ever the
>> touch screeen driver is loaded.
>>
>> That map will be something like (in binary
>> 000000
>> 000011
>> 000100
>> 001000
>> 010000
>> 100000
>> 001100
>> 010100
>> 011000
>> 100100
>> 101000
>> 110000
>> 011100
>> 101100
>> 110100
>> 111000
>> 111100
>>
>> thus any combination of the ADC channels, but always all or none of the
>> touchscreen (none when ever the ADC channels are on) the order above
>> ensures we always turn on the minimum possible for a given requirement.
>>
>> Hence whenever the touch screen is there it'll lock out the ADC usage.
>> Your postenable can look at what is there and put it in the right mode.
>>
>
> I'll dive more into that.
>
>> After that, break your fifo read up into individual pairs of readings
>> and push those out.
>>
>> That way we end up using the interface in the standard fashion.
>>
>> You'll also need fix the usage of the fifo for ADC mode which suffers
>> from the same problem. There all sorts of nasty crashes might occur
>> or you might just loose data
>>
> [...]
>>> +/*
>>> + * This function will be called by iio_push_to_buffers from another driver
>>> + * (namely sunxi-gpadc-iio). It will be passed the buffer filled with input
>>> + * values (X value then Y value) and the sunxi_gpadc_ts structure representing
>>> + * the device.
>>> + */
>>> +static int sunxi_gpadc_ts_callback(const void *data, void *private)
>>> +{
>>> + const struct sunxi_gpadc_buffer *buffer = data;
>>> + struct sunxi_gpadc_ts *info = private;
>>> + int i = 0;
>>> +
>>> + /* Locations in the first buffer after an up event are unreliable */
>>> + if (info->ignore_fifo_data) {
>>> + info->ignore_fifo_data = false;
>>> + return 0;
>>> + }
>>> +
>> It doesn't work like this at all. You'll get one scan only on each call of
>> this function. As I said in the previous driver, if there is a true reason
>> to do this (and I'm unconvinced as yet) then we need to add support in the
>> iio core etc for this (and emulating it when multiple scan passing isn't
>> happening).
>>
>> I guess this will work, as you are passing the buffer size as a side
>> band, but it is definitely not how that ABI is meant to be used.
>>
>> Also, you grab 4 channels, and only two are used here. Please explain...
>>
>
> Hum. Actually, that's a mistake. I'm quiet confused about how I should
> do it while I never read channels from the consumer. I still "need" one
> for "linking" the consumer and the provider but in the meantime, I'm
> never using that channel.
You are, because the demux is only sending you the channels you
are registered for. Thus the provider should push whatever it
gets to the buffers and by the time it hits the consumer it should
get only what it needs.
It's not so interesting with this hardware because you can't do
general purpose reads at the same time as the touchscreen stuff is
running (annoyingly). With hardware that can do any combination of
channels you end up with for example:
Provider - pushing out a superset of all the channels anyone cares
about.
Consumer 1 (touch screen) gets just the x and y coordinates when pen
is down.
Consumer 2 (temperature - thermal) gets just the temperature.
Consumer 3 (e.g. battery monitory) gets just the charger voltages etc.
Consumer 4 (stretching here - analog accelerometer) gets just
accelerations for the input bridge I never get round to finally
submitting.
Jonathan
^ permalink raw reply
* [PATCH 1/4] mfd: ti_am335x_tscadc: store physical address
From: Lee Jones @ 2016-09-27 19:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160921161134.6951-2-mugunthanvnm@ti.com>
On Wed, 21 Sep 2016, Mugunthan V N wrote:
> store the physical address of the device in its priv to use it
> for DMA addressing in the client drivers.
>
> Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
> ---
> drivers/mfd/ti_am335x_tscadc.c | 1 +
> include/linux/mfd/ti_am335x_tscadc.h | 1 +
> 2 files changed, 2 insertions(+)
>
> diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c
> index c8f027b..0f3fab4 100644
> --- a/drivers/mfd/ti_am335x_tscadc.c
> +++ b/drivers/mfd/ti_am335x_tscadc.c
> @@ -183,6 +183,7 @@ static int ti_tscadc_probe(struct platform_device *pdev)
> tscadc->irq = err;
>
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + tscadc->tscadc_phys_base = res->start;
This is unusual. Can't you use a virt_to_phys() variant instead?
> tscadc->tscadc_base = devm_ioremap_resource(&pdev->dev, res);
> if (IS_ERR(tscadc->tscadc_base))
> return PTR_ERR(tscadc->tscadc_base);
> diff --git a/include/linux/mfd/ti_am335x_tscadc.h b/include/linux/mfd/ti_am335x_tscadc.h
> index 7f55b8b..e45a208 100644
> --- a/include/linux/mfd/ti_am335x_tscadc.h
> +++ b/include/linux/mfd/ti_am335x_tscadc.h
> @@ -155,6 +155,7 @@ struct ti_tscadc_dev {
> struct device *dev;
> struct regmap *regmap;
> void __iomem *tscadc_base;
> + phys_addr_t tscadc_phys_base;
> int irq;
> int used_cells; /* 1-2 */
> int tsc_wires;
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH 3/5] iio: adc: sunxi-gpadc-iio: enable iio_buffers
From: Jonathan Cameron @ 2016-09-27 19:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <433c4869-88ed-5821-2db2-67dbaa6541f7@free-electrons.com>
On 25/09/16 20:57, Quentin Schulz wrote:
> On 25/09/2016 11:10, Jonathan Cameron wrote:
>> On 24/09/16 18:40, Quentin Schulz wrote:
>>> Hi Jonathan,
>>>
>>> Sorry for the (long) delay, I did not have time to work on it. I'll
>>> mainly work in my free time now.
>>>
>>> Keep in mind this patch was proposed based on the v2 of the ADC patches.
>>> Since then, substantial changes have been made and I'm working on
>>> rebasing this series of patches on the v6, so comments here might
>>> include references to code parts added later in the ADC patch series.
>>>
>>> On 24/07/2016 13:03, Jonathan Cameron wrote:
>>>> On 20/07/16 09:29, Quentin Schulz wrote:
>>>>> This enables the use of buffers on ADC channels of sunxi-gpadc-iio driver.
>>>>> It also prepares the code which will be used by the touchscreen driver
>>>>> named sunxi-gpadc-ts.
>>>>>
>>>>> The GPADC on Allwinner SoCs (A10, A13 and A31) has a 12 bits register for
>>>>> conversion's data. The GPADC uses the same ADC channels for the ADC and the
>>>>> touchscreen therefore exposes these channels to the sunxi-gpadc-ts iio
>>>>> consumer which will be in charge of reading data from these channels for
>>>>> the input framework.
>>>>>
>>>>> The temperature can only be read when in touchscreen mode. This means if
>>>>> the buffers are being used for the ADC, the temperature sensor cannot be
>>>>> read.
>>>> That may be the bizarest hardware restriction I've heard of in a while! :)
>>>>>
>>>>> When a FIFO_DATA_PENDING irq occurs, its handler will read the entire FIFO
>>>>> and fill a buffer before sending it to the consumers which registered in
>>>>> IIO for the ADC channels.
>>>>>
>>>>> When a consumer starts buffering ADC channels,
>>>>> sunxi_gpadc_buffer_postenable is called and will enable FIFO_DATA_PENDING
>>>>> irq and select the mode in which the GPADC should run (ADC or touchscreen)
>>>>> depending on a property of the DT ("allwinner,ts-attached").
>>>>> When the consumer stops buffering, it disables the same irq.
>>>> Hmm. Might be possible to distinguish which consumer caused the start.
>>>> Thus, if the touchscreen is there we would know purely based on the
>>>> driver being the requester that we need to be in touchscreen mode.
>>>>
>>>
>>> As of yet, can't see in which way I can retrieve the consumer in
>>> provider code. Maybe I'm missing something, I don't know?
>> I don't think we have a current way of doing this... Might be possible
>> to add one, but it would be a rather odd bit of reverse looking up.
> [...]
>>>>> @@ -101,19 +104,43 @@ struct sunxi_gpadc_dev {
>>>>> unsigned int fifo_data_irq;
>>>>> unsigned int temp_data_irq;
>>>>> unsigned int flags;
>>>>> + struct iio_dev *indio_dev;
>>>> I was suprised to see this as normally it is cleaner to structure
>>>> the whole code to go in one direction through the structures (which is
>>>> why we don't provide a generic iio_device_from_priv bit of pointer magic).
>>>>
>>>> Anyhow, don't htink you are actually using it ;)
>>>>
>>>
>>> I'm using to push to buffers from the irq handler since I pass the local
>>> structure (sunxi_gpadc_dev) to the irq handler when registering it. But
>>> I guess I can pass the iio_dev instead and remove this from the local
>>> structure.
>> I'd prefer passing the iio_dev and keep all lookups in one direction.
>
> ACK.
>
>>>
>>> [...]
>>>>> static int sunxi_gpadc_adc_read(struct iio_dev *indio_dev, int channel,
>>>>> int *val)
>>>>> {
>>>>> struct sunxi_gpadc_dev *info = iio_priv(indio_dev);
>>>>> + bool buffered = info->buffered;
>>>> Not worth the local version...
>>>>> int ret = 0;
>>>>> + unsigned int reg;
>>>>>
>>>>> mutex_lock(&indio_dev->mlock);
>>>>>
>>>>> reinit_completion(&info->completion);
>>>>> +
>>>>> + reg = SUNXI_GPADC_TP_FIFO_TRIG_LEVEL(1) | SUNXI_GPADC_TP_FIFO_FLUSH;
>>>>> + regmap_update_bits(info->regmap, SUNXI_GPADC_TP_INT_FIFOC, reg, reg);
>>>> I'd put it in directly rahter than having a reg local variable. To mind
>>>> mind that would be slightly easier to understand.
>>>>> +
>>>>> if (info->flags & SUNXI_GPADC_ARCH_SUN6I)
>>>>> regmap_write(info->regmap, SUNXI_GPADC_TP_CTRL1,
>>>>> SUNXI_GPADC_SUN6I_TP_MODE_EN |
>>>>> @@ -153,9 +185,9 @@ static int sunxi_gpadc_adc_read(struct iio_dev *indio_dev, int channel,
>>>>> SUNXI_GPADC_TP_MODE_EN |
>>>>> SUNXI_GPADC_TP_ADC_SELECT |
>>>>> SUNXI_GPADC_ADC_CHAN_SELECT(channel));
>>>>> - regmap_write(info->regmap, SUNXI_GPADC_TP_INT_FIFOC,
>>>>> - SUNXI_GPADC_TP_FIFO_TRIG_LEVEL(1) |
>>>>> - SUNXI_GPADC_TP_FIFO_FLUSH);
>>>> Whole load of infrastructure in place to lock buffered mode out and
>>>> revent transitions when we can't have them.
>>>>
>>>> iio_claim_direct_mode etc. I think you can just use that here?
>>>> If you need to do extra checks on it being enabled that should be
>>>> fine too.
>>>>
>>>
>>> Yes, way better with iio_device_claim_direct_mode and iio_buffer_enabled!
>>>
>>>> As a general rule, it makes sense to simply disable polled reads
>>>> if in buffered mode. Leads to much simpler code and generally
>>>> the data is already known to userspace anyway.
>>>>
>>>
>>> That's what I try to do.
>>> However, I think the temperature of the SoC is an interesting feature to
>>> have. Since it ("hardwarely") works while the ADC is read in touchscreen
>>> mode (even in buffer mode), I guess it could be a good idea to allow it
>>> in the driver. If we don't do that, boards with a touchscreen connected
>>> to the ADC of the SoC will not get SoC temperatures and can't have
>>> proper thermal management. We already have one board in that case: the
>>> PocketCHIP.
>>>
>>> Therefore, I also need to know if when the buffer is enabled, if it's
>>> for buffering ADC data or touchscreen data. If it's for ADC data, then I
>>> should disable temperature readings since it will return senseless
>>> values (from memory, always 0 which means something like -144?C).
>> Nice so no thermal management if we don't have a touch screen :)
>
> I think that's a big constraint. I think we should be able to read the
> temperature when the ADC is in either touchscreen or ADC mode but ONLY
> in DIRECT_MODE. While in BUFFER_MODE, we should enable temperature
> reading only when the touchscreen is present.
It would certainly be preferable to do so.
>
> That might induce a problem with the thermal framework I think. I've had
> some problem with temperature reading's timeout so I'm reading a
> manually "cached" temperature which is updated when the temperature
> reading is done. However, it will never be updated when the ADC is in
> buffered ADC mode. I don't know if in that case it is better to
> unregister the thermal device, to give outdated values or to notify the
> thermal framework the temperature readings timed out (which is verbose).
> [...]
Definitely need some input from the thermal guys on this. Perhaps
they need to have a way of saying -EBUSY.
>>>>> @@ -261,7 +302,29 @@ static irqreturn_t sunxi_gpadc_temp_data_irq_handler(int irq, void *dev_id)
>>>>> static irqreturn_t sunxi_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
>>>>> {
>>>>> struct sunxi_gpadc_dev *info = dev_id;
>>>>> - int ret;
>>>>> + int ret, reg, i, fifo_count;
>>>>> +
>>>>> + if (info->buffered) {
>>>>> + if (regmap_read(info->regmap, SUNXI_GPADC_TP_INT_FIFOS, ®))
>>>>> + return IRQ_HANDLED;
>>>>> +
>>>>> + fifo_count = (reg & SUNXI_GPADC_RXA_CNT) >> 8;
>>>>> + /* Sometimes, the interrupt occurs when the FIFO is empty. */
>>>>> + if (!fifo_count)
>>>>> + return IRQ_HANDLED;
>>>>> +
>>>>> + for (i = 0; i < fifo_count; i++) {
>>>>> + if (regmap_read(info->regmap, SUNXI_GPADC_TP_DATA,
>>>>> + &info->buffer.buffer[i]))
>>>>> + return IRQ_HANDLED;
>>>>> + }
>>>>> +
>>>>> + info->buffer.buff_size = i;
>>>>> +
>>>>> + iio_push_to_buffers(info->indio_dev, &info->buffer);
>>>> This is expecting a single 'scan' - e.g. set of channels read at one
>>>> time. Here I think we could have repeated sets of channels?
>>>> (at least that would be what is normally meant by a fifo in such
>>>> a device).
>>>>
>>>> If so you need to read 'whole' scans and push them one at a time.
>>>> We don't yet have a bulk iio_push_to_buffers, though we can add
>>>> one if it makes sense. Care will be needed though as we'd need
>>>> handle the case of different consumers either supporting or
>>>> not supporting this new functionality. Not particularly hard though
>>>> if it is worth doing.
>>>
>>> I didn't know it was meant for only one scan. Then I need a bulk
>>> iio_push_to_buffers.
>> We've had a few cases where that would be handy recently.
>> The bit that makes it complex is if we are doing any demux of the channels
>> to multiple consumers. Could be done by falling back to separating
>> the scan's out and pushing them one by one through the demux though.
>> Not sure there is a better way to do it though...
>>>
>>> I have a rather big problem. The whole first FIFO at each touch is
>>> unusable so I have to drop it. I can detect the beginning of a touch
>>> when the TP_UP irq occurs, then I know the next full FIFO the consumer
>>> receives by callback is to be dropped. If I use push_to_buffers to send
>>> coordinates by coordinates, the consumer has no mean to know when the
>>> second FIFO (the first to be valid) starts and can be used. Either we
>>> can find a way to notify the consumer of the start of a new FIFO or I
>>> have to use a bulk iio_push_to_buffers.
>> Nasty indeed.
>>>
>>> The workaround would be to register the TP_UP irq in the provider (the
>>> ADC driver) and do not send the first FIFO to the consumer. But then, we
>>> need a way to know which consumer requests buffering to know when to
>>> enable this irq and do all touchscreen-only logic (dropping first
>>> frame). And I guess we don't have something like that yet. Or I could
>>> only code a buffering in touchscreen mode and add the ADC buffering
>>> later? But it doesn't feel right to do what I think should be handled
>>> (TP_UP irq handler and first FIFO dropping) in the consumer, in the
>>> provider.
>> Would indeed by the nicer way of doing it, but we are ultimately working
>> around a hardware issue (to my mind it should never return rubbish!)
>> so I'd not worry too much about where the fix is.
>>>
>>> So it's quiet a dead-end yet if I can't use iio_push_to_buffers with a
>>> whole FIFO (which you told is not how it is meant to be used).
>> It only worked here because you had control of both ends of the link.
>>
>> First thought is that we should add a bulk push to buffers, but
>> that a little bit of fiddly code would be needed to unwind the
>> data in the demux if needed. Probably not too hard to do. It would then
>> need to repackage the data up as a bulk buffer data block to send onwards.
>>
>> To do this I think you'd need to:
>> 1) Add core support to have a bulk push with the right magic around to call
>> the demux code in a loop over all the elements before pushing on.
>> 2) Bulk handling in the callback buffer.
>> 3) Kfifo bulk handling (mostly to allow us to test the demux code).
>>
>> Actually, short of stuff I haven't thought of, doesn't look too tricky
>> and useful feature to have in general.
>>
>
> Then I guess we'll have to do it :) I might need a lot of guiding though
> but maybe that's more of an IRC chat or non-lkml conversation?
Sure, funnily enough I'm updating the sca3000 driver to finally
lift it out of staging and a bulk write would help there as well.
(tends to be copying 32 scans + at a time due to a hardware fifo).
Looking at the new kionix parts which have 8K hardware fifos this gets
even more interesting (though perhaps we should handle as pure
hardware fifos without the front end kfifo.)
>
> Thanks,
> Quentin
>
^ permalink raw reply
* next-20160927 build: 2 failures 4 warnings (next-20160927)
From: Lee Jones @ 2016-09-27 19:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927160036.y3ti3gzt4ebg2vyz@sirena.org.uk>
On Tue, 27 Sep 2016, Mark Brown wrote:
> On Tue, Sep 27, 2016 at 10:49:27AM +0100, Build bot for Mark Brown wrote:
>
> -next is still failing to build an arm and arm64 allmodconfig due to:
>
> > arm64-allmodconfig
> > ERROR: "irq_set_parent" [drivers/mfd/tps65217.ko] undefined!
>
> > arm-allmodconfig
> > ERROR: "irq_set_parent" [drivers/mfd/tps65217.ko] undefined!
>
> due to 262d5cc6ceb293 (mfd: tps65217: Add support for IRQs) since
> irq_set_parent() isn't exported. There was a fix posted adding the
> export to the IRQ subsystem but it's still not been applied, the
> function is being used in order to enable lazy IRQ disabling for
> threaded interrupts:
>
> https://www.spinics.net/lists/arm-kernel/msg532864.html
Right H-hour is fast approaching. How are we going to resolve this?
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v2 3/8] i2c: bcm2835: Use ratelimited logging on transfer errors
From: Noralf Trønnes @ 2016-09-27 19:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <74D9ED33-1B99-4ED6-88B5-879950D160C8@martin.sperl.org>
Den 27.09.2016 15:01, skrev Martin Sperl:
>> On 27 Sep 2016, at 13:57, Noralf Tr?nnes <noralf@tronnes.org> wrote:
>>
>> Writing to an AT24C32 generates on average 2x i2c transfer errors per
>> 32-byte page write. Which amounts to a lot for a 4k write. This is due
>> to the fact that the chip doesn't respond during it's internal write
>> cycle when the at24 driver tries and retries the next write.
>> Reduce this flooding of the log by using dev_err_ratelimited().
>>
>> Signed-off-by: Noralf Tr?nnes <noralf@tronnes.org>
>> Reviewed-by: Eric Anholt <eric@anholt.net>
>> ---
>> drivers/i2c/busses/i2c-bcm2835.c | 3 ++-
>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
>> index df036ed..370a322 100644
>> --- a/drivers/i2c/busses/i2c-bcm2835.c
>> +++ b/drivers/i2c/busses/i2c-bcm2835.c
>> @@ -207,7 +207,8 @@ static int bcm2835_i2c_xfer_msg(struct bcm2835_i2c_dev *i2c_dev,
>> (msg->flags & I2C_M_IGNORE_NAK))
>> return 0;
>>
>> - dev_err(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err);
>> + dev_err_ratelimited(i2c_dev->dev, "i2c transfer failed: %x\n",
>> + i2c_dev->msg_err);
> Do we really need this error message at all?
>
> Maybe just remove it instead, because error messages during
> "normal"/successfull operations of at24 seems strange.
>
> Or make it a debug message instead.
I have looked through 64 i2c bus drivers, 8 use dev_err and 2 use dev_warn
on transfer errors (not timeouts). Several use dev_dbg.
I'll change it to dev_dbg instead. Thanks.
Noralf.
^ permalink raw reply
* [PATCH v2 8/8] ARM: bcm2835: Disable i2c2 in the Device Tree
From: Noralf Trønnes @ 2016-09-27 19:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <256118042.194076.147d5d83-f402-4ba4-b7de-4ab57a0e29ad.open-xchange@email.1und1.de>
Den 27.09.2016 19:25, skrev Stefan Wahren:
>> Noralf Tr?nnes <noralf@tronnes.org> hat am 27. September 2016 um 13:57
>> geschrieben:
>>
>>
>> i2c2 is connected to the HDMI connector and is controlled by the
>> firmware. Disable it to stay out of harms way.
> Until this point the commit message is okay, the rest is more confusing.
>
> Btw this should avoid a warning about missing clock frequency.
>
>> From the downstream commit:
>> i2c-bcm2708/BCM270X_DT: Add support for I2C2
>>
>> The third I2C bus (I2C2) is normally reserved for HDMI use. Careless
>> use of this bus can break an attached display - use with caution.
>>
>> It is recommended to disable accesses by VideoCore by setting
>> hdmi_ignore_edid=1 or hdmi_edid_file=1 in config.txt.
>>
>> Signed-off-by: Noralf Tr?nnes <noralf@tronnes.org>
>> ---
>> arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 ----
>> 1 file changed, 4 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi
>> b/arch/arm/boot/dts/bcm2835-rpi.dtsi
>> index e9b47b2..8bffbee 100644
>> --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
>> +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
>> @@ -59,10 +59,6 @@
>> clock-frequency = <100000>;
>> };
>>
>> -&i2c2 {
>> - status = "okay";
>> -};
>> -
> I'm not sure if this the right fix. According to bcm283x.dtsi the 3 i2c busses
> have the same compatible string "brcm,bcm2835-i2c", but the changelog suggests
> that this bus is "special".
I just rounded up all the differences from downstream that I knew about
into this patchset. But looking closer I see that the vc4 driver uses
i2c2. So I'll drop this patch.
Noralf.
> Shouldn't we use a different compatible string? Our intention isn't to disable
> i2c2 but avoid any claims of the usual i2c driver.
>
>> &sdhci {
>> status = "okay";
>> bus-width = <4>;
>> --
>> 2.8.2
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* linux-next: manual merge of the gpio tree with the arm-soc tree
From: Tony Lindgren @ 2016-09-27 19:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927150542.7e81e7ee@canb.auug.org.au>
* Stephen Rothwell <sfr@canb.auug.org.au> [160926 22:06]:
> Hi Linus,
>
> Today's linux-next merge of the gpio tree got a conflict in:
>
> arch/arm/mach-omap2/board-rx51-peripherals.c
>
> between commit:
>
> 9b7141d01a76 ("ARM: OMAP2+: Drop legacy board file for n900")
>
> from the arm-soc tree and commit:
>
> 9132ce450bd1 ("ARM: omap2: fix missing include")
>
> from the gpio tree.
>
> I fixed it up (the former removed the file, so I did that) and can
> carry the fix as necessary. This is now fixed as far as linux-next is
> concerned, but any non trivial conflicts should be mentioned to your
> upstream maintainer when your tree is submitted for merging. You may
> also want to consider cooperating with the maintainer of the conflicting
> tree to minimise any particularly complex conflicts.
Yes thanks removing it the way to go.
Regards,
Tony
^ permalink raw reply
* [PATCH 3/3] KVM: arm/arm64: Support arch timers with a userspace gic
From: Christoffer Dall @ 2016-09-27 19:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927190806.22988-1-christoffer.dall@linaro.org>
From: Alexander Graf <agraf@suse.de>
If you're running with a userspace gic or other interrupt constroller
(that is no vgic in the kernel), then you have so far not been able to
use the architected timers, because the output of the architected
timers, which are driven inside the kernel, was a kernel-only construct
between the arch timer code and the vgic.
This patch implements the new KVM_CAP_ARM_TIMER feature, where we use a
side channel on the kvm_run structure, run->s.regs.timer_irq_level, to
always notify userspace of the timer output level when using a userspace
irqchip.
This works by ensureing that before we enter the guest, if the timer
output level has changed compared to what we last told userspace, we
don't enter the guest, but instead return to userspace to notify it of
the new level. If we are exiting, because of an MMIO for example, and
the level changed at the same time, the value is also updated and
userspace can sample the line as it needs. This is nicely achieved
simply always updating the timer_irq_level field after the main run
loop.
Note that the kvm_timer_update_irq trace event is changed to show the
host IRQ number for the timer instead of the guest IRQ number, because
the kernel no longer know which IRQ userspace wires up the timer signal
to.
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
arch/arm/kvm/arm.c | 19 ++++----
include/kvm/arm_arch_timer.h | 2 +
virt/kvm/arm/arch_timer.c | 105 +++++++++++++++++++++++++++++++++++--------
3 files changed, 98 insertions(+), 28 deletions(-)
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 85a3f90..712695d 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -187,6 +187,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_ARM_PSCI_0_2:
case KVM_CAP_READONLY_MEM:
case KVM_CAP_MP_STATE:
+ case KVM_CAP_ARM_TIMER:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
@@ -474,13 +475,7 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
return ret;
}
- /*
- * Enable the arch timers only if we have an in-kernel VGIC
- * and it has been properly initialized, since we cannot handle
- * interrupts from the virtual timer with a userspace gic.
- */
- if (irqchip_in_kernel(kvm) && vgic_initialized(kvm))
- ret = kvm_timer_enable(vcpu);
+ ret = kvm_timer_enable(vcpu);
return ret;
}
@@ -594,9 +589,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
local_irq_disable();
/*
- * Re-check atomic conditions
+ * If we have a singal pending, or need to notify a userspace
+ * irqchip about timer level changes, then we exit (and update
+ * the timer level state in kvm_timer_update_run below).
*/
- if (signal_pending(current)) {
+ if (signal_pending(current) ||
+ kvm_timer_should_notify_user(vcpu)) {
ret = -EINTR;
run->exit_reason = KVM_EXIT_INTR;
}
@@ -668,6 +666,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
ret = handle_exit(vcpu, run, ret);
}
+ /* Tell userspace about the arch timer output level */
+ kvm_timer_update_run(vcpu);
+
if (vcpu->sigset_active)
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
return ret;
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index dda39d8..7157e73 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -65,6 +65,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu,
void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu);
void kvm_timer_sync_hwstate(struct kvm_vcpu *vcpu);
+bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu);
+void kvm_timer_update_run(struct kvm_vcpu *vcpu);
void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu);
u64 kvm_arm_timer_get_reg(struct kvm_vcpu *, u64 regid);
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 824ed26..c645b7d 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -166,6 +166,22 @@ bool kvm_timer_should_fire(struct kvm_vcpu *vcpu)
return cval <= now;
}
+/*
+ * Reflect the timer output level into the kvm_run structure
+ */
+void kvm_timer_update_run(struct kvm_vcpu *vcpu)
+{
+ struct kvm_sync_regs *regs = &vcpu->run->s.regs;
+
+ if (likely(irqchip_in_kernel(vcpu->kvm)))
+ return;
+
+ /* Populate the timer bitmap for user space */
+ regs->timer_irq_level &= ~KVM_ARM_TIMER_VTIMER;
+ if (vcpu->arch.timer_cpu.irq.level)
+ regs->timer_irq_level |= KVM_ARM_TIMER_VTIMER;
+}
+
static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level)
{
int ret;
@@ -173,12 +189,17 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level)
timer->active_cleared_last = false;
timer->irq.level = new_level;
- trace_kvm_timer_update_irq(vcpu->vcpu_id, timer->irq.irq,
+ trace_kvm_timer_update_irq(vcpu->vcpu_id, host_vtimer_irq,
timer->irq.level);
- ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
- timer->irq.irq,
- timer->irq.level);
- WARN_ON(ret);
+
+ if (likely(irqchip_in_kernel(vcpu->kvm))) {
+ /* Fire the timer in the VGIC */
+ ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
+ timer->irq.irq,
+ timer->irq.level);
+
+ WARN_ON(ret);
+ }
}
/*
@@ -195,7 +216,7 @@ static void kvm_timer_update_state(struct kvm_vcpu *vcpu)
* because the guest would never see the interrupt. Instead wait
* until we call this function from kvm_timer_flush_hwstate.
*/
- if (!timer->enabled)
+ if (unlikely(!timer->enabled))
return;
if (kvm_timer_should_fire(vcpu) != timer->irq.level)
@@ -238,24 +259,12 @@ void kvm_timer_unschedule(struct kvm_vcpu *vcpu)
timer_disarm(timer);
}
-/**
- * kvm_timer_flush_hwstate - prepare to move the virt timer to the cpu
- * @vcpu: The vcpu pointer
- *
- * Check if the virtual timer has expired while we were running in the host,
- * and inject an interrupt if that was the case.
- */
-void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
+static void kvm_timer_flush_hwstate_vgic(struct kvm_vcpu *vcpu)
{
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
bool phys_active;
int ret;
- if (unlikely(!timer->enabled))
- return;
-
- kvm_timer_update_state(vcpu);
-
/*
* If we enter the guest with the virtual input level to the VGIC
* asserted, then we have already told the VGIC what we need to, and
@@ -307,6 +316,56 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
timer->active_cleared_last = !phys_active;
}
+bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)
+{
+ struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+ bool run_level = vcpu->run->s.regs.timer_irq_level & KVM_ARM_TIMER_VTIMER;
+
+ if (likely(irqchip_in_kernel(vcpu->kvm)))
+ return false;
+
+ return timer->irq.level != run_level;
+}
+
+static void kvm_timer_flush_hwstate_user(struct kvm_vcpu *vcpu)
+{
+ struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+
+ /*
+ * To prevent continuously exiting from the guest, we mask the
+ * physical interrupt such that the guest can make forward progress.
+ * Once we detect the output level being deasserted, we unmask the
+ * interrupt again so that we exit from the guest when the timer
+ * fires.
+ */
+ if (timer->irq.level)
+ disable_percpu_irq(host_vtimer_irq);
+ else
+ enable_percpu_irq(host_vtimer_irq, 0);
+}
+
+/**
+ * kvm_timer_flush_hwstate - prepare to move the virt timer to the cpu
+ * @vcpu: The vcpu pointer
+ *
+ * Check if the virtual timer has expired while we were running in the host,
+ * and inject an interrupt if that was the case.
+ */
+void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
+{
+ struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
+
+ if (unlikely(!timer->enabled))
+ return;
+
+ kvm_timer_update_state(vcpu);
+
+ if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
+ kvm_timer_flush_hwstate_user(vcpu);
+ else
+ kvm_timer_flush_hwstate_vgic(vcpu);
+}
+
/**
* kvm_timer_sync_hwstate - sync timer state from cpu
* @vcpu: The vcpu pointer
@@ -473,6 +532,13 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
if (timer->enabled)
return 0;
+ /* Without a VGIC we do not map virtual IRQs to physical IRQs */
+ if (!irqchip_in_kernel(vcpu->kvm))
+ goto no_vgic;
+
+ if (!vgic_initialized(vcpu->kvm))
+ return -ENODEV;
+
/*
* Find the physical IRQ number corresponding to the host_vtimer_irq
*/
@@ -496,6 +562,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
if (ret)
return ret;
+no_vgic:
/*
* There is a potential race here between VCPUs starting for the first
--
2.9.0
^ permalink raw reply related
* [PATCH 2/3] KVM: arm/arm64: Add ARM arch timer interrupts ABI
From: Christoffer Dall @ 2016-09-27 19:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927190806.22988-1-christoffer.dall@linaro.org>
From: Alexander Graf <agraf@suse.de>
We have 2 modes for dealing with interrupts in the ARM world. We can
either handle them all using hardware acceleration through the vgic or
we can emulate a gic in user space and only drive CPU IRQ pins from
there.
Unfortunately, when driving IRQs from user space, we never tell user
space about timer events that may result in interrupt line state
changes, so we lose out on timer events if we run with user space gic
emulation.
Define an ABI to publish the timer output level to userspace.
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
Documentation/virtual/kvm/api.txt | 29 +++++++++++++++++++++++++++++
arch/arm/include/uapi/asm/kvm.h | 2 ++
arch/arm64/include/uapi/asm/kvm.h | 2 ++
include/uapi/linux/kvm.h | 6 ++++++
4 files changed, 39 insertions(+)
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 739db9a..2adf600 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3928,3 +3928,32 @@ In order to use SynIC, it has to be activated by setting this
capability via KVM_ENABLE_CAP ioctl on the vcpu fd. Note that this
will disable the use of APIC hardware virtualization even if supported
by the CPU, as it's incompatible with SynIC auto-EOI behavior.
+
+8.3 KVM_CAP_ARM_TIMER
+
+Architectures: arm, arm64
+This capability, if KVM_CHECK_EXTENSION indicates that it is available, means
+that if userspace creates a VM without an in-kernel interrupt controller, it
+will be notified of changes to the output level of ARM architected timers
+presented to the VM. For such VMs, on every return to userspace, the kernel
+updates the vcpu's run->s.regs.timer_irq_level field to represent the actual
+output level of the timers.
+
+Whenever kvm detects a change in the timer output level, kvm guarantees at
+least one return to userspace before running the VM. This exit could either
+be a KVM_EXIT_INTR or any other exit event, like KVM_EXIT_MMIO. This way,
+userspace can always sample the timer output level and re-compute the state of
+the userspace interrupt controller. Userspace should always check the state
+of run->s.regs.timer_irq_level on every kvm exit. The value in
+run->s.regs.timer_irq_level should be considered a level triggered interrupt
+signal.
+
+The field run->s.regs.timer_irq_level is available independent of
+run->kvm_valid_regs or run->kvm_dirty_regs bits.
+
+Currently the following bits are defined for the timer_irq_level bitmap:
+
+ KVM_ARM_TIMER_VTIMER - virtual timer
+
+Future versions of kvm may implement additional timer events. These will get
+indicated by additional KVM_CAP extensions.
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index b38c10c..23c2e77 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -112,6 +112,8 @@ struct kvm_debug_exit_arch {
};
struct kvm_sync_regs {
+ /* Used with KVM_CAP_ARM_TIMER */
+ u8 timer_irq_level;
};
struct kvm_arch_memory_slot {
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 3051f86..411d62a 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -143,6 +143,8 @@ struct kvm_debug_exit_arch {
#define KVM_GUESTDBG_USE_HW (1 << 17)
struct kvm_sync_regs {
+ /* Used with KVM_CAP_ARM_TIMER */
+ u8 timer_irq_level;
};
struct kvm_arch_memory_slot {
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 300ef25..c293fc9 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -870,6 +870,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_S390_USER_INSTR0 130
#define KVM_CAP_MSI_DEVID 131
#define KVM_CAP_PPC_HTM 132
+#define KVM_CAP_ARM_TIMER 133
#ifdef KVM_CAP_IRQ_ROUTING
@@ -1327,4 +1328,9 @@ struct kvm_assigned_msix_entry {
#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
+/* Available with KVM_CAP_ARM_TIMER */
+
+/* Bits for run->s.regs.timer_irq_level */
+#define KVM_ARM_TIMER_VTIMER (1 << 0)
+
#endif /* __LINUX_KVM_H */
--
2.9.0
^ permalink raw reply related
* [PATCH 1/3] KVM: arm/arm64: Cleanup the arch timer code's irqchip checking
From: Christoffer Dall @ 2016-09-27 19:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927190806.22988-1-christoffer.dall@linaro.org>
Currently we check if we have an in-kernel irqchip and if the vgic was
properly implemented several places in the arch timer code. But, we
already predicate our enablement of the arm timers on having a valid
and initialized gic, so we can simply check if the timers are enabled or
not.
This also gets rid of the ugly "error that's not an error but used to
signal that the timer shouldn't poke the gic" construct we have.
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/arch_timer.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 27a1f63..824ed26 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -171,8 +171,6 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level)
int ret;
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
- BUG_ON(!vgic_initialized(vcpu->kvm));
-
timer->active_cleared_last = false;
timer->irq.level = new_level;
trace_kvm_timer_update_irq(vcpu->vcpu_id, timer->irq.irq,
@@ -187,7 +185,7 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level)
* Check if there was a change in the timer state (should we raise or lower
* the line level to the GIC).
*/
-static int kvm_timer_update_state(struct kvm_vcpu *vcpu)
+static void kvm_timer_update_state(struct kvm_vcpu *vcpu)
{
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
@@ -197,13 +195,11 @@ static int kvm_timer_update_state(struct kvm_vcpu *vcpu)
* because the guest would never see the interrupt. Instead wait
* until we call this function from kvm_timer_flush_hwstate.
*/
- if (!vgic_initialized(vcpu->kvm) || !timer->enabled)
- return -ENODEV;
+ if (!timer->enabled)
+ return;
if (kvm_timer_should_fire(vcpu) != timer->irq.level)
kvm_timer_update_irq(vcpu, !timer->irq.level);
-
- return 0;
}
/*
@@ -255,9 +251,11 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
bool phys_active;
int ret;
- if (kvm_timer_update_state(vcpu))
+ if (unlikely(!timer->enabled))
return;
+ kvm_timer_update_state(vcpu);
+
/*
* If we enter the guest with the virtual input level to the VGIC
* asserted, then we have already told the VGIC what we need to, and
--
2.9.0
^ permalink raw reply related
* [PATCH 0/3] Support userspace irqchip with arch timers
From: Christoffer Dall @ 2016-09-27 19:08 UTC (permalink / raw)
To: linux-arm-kernel
Hi Alex,
Marc and I have been looking at this during Linaro connect and have
slightly reworked your patch into this small series.
It would be good if you could have a look at it and test it out.
I've tested it with your QEMU, and it works for UP, but secondary CPUs
fail to come up, and it looks like the kernel never gets an IPI for
those CPUs from userspace. Any chance you're willing to take a look at
that?
Also, let me know if the split of your patch with preserving your
authorship is ok with you.
Thanks,
-Christoffer
---
This series slightly reworks the patches to support architected timers
with a userspace irqchip sent by Alexander Graf [1].
We first cleanup some of the timer code to make it easier to understand
what is being done in the later patches, and then split up the
implementation into two separate patches (maintaining original
authorship).
Several changes have been made compared to v7 of the original single
patch, including:
- Rewording ABI documentation to be more in line with the ARM
architecture
- Add an explicit check for needing to notify userspace of a level
change instead of propagating the value
- Changes to commenting throughout to more accurately describe the
architecture concepts we try to maintain
- Reword of functions, for example from sync to update when the date
only flows one direction
These patches are based on two fixes necessary to test them which deal
with running kernel code without an in-kernl irqchip, and they are both
in kvmarm/next[2].
[1]: https://lists.cs.columbia.edu/pipermail/kvmarm/2016-September/021867.html
[2]: git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git next
Alexander Graf (2):
KVM: arm/arm64: Add ARM arch timer interrupts ABI
KVM: arm/arm64: Support arch timers with a userspace gic
Christoffer Dall (1):
KVM: arm/arm64: Cleanup the arch timer code's irqchip checking
Documentation/virtual/kvm/api.txt | 29 ++++++++++
arch/arm/include/uapi/asm/kvm.h | 2 +
arch/arm/kvm/arm.c | 19 +++----
arch/arm64/include/uapi/asm/kvm.h | 2 +
include/kvm/arm_arch_timer.h | 2 +
include/uapi/linux/kvm.h | 6 +++
virt/kvm/arm/arch_timer.c | 111 ++++++++++++++++++++++++++++++--------
7 files changed, 139 insertions(+), 32 deletions(-)
--
2.9.0
^ permalink raw reply
* [PATCH v2 8/8] ARM: bcm2835: Disable i2c2 in the Device Tree
From: Jan Kandziora @ 2016-09-27 18:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <256118042.194076.147d5d83-f402-4ba4-b7de-4ab57a0e29ad.open-xchange@email.1und1.de>
Am 27.09.2016 um 19:25 schrieb Stefan Wahren:
>
>> Noralf Tr?nnes <noralf@tronnes.org> hat am 27. September 2016 um 13:57
>> geschrieben:
>>
>>
>> i2c2 is connected to the HDMI connector and is controlled by the
>> firmware. Disable it to stay out of harms way.
>
> Until this point the commit message is okay, the rest is more confusing.
>
> Btw this should avoid a warning about missing clock frequency.
>
>>
>> From the downstream commit:
>> i2c-bcm2708/BCM270X_DT: Add support for I2C2
>>
>> The third I2C bus (I2C2) is normally reserved for HDMI use. Careless
>> use of this bus can break an attached display - use with caution.
>>
>> It is recommended to disable accesses by VideoCore by setting
>> hdmi_ignore_edid=1 or hdmi_edid_file=1 in config.txt.
>>
>> Signed-off-by: Noralf Tr?nnes <noralf@tronnes.org>
>> ---
>> arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 ----
>> 1 file changed, 4 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi
>> b/arch/arm/boot/dts/bcm2835-rpi.dtsi
>> index e9b47b2..8bffbee 100644
>> --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
>> +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
>> @@ -59,10 +59,6 @@
>> clock-frequency = <100000>;
>> };
>>
>> -&i2c2 {
>> - status = "okay";
>> -};
>> -
>
> I'm not sure if this the right fix. According to bcm283x.dtsi the 3 i2c busses
> have the same compatible string "brcm,bcm2835-i2c", but the changelog suggests
> that this bus is "special".
>
> Shouldn't we use a different compatible string? Our intention isn't to disable
> i2c2 but avoid any claims of the usual i2c driver.
>
i2c2 should not be generally disabled.
There's dtparam=i2c2_iknowwhatimdoing which enables CPU access to this
bus. It's useful for reading out the monitor EDID by the CPU, and for
accessing controls (backlight, volume) on certain monitors.
And I have a I2C touchscreen controller on HDMI DDC.
>> &sdhci {
>> status = "okay";
>> bus-width = <4>;
>> --
>> 2.8.2
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> --
> To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* [PATCH 0/4] kill get_clock_tick_rate()
From: Robert Jarzmik @ 2016-09-27 18:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87twd2bgtl.fsf@belgarion.home>
Robert Jarzmik <robert.jarzmik@free.fr> writes:
>> Hi,
>>
>> This serie aims at killing get_clock_tick_rate() from pxa and sa1100 and replace
>> it by clock API calls.
>>
>> I'd like to have this reviewed and acked afterwards at least by :
>> - Russell for the mach-sa1100 and sa1100_wdt.c
>> - Stephen or Michael for the clk-pxa25x.c
>> - Thomas or Daniel for the clocksource part
>> - Wim for sa1100_wdt.c
Thanks to all for tests and acks, queued to pxa/for-next.
Cheers.
--
Robert
^ permalink raw reply
* [PULL 50/50] KVM: arm/arm64: vgic: Don't flush/sync without a working vgic
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
If the vgic hasn't been created and initialized, we shouldn't attempt to
look at its data structures or flush/sync anything to the GIC hardware.
This fixes an issue reported by Alexander Graf when using a userspace
irqchip.
Fixes: 0919e84c0fc1 ("KVM: arm/arm64: vgic-new: Add IRQ sync/flush framework")
Cc: stable at vger.kernel.org
Reported-by: Alexander Graf <agraf@suse.de>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
Note that this is rework of a patch submitted by Alexander Graf, but
slightly reworked to use vgic_initialized instead of vgic_enabled, as
discussed on the list.
virt/kvm/arm/vgic/vgic.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index 8a529a7..2893d5b 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -645,6 +645,9 @@ next:
/* Sync back the hardware VGIC state into our emulation after a guest's run. */
void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
{
+ if (unlikely(!vgic_initialized(vcpu->kvm)))
+ return;
+
vgic_process_maintenance_interrupt(vcpu);
vgic_fold_lr_state(vcpu);
vgic_prune_ap_list(vcpu);
@@ -653,6 +656,9 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
/* Flush our emulation state into the GIC hardware before entering the guest. */
void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
{
+ if (unlikely(!vgic_initialized(vcpu->kvm)))
+ return;
+
spin_lock(&vcpu->arch.vgic_cpu.ap_list_lock);
vgic_flush_lr_state(vcpu);
spin_unlock(&vcpu->arch.vgic_cpu.ap_list_lock);
--
2.9.0
^ permalink raw reply related
* [PULL 49/50] KVM: arm64: Require in-kernel irqchip for PMU support
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
If userspace creates a PMU for the VCPU, but doesn't create an in-kernel
irqchip, then we end up in a nasty path where we try to take an
uninitialized spinlock, which can lead to all sorts of breakages.
Luckily, QEMU always creates the VGIC before the PMU, so we can
establish this as ABI and check for the VGIC in the PMU init stage.
This can be relaxed at a later time if we want to support PMU with a
userspace irqchip.
Cc: stable at vger.kernel.org
Cc: Shannon Zhao <shannon.zhao@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
Documentation/virtual/kvm/devices/vcpu.txt | 4 +++-
virt/kvm/arm/pmu.c | 8 ++++++++
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/Documentation/virtual/kvm/devices/vcpu.txt b/Documentation/virtual/kvm/devices/vcpu.txt
index c041658..02f5068 100644
--- a/Documentation/virtual/kvm/devices/vcpu.txt
+++ b/Documentation/virtual/kvm/devices/vcpu.txt
@@ -30,4 +30,6 @@ Returns: -ENODEV: PMUv3 not supported
attribute
-EBUSY: PMUv3 already initialized
-Request the initialization of the PMUv3.
+Request the initialization of the PMUv3. This must be done after creating the
+in-kernel irqchip. Creating a PMU with a userspace irqchip is currently not
+supported.
diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
index a027569..6e9c40e 100644
--- a/virt/kvm/arm/pmu.c
+++ b/virt/kvm/arm/pmu.c
@@ -423,6 +423,14 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu)
if (!kvm_arm_support_pmu_v3())
return -ENODEV;
+ /*
+ * We currently require an in-kernel VGIC to use the PMU emulation,
+ * because we do not support forwarding PMU overflow interrupts to
+ * userspace yet.
+ */
+ if (!irqchip_in_kernel(vcpu->kvm) || !vgic_initialized(vcpu->kvm))
+ return -ENODEV;
+
if (!test_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features) ||
!kvm_arm_pmu_irq_initialized(vcpu))
return -ENXIO;
--
2.9.0
^ permalink raw reply related
* [PULL 48/50] ARM: gic-v3: Work around definition of gic_write_bpr1
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
From: Marc Zyngier <marc.zyngier@arm.com>
A new accessor for gic_write_bpr1 is added to arch_gicv3.h in 4.9,
whilst the CP15 accessors are redifined in a separate branch.
This leads to a horrible clash, where the new accessor ends up with
a crap "asm volatile" definition.
Work around this by carrying our own definition of gic_write_bpr1,
creating a small conflict which will be obvious to resolve.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/include/asm/arch_gicv3.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index 996848e..1fee657 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -216,6 +216,15 @@ static inline void gic_write_sre(u32 val)
isb();
}
+static inline void gic_write_bpr1(u32 val)
+{
+#if defined(__write_sysreg) && defined(ICC_BPR1)
+ write_sysreg(val, ICC_BPR1);
+#else
+ asm volatile("mcr " __stringify(ICC_BPR1) : : "r" (val));
+#endif
+}
+
/*
* Even in 32bit systems that use LPAE, there is no guarantee that the I/O
* interface provides true 64bit atomic accesses, so using strd/ldrd doesn't
--
2.9.0
^ permalink raw reply related
* [PULL 47/50] arm64: KVM: Remove duplicating init code for setting VMID
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
From: Vladimir Murzin <vladimir.murzin@arm.com>
By now both VHE and non-VHE initialisation sequences query supported
VMID size. Lets keep only single instance of this code under
init_common_resources().
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/kvm/arm.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 75f130e..85a3f90 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -1178,6 +1178,10 @@ static int init_common_resources(void)
return -ENOMEM;
}
+ /* set size of VMID supported by CPU */
+ kvm_vmid_bits = kvm_get_vmid_bits();
+ kvm_info("%d-bit VMID\n", kvm_vmid_bits);
+
return 0;
}
@@ -1243,10 +1247,6 @@ static void teardown_hyp_mode(void)
static int init_vhe_mode(void)
{
- /* set size of VMID supported by CPU */
- kvm_vmid_bits = kvm_get_vmid_bits();
- kvm_info("%d-bit VMID\n", kvm_vmid_bits);
-
kvm_info("VHE mode initialized successfully\n");
return 0;
}
@@ -1330,10 +1330,6 @@ static int init_hyp_mode(void)
}
}
- /* set size of VMID supported by CPU */
- kvm_vmid_bits = kvm_get_vmid_bits();
- kvm_info("%d-bit VMID\n", kvm_vmid_bits);
-
kvm_info("Hyp mode initialized successfully\n");
return 0;
--
2.9.0
^ permalink raw reply related
* [PULL 46/50] ARM: KVM: Support vgic-v3
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
From: Vladimir Murzin <vladimir.murzin@arm.com>
This patch allows to build and use vgic-v3 in 32-bit mode.
Unfortunately, it can not be split in several steps without extra
stubs to keep patches independent and bisectable. For instance,
virt/kvm/arm/vgic/vgic-v3.c uses function from vgic-v3-sr.c, handling
access to GICv3 cpu interface from the guest requires vgic_v3.vgic_sre
to be already defined.
It is how support has been done:
* handle SGI requests from the guest
* report configured SRE on access to GICv3 cpu interface from the guest
* required vgic-v3 macros are provided via uapi.h
* static keys are used to select GIC backend
* to make vgic-v3 build KVM_ARM_VGIC_V3 guard is removed along with
the static inlines
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/include/asm/kvm_asm.h | 3 +++
arch/arm/include/asm/kvm_host.h | 5 ++++
arch/arm/include/asm/kvm_hyp.h | 3 +++
arch/arm/include/uapi/asm/kvm.h | 7 +++++
arch/arm/kvm/Makefile | 2 ++
arch/arm/kvm/coproc.c | 35 ++++++++++++++++++++++++
arch/arm/kvm/hyp/Makefile | 1 +
arch/arm/kvm/hyp/switch.c | 12 +++++++--
arch/arm64/kvm/Kconfig | 4 ---
include/kvm/arm_vgic.h | 8 ------
virt/kvm/arm/vgic/vgic-kvm-device.c | 8 ------
virt/kvm/arm/vgic/vgic-mmio.c | 2 --
virt/kvm/arm/vgic/vgic-mmio.h | 2 --
virt/kvm/arm/vgic/vgic.h | 54 -------------------------------------
14 files changed, 66 insertions(+), 80 deletions(-)
diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 05e47fa..d7ea6bc 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -72,6 +72,9 @@ extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
extern void __init_stage2_translation(void);
extern void __kvm_hyp_reset(unsigned long);
+
+extern u64 __vgic_v3_get_ich_vtr_el2(void);
+extern void __vgic_v3_init_lrs(void);
#endif
#endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index de338d9..c2c40a7 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -39,7 +39,12 @@
#include <kvm/arm_vgic.h>
+
+#ifdef CONFIG_ARM_GIC_V3
+#define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
+#else
#define KVM_MAX_VCPUS VGIC_V2_MAX_CPUS
+#endif
#define KVM_REQ_VCPU_EXIT 8
diff --git a/arch/arm/include/asm/kvm_hyp.h b/arch/arm/include/asm/kvm_hyp.h
index e604ad68..343135e 100644
--- a/arch/arm/include/asm/kvm_hyp.h
+++ b/arch/arm/include/asm/kvm_hyp.h
@@ -106,6 +106,9 @@ void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
void __sysreg_save_state(struct kvm_cpu_context *ctxt);
void __sysreg_restore_state(struct kvm_cpu_context *ctxt);
+void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
+void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
+
void asmlinkage __vfp_save_state(struct vfp_hard_struct *vfp);
void asmlinkage __vfp_restore_state(struct vfp_hard_struct *vfp);
static inline bool __vfp_enabled(void)
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index a2b3eb3..b38c10c 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -84,6 +84,13 @@ struct kvm_regs {
#define KVM_VGIC_V2_DIST_SIZE 0x1000
#define KVM_VGIC_V2_CPU_SIZE 0x2000
+/* Supported VGICv3 address types */
+#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
+#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
+
+#define KVM_VGIC_V3_DIST_SIZE SZ_64K
+#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
+
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
#define KVM_ARM_VCPU_PSCI_0_2 1 /* CPU uses PSCI v0.2 */
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index 339ec88..f19842e 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -27,8 +27,10 @@ obj-y += $(KVM)/arm/vgic/vgic.o
obj-y += $(KVM)/arm/vgic/vgic-init.o
obj-y += $(KVM)/arm/vgic/vgic-irqfd.o
obj-y += $(KVM)/arm/vgic/vgic-v2.o
+obj-y += $(KVM)/arm/vgic/vgic-v3.o
obj-y += $(KVM)/arm/vgic/vgic-mmio.o
obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
+obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
obj-y += $(KVM)/irqchip.o
obj-y += $(KVM)/arm/arch_timer.o
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 1bb2b79..3e5e419 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -228,6 +228,35 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
return true;
}
+static bool access_gic_sgi(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r)
+{
+ u64 reg;
+
+ if (!p->is_write)
+ return read_from_write_only(vcpu, p);
+
+ reg = (u64)*vcpu_reg(vcpu, p->Rt2) << 32;
+ reg |= *vcpu_reg(vcpu, p->Rt1) ;
+
+ vgic_v3_dispatch_sgi(vcpu, reg);
+
+ return true;
+}
+
+static bool access_gic_sre(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r)
+{
+ if (p->is_write)
+ return ignore_write(vcpu, p);
+
+ *vcpu_reg(vcpu, p->Rt1) = vcpu->arch.vgic_cpu.vgic_v3.vgic_sre;
+
+ return true;
+}
+
/*
* We could trap ID_DFR0 and tell the guest we don't support performance
* monitoring. Unfortunately the patch to make the kernel check ID_DFR0 was
@@ -361,10 +390,16 @@ static const struct coproc_reg cp15_regs[] = {
{ CRn(10), CRm( 3), Op1( 0), Op2( 1), is32,
access_vm_reg, reset_unknown, c10_AMAIR1},
+ /* ICC_SGI1R */
+ { CRm64(12), Op1( 0), is64, access_gic_sgi},
+
/* VBAR: swapped by interrupt.S. */
{ CRn(12), CRm( 0), Op1( 0), Op2( 0), is32,
NULL, reset_val, c12_VBAR, 0x00000000 },
+ /* ICC_SRE */
+ { CRn(12), CRm(12), Op1( 0), Op2(5), is32, access_gic_sre },
+
/* CONTEXTIDR/TPIDRURW/TPIDRURO/TPIDRPRW: swapped by interrupt.S. */
{ CRn(13), CRm( 0), Op1( 0), Op2( 1), is32,
access_vm_reg, reset_val, c13_CID, 0x00000000 },
diff --git a/arch/arm/kvm/hyp/Makefile b/arch/arm/kvm/hyp/Makefile
index 8dfa5f7..3023bb5 100644
--- a/arch/arm/kvm/hyp/Makefile
+++ b/arch/arm/kvm/hyp/Makefile
@@ -5,6 +5,7 @@
KVM=../../../../virt/kvm
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v3-sr.o
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
obj-$(CONFIG_KVM_ARM_HOST) += tlb.o
diff --git a/arch/arm/kvm/hyp/switch.c b/arch/arm/kvm/hyp/switch.c
index 9da16fd..92678b7 100644
--- a/arch/arm/kvm/hyp/switch.c
+++ b/arch/arm/kvm/hyp/switch.c
@@ -14,6 +14,7 @@
* 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/jump_label.h>
#include <asm/kvm_asm.h>
#include <asm/kvm_hyp.h>
@@ -83,14 +84,21 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
write_sysreg(read_sysreg(MIDR), VPIDR);
}
+
static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
{
- __vgic_v2_save_state(vcpu);
+ if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+ __vgic_v3_save_state(vcpu);
+ else
+ __vgic_v2_save_state(vcpu);
}
static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
{
- __vgic_v2_restore_state(vcpu);
+ if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+ __vgic_v3_restore_state(vcpu);
+ else
+ __vgic_v2_restore_state(vcpu);
}
static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 7ba9164..6eaf12c 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -19,9 +19,6 @@ if VIRTUALIZATION
config KVM_ARM_VGIC_V3_ITS
bool
-config KVM_ARM_VGIC_V3
- bool
-
config KVM
bool "Kernel-based Virtual Machine (KVM) support"
depends on OF
@@ -37,7 +34,6 @@ config KVM
select KVM_VFIO
select HAVE_KVM_EVENTFD
select HAVE_KVM_IRQFD
- select KVM_ARM_VGIC_V3
select KVM_ARM_VGIC_V3_ITS
select KVM_ARM_PMU if HW_PERF_EVENTS
select HAVE_KVM_MSI
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 8d22adc..002f092 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -225,7 +225,6 @@ struct vgic_v2_cpu_if {
};
struct vgic_v3_cpu_if {
-#ifdef CONFIG_KVM_ARM_VGIC_V3
u32 vgic_hcr;
u32 vgic_vmcr;
u32 vgic_sre; /* Restored only, change ignored */
@@ -235,7 +234,6 @@ struct vgic_v3_cpu_if {
u32 vgic_ap0r[4];
u32 vgic_ap1r[4];
u64 vgic_lr[VGIC_V3_MAX_LRS];
-#endif
};
struct vgic_cpu {
@@ -304,13 +302,7 @@ bool kvm_vcpu_has_pending_irqs(struct kvm_vcpu *vcpu);
void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
-#ifdef CONFIG_KVM_ARM_VGIC_V3
void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
-#else
-static inline void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg)
-{
-}
-#endif
/**
* kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
index 89ef9bc..ce1f4ed 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -71,7 +71,6 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
addr_ptr = &vgic->vgic_cpu_base;
alignment = SZ_4K;
break;
-#ifdef CONFIG_KVM_ARM_VGIC_V3
case KVM_VGIC_V3_ADDR_TYPE_DIST:
type_needed = KVM_DEV_TYPE_ARM_VGIC_V3;
addr_ptr = &vgic->vgic_dist_base;
@@ -82,7 +81,6 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
addr_ptr = &vgic->vgic_redist_base;
alignment = SZ_64K;
break;
-#endif
default:
r = -ENODEV;
goto out;
@@ -219,7 +217,6 @@ int kvm_register_vgic_device(unsigned long type)
ret = kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
KVM_DEV_TYPE_ARM_VGIC_V2);
break;
-#ifdef CONFIG_KVM_ARM_VGIC_V3
case KVM_DEV_TYPE_ARM_VGIC_V3:
ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
KVM_DEV_TYPE_ARM_VGIC_V3);
@@ -230,7 +227,6 @@ int kvm_register_vgic_device(unsigned long type)
ret = kvm_vgic_register_its_device();
#endif
break;
-#endif
}
return ret;
@@ -434,8 +430,6 @@ struct kvm_device_ops kvm_arm_vgic_v2_ops = {
.has_attr = vgic_v2_has_attr,
};
-#ifdef CONFIG_KVM_ARM_VGIC_V3
-
static int vgic_v3_set_attr(struct kvm_device *dev,
struct kvm_device_attr *attr)
{
@@ -478,5 +472,3 @@ struct kvm_device_ops kvm_arm_vgic_v3_ops = {
.get_attr = vgic_v3_get_attr,
.has_attr = vgic_v3_has_attr,
};
-
-#endif /* CONFIG_KVM_ARM_VGIC_V3 */
diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
index 3bad3c5..e18b30d 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.c
+++ b/virt/kvm/arm/vgic/vgic-mmio.c
@@ -550,11 +550,9 @@ int vgic_register_dist_iodev(struct kvm *kvm, gpa_t dist_base_address,
case VGIC_V2:
len = vgic_v2_init_dist_iodev(io_device);
break;
-#ifdef CONFIG_KVM_ARM_VGIC_V3
case VGIC_V3:
len = vgic_v3_init_dist_iodev(io_device);
break;
-#endif
default:
BUG_ON(1);
}
diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
index 80f92ce..4c34d39 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.h
+++ b/virt/kvm/arm/vgic/vgic-mmio.h
@@ -162,12 +162,10 @@ unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev);
unsigned int vgic_v3_init_dist_iodev(struct vgic_io_device *dev);
-#ifdef CONFIG_KVM_ARM_VGIC_V3
u64 vgic_sanitise_outer_cacheability(u64 reg);
u64 vgic_sanitise_inner_cacheability(u64 reg);
u64 vgic_sanitise_shareability(u64 reg);
u64 vgic_sanitise_field(u64 reg, u64 field_mask, int field_shift,
u64 (*sanitise_fn)(u64));
-#endif
#endif
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 100045f..9d9e014 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -72,7 +72,6 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
kref_get(&irq->refcount);
}
-#ifdef CONFIG_KVM_ARM_VGIC_V3
void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu);
void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu);
void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr);
@@ -91,60 +90,7 @@ bool vgic_has_its(struct kvm *kvm);
int kvm_vgic_register_its_device(void);
void vgic_enable_lpis(struct kvm_vcpu *vcpu);
int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
-#endif
-
#else
-static inline void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline void vgic_v3_populate_lr(struct kvm_vcpu *vcpu,
- struct vgic_irq *irq, int lr)
-{
-}
-
-static inline void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr)
-{
-}
-
-static inline void vgic_v3_set_underflow(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline
-void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
-{
-}
-
-static inline
-void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
-{
-}
-
-static inline void vgic_v3_enable(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline int vgic_v3_probe(const struct gic_kvm_info *info)
-{
- return -ENODEV;
-}
-
-static inline int vgic_v3_map_resources(struct kvm *kvm)
-{
- return -ENODEV;
-}
-
-static inline int vgic_register_redist_iodevs(struct kvm *kvm,
- gpa_t dist_base_address)
-{
- return -ENODEV;
-}
-
static inline int vgic_register_its_iodevs(struct kvm *kvm)
{
return -ENODEV;
--
2.9.0
^ permalink raw reply related
* [PULL 45/50] ARM: gic-v3: Introduce 32-to-64-bit mappings for GICv3 cpu registers
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
From: Vladimir Murzin <vladimir.murzin@arm.com>
vgic-v3 save/restore routines are written in such way that they map
arm64 system register naming nicely, but it does not fit to arm
world. To keep virt/kvm/arm/hyp/vgic-v3-sr.c untouched we create a
mapping with a function for each register mapping the 32-bit to the
64-bit accessors.
Please, note that 64-bit wide ICH_LR is split in two 32-bit halves
(ICH_LR and ICH_LRC) accessed independently.
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/include/asm/arch_gicv3.h | 64 +++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index af25c32..996848e 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -96,6 +96,70 @@
#define ICH_AP1R2 __AP1Rx(2)
#define ICH_AP1R3 __AP1Rx(3)
+/* A32-to-A64 mappings used by VGIC save/restore */
+
+#define CPUIF_MAP(a32, a64) \
+static inline void write_ ## a64(u32 val) \
+{ \
+ write_sysreg(val, a32); \
+} \
+static inline u32 read_ ## a64(void) \
+{ \
+ return read_sysreg(a32); \
+} \
+
+#define CPUIF_MAP_LO_HI(a32lo, a32hi, a64) \
+static inline void write_ ## a64(u64 val) \
+{ \
+ write_sysreg(lower_32_bits(val), a32lo);\
+ write_sysreg(upper_32_bits(val), a32hi);\
+} \
+static inline u64 read_ ## a64(void) \
+{ \
+ u64 val = read_sysreg(a32lo); \
+ \
+ val |= (u64)read_sysreg(a32hi) << 32; \
+ \
+ return val; \
+}
+
+CPUIF_MAP(ICH_HCR, ICH_HCR_EL2)
+CPUIF_MAP(ICH_VTR, ICH_VTR_EL2)
+CPUIF_MAP(ICH_MISR, ICH_MISR_EL2)
+CPUIF_MAP(ICH_EISR, ICH_EISR_EL2)
+CPUIF_MAP(ICH_ELSR, ICH_ELSR_EL2)
+CPUIF_MAP(ICH_VMCR, ICH_VMCR_EL2)
+CPUIF_MAP(ICH_AP0R3, ICH_AP0R3_EL2)
+CPUIF_MAP(ICH_AP0R2, ICH_AP0R2_EL2)
+CPUIF_MAP(ICH_AP0R1, ICH_AP0R1_EL2)
+CPUIF_MAP(ICH_AP0R0, ICH_AP0R0_EL2)
+CPUIF_MAP(ICH_AP1R3, ICH_AP1R3_EL2)
+CPUIF_MAP(ICH_AP1R2, ICH_AP1R2_EL2)
+CPUIF_MAP(ICH_AP1R1, ICH_AP1R1_EL2)
+CPUIF_MAP(ICH_AP1R0, ICH_AP1R0_EL2)
+CPUIF_MAP(ICC_HSRE, ICC_SRE_EL2)
+CPUIF_MAP(ICC_SRE, ICC_SRE_EL1)
+
+CPUIF_MAP_LO_HI(ICH_LR15, ICH_LRC15, ICH_LR15_EL2)
+CPUIF_MAP_LO_HI(ICH_LR14, ICH_LRC14, ICH_LR14_EL2)
+CPUIF_MAP_LO_HI(ICH_LR13, ICH_LRC13, ICH_LR13_EL2)
+CPUIF_MAP_LO_HI(ICH_LR12, ICH_LRC12, ICH_LR12_EL2)
+CPUIF_MAP_LO_HI(ICH_LR11, ICH_LRC11, ICH_LR11_EL2)
+CPUIF_MAP_LO_HI(ICH_LR10, ICH_LRC10, ICH_LR10_EL2)
+CPUIF_MAP_LO_HI(ICH_LR9, ICH_LRC9, ICH_LR9_EL2)
+CPUIF_MAP_LO_HI(ICH_LR8, ICH_LRC8, ICH_LR8_EL2)
+CPUIF_MAP_LO_HI(ICH_LR7, ICH_LRC7, ICH_LR7_EL2)
+CPUIF_MAP_LO_HI(ICH_LR6, ICH_LRC6, ICH_LR6_EL2)
+CPUIF_MAP_LO_HI(ICH_LR5, ICH_LRC5, ICH_LR5_EL2)
+CPUIF_MAP_LO_HI(ICH_LR4, ICH_LRC4, ICH_LR4_EL2)
+CPUIF_MAP_LO_HI(ICH_LR3, ICH_LRC3, ICH_LR3_EL2)
+CPUIF_MAP_LO_HI(ICH_LR2, ICH_LRC2, ICH_LR2_EL2)
+CPUIF_MAP_LO_HI(ICH_LR1, ICH_LRC1, ICH_LR1_EL2)
+CPUIF_MAP_LO_HI(ICH_LR0, ICH_LRC0, ICH_LR0_EL2)
+
+#define read_gicreg(r) read_##r()
+#define write_gicreg(v, r) write_##r(v)
+
/* Low-level accessors */
static inline void gic_write_eoir(u32 irq)
--
2.9.0
^ permalink raw reply related
* [PULL 44/50] ARM: Move system register accessors to asm/cp15.h
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
From: Vladimir Murzin <vladimir.murzin@arm.com>
Headers linux/irqchip/arm-gic.v3.h and arch/arm/include/asm/kvm_hyp.h
are included in virt/kvm/arm/hyp/vgic-v3-sr.c and both define macros
called __ACCESS_CP15 and __ACCESS_CP15_64 which obviously creates a
conflict. These macros were introduced independently for GIC and KVM
and, in fact, do the same thing.
As an option we could add prefixes to KVM and GIC version of macros so
they won't clash, but it'd introduce code duplication. Alternatively,
we could keep macro in, say, GIC header and include it in KVM one (or
vice versa), but such dependency would not look nicer.
So we follow arm64 way (it handles this via sysreg.h) and move only
single set of macros to asm/cp15.h
Cc: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/include/asm/arch_gicv3.h | 27 +++++++++++----------------
arch/arm/include/asm/cp15.h | 15 +++++++++++++++
arch/arm/include/asm/kvm_hyp.h | 15 +--------------
3 files changed, 27 insertions(+), 30 deletions(-)
diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index e08d151..af25c32 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -22,9 +22,7 @@
#include <linux/io.h>
#include <asm/barrier.h>
-
-#define __ACCESS_CP15(CRn, Op1, CRm, Op2) p15, Op1, %0, CRn, CRm, Op2
-#define __ACCESS_CP15_64(Op1, CRm) p15, Op1, %Q0, %R0, CRm
+#include <asm/cp15.h>
#define ICC_EOIR1 __ACCESS_CP15(c12, 0, c12, 1)
#define ICC_DIR __ACCESS_CP15(c12, 0, c11, 1)
@@ -102,58 +100,55 @@
static inline void gic_write_eoir(u32 irq)
{
- asm volatile("mcr " __stringify(ICC_EOIR1) : : "r" (irq));
+ write_sysreg(irq, ICC_EOIR1);
isb();
}
static inline void gic_write_dir(u32 val)
{
- asm volatile("mcr " __stringify(ICC_DIR) : : "r" (val));
+ write_sysreg(val, ICC_DIR);
isb();
}
static inline u32 gic_read_iar(void)
{
- u32 irqstat;
+ u32 irqstat = read_sysreg(ICC_IAR1);
- asm volatile("mrc " __stringify(ICC_IAR1) : "=r" (irqstat));
dsb(sy);
+
return irqstat;
}
static inline void gic_write_pmr(u32 val)
{
- asm volatile("mcr " __stringify(ICC_PMR) : : "r" (val));
+ write_sysreg(val, ICC_PMR);
}
static inline void gic_write_ctlr(u32 val)
{
- asm volatile("mcr " __stringify(ICC_CTLR) : : "r" (val));
+ write_sysreg(val, ICC_CTLR);
isb();
}
static inline void gic_write_grpen1(u32 val)
{
- asm volatile("mcr " __stringify(ICC_IGRPEN1) : : "r" (val));
+ write_sysreg(val, ICC_IGRPEN1);
isb();
}
static inline void gic_write_sgi1r(u64 val)
{
- asm volatile("mcrr " __stringify(ICC_SGI1R) : : "r" (val));
+ write_sysreg(val, ICC_SGI1R);
}
static inline u32 gic_read_sre(void)
{
- u32 val;
-
- asm volatile("mrc " __stringify(ICC_SRE) : "=r" (val));
- return val;
+ return read_sysreg(ICC_SRE);
}
static inline void gic_write_sre(u32 val)
{
- asm volatile("mcr " __stringify(ICC_SRE) : : "r" (val));
+ write_sysreg(val, ICC_SRE);
isb();
}
diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
index c3f1152..dbdbce1 100644
--- a/arch/arm/include/asm/cp15.h
+++ b/arch/arm/include/asm/cp15.h
@@ -49,6 +49,21 @@
#ifdef CONFIG_CPU_CP15
+#define __ACCESS_CP15(CRn, Op1, CRm, Op2) \
+ "mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
+#define __ACCESS_CP15_64(Op1, CRm) \
+ "mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
+
+#define __read_sysreg(r, w, c, t) ({ \
+ t __val; \
+ asm volatile(r " " c : "=r" (__val)); \
+ __val; \
+})
+#define read_sysreg(...) __read_sysreg(__VA_ARGS__)
+
+#define __write_sysreg(v, r, w, c, t) asm volatile(w " " c : : "r" ((t)(v)))
+#define write_sysreg(v, ...) __write_sysreg(v, __VA_ARGS__)
+
extern unsigned long cr_alignment; /* defined in entry-armv.S */
static inline unsigned long get_cr(void)
diff --git a/arch/arm/include/asm/kvm_hyp.h b/arch/arm/include/asm/kvm_hyp.h
index 6eaff28..e604ad68 100644
--- a/arch/arm/include/asm/kvm_hyp.h
+++ b/arch/arm/include/asm/kvm_hyp.h
@@ -20,28 +20,15 @@
#include <linux/compiler.h>
#include <linux/kvm_host.h>
+#include <asm/cp15.h>
#include <asm/kvm_mmu.h>
#include <asm/vfp.h>
#define __hyp_text __section(.hyp.text) notrace
-#define __ACCESS_CP15(CRn, Op1, CRm, Op2) \
- "mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
-#define __ACCESS_CP15_64(Op1, CRm) \
- "mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
#define __ACCESS_VFP(CRn) \
"mrc", "mcr", __stringify(p10, 7, %0, CRn, cr0, 0), u32
-#define __write_sysreg(v, r, w, c, t) asm volatile(w " " c : : "r" ((t)(v)))
-#define write_sysreg(v, ...) __write_sysreg(v, __VA_ARGS__)
-
-#define __read_sysreg(r, w, c, t) ({ \
- t __val; \
- asm volatile(r " " c : "=r" (__val)); \
- __val; \
-})
-#define read_sysreg(...) __read_sysreg(__VA_ARGS__)
-
#define write_special(v, r) \
asm volatile("msr " __stringify(r) ", %0" : : "r" (v))
#define read_special(r) ({ \
--
2.9.0
^ permalink raw reply related
* [PULL 43/50] ARM: Introduce MPIDR_LEVEL_SHIFT macro
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
From: Vladimir Murzin <vladimir.murzin@arm.com>
vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
encode the affinity in a form compatible with ICC_SGI* registers.
Unfortunately, that macro is missing on ARM, so let's add it.
Cc: Russell King <rmk+kernel@armlinux.org.uk>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm/include/asm/cputype.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index 1ee94c7..e2d94c1 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -55,6 +55,7 @@
#define MPIDR_LEVEL_BITS 8
#define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
+#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
#define MPIDR_AFFINITY_LEVEL(mpidr, level) \
((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
--
2.9.0
^ permalink raw reply related
* [PULL 42/50] KVM: arm: vgic: Support 64-bit data manipulation on 32-bit host systems
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
From: Vladimir Murzin <vladimir.murzin@arm.com>
We have couple of 64-bit registers defined in GICv3 architecture, so
unsigned long accesses to these registers will only access a single
32-bit part of that regitser. On the other hand these registers can't
be accessed as 64-bit with a single instruction like ldrd/strd or
ldmia/stmia if we run a 32-bit host because KVM does not support
access to MMIO space done by these instructions.
It means that a 32-bit guest accesses these registers in 32-bit
chunks, so the only thing we need to do is to ensure that
extract_bytes() always takes 64-bit data.
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/vgic/vgic-mmio-v3.c | 2 +-
virt/kvm/arm/vgic/vgic-mmio.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index 6385ed5..0d3c76a 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -23,7 +23,7 @@
#include "vgic-mmio.h"
/* extract @num bytes at @offset bytes offset in data */
-unsigned long extract_bytes(unsigned long data, unsigned int offset,
+unsigned long extract_bytes(u64 data, unsigned int offset,
unsigned int num)
{
return (data >> (offset * 8)) & GENMASK_ULL(num * 8 - 1, 0);
diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
index 0b3ecf9..80f92ce 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.h
+++ b/virt/kvm/arm/vgic/vgic-mmio.h
@@ -96,7 +96,7 @@ unsigned long vgic_data_mmio_bus_to_host(const void *val, unsigned int len);
void vgic_data_host_to_mmio_bus(void *buf, unsigned int len,
unsigned long data);
-unsigned long extract_bytes(unsigned long data, unsigned int offset,
+unsigned long extract_bytes(u64 data, unsigned int offset,
unsigned int num);
u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
--
2.9.0
^ permalink raw reply related
* [PULL 41/50] KVM: arm: vgic: Fix compiler warnings when built for 32-bit
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
From: Vladimir Murzin <vladimir.murzin@arm.com>
Well, this patch is looking ahead of time, but we'll get following
compiler warnings as soon as we introduce vgic-v3 to 32-bit world
CC arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.o
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_mmio_read_v3r_typer':
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:184:35: warning: left shift count >= width of type [-Wshift-count-overflow]
value = (mpidr & GENMASK(23, 0)) << 32;
^
In file included from ./include/linux/kernel.h:10:0,
from ./include/asm-generic/bug.h:13,
from ./arch/arm/include/asm/bug.h:59,
from ./include/linux/bug.h:4,
from ./include/linux/io.h:23,
from ./arch/arm/include/asm/arch_gicv3.h:23,
from ./include/linux/irqchip/arm-gic-v3.h:411,
from arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:14:
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_v3_dispatch_sgi':
./include/linux/bitops.h:6:24: warning: left shift count >= width of type [-Wshift-count-overflow]
#define BIT(nr) (1UL << (nr))
^
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:614:20: note: in expansion of macro 'BIT'
broadcast = reg & BIT(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
^
Let's fix them now.
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
virt/kvm/arm/vgic/vgic-mmio-v3.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index acbe691..6385ed5 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -181,7 +181,7 @@ static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu,
int target_vcpu_id = vcpu->vcpu_id;
u64 value;
- value = (mpidr & GENMASK(23, 0)) << 32;
+ value = (u64)(mpidr & GENMASK(23, 0)) << 32;
value |= ((target_vcpu_id & 0xffff) << 8);
if (target_vcpu_id == atomic_read(&vcpu->kvm->online_vcpus) - 1)
value |= GICR_TYPER_LAST;
@@ -611,7 +611,7 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg)
bool broadcast;
sgi = (reg & ICC_SGI1R_SGI_ID_MASK) >> ICC_SGI1R_SGI_ID_SHIFT;
- broadcast = reg & BIT(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
+ broadcast = reg & BIT_ULL(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
target_cpus = (reg & ICC_SGI1R_TARGET_LIST_MASK) >> ICC_SGI1R_TARGET_LIST_SHIFT;
mpidr = SGI_AFFINITY_LEVEL(reg, 3);
mpidr |= SGI_AFFINITY_LEVEL(reg, 2);
--
2.9.0
^ permalink raw reply related
* [PULL 40/50] KVM: arm64: vgic-its: Introduce config option to guard ITS specific code
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
From: Vladimir Murzin <vladimir.murzin@arm.com>
By now ITS code guarded with KVM_ARM_VGIC_V3 config option which was
introduced to hide everything specific to vgic-v3 from 32-bit world.
We are going to support vgic-v3 in 32-bit world and KVM_ARM_VGIC_V3
will gone, but we don't have support for ITS there yet and we need to
continue keeping ITS away.
Introduce the new config option to prevent ITS code being build in
32-bit mode when support for vgic-v3 is done.
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm64/kvm/Kconfig | 4 ++++
virt/kvm/arm/vgic/vgic-kvm-device.c | 3 +++
virt/kvm/arm/vgic/vgic-mmio-v3.c | 2 ++
virt/kvm/arm/vgic/vgic.h | 4 ++++
4 files changed, 13 insertions(+)
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 9c9edc9..7ba9164 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -16,6 +16,9 @@ menuconfig VIRTUALIZATION
if VIRTUALIZATION
+config KVM_ARM_VGIC_V3_ITS
+ bool
+
config KVM_ARM_VGIC_V3
bool
@@ -35,6 +38,7 @@ config KVM
select HAVE_KVM_EVENTFD
select HAVE_KVM_IRQFD
select KVM_ARM_VGIC_V3
+ select KVM_ARM_VGIC_V3_ITS
select KVM_ARM_PMU if HW_PERF_EVENTS
select HAVE_KVM_MSI
select HAVE_KVM_IRQCHIP
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
index 163b057..89ef9bc 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -223,9 +223,12 @@ int kvm_register_vgic_device(unsigned long type)
case KVM_DEV_TYPE_ARM_VGIC_V3:
ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
KVM_DEV_TYPE_ARM_VGIC_V3);
+
+#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
if (ret)
break;
ret = kvm_vgic_register_its_device();
+#endif
break;
#endif
}
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index 90d8181..acbe691 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -42,6 +42,7 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
return reg | ((u64)val << lower);
}
+#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
bool vgic_has_its(struct kvm *kvm)
{
struct vgic_dist *dist = &kvm->arch.vgic;
@@ -51,6 +52,7 @@ bool vgic_has_its(struct kvm *kvm)
return dist->has_its;
}
+#endif
static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
gpa_t addr, unsigned int len)
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 6c4625c..100045f 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -84,11 +84,15 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu);
int vgic_v3_probe(const struct gic_kvm_info *info);
int vgic_v3_map_resources(struct kvm *kvm);
int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
+
+#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
int vgic_register_its_iodevs(struct kvm *kvm);
bool vgic_has_its(struct kvm *kvm);
int kvm_vgic_register_its_device(void);
void vgic_enable_lpis(struct kvm_vcpu *vcpu);
int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
+#endif
+
#else
static inline void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu)
{
--
2.9.0
^ permalink raw reply related
* [PULL 39/50] arm64: KVM: Move vgic-v3 save/restore to virt/kvm/arm/hyp
From: Christoffer Dall @ 2016-09-27 18:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160927180558.14699-1-christoffer.dall@linaro.org>
From: Vladimir Murzin <vladimir.murzin@arm.com>
So we can reuse the code under arch/arm
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
arch/arm64/kvm/hyp/Makefile | 2 +-
{arch/arm64/kvm => virt/kvm/arm}/hyp/vgic-v3-sr.c | 0
2 files changed, 1 insertion(+), 1 deletion(-)
rename {arch/arm64/kvm => virt/kvm/arm}/hyp/vgic-v3-sr.c (100%)
diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
index 0c85feb..aaf42ae 100644
--- a/arch/arm64/kvm/hyp/Makefile
+++ b/arch/arm64/kvm/hyp/Makefile
@@ -5,9 +5,9 @@
KVM=../../../../virt/kvm
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v3-sr.o
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
-obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o
obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
obj-$(CONFIG_KVM_ARM_HOST) += entry.o
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
similarity index 100%
rename from arch/arm64/kvm/hyp/vgic-v3-sr.c
rename to virt/kvm/arm/hyp/vgic-v3-sr.c
--
2.9.0
^ 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