* [PATCH next] arm64: remove "SMP: Total of %d processors activated." message
From: Will Deacon @ 2016-11-17 14:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479367946-38771-1-git-send-email-wangkefeng.wang@huawei.com>
On Thu, Nov 17, 2016 at 03:32:26PM +0800, Kefeng Wang wrote:
> There is a common SMP boot message in generic code on all arches,
> kill "SMP: Total of %d processors activated." in smp_cpus_done()
> on arm64.
>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> ---
> Boot message on qemu.
> [ 0.375116] smp: Brought up 1 node, 8 CPUs
> [ 0.383749] SMP: Total of 8 processors activated.
>
> arch/arm64/kernel/smp.c | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index cb87234..9db4a95 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -428,7 +428,6 @@ static void __init hyp_mode_check(void)
>
> void __init smp_cpus_done(unsigned int max_cpus)
> {
> - pr_info("SMP: Total of %d processors activated.\n", num_online_cpus());
> setup_cpu_features();
> hyp_mode_check();
> apply_alternatives_all();
Why? Are you proposing the same change to other architectures? Are you paid
per patch?
Will
^ permalink raw reply
* [PATCH] arm64: mm: Fix memmap to be initialized for the entire section
From: Will Deacon @ 2016-11-17 14:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161109195132.GZ22012@rric.localdomain>
On Wed, Nov 09, 2016 at 08:51:32PM +0100, Robert Richter wrote:
> Thus, I don't see where my patch breaks code. Even acpi_os_ioremap()
> keeps the same behaviour as before since it still uses memblock_is_
> memory(). Could you more describe your concerns why do you think this
> patch breaks the kernel and moves the problem somewhere else? I
> believe it fixes the problem at all.
acpi_os_ioremap always ends up in __ioremap_caller, regardless of
memblock_is_memory(). __ioremap_caller then fails if pfn_valid is true.
Will
^ permalink raw reply
* Boot failures in -next due to 'ARM: dts: imx: Remove skeleton.dtsi'
From: Guenter Roeck @ 2016-11-17 14:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161117105513.GA12273@leverpostej>
On 11/17/2016 02:55 AM, Mark Rutland wrote:
> On Wed, Nov 16, 2016 at 02:40:24PM -0800, Guenter Roeck wrote:
>> On Wed, Nov 16, 2016 at 08:27:09PM -0200, Fabio Estevam wrote:
>>> Hi Guenter,
>>>
>>> On Wed, Nov 16, 2016 at 8:10 PM, Guenter Roeck <linux@roeck-us.net> wrote:
>>>>
>>>> Anyway, I guess the problem is that the "official" dtb files no longer provide
>>>> the skeleton /chosen and /memory nodes (and maybe others), and qemu seems to
>>>> expect that they are provided. Is that correct ?
>>>
>>> imx6qdl-sabrelite.dtsi provides chosen and memory nodes.
>>
>> Yes, but not the 'device_type' property, which the kernel seems to expect.
>
> Memory nodes require this property per ePAPR and the devicetree.org
> spec, so the bug is that we didn't add those when removing the
> skeleton.dtsi include.
>
The downside from qemu perspective is that the real hardware seems
to add the property unconditionally, or the boot failure would have
been seen there as well.
I submitted https://patchwork.ozlabs.org/patch/695951/; we'll see how it goes.
Guenter
>> The qemu patch below fixes the problem for sabrelite, I just don't know
>> if that is really the way to go. You tell me; I'll be happy to submit
>> the necessary patch(es) into qemu.
>
> As above, I don't think the below patch is necessary. The dt should have
> this property to begin with.
>
>> The same is true for 'chosen'. Right now qemu expects this node to exist.
>> It does exist for sabrelite, but apparently not for imx25-pdk.
>
> Having QEMU create a /chosen node if one does not exist already sounds
> sensible to me.
>
> Thanks,
> Mark.
>
>> Guenter
>>
>> ---
>> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
>> index 1b913a4..080d1e5 100644
>> --- a/hw/arm/boot.c
>> +++ b/hw/arm/boot.c
>> @@ -486,6 +486,12 @@ static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
>> g_free(nodename);
>> }
>> } else {
>> + Error *err = NULL;
>> +
>> + if (!qemu_fdt_getprop(fdt, "/memory", "device_type", NULL, &err)) {
>> + qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
>> + }
>> +
>> rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
>> acells, binfo->loader_start,
>> scells, binfo->ram_size);
>
^ permalink raw reply
* [PATCH 0/3] thermal: Fix module autoload for drivers
From: Eduardo Valentin @ 2016-11-17 14:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CABxcv==keE6X5B1R+DSaZewVDdpCtuGF5j4S46YF3pncHT8q2Q@mail.gmail.com>
On Thu, Nov 17, 2016 at 08:50:11AM -0300, Javier Martinez Canillas wrote:
> Hello Eduardo,
>
> On Fri, Oct 14, 2016 at 11:34 AM, Javier Martinez Canillas
> <javier@osg.samsung.com> wrote:
> > Hello,
> >
> > This small series contains trivial fixes to allow modules to be autoloaded
> > when its correspoinding thermal device is registered.
> >
> > Best regards,
> > Javier
> >
> >
> > Javier Martinez Canillas (3):
> > thermal: max77620: Fix module autoload
> > thermal: tango: Fix module autoload
> > thermal: db8500: Fix module autoload
> >
>
> Any comments about these patches?
So far no. I am finalizing a couple of automated testing, but they are
in my queue.
Thanks for the fixes.
BR,
>
> Best regards,
> Javier
^ permalink raw reply
* [PATCH v5 1/7] drm: sunxi: Add a basic DRM driver for Allwinner DE2
From: Jean-Francois Moine @ 2016-11-17 14:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161116213306.s5o5zi7pgppwuq7t@lukather>
On Wed, 16 Nov 2016 22:33:06 +0100
Maxime Ripard <maxime.ripard@free-electrons.com> wrote:
> > > > The Device Engine just handles the planes of the LCDs, but, indeed,
> > > > the LCDs must know about the DE and the DE must know about the LCDs.
> > > > There are 2 ways to realize this knowledge in the DT:
> > > > 1) either the DE has one or two phandle's to the LCDs,
> > > > 2) or the LCDs have a phandle to the DE.
> > > >
> > > > I chose the 1st way, the DE ports pointing to the endpoint of the LCDs
> > > > which is part of the video link (OF-graph LCD <-> connector).
> > > > It would be possible to have phandles to the LCDs themselves, but this
> > > > asks for more code.
> > > >
> > > > The second way is also possible, but it also complexifies a bit the
> > > > exchanges DE <-> LCD.
> > >
> > > I'm still not sure how it would complexify anything, and why you can't
> > > use the display graph to model the relation between the display engine
> > > and the TCON (and why you want to use a generic property that refers
> > > to the of-graph while it really isn't).
> >
> > Complexification:
> > 1- my solution:
> > At startup time, the DE device is the DRM device.
>
> How do you deal with SoCs with multiple display engines then?
In the H3, A83T and A64, there is only one DE.
If many DEs in a SoC, there may be either one DRM device per DE or one
DRM device for the whole system. In this last case, the (global) DE
would have many resources (many I/O memory maps / IRQs..) and the
physical DE of each endpoint would be indicated by the position of its
phandle in the 'ports' array (DT documentation).
> > It has to know the devices entering in the video chains.
> > The CRTCs (LCD/TCON) are found by
> > ports[i] -> parent
> > The connectors are found by
> > ports[i] -> endpoint -> remote_endpoint -> parent
> > 2- with ports pointing to the LCDs:
> > The CRTCs (LCD/TCON) are simply
> > ports[i]
> > The connectors are found by
> > loop on all ports of ports[i]
> > ports[i][j] -> endpoint -> remote_endpoint -> parent
> > 3- with a phandle to the DE in the LCDs:
>
> What do you mean with LCD? Panels? Why would panels have a phandle to
> the display engine?
LCD is the same as CRTC. I don't think people will connect old CRT's to
their new ARM boards. LCD's may be panels, modern TV sets, or any
digital display. The word LCD seems clearer to me in this context, even
if there may a DAC as an ancoder.
> > The DE cannot be the DRM device because there is no information about
> > the video devices in the DT. Then, the DRM devices are the LCDs.
> > These LCDs must give their indices to the DE. So, the DE must implement
> > some callback function to accept a LCD definition, and there must be
> > a list of DEs in the driver to make the association DE <-> LCD[i]
> > Some more problem may be raised if a user wants to have the same frame
> > buffer on the 2 LCDs of a DE.
>
> I have no idea what you're talking about, sorry.
Here is the DT (I am using back 'CRTC'):
de: display-controller at xxx {
...
};
crtc0: crt-controller at xxx{
...
display-controller = <&de>;
ports {
... /* to the crtc0 connectors */
}
};
crtc1: crt-controller at xxx{
...
display-controller = <&de>;
ports {
... /* to the crtc1 connectors */
};
};
There are 2 DRM devices: one on crtc0, the other one on crtc1.
The DE device is isolated. But, to treat the planes, it must receive
information about the CRTCs. How?
> > Anyway, my solution is already used in the IMX Soc.
> > See 'display-subsystem' in arch/arm/boot/dts/imx6q.dtsi for an example.
>
> Pointing out random example in the tree doesn't make a compelling
> argument.
This is not a random example. There was a thread about the 'ports'
phandle in the DT definition of the IMX video subsystem, and what kind
of OF function should be used (see one of my previous mails). In the DRI
list, nobody objected about the phandle by itself.
> > > > > > > Panel functions? In the CRTC driver?
> > > > > >
> > > > > > Yes, dumb panel.
> > > > >
> > > > > What do you mean by that? Using a Parallel/RGB interface?
> > > >
> > > > Sorry, I though this was a well-known name. The 'dump panel' was used
> > > > in the documentation of my previous ARM machine as the video frame sent
> > > > to the HDMI controller. 'video_frame' is OK for you?
> > >
> > > If it's the frame sent to the encoder, then it would be the CRTC by
> > > DRM's nomenclature.
> >
> > The CRTC is a software entity. The frame buffer is a hardware entity.
>
> Why are you about framebuffer now, this is nowhere in that
> discussion. Any way, the framebuffer is also what is put in a plane,
> so there's a name collision here, and you'll probably want to change
> it.
>
> Judging by the previous discussion, this should really be called
> encoder if it encodes the frames on a bus format, or CRTC if it
> composes the planes.
I think that we will end in agreeing on the words. We just need some
time!
Here is how I understand the Allwinner's DE2:
- the TCON is the piece of hardware which gets some memory area and
sends it to a bus according to some configuation (screen resolution,
timings...). The bus data are encoded and transmitted to the connector.
At the end, the display device receives frames. So, going back to the
TCON, the memory are is the frame buffer.
- this frame buffer is virtual, empty, 'dumb', it is a dumb panel!
It is filled by planes. This job is done by a specific image
processor, the one contained in the DE2.
- the DE2 processor gets the plane source images from the SoC memory.
It adjusts the images according to many configuration parameters and
includes the result into the frame buffer.
So:
LCD = CRTC = frame buffer = dumb panel = TCON
- LCD = hardware piece of a display device (terminal side) which renders
the colored pixels in a digital way. By extension, the hardware part
(computer side) of a display engine which handles the definitions of
a digital or analog physical display device. By extension also,
the software structure (driver side) which defines a physical screen.
- CRTC = DRM software entity which handles the definitions of a screen,
but not just a CRT.
- frame buffer = piece of memory which contains the images which are
sent to a screen.
- dumb panel = abstract entity which defines the characteristics of a
physical screen.
You may note that, in the DE2 scheme, the TCON and LCD are not in the
same (software) device while they are part of the same DRM software
entity, the CTRC.
> > > > > If it is similar, I think hardcoding the pipe number is pretty bad,
> > > > > because that would restrict the combination of planes and formats,
> > > > > while some other might have worked.
> > > >
> > > > From what I understood about the DE2, the pipes just define the priority
> > > > of the overlay channels (one pipe for one channel).
> > > > With the cursor constraint, there must be at least 2 channels in
> > > > order (primary, cursor). Then, with these 2 channels/pipes, there can be
> > > > 6 so-called overlay planes (3 RGB/YUV and 3 RGB only).
> > > > Enabling the pipes 2 and 3 (LCD 0 only) would offer 8 more planes, but
> > > > RGB only. Then, it might be useful to have dynamic pipes.
> > >
> > > That's very valuable (and definitely should go into a comment),
> > > thanks!
> > >
> > > I still believe that's it should be into a (simple at first)
> > > atomic_check. That would be easier to extend and quite easy to
> > > document and get simply by looking at the code.
> >
> > Sorry for I don't understand what you mean.
>
> You can check all the constraints you exposed above in atomic_check
> instead of hardcoding it.
Sorry, but I don't like to run useless code for pure static definition.
> > The DE and the LCDs are different devices on different drivers.
> > A DE must be only one device because it has to handle concurent
> > accesses from its 2 LCDs. Then 2 drivers.
>
> If it's different drivers, why are they in the same module?
>
> > But only one module. Why? Because there cannot be double direction
> > calls from one module to an other one, and, in our case, for example,
> > - the DRM (DE) device must call vblank functions which are handled in
> > the CRTC (TCON) device, and
> > - the CRTC device must call DE initialization functions at startup time.
>
> I'm sorry, but that doesn't make any sense. The crtc device should
> take care of the CRTC functions. Your DRM CRTC and encoders can
> definitely be shared across different devices, you can have a look at
> how we're doing it for sun4i.
>
> We basically have 3 drivers to create most of the display pipeline:
> - One for the DRM device
> - One for the display engine
> - One for the TCON
Your DRM device is useless. It is simpler to have the DRM device as the
display engine.
Also, maybe, you have not the constraint the DE being shared between
2 CRTCs.
> Once they have all loaded and registered in the component framework,
> their bind callback is called, and it's when the DRM entities are
> created using exported functions to manipulate what needs to be setup.
>
> It's definitely doable, it just takes some effort.
It seems you did not look at what I have coded...
> > On the other side, removing the cursor would just let one more plane.
> > Do we really need this one? In other words, I'd be pleased to know how
> > you run 7 applications doing video overlay.
>
> You can use those planes to do composition too, with each application
> having one or more plane. Android uses that.
>
> There's no argument to have a cursor plane, really. Even regular
> graphic stack like X can use a regular overlay to have its cursor on
> it. It doesn't *remove* anything, it just allows to use the plane for
> what it was supposed to be used for.
I'd be glad to know how you can have a hardware cursor without defining
it in drm_crtc_init_with_planes().
--
Ken ar c'henta? | ** Breizh ha Linux atav! **
Jef | http://moinejf.free.fr/
^ permalink raw reply
* [PATCH 0/3] thermal: Fix module autoload for drivers
From: Javier Martinez Canillas @ 2016-11-17 14:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161117145327.GA2781@localhost.localdomain>
Hello Eduardo,
On 11/17/2016 11:53 AM, Eduardo Valentin wrote:
> On Thu, Nov 17, 2016 at 08:50:11AM -0300, Javier Martinez Canillas wrote:
>> Hello Eduardo,
>>
>> On Fri, Oct 14, 2016 at 11:34 AM, Javier Martinez Canillas
>> <javier@osg.samsung.com> wrote:
>>> Hello,
>>>
>>> This small series contains trivial fixes to allow modules to be autoloaded
>>> when its correspoinding thermal device is registered.
>>>
>>> Best regards,
>>> Javier
>>>
>>>
>>> Javier Martinez Canillas (3):
>>> thermal: max77620: Fix module autoload
>>> thermal: tango: Fix module autoload
>>> thermal: db8500: Fix module autoload
>>>
>>
>> Any comments about these patches?
>
> So far no. I am finalizing a couple of automated testing, but they are
> in my queue.
>
Ok, I also got your automated emails about them being applied.
> Thanks for the fixes.
>
Thanks.
> BR,
>
>>
>> Best regards,
>> Javier
Best regards,
--
Javier Martinez Canillas
Open Source Group
Samsung Research America
^ permalink raw reply
* Boot failures in -next due to 'ARM: dts: imx: Remove skeleton.dtsi'
From: Mark Rutland @ 2016-11-17 15:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <198d764e-1612-81b4-5f4e-0c221a23c8e0@roeck-us.net>
On Thu, Nov 17, 2016 at 06:44:55AM -0800, Guenter Roeck wrote:
> On 11/17/2016 02:55 AM, Mark Rutland wrote:
> >On Wed, Nov 16, 2016 at 02:40:24PM -0800, Guenter Roeck wrote:
> >>On Wed, Nov 16, 2016 at 08:27:09PM -0200, Fabio Estevam wrote:
> >>>Hi Guenter,
> >>>
> >>>On Wed, Nov 16, 2016 at 8:10 PM, Guenter Roeck <linux@roeck-us.net> wrote:
> >>>>
> >>>>Anyway, I guess the problem is that the "official" dtb files no longer provide
> >>>>the skeleton /chosen and /memory nodes (and maybe others), and qemu seems to
> >>>>expect that they are provided. Is that correct ?
> >>>
> >>>imx6qdl-sabrelite.dtsi provides chosen and memory nodes.
> >>
> >>Yes, but not the 'device_type' property, which the kernel seems to expect.
> >
> >Memory nodes require this property per ePAPR and the devicetree.org
> >spec, so the bug is that we didn't add those when removing the
> >skeleton.dtsi include.
>
> The downside from qemu perspective is that the real hardware seems
> to add the property unconditionally, or the boot failure would have
> been seen there as well.
>
> I submitted https://patchwork.ozlabs.org/patch/695951/; we'll see how it goes.
Sure, the firmare/bootlaoder you're using may add this automatically.
My worry is that adding this to a generic file in QEMU only serves to
mask this class of bug for other boards (i.e. they'll work fine in QEMU,
but not on real HW using whatever bootlaoder happens ot be there).
Thanks,
Mark.
^ permalink raw reply
* [PATCH V8 2/6] thermal: bcm2835: add thermal driver for bcm2835 soc
From: Eduardo Valentin @ 2016-11-17 15:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <766e1b70-d83a-eb52-fa2b-aec435e85673@martin.sperl.org>
Hello Martin,
On Thu, Nov 17, 2016 at 10:51:33AM +0100, Martin Sperl wrote:
>
>
> On 17.11.2016 03:11, Eduardo Valentin wrote:
> >Hey Martin,
> >
> >Very sorry for the late feedback. Not so sure if this one got queued
> >already or not. Anyways, just minor questions as follows:
> >
> >On Wed, Nov 02, 2016 at 10:18:22AM +0000, kernel at martin.sperl.org wrote:
> >>From: Martin Sperl <kernel@martin.sperl.org>
> >>
> >>Add basic thermal driver for bcm2835 SOC.
> >>
> >>This driver currently relies on the firmware setting up the
> >>tsense HW block and does not set it up itself.
> >>
> >>Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
> >>Acked-by: Eric Anholt <eric@anholt.net>
> >>Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
> >>
> ...
> >>+static int bcm2835_thermal_adc2temp(
> >>+ const struct bcm2835_thermal_info *info, u32 adc)
> >>+{
> >>+ return info->offset + (adc * info->slope);
> >
> >Any specific reason we cannot use thermal_zone_params->slope and
> >thermal_zone_params->offset?
>
> You could - the patch was just rebased to 4.9 and those slope and
> offset just got merged during this cycle.
>
> Do we really need to modify it - the patch has been around since 4.6.
>
> >>+
> >>+static int bcm2835_thermal_get_trip_temp(
> >>+ struct thermal_zone_device *tz, int trip, int *temp)
> >>+{
> >>+ struct bcm2835_thermal_data *data = tz->devdata;
> >>+ u32 val = readl(data->regs + BCM2835_TS_TSENSCTL);
> >>+
> >>+ /* get the THOLD bits */
> >>+ val &= BCM2835_TS_TSENSCTL_THOLD_MASK;
> >>+ val >>= BCM2835_TS_TSENSCTL_THOLD_SHIFT;
> >>+
> >>+ /* if it is zero then use the info value */
> >>+ if (val)
> >
> >Is this a read only register or is this driver supposed to program it?
> >In which scenario it would be 0? Can this be added as comments?
>
> It is RW, but the Firmware typically sets up the thermal device with the
> correct values already - this is just a fallback.
OK, but how do you differentiate from a buggy firmware or misconfigured
hardware? How do you know if the firmware is supposed to be loaded and
ready? There is no firmware loading in this driver. Also, there is no
dependency with a driver that loads firmware, or at least, I missed it.
>
> >>+static int bcm2835_thermal_get_temp(struct thermal_zone_device *tz,
> >>+ int *temp)
> >>+{
> >>+ struct bcm2835_thermal_data *data = tz->devdata;
> >>+ u32 val = readl(data->regs + BCM2835_TS_TSENSSTAT);
> >>+
> >>+ if (!(val & BCM2835_TS_TSENSSTAT_VALID))
> >
> >What cases you would get the valid bit not set? Do you need to wait for
> >the conversion to finish?
>
> I guess: if you have just enabled the HW-block (which the FW does much
> in advance) and start to read the value immediately (before the first sample
> period has finished), then this will not be valid.
>
Then again, how does this driver make sure the initialization procedure
is correct, and that by the time it is using the hardware, the hardware
is in a sane state?
Back to the original question, does it mean the hardware is in
some sort of continuous ADC conversion mode or reading the temperature
requires specific steps to get the conversion done, and therefore you
are checking the valid bit here?
> So do you need another version of the patchset that uses that new API?
I think the API usage is change that can be done together with
clarification for the above questions too: on hardware state,
firmware loading, maybe a master driver dependency, and the ADC
conversion sequence, which are not well clear to me on this driver. As long as
this is clarified and documented in the code (can be simple comments so
it is clear to whoever reads in the future), then I would be OK with
this driver.
>
> Thanks,
> Martin
^ permalink raw reply
* [PATCH] arm64: mm: Fix memmap to be initialized for the entire section
From: Robert Richter @ 2016-11-17 15:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161117142528.GJ22855@arm.com>
Thanks for your answer.
On 17.11.16 14:25:29, Will Deacon wrote:
> On Wed, Nov 09, 2016 at 08:51:32PM +0100, Robert Richter wrote:
> > Thus, I don't see where my patch breaks code. Even acpi_os_ioremap()
> > keeps the same behaviour as before since it still uses memblock_is_
> > memory(). Could you more describe your concerns why do you think this
> > patch breaks the kernel and moves the problem somewhere else? I
> > believe it fixes the problem at all.
>
> acpi_os_ioremap always ends up in __ioremap_caller, regardless of
> memblock_is_memory(). __ioremap_caller then fails if pfn_valid is true.
But that's the reason my patch changed the code to use memblock_is_
map_memory() instead. I was looking into the users of pfn_valid() esp.
in arm64 code and changed it where required.
This week I looked into the kernel again for code that might break by
a pfn_valid() change. I found try_ram_remap() in memremap.c that has
changed behaviour now, but this is explicit for MEMREMAP_WB, so it
should be fine.
Maybe it might be better to use page_is_ram() in addition to
pfn_valid() where necessary. This should work now after commit:
e7cd190385d1 arm64: mark reserved memblock regions explicitly in iomem
I still think pfn_valid() is not the correct use to determine the mem
attributes for mappings, there are further checks required.
The risk of breaking something with my patch is small and limited only
to the mapping of efi reserved regions (which is the state of 4.4). If
something breaks anyway it can easily be fixed by adding more checks
to pfn_valid() as suggested above.
-Robert
^ permalink raw reply
* [PATCH] ARM: qcom_defconfig: Enable RPM/RPM-SMD clocks
From: Georgi Djakov @ 2016-11-17 15:20 UTC (permalink / raw)
To: linux-arm-kernel
Enable support for clocks, controlled by the RPM processor on
Qualcomm platforms.
Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---
arch/arm/configs/qcom_defconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index 9f6d2a69a6f7..553d0a5827f2 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -158,6 +158,8 @@ CONFIG_DMADEVICES=y
CONFIG_QCOM_BAM_DMA=y
CONFIG_STAGING=y
CONFIG_COMMON_CLK_QCOM=y
+CONFIG_QCOM_CLK_RPM=y
+CONFIG_QCOM_CLK_SMD_RPM=y
CONFIG_APQ_MMCC_8084=y
CONFIG_IPQ_LCC_806X=y
CONFIG_MSM_GCC_8660=y
^ permalink raw reply related
* [PATCH -next] ARM: dts: omap5: replace gpio-key,wakeup with wakeup-source property
From: Tony Lindgren @ 2016-11-17 15:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479138250-17780-1-git-send-email-sudeep.holla@arm.com>
* Sudeep Holla <sudeep.holla@arm.com> [161114 07:44]:
> Though the keyboard driver for GPIO buttons(gpio-keys) will continue to
> check for/support the legacy "gpio-key,wakeup" boolean property to
> enable gpio buttons as wakeup source, "wakeup-source" is the new
> standard binding.
>
> This patch replaces the legacy "gpio-key,wakeup" with the unified
> "wakeup-source" property in order to avoid any further copy-paste
> duplication.
>
> Cc: "Beno?t Cousson" <bcousson@baylibre.com>
> Cc: Tony Lindgren <tony@atomide.com>
> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> ---
> arch/arm/boot/dts/omap5-uevm.dts | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> Hi,
>
> Inspite of getting rid of most of the legacy property almost a year ago,
> addition of new platforms have brought this back and over time it's
> now found again in few places. Just get rid of them *again*
Thanks for the annual check up :)
Acked-by: Tony Lindgren <tony@atomide.com>
Please let me know if you want me to pick this up instead.
> diff --git a/arch/arm/boot/dts/omap5-uevm.dts b/arch/arm/boot/dts/omap5-uevm.dts
> index 2fcdc516da45..a8c72611fbe3 100644
> --- a/arch/arm/boot/dts/omap5-uevm.dts
> +++ b/arch/arm/boot/dts/omap5-uevm.dts
> @@ -41,7 +41,7 @@
> label = "BTN1";
> linux,code = <169>;
> gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; /* gpio3_83 */
> - gpio-key,wakeup;
> + wakeup-source;
> autorepeat;
> debounce_interval = <50>;
> };
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH -next] ARM: dts: omap5: replace gpio-key,wakeup with wakeup-source property
From: Sudeep Holla @ 2016-11-17 15:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161117152717.GS4082@atomide.com>
On 17/11/16 15:27, Tony Lindgren wrote:
> * Sudeep Holla <sudeep.holla@arm.com> [161114 07:44]:
>> Though the keyboard driver for GPIO buttons(gpio-keys) will continue to
>> check for/support the legacy "gpio-key,wakeup" boolean property to
>> enable gpio buttons as wakeup source, "wakeup-source" is the new
>> standard binding.
>>
>> This patch replaces the legacy "gpio-key,wakeup" with the unified
>> "wakeup-source" property in order to avoid any further copy-paste
>> duplication.
>>
>> Cc: "Beno?t Cousson" <bcousson@baylibre.com>
>> Cc: Tony Lindgren <tony@atomide.com>
>> Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
>> ---
>> arch/arm/boot/dts/omap5-uevm.dts | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> Hi,
>>
>> Inspite of getting rid of most of the legacy property almost a year ago,
>> addition of new platforms have brought this back and over time it's
>> now found again in few places. Just get rid of them *again*
>
> Thanks for the annual check up :)
>
> Acked-by: Tony Lindgren <tony@atomide.com>
>
> Please let me know if you want me to pick this up instead.
Yes that would be better. Also it's present only in your -next,
looks like something newly added via commit 2d46c0c60725 ("ARM:
dts: omap5 uevm: add USR1 button")
--
Regards,
Sudeep
^ permalink raw reply
* [PATCH v4] arm64: dts: qcom: Add msm8916 CoreSight components
From: Georgi Djakov @ 2016-11-17 15:35 UTC (permalink / raw)
To: linux-arm-kernel
From: "Ivan T. Ivanov" <ivan.ivanov@linaro.org>
Add initial set of CoreSight components found on Qualcomm's 8x16 chipset.
Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---
This patch was on hold for some time, as it has a dependency on RPM clocks,
which is now merged into clk-next.
Changes since v3: (https://lkml.org/lkml/2015/5/11/134)
* Include msm8916-coresight.dtsi into msm8916.dtsi
Changes since v2: (https://lkml.org/lkml/2015/4/29/242)
* Added "1x" to "qcom,coresight-replicator" compatible string, to match what
devicetree bindings documentations says.
arch/arm64/boot/dts/qcom/msm8916-coresight.dtsi | 254 ++++++++++++++++++++++++
arch/arm64/boot/dts/qcom/msm8916.dtsi | 2 +
2 files changed, 256 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/msm8916-coresight.dtsi
diff --git a/arch/arm64/boot/dts/qcom/msm8916-coresight.dtsi b/arch/arm64/boot/dts/qcom/msm8916-coresight.dtsi
new file mode 100644
index 000000000000..900f1f484a0a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8916-coresight.dtsi
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2013 - 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+
+&soc {
+
+ tpiu at 820000 {
+ compatible = "arm,coresight-tpiu", "arm,primecell";
+ reg = <0x820000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+
+ port {
+ tpiu_in: endpoint {
+ slave-mode;
+ remote-endpoint = <&replicator_out1>;
+ };
+ };
+ };
+
+ funnel at 821000 {
+ compatible = "arm,coresight-funnel", "arm,primecell";
+ reg = <0x821000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * Not described input ports:
+ * 0 - connected to Resource and Power Manger CPU ETM
+ * 1 - not-connected
+ * 2 - connected to Modem CPU ETM
+ * 3 - not-connected
+ * 5 - not-connected
+ * 6 - connected trought funnel to Wireless CPU ETM
+ * 7 - connected to STM component
+ */
+ port at 4 {
+ reg = <4>;
+ funnel0_in4: endpoint {
+ slave-mode;
+ remote-endpoint = <&funnel1_out>;
+ };
+ };
+ port at 8 {
+ reg = <0>;
+ funnel0_out: endpoint {
+ remote-endpoint = <&etf_in>;
+ };
+ };
+ };
+ };
+
+ replicator at 824000 {
+ compatible = "qcom,coresight-replicator1x", "arm,primecell";
+ reg = <0x824000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port at 0 {
+ reg = <0>;
+ replicator_out0: endpoint {
+ remote-endpoint = <&etr_in>;
+ };
+ };
+ port at 1 {
+ reg = <1>;
+ replicator_out1: endpoint {
+ remote-endpoint = <&tpiu_in>;
+ };
+ };
+ port at 2 {
+ reg = <0>;
+ replicator_in: endpoint {
+ slave-mode;
+ remote-endpoint = <&etf_out>;
+ };
+ };
+ };
+ };
+
+ etf at 825000 {
+ compatible = "arm,coresight-tmc", "arm,primecell";
+ reg = <0x825000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port at 0 {
+ reg = <0>;
+ etf_out: endpoint {
+ slave-mode;
+ remote-endpoint = <&funnel0_out>;
+ };
+ };
+ port at 1 {
+ reg = <0>;
+ etf_in: endpoint {
+ remote-endpoint = <&replicator_in>;
+ };
+ };
+ };
+ };
+
+ etr at 826000 {
+ compatible = "arm,coresight-tmc", "arm,primecell";
+ reg = <0x826000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+
+ port {
+ etr_in: endpoint {
+ slave-mode;
+ remote-endpoint = <&replicator_out0>;
+ };
+ };
+ };
+
+ funnel at 841000 { /* APSS funnel only 4 inputs are used */
+ compatible = "arm,coresight-funnel", "arm,primecell";
+ reg = <0x841000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port at 0 {
+ reg = <0>;
+ funnel1_in0: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm0_out>;
+ };
+ };
+ port at 1 {
+ reg = <1>;
+ funnel1_in1: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm1_out>;
+ };
+ };
+ port at 2 {
+ reg = <2>;
+ funnel1_in2: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm2_out>;
+ };
+ };
+ port at 3 {
+ reg = <3>;
+ funnel1_in3: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm3_out>;
+ };
+ };
+ port at 4 {
+ reg = <0>;
+ funnel1_out: endpoint {
+ remote-endpoint = <&funnel0_in4>;
+ };
+ };
+ };
+ };
+
+ etm at 85c000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0x85c000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+
+ cpu = <&CPU0>;
+
+ port {
+ etm0_out: endpoint {
+ remote-endpoint = <&funnel1_in0>;
+ };
+ };
+ };
+
+ etm at 85d000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0x85d000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+
+ cpu = <&CPU1>;
+
+ port {
+ etm1_out: endpoint {
+ remote-endpoint = <&funnel1_in1>;
+ };
+ };
+ };
+
+ etm at 85e000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0x85e000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+
+ cpu = <&CPU2>;
+
+ port {
+ etm2_out: endpoint {
+ remote-endpoint = <&funnel1_in2>;
+ };
+ };
+ };
+
+ etm at 85f000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0x85f000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "atclk";
+
+ cpu = <&CPU3>;
+
+ port {
+ etm3_out: endpoint {
+ remote-endpoint = <&funnel1_in3>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi
index 4221b7d2c0ce..bfaeb9364190 100644
--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -14,6 +14,7 @@
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/qcom,gcc-msm8916.h>
#include <dt-bindings/reset/qcom,gcc-msm8916.h>
+#include <dt-bindings/clock/qcom,rpmcc.h>
/ {
model = "Qualcomm Technologies, Inc. MSM8916";
@@ -993,4 +994,5 @@
};
};
+#include "msm8916-coresight.dtsi"
#include "msm8916-pins.dtsi"
^ permalink raw reply related
* [PATCH] ARM: dts: qcom: Add apq8064 CoreSight components
From: Georgi Djakov @ 2016-11-17 15:36 UTC (permalink / raw)
To: linux-arm-kernel
From: "Ivan T. Ivanov" <ivan.ivanov@linaro.org>
Add initial set of CoreSight components found on Qualcomm's
8064 chipset.
Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---
arch/arm/boot/dts/qcom-apq8064-coresight.dtsi | 196 ++++++++++++++++++++++++++
arch/arm/boot/dts/qcom-apq8064.dtsi | 11 +-
2 files changed, 203 insertions(+), 4 deletions(-)
create mode 100644 arch/arm/boot/dts/qcom-apq8064-coresight.dtsi
diff --git a/arch/arm/boot/dts/qcom-apq8064-coresight.dtsi b/arch/arm/boot/dts/qcom-apq8064-coresight.dtsi
new file mode 100644
index 000000000000..9395fddb1bf0
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-apq8064-coresight.dtsi
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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.
+ */
+
+&soc {
+
+ etb at 1a01000 {
+ compatible = "coresight-etb10", "arm,primecell";
+ reg = <0x1a01000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>;
+ clock-names = "apb_pclk";
+
+ port {
+ etb_in: endpoint {
+ slave-mode;
+ remote-endpoint = <&replicator_out0>;
+ };
+ };
+ };
+
+ tpiu at 1a03000 {
+ compatible = "arm,coresight-tpiu", "arm,primecell";
+ reg = <0x1a03000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>;
+ clock-names = "apb_pclk";
+
+ port {
+ tpiu_in: endpoint {
+ slave-mode;
+ remote-endpoint = <&replicator_out1>;
+ };
+ };
+ };
+
+ replicator {
+ compatible = "arm,coresight-replicator";
+
+ clocks = <&rpmcc RPM_QDSS_CLK>;
+ clock-names = "apb_pclk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port at 0 {
+ reg = <0>;
+ replicator_out0: endpoint {
+ remote-endpoint = <&etb_in>;
+ };
+ };
+ port at 1 {
+ reg = <1>;
+ replicator_out1: endpoint {
+ remote-endpoint = <&tpiu_in>;
+ };
+ };
+ port at 2 {
+ reg = <0>;
+ replicator_in: endpoint {
+ slave-mode;
+ remote-endpoint = <&funnel_out>;
+ };
+ };
+ };
+ };
+
+ funnel at 1a04000 {
+ compatible = "arm,coresight-funnel", "arm,primecell";
+ reg = <0x1a04000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>;
+ clock-names = "apb_pclk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /*
+ * Not described input ports:
+ * 2 - connected to STM component
+ * 3 - not-connected
+ * 6 - not-connected
+ * 7 - not-connected
+ */
+ port at 0 {
+ reg = <0>;
+ funnel_in0: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm0_out>;
+ };
+ };
+ port at 1 {
+ reg = <1>;
+ funnel_in1: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm1_out>;
+ };
+ };
+ port at 4 {
+ reg = <4>;
+ funnel_in4: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm2_out>;
+ };
+ };
+ port at 5 {
+ reg = <5>;
+ funnel_in5: endpoint {
+ slave-mode;
+ remote-endpoint = <&etm3_out>;
+ };
+ };
+ port at 8 {
+ reg = <0>;
+ funnel_out: endpoint {
+ remote-endpoint = <&replicator_in>;
+ };
+ };
+ };
+ };
+
+ etm at 1a1c000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0x1a1c000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>;
+ clock-names = "apb_pclk";
+
+ cpu = <&CPU0>;
+
+ port {
+ etm0_out: endpoint {
+ remote-endpoint = <&funnel_in0>;
+ };
+ };
+ };
+
+ etm at 1a1d000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0x1a1d000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>;
+ clock-names = "apb_pclk";
+
+ cpu = <&CPU1>;
+
+ port {
+ etm1_out: endpoint {
+ remote-endpoint = <&funnel_in1>;
+ };
+ };
+ };
+
+ etm at 1a1e000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0x1a1e000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>;
+ clock-names = "apb_pclk";
+
+ cpu = <&CPU2>;
+
+ port {
+ etm2_out: endpoint {
+ remote-endpoint = <&funnel_in4>;
+ };
+ };
+ };
+
+ etm at 1a1f000 {
+ compatible = "arm,coresight-etm3x", "arm,primecell";
+ reg = <0x1a1f000 0x1000>;
+
+ clocks = <&rpmcc RPM_QDSS_CLK>;
+ clock-names = "apb_pclk";
+
+ cpu = <&CPU3>;
+
+ port {
+ etm3_out: endpoint {
+ remote-endpoint = <&funnel_in5>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
index 268bd470c865..18469c632e2f 100644
--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
+++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
@@ -4,6 +4,7 @@
#include <dt-bindings/clock/qcom,gcc-msm8960.h>
#include <dt-bindings/reset/qcom,gcc-msm8960.h>
#include <dt-bindings/clock/qcom,mmcc-msm8960.h>
+#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/soc/qcom,gsbi.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -27,7 +28,7 @@
#address-cells = <1>;
#size-cells = <0>;
- cpu at 0 {
+ CPU0: cpu at 0 {
compatible = "qcom,krait";
enable-method = "qcom,kpss-acc-v1";
device_type = "cpu";
@@ -38,7 +39,7 @@
cpu-idle-states = <&CPU_SPC>;
};
- cpu at 1 {
+ CPU1: cpu at 1 {
compatible = "qcom,krait";
enable-method = "qcom,kpss-acc-v1";
device_type = "cpu";
@@ -49,7 +50,7 @@
cpu-idle-states = <&CPU_SPC>;
};
- cpu at 2 {
+ CPU2: cpu at 2 {
compatible = "qcom,krait";
enable-method = "qcom,kpss-acc-v1";
device_type = "cpu";
@@ -60,7 +61,7 @@
cpu-idle-states = <&CPU_SPC>;
};
- cpu at 3 {
+ CPU3: cpu at 3 {
compatible = "qcom,krait";
enable-method = "qcom,kpss-acc-v1";
device_type = "cpu";
@@ -1418,4 +1419,6 @@
};
};
};
+
+#include "qcom-apq8064-coresight.dtsi"
#include "qcom-apq8064-pins.dtsi"
^ permalink raw reply related
* [PATCH] ARM: Drop fixed 200 Hz timer requirement from Exynos platforms
From: Javier Martinez Canillas @ 2016-11-17 15:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479148025-469-1-git-send-email-krzk@kernel.org>
Hello Krzysztof,
On 11/14/2016 03:27 PM, Krzysztof Kozlowski wrote:
> All Samsung platforms, including the Exynos, are selecting HZ_FIXED with
> 200 Hz. Unfortunately in case of multiplatform image this affects also
> other platforms when Exynos is selected.
>
> This looks like an very old legacy code, dating back to initial
> upstreaming of S3C24xx. Probably it was required for s3c24xx timer
> driver, which was removed in commit ad38bdd15d5b ("ARM: SAMSUNG: Remove
> unused plat-samsung/time.c").
>
> Since then, this fixed 200 Hz spread everywhere, including out-of-tree
> Samsung kernels (SoC vendor's and Tizen's). I believe this choice
> was rather an effect of coincidence instead of conscious choice. In
> fact Exynos can work with different timers.
>
> Few perf mem and sched tests on Odroid XU3 board (Exynos5422, 4x Cortex
> A7, 4x Cortex A15) show no regressions when switching from 200 Hz to
> other values.
>
> Reported-by: Lee Jones <lee.jones@linaro.org>
> Reported-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
>
> ---
>
> Testing on other Exynos platforms would be appreciated.
I tested this patch on an Exynos5800 Peach Pi Chromebook with different
HZ values (100/200/250/300/500/1000), and found no issues.
Tested-by: Javier Martinez Canillas <javier@osg.samsung.com>
Best regards,
--
Javier Martinez Canillas
Open Source Group
Samsung Research America
^ permalink raw reply
* [PATCH -next] ARM: dts: omap5: replace gpio-key,wakeup with wakeup-source property
From: Tony Lindgren @ 2016-11-17 15:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8d06724a-98af-05ab-f5a8-07c552722fca@arm.com>
* Sudeep Holla <sudeep.holla@arm.com> [161117 07:32]:
>
>
> On 17/11/16 15:27, Tony Lindgren wrote:
> > * Sudeep Holla <sudeep.holla@arm.com> [161114 07:44]:
> > > Though the keyboard driver for GPIO buttons(gpio-keys) will continue to
> > > check for/support the legacy "gpio-key,wakeup" boolean property to
> > > enable gpio buttons as wakeup source, "wakeup-source" is the new
> > > standard binding.
> > >
> > > This patch replaces the legacy "gpio-key,wakeup" with the unified
> > > "wakeup-source" property in order to avoid any further copy-paste
> > > duplication.
> > >
> > > Cc: "Beno?t Cousson" <bcousson@baylibre.com>
> > > Cc: Tony Lindgren <tony@atomide.com>
> > > Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
> > > ---
> > > arch/arm/boot/dts/omap5-uevm.dts | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > Hi,
> > >
> > > Inspite of getting rid of most of the legacy property almost a year ago,
> > > addition of new platforms have brought this back and over time it's
> > > now found again in few places. Just get rid of them *again*
> >
> > Thanks for the annual check up :)
> >
> > Acked-by: Tony Lindgren <tony@atomide.com>
> >
> > Please let me know if you want me to pick this up instead.
>
> Yes that would be better. Also it's present only in your -next,
> looks like something newly added via commit 2d46c0c60725 ("ARM:
> dts: omap5 uevm: add USR1 button")
OK applied into omap-for-v4.10/dt:omap-for-v4.10/dt thanks.
Tony
^ permalink raw reply
* ILP32 for ARM64: testing with glibc testsuite
From: Catalin Marinas @ 2016-11-17 15:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CC4F99A7-1FD2-486A-BD66-ED06F1B8BF50@linaro.org>
On Wed, Nov 16, 2016 at 03:22:26PM +0400, Maxim Kuvyrkov wrote:
> Regarding ILP32 runtime, my opinion is that it is acceptable for ILP32
> to have extra failures compared to LP64, since these are not
> regressions, but, rather, failures of a new configuration.
I disagree with this. We definitely need to understand why they fail,
otherwise we run the risk of potential glibc or kernel implementation
bugs becoming ABI.
--
Catalin
^ permalink raw reply
* [PATCH 1/2] arm64: defconfig: enable I2C and DW MMC controller on rockchip platform
From: Heiko Stuebner @ 2016-11-17 15:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473248790-27101-1-git-send-email-andy.yan@rock-chips.com>
Am Mittwoch, 7. September 2016, 19:46:30 CET schrieb Andy Yan:
> I2C and MMC are very basic modules for a board to bootup, as I2C always
> used to configure PMIC and MMC devices often used to store filesytem.
> So enable them here to let the rockchip based arm64 boards can bootup.
>
> Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
applied to a defconfig64 branch, after moving I2C_RK3X between QUP and TEGRA
RCAR seems to be an exception to the otherwise alphabetically sorted list.
Heiko
^ permalink raw reply
* [PATCH v8 6/7] arm/arm64: vgic: Implement VGICv3 CPU interface access
From: Vijay Kilari @ 2016-11-17 15:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161116185232.GF3811@cbox>
On Thu, Nov 17, 2016 at 12:22 AM, Christoffer Dall
<christoffer.dall@linaro.org> wrote:
> On Fri, Nov 04, 2016 at 04:43:32PM +0530, vijay.kilari at gmail.com wrote:
>> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
>>
>> VGICv3 CPU interface registers are accessed using
>> KVM_DEV_ARM_VGIC_CPU_SYSREGS ioctl. These registers are accessed
>> as 64-bit. The cpu MPIDR value is passed along with register id.
>> is used to identify the cpu for registers access.
>>
>> The version of VGIC v3 specification is define here
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/445611.html
>>
>> Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
>> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
>> ---
>> arch/arm64/include/uapi/asm/kvm.h | 3 +
>> arch/arm64/kvm/Makefile | 1 +
>> include/kvm/arm_vgic.h | 9 +
>> virt/kvm/arm/vgic/vgic-kvm-device.c | 27 +++
>> virt/kvm/arm/vgic/vgic-mmio-v3.c | 19 +++
>> virt/kvm/arm/vgic/vgic-sys-reg-v3.c | 324 ++++++++++++++++++++++++++++++++++++
>> virt/kvm/arm/vgic/vgic-v3.c | 8 +
>> virt/kvm/arm/vgic/vgic.h | 4 +
>> 8 files changed, 395 insertions(+)
>>
>> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
>> index 56dc08d..91c7137 100644
>> --- a/arch/arm64/include/uapi/asm/kvm.h
>> +++ b/arch/arm64/include/uapi/asm/kvm.h
>> @@ -206,9 +206,12 @@ struct kvm_arch_memory_slot {
>> (0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
>> #define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
>> #define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
>> +#define KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0xffff)
>> #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
>> #define KVM_DEV_ARM_VGIC_GRP_CTRL 4
>> #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
>> +#define KVM_DEV_ARM_VGIC_CPU_SYSREGS 6
>> +
>> #define KVM_DEV_ARM_VGIC_CTRL_INIT 0
>>
>> /* Device Control API on vcpu fd */
>> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
>> index d50a82a..1a14e29 100644
>> --- a/arch/arm64/kvm/Makefile
>> +++ b/arch/arm64/kvm/Makefile
>> @@ -32,5 +32,6 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v3.o
>> kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-kvm-device.o
>> kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-its.o
>> kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/irqchip.o
>> +kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-sys-reg-v3.o
>
> Thi is making me wonder: Are we properly handling GICv3 save/restore
> for AArch32 now that we have GICv3 support for AArch32? By properly I
> mean that either it is clearly only supported on AArch64 systems or it's
> supported on both AArch64 and AArch32, but it shouldn't break randomly
> on AArch32.
It supports both AArch64 and AArch64 in handling of system registers
save/restore.
All system registers that we save/restore are 32-bit for both aarch64
and aarch32.
Though opcode op0 should be zero for aarch32, the remaining Op and CRn codes
are same. However the codes sent by qemu is matched and register
are handled properly irrespective of AArch32 or AArch64.
I don't have platform which support AArch32 guests to verify.
>
>> kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
>> kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index 002f092..730a18a 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -71,6 +71,9 @@ struct vgic_global {
>>
>> /* GIC system register CPU interface */
>> struct static_key_false gicv3_cpuif;
>> +
>> + /* Cache ICH_VTR_EL2 reg value */
>> + u32 ich_vtr_el2;
>> };
>>
>> extern struct vgic_global kvm_vgic_global_state;
>> @@ -269,6 +272,12 @@ struct vgic_cpu {
>> u64 pendbaser;
>>
>> bool lpis_enabled;
>> +
>> + /* Cache guest priority bits */
>> + u32 num_pri_bits;
>> +
>> + /* Cache guest interrupt ID bits */
>> + u32 num_id_bits;
>> };
>>
>> extern struct static_key_false vgic_v2_cpuif_trap;
>> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> index 6c7d30c..da532d1 100644
>> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
>> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
>> @@ -504,6 +504,14 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
>> if (!is_write)
>> *reg = tmp32;
>> break;
>> + case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
>> + u64 regid;
>> +
>> + regid = (attr->attr & KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK);
>> + ret = vgic_v3_cpu_sysregs_uaccess(vcpu, is_write,
>> + regid, reg);
>> + break;
>> + }
>> default:
>> ret = -EINVAL;
>> break;
>> @@ -537,6 +545,15 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
>> reg = tmp32;
>> return vgic_v3_attr_regs_access(dev, attr, ®, true);
>> }
>> + case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
>> + u64 __user *uaddr = (u64 __user *)(long)attr->addr;
>> + u64 reg;
>> +
>> + if (get_user(reg, uaddr))
>> + return -EFAULT;
>> +
>> + return vgic_v3_attr_regs_access(dev, attr, ®, true);
>> + }
>> }
>> return -ENXIO;
>> }
>> @@ -563,6 +580,15 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
>> tmp32 = reg;
>> return put_user(tmp32, uaddr);
>> }
>> + case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
>> + u64 __user *uaddr = (u64 __user *)(long)attr->addr;
>> + u64 reg;
>> +
>> + ret = vgic_v3_attr_regs_access(dev, attr, ®, false);
>> + if (ret)
>> + return ret;
>> + return put_user(reg, uaddr);
>> + }
>> }
>>
>> return -ENXIO;
>> @@ -581,6 +607,7 @@ static int vgic_v3_has_attr(struct kvm_device *dev,
>> break;
>> case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
>> case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
>> + case KVM_DEV_ARM_VGIC_CPU_SYSREGS:
>> return vgic_v3_has_attr_regs(dev, attr);
>> case KVM_DEV_ARM_VGIC_GRP_NR_IRQS:
>> return 0;
>> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> index b35fb83..519b919 100644
>> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
>> @@ -23,6 +23,7 @@
>>
>> #include "vgic.h"
>> #include "vgic-mmio.h"
>> +#include "sys_regs.h"
>>
>> /* extract @num bytes at @offset bytes offset in data */
>> unsigned long extract_bytes(u64 data, unsigned int offset,
>> @@ -639,6 +640,24 @@ int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
>> nr_regions = ARRAY_SIZE(vgic_v3_rdbase_registers);
>> break;
>> }
>> + case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
>> + u64 reg, id;
>> + unsigned long vgic_mpidr, mpidr_reg;
>> + struct kvm_vcpu *vcpu;
>> +
>> + vgic_mpidr = (attr->attr & KVM_DEV_ARM_VGIC_V3_MPIDR_MASK) >>
>> + KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT;
>> +
>> + /* Convert plain mpidr value to MPIDR reg format */
>> + mpidr_reg = VGIC_TO_MPIDR(vgic_mpidr);
>> +
>> + vcpu = kvm_mpidr_to_vcpu(dev->kvm, mpidr_reg);
>> + if (!vcpu)
>> + return -EINVAL;
>> +
>> + id = (attr->attr & KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK);
>> + return vgic_v3_has_cpu_sysregs_attr(vcpu, 0, id, ®);
>> + }
>> default:
>> return -ENXIO;
>> }
>> diff --git a/virt/kvm/arm/vgic/vgic-sys-reg-v3.c b/virt/kvm/arm/vgic/vgic-sys-reg-v3.c
>> new file mode 100644
>> index 0000000..69d8597
>> --- /dev/null
>> +++ b/virt/kvm/arm/vgic/vgic-sys-reg-v3.c
>
> Shouldn't we have a GPL header here?
>
>> @@ -0,0 +1,324 @@
>> +#include <linux/irqchip/arm-gic-v3.h>
>> +#include <linux/kvm.h>
>> +#include <linux/kvm_host.h>
>> +#include <kvm/iodev.h>
>> +#include <kvm/arm_vgic.h>
>> +#include <asm/kvm_emulate.h>
>> +#include <asm/kvm_arm.h>
>> +#include <asm/kvm_mmu.h>
>> +
>> +#include "vgic.h"
>> +#include "vgic-mmio.h"
>> +#include "sys_regs.h"
>> +
>> +static bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>> + const struct sys_reg_desc *r)
>> +{
>> + struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu;
>> + struct vgic_vmcr vmcr;
>> + u64 val;
>> + u32 num_pri_bits, num_id_bits;
>> +
>> + vgic_get_vmcr(vcpu, &vmcr);
>> + if (p->is_write) {
>> + val = p->regval;
>> +
>> + /*
>> + * Does not allow update of ICC_CTLR_EL1 if HW does not support
>> + * guest programmed ID and PRI bits
>> + */
>
> I would suggest rewording this comment:
> Disallow restoring VM state not supported by this hardware.
>
>> + num_pri_bits = ((val & ICC_CTLR_EL1_PRI_BITS_MASK) >>
>> + ICC_CTLR_EL1_PRI_BITS_SHIFT) + 1;
>> + if (num_pri_bits > vgic_v3_cpu->num_pri_bits)
>> + return false;
>> +
>> + vgic_v3_cpu->num_pri_bits = num_pri_bits;
>
> hmmm, this looks weird to me, because vgic_v3_cpu->num_pri_bits I don't
> understand which effect this is intended to have?
>
> Sure, it may limit what you do with other registers later, but since
> there's no ordering requirement that the ctlr be restored first, I'm not
> sure it makes sense.
>
> Also, since this field is RO in the ICH_VTR, we'll have a strange
> situation during runtime after a GICv3 restore where the
> vgic_v3_cpu->num_pri_its differs from the hardware's ICH_VTR_EL2 field,
> which is never the case if you didn't do a save/restore.
Yes, but in any case, vgic_v3_cpu->num_pri_bits will be always less
than HW supported
value.
>
> Finally, should we somehow ensure that this field is set to the same
> value across VCPUs or is that not an architectural requirement?
>
Yes it is nice to have it same across VCPUs. But should be ok as
we are ensuring value is not greater than HW supported value.
There is no single point of place where we can make such a check
>> +
>> + num_id_bits = (val & ICC_CTLR_EL1_ID_BITS_MASK) >>
>> + ICC_CTLR_EL1_ID_BITS_SHIFT;
>> + if (num_id_bits > vgic_v3_cpu->num_id_bits)
>> + return false;
>> +
>> + vgic_v3_cpu->num_id_bits = num_id_bits;
>
> same questions
>
>> +
>> + vmcr.ctlr &= ~(ICH_VMCR_CBPR_MASK | ICH_VMCR_EOIM_MASK);
>> + vmcr.ctlr |= ((val & ICC_CTLR_EL1_CBPR_MASK) >>
>> + ICC_CTLR_EL1_CBPR_SHIFT) << ICH_VMCR_CBPR_SHIFT;
>> + vmcr.ctlr |= ((val & ICC_CTLR_EL1_EOImode_MASK) >>
>> + ICC_CTLR_EL1_EOImode_SHIFT) <<
>> + ICH_VMCR_EOIM_SHIFT;
>
> I'm really confused here. Is the vmcr.ctlr field in the ICC_CTLR_EL1
> format or in the VMCR format? I would assume the former, since
> otherwise I don't get the point with this indirection, and for GICv2
> vmcr.ctlr captures the GICC_CTLR value and git_set_vmcr transforms this
> into VMCR values.
>
> Having a line that says "ctlr &= ~ICH_VMCR" should make some alarm bells
> ring.
I will check and fix it.
>
>> + vgic_set_vmcr(vcpu, &vmcr);
>
> Should we check compatibility between the source and destination for the
> SEIS and A3V support here?
Can be checked. But I feel A3V check makes more sense than checking for
SEIS.
>
>> + } else {
>> + val = 0;
>> + val |= (vgic_v3_cpu->num_pri_bits - 1) <<
>> + ICC_CTLR_EL1_PRI_BITS_SHIFT;
>> + val |= vgic_v3_cpu->num_id_bits <<
>> + ICC_CTLR_EL1_ID_BITS_SHIFT;
>> + val |= ((kvm_vgic_global_state.ich_vtr_el2 &
>> + ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT) <<
>> + ICC_CTLR_EL1_SEIS_SHIFT;
>> + val |= ((kvm_vgic_global_state.ich_vtr_el2 &
>> + ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT) <<
>> + ICC_CTLR_EL1_A3V_SHIFT;
>> + val |= ((vmcr.ctlr & ICH_VMCR_CBPR_MASK) >>
>> + ICH_VMCR_CBPR_SHIFT) << ICC_CTLR_EL1_CBPR_SHIFT;
>> + val |= ((vmcr.ctlr & ICH_VMCR_EOIM_MASK) >>
>> + ICH_VMCR_EOIM_SHIFT) << ICC_CTLR_EL1_EOImode_SHIFT;
>
> again, these last two look weird to me.
>
>> +
>> + p->regval = val;
>> + }
>> +
>> + return true;
>> +}
>> +
>> +static bool access_gic_pmr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>> + const struct sys_reg_desc *r)
>> +{
>> + struct vgic_vmcr vmcr;
>> +
>> + vgic_get_vmcr(vcpu, &vmcr);
>> + if (p->is_write) {
>> + vmcr.pmr = (p->regval & ICC_PMR_EL1_MASK) >> ICC_PMR_EL1_SHIFT;
>> + vgic_set_vmcr(vcpu, &vmcr);
>> + } else {
>> + p->regval = (vmcr.pmr << ICC_PMR_EL1_SHIFT) & ICC_PMR_EL1_MASK;
>> + }
>> +
>> + return true;
>> +}
>> +
>> +static bool access_gic_bpr0(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>> + const struct sys_reg_desc *r)
>> +{
>> + struct vgic_vmcr vmcr;
>> +
>> + vgic_get_vmcr(vcpu, &vmcr);
>> + if (p->is_write) {
>> + vmcr.bpr = (p->regval & ICC_BPR0_EL1_MASK) >>
>> + ICC_BPR0_EL1_SHIFT;
>> + vgic_set_vmcr(vcpu, &vmcr);
>> + } else {
>> + p->regval = (vmcr.bpr << ICC_BPR0_EL1_SHIFT) &
>> + ICC_BPR0_EL1_MASK;
>> + }
>> +
>> + return true;
>> +}
>> +
>> +static bool access_gic_bpr1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>> + const struct sys_reg_desc *r)
>> +{
>> + struct vgic_vmcr vmcr;
>> +
>> + if (!p->is_write)
>> + p->regval = 0;
>> +
>> + vgic_get_vmcr(vcpu, &vmcr);
>> + if (!((vmcr.ctlr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT)) {
>> + if (p->is_write) {
>> + vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >>
>> + ICC_BPR1_EL1_SHIFT;
>> + vgic_set_vmcr(vcpu, &vmcr);
>> + } else {
>> + p->regval = (vmcr.abpr << ICC_BPR1_EL1_SHIFT) &
>> + ICC_BPR1_EL1_MASK;
>> + }
>> + } else {
>> + if (!p->is_write)
>> + p->regval = min((vmcr.bpr + 1), 7U);
>> + }
>> +
>> + return true;
>> +}
>> +
>> +static bool access_gic_grpen0(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>> + const struct sys_reg_desc *r)
>> +{
>> + struct vgic_vmcr vmcr;
>> +
>> + vgic_get_vmcr(vcpu, &vmcr);
>> + if (p->is_write) {
>> + vmcr.grpen0 = (p->regval & ICC_IGRPEN0_EL1_MASK) >>
>> + ICC_IGRPEN0_EL1_SHIFT;
>> + vgic_set_vmcr(vcpu, &vmcr);
>> + } else {
>> + p->regval = (vmcr.grpen0 << ICC_IGRPEN0_EL1_SHIFT) &
>> + ICC_IGRPEN0_EL1_MASK;
>> + }
>> +
>> + return true;
>> +}
>> +
>> +static bool access_gic_grpen1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>> + const struct sys_reg_desc *r)
>> +{
>> + struct vgic_vmcr vmcr;
>> +
>> + vgic_get_vmcr(vcpu, &vmcr);
>> + if (p->is_write) {
>> + vmcr.grpen1 = (p->regval & ICC_IGRPEN1_EL1_MASK) >>
>> + ICC_IGRPEN1_EL1_SHIFT;
>> + vgic_set_vmcr(vcpu, &vmcr);
>> + } else {
>> + p->regval = (vmcr.grpen1 << ICC_IGRPEN1_EL1_SHIFT) &
>> + ICC_IGRPEN1_EL1_MASK;
>> + }
>> +
>> + return true;
>> +}
>> +
>> +static void vgic_v3_access_apr_reg(struct kvm_vcpu *vcpu,
>> + struct sys_reg_params *p, u8 apr, u8 idx)
>> +{
>> + struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
>> + uint32_t *ap_reg;
>> +
>> + if (apr)
>> + ap_reg = &vgicv3->vgic_ap1r[idx];
>> + else
>> + ap_reg = &vgicv3->vgic_ap0r[idx];
>> +
>> + if (p->is_write)
>> + *ap_reg = p->regval;
>> + else
>> + p->regval = *ap_reg;
>> +}
>> +
>> +static void access_gic_aprn(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>> + const struct sys_reg_desc *r, u8 apr)
>> +{
>> + struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu;
>> + u8 idx = r->Op2 & 3;
>> +
>> + switch (vgic_v3_cpu->num_pri_bits) {
>> + case 7:
>> + if (idx > 3)
>> + goto err;
>
> idx cannot be higher than three given the mask above, right?
>
>> + vgic_v3_access_apr_reg(vcpu, p, apr, idx);
>> + break;
>> + case 6:
>> + if (idx > 1)
>> + goto err;
>> + vgic_v3_access_apr_reg(vcpu, p, apr, idx);
>> + break;
>> + default:
>> + if (idx > 0)
>> + goto err;
>> + vgic_v3_access_apr_reg(vcpu, p, apr, idx);
>> + }
>
> what's the rationale behind ignoring the case where userspace is using
> unsupported priorities? Is it that this will be checked during
> save/restore of the ctlr?
>
> This sort of thing just looks like the case that's impossible to debug,
> because userspace could be scratching its head trying to understand why
> the value it wrote isn't recorded anywhere...
>
> If there's a good rationale for doing it this way, then could we have a
> comment to that effect?
Accessing umplemented priority registers raised UNDEF exception.
So userspace accesing should be ignored instead of recording unsupported
values.
>
>> +
>> + return;
>> +err:
>> + if (!p->is_write)
>> + p->regval = 0;
>> +}
>> +
>> +static bool access_gic_ap0r(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>> + const struct sys_reg_desc *r)
>> +{
>> + access_gic_aprn(vcpu, p, r, 0);
>> +
>> + return true;
>> +}
>> +
>> +static bool access_gic_ap1r(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>> + const struct sys_reg_desc *r)
>> +{
>> + access_gic_aprn(vcpu, p, r, 1);
>> +
>> + return true;
>> +}
>> +
>> +static bool access_gic_sre(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>> + const struct sys_reg_desc *r)
>> +{
>> + struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
>> +
>> + /* Validate SRE bit */
>> + if (p->is_write) {
>> + if (!(p->regval & ICC_SRE_EL1_SRE))
>> + return false;
>> + } else {
>> + p->regval = vgicv3->vgic_sre;
>> + }
>> +
>> + return true;
>> +}
>> +
>> +static const struct sys_reg_desc gic_v3_icc_reg_descs[] = {
>> + /* ICC_PMR_EL1 */
>> + { Op0(3), Op1(0), CRn(4), CRm(6), Op2(0), access_gic_pmr },
>> + /* ICC_BPR0_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(8), Op2(3), access_gic_bpr0 },
>> + /* ICC_AP0R0_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(8), Op2(4), access_gic_ap0r },
>> + /* ICC_AP0R1_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(8), Op2(5), access_gic_ap0r },
>> + /* ICC_AP0R2_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(8), Op2(6), access_gic_ap0r },
>> + /* ICC_AP0R3_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(8), Op2(7), access_gic_ap0r },
>> + /* ICC_AP1R0_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(9), Op2(0), access_gic_ap1r },
>> + /* ICC_AP1R1_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(9), Op2(1), access_gic_ap1r },
>> + /* ICC_AP1R2_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(9), Op2(2), access_gic_ap1r },
>> + /* ICC_AP1R3_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(9), Op2(3), access_gic_ap1r },
>> + /* ICC_BPR1_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(12), Op2(3), access_gic_bpr1 },
>> + /* ICC_CTLR_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(12), Op2(4), access_gic_ctlr },
>> + /* ICC_SRE_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(12), Op2(5), access_gic_sre },
>> + /* ICC_IGRPEN0_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(12), Op2(6), access_gic_grpen0 },
>> + /* ICC_GRPEN1_EL1 */
>> + { Op0(3), Op1(0), CRn(12), CRm(12), Op2(7), access_gic_grpen1 },
>> +};
>> +
>> +int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id,
>> + u64 *reg)
>> +{
>> + struct sys_reg_params params;
>> + u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
>> +
>> + params.regval = *reg;
>> + params.is_write = is_write;
>> + params.is_aarch32 = false;
>> + params.is_32bit = false;
>> +
>> + if (find_reg_by_id(sysreg, ¶ms, gic_v3_icc_reg_descs,
>> + ARRAY_SIZE(gic_v3_icc_reg_descs)))
>> + return 0;
>> +
>> + return -ENXIO;
>> +}
>> +
>> +int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id,
>> + u64 *reg)
>> +{
>> + struct sys_reg_params params;
>> + const struct sys_reg_desc *r;
>> + u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
>> +
>> + if (is_write)
>> + params.regval = *reg;
>> + params.is_write = is_write;
>> + params.is_aarch32 = false;
>> + params.is_32bit = false;
>> +
>> + r = find_reg_by_id(sysreg, ¶ms, gic_v3_icc_reg_descs,
>> + ARRAY_SIZE(gic_v3_icc_reg_descs));
>> + if (!r)
>> + return -ENXIO;
>> +
>> + if (!r->access(vcpu, ¶ms, r))
>> + return -EINVAL;
>
> According to the API, EINVAL meansinvalid mpidr. Should we expand on
> how it can be used or allocate a new error code?
How abt EACCES error code?
>
>> +
>> + if (!is_write)
>> + *reg = params.regval;
>> +
>> + return 0;
>> +}
>> diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
>> index 967c295..1139971 100644
>> --- a/virt/kvm/arm/vgic/vgic-v3.c
>> +++ b/virt/kvm/arm/vgic/vgic-v3.c
>> @@ -228,6 +228,13 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu)
>> vgic_v3->vgic_sre = 0;
>> }
>>
>> + vcpu->arch.vgic_cpu.num_id_bits = (kvm_vgic_global_state.ich_vtr_el2 &
>> + ICH_VTR_ID_BITS_MASK) >>
>> + ICH_VTR_ID_BITS_SHIFT;
>> + vcpu->arch.vgic_cpu.num_pri_bits = ((kvm_vgic_global_state.ich_vtr_el2 &
>> + ICH_VTR_PRI_BITS_MASK) >>
>> + ICH_VTR_PRI_BITS_SHIFT) + 1;
>> +
>> /* Get the show on the road... */
>> vgic_v3->vgic_hcr = ICH_HCR_EN;
>> }
>> @@ -328,6 +335,7 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
>> */
>> kvm_vgic_global_state.nr_lr = (ich_vtr_el2 & 0xf) + 1;
>> kvm_vgic_global_state.can_emulate_gicv2 = false;
>> + kvm_vgic_global_state.ich_vtr_el2 = ich_vtr_el2;
>>
>> if (!info->vcpu.start) {
>> kvm_info("GICv3: no GICV resource entry\n");
>> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
>> index c461f6b..0e632d0 100644
>> --- a/virt/kvm/arm/vgic/vgic.h
>> +++ b/virt/kvm/arm/vgic/vgic.h
>> @@ -126,6 +126,10 @@ int vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
>> int offset, u32 *val);
>> int vgic_v3_redist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
>> int offset, u32 *val);
>> +int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write,
>> + u64 id, u64 *val);
>> +int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id,
>> + u64 *reg);
>> #else
>> static inline int vgic_register_its_iodevs(struct kvm *kvm)
>> {
>> --
>
>
> Thanks,
> -Christoffer
^ permalink raw reply
* [PATCH v8 5/7] arm/arm64: vgic: Introduce VENG0 and VENG1 fields to vmcr struct
From: Christoffer Dall @ 2016-11-17 16:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CALicx6vP8FyaGa3f=T6RdC+Qd0iYMWiQ5g+g0_KQG6kzoJtzFA@mail.gmail.com>
On Thu, Nov 17, 2016 at 06:12:39PM +0530, Vijay Kilari wrote:
> On Thu, Nov 17, 2016 at 12:22 AM, Christoffer Dall
> <christoffer.dall@linaro.org> wrote:
> > On Fri, Nov 04, 2016 at 04:43:31PM +0530, vijay.kilari at gmail.com wrote:
> >> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> >>
> >> ICC_VMCR_EL2 supports virtual access to ICC_IGRPEN1_EL1.Enable
> >> and ICC_IGRPEN0_EL1.Enable fields. Add grpen0 and grpen1 member
> >> variables to struct vmcr to support read and write of these fields.
> >>
> >> Also refactor vgic_set_vmcr and vgic_get_vmcr() code.
> >> Drop ICH_VMCR_CTLR_SHIFT and ICH_VMCR_CTLR_MASK macros and instead
> >> use ICH_VMCR_EOI* and ICH_VMCR_CBPR* macros
> >> .
> >> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> >> ---
> >> include/linux/irqchip/arm-gic-v3.h | 2 --
> >> virt/kvm/arm/vgic/vgic-mmio-v2.c | 16 ----------------
> >> virt/kvm/arm/vgic/vgic-mmio.c | 16 ++++++++++++++++
> >> virt/kvm/arm/vgic/vgic-v3.c | 10 ++++++++--
> >> virt/kvm/arm/vgic/vgic.h | 5 +++++
> >> 5 files changed, 29 insertions(+), 20 deletions(-)
> >>
> >> diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
> >> index d48d886..61646aa 100644
> >> --- a/include/linux/irqchip/arm-gic-v3.h
> >> +++ b/include/linux/irqchip/arm-gic-v3.h
> >> @@ -404,8 +404,6 @@
> >> #define ICH_HCR_EN (1 << 0)
> >> #define ICH_HCR_UIE (1 << 1)
> >>
> >> -#define ICH_VMCR_CTLR_SHIFT 0
> >> -#define ICH_VMCR_CTLR_MASK (0x21f << ICH_VMCR_CTLR_SHIFT)
> >> #define ICH_VMCR_CBPR_SHIFT 4
> >> #define ICH_VMCR_CBPR_MASK (1 << ICH_VMCR_CBPR_SHIFT)
> >> #define ICH_VMCR_EOIM_SHIFT 9
> >> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v2.c b/virt/kvm/arm/vgic/vgic-mmio-v2.c
> >> index 2cb04b7..ad353b5 100644
> >> --- a/virt/kvm/arm/vgic/vgic-mmio-v2.c
> >> +++ b/virt/kvm/arm/vgic/vgic-mmio-v2.c
> >> @@ -212,22 +212,6 @@ static void vgic_mmio_write_sgipends(struct kvm_vcpu *vcpu,
> >> }
> >> }
> >>
> >> -static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
> >> -{
> >> - if (kvm_vgic_global_state.type == VGIC_V2)
> >> - vgic_v2_set_vmcr(vcpu, vmcr);
> >> - else
> >> - vgic_v3_set_vmcr(vcpu, vmcr);
> >> -}
> >> -
> >> -static void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
> >> -{
> >> - if (kvm_vgic_global_state.type == VGIC_V2)
> >> - vgic_v2_get_vmcr(vcpu, vmcr);
> >> - else
> >> - vgic_v3_get_vmcr(vcpu, vmcr);
> >> -}
> >> -
> >> #define GICC_ARCH_VERSION_V2 0x2
> >>
> >> /* These are for userland accesses only, there is no guest-facing emulation. */
> >> diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
> >> index 9939d1d..173d6f0 100644
> >> --- a/virt/kvm/arm/vgic/vgic-mmio.c
> >> +++ b/virt/kvm/arm/vgic/vgic-mmio.c
> >> @@ -416,6 +416,22 @@ int vgic_validate_mmio_region_addr(struct kvm_device *dev,
> >> return -ENXIO;
> >> }
> >>
> >> +void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
> >> +{
> >> + if (kvm_vgic_global_state.type == VGIC_V2)
> >> + vgic_v2_set_vmcr(vcpu, vmcr);
> >> + else
> >> + vgic_v3_set_vmcr(vcpu, vmcr);
> >> +}
> >> +
> >> +void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
> >> +{
> >> + if (kvm_vgic_global_state.type == VGIC_V2)
> >> + vgic_v2_get_vmcr(vcpu, vmcr);
> >> + else
> >> + vgic_v3_get_vmcr(vcpu, vmcr);
> >> +}
> >> +
> >> /*
> >> * kvm_mmio_read_buf() returns a value in a format where it can be converted
> >> * to a byte array and be directly observed as the guest wanted it to appear
> >> diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
> >> index 9f0dae3..967c295 100644
> >> --- a/virt/kvm/arm/vgic/vgic-v3.c
> >> +++ b/virt/kvm/arm/vgic/vgic-v3.c
> >> @@ -175,10 +175,13 @@ void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
> >> {
> >> u32 vmcr;
> >>
> >> - vmcr = (vmcrp->ctlr << ICH_VMCR_CTLR_SHIFT) & ICH_VMCR_CTLR_MASK;
> >> + vmcr = (vmcrp->ctlr << ICH_VMCR_CBPR_SHIFT) & ICH_VMCR_CBPR_MASK;
> >> + vmcr |= (vmcrp->ctlr << ICH_VMCR_EOIM_SHIFT) & ICH_VMCR_EOIM_MASK;
> >
> > This looks weird: The EOImode field is bit[2] in the CTLR, and VEOIM is
> > bit[9] in the ICH_VMCR, but you're just shifting the ctlr field left by
> > 9 and then masking off everything by bit 9, so you'll end with never
> > being able to set VEOIM I think...
> >
> OK
> > Also, we do we now forget about VFIQEn and VAckCtl? The latter I can
> > understand because it's deprecated, but why the first? This particular
> > piece of information would be very nice to have in the commit message.
>
> I understand that group 0 interrupts are not handled. So vFIQEn can be ignored.
> Spec says, if SRE=1 (non-secure) this bit is RES1 also it is alias to
> ICC_CTLR_EL1
> if SRE is 1. However there is no bit in ICC_CTLR_EL1 for FIQen. It is defined
> only in GICV_CTLR which is used when SRE=0.
So you should add a comment or the very least add to the commit message
that we ignore the FIQen bit, because our GIC emulation always implies
SRE=1 which means the vFIQEn bit is also RES1 (if I got this right).
-Christoffer
^ permalink raw reply
* [PATCH 2/2] arm64: defconfig: enable MFD RK808 and RK808 regulator
From: Heiko Stuebner @ 2016-11-17 16:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1473249028-27161-1-git-send-email-andy.yan@rock-chips.com>
Am Mittwoch, 7. September 2016, 19:50:28 CET schrieb Andy Yan:
> Many rockchip based arm64 boards use RK808 as PMIC, so
> enabe it here let the board bootup normally.
>
> Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
applied to a defconfig64 branch after adding rk808-rtc as module and rk808-clk
output as builtin as well.
Thanks
Heiko
^ permalink raw reply
* [PATCH v8 6/7] arm/arm64: vgic: Implement VGICv3 CPU interface access
From: Christoffer Dall @ 2016-11-17 16:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CALicx6t5D5n3dDQzeKZNUWdS-q5LNiSq-UrP4HdmbdUCj1tF1g@mail.gmail.com>
On Thu, Nov 17, 2016 at 09:25:59PM +0530, Vijay Kilari wrote:
> On Thu, Nov 17, 2016 at 12:22 AM, Christoffer Dall
> <christoffer.dall@linaro.org> wrote:
> > On Fri, Nov 04, 2016 at 04:43:32PM +0530, vijay.kilari at gmail.com wrote:
> >> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> >>
> >> VGICv3 CPU interface registers are accessed using
> >> KVM_DEV_ARM_VGIC_CPU_SYSREGS ioctl. These registers are accessed
> >> as 64-bit. The cpu MPIDR value is passed along with register id.
> >> is used to identify the cpu for registers access.
> >>
> >> The version of VGIC v3 specification is define here
> >> http://lists.infradead.org/pipermail/linux-arm-kernel/2016-July/445611.html
> >>
> >> Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
> >> Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
> >> ---
> >> arch/arm64/include/uapi/asm/kvm.h | 3 +
> >> arch/arm64/kvm/Makefile | 1 +
> >> include/kvm/arm_vgic.h | 9 +
> >> virt/kvm/arm/vgic/vgic-kvm-device.c | 27 +++
> >> virt/kvm/arm/vgic/vgic-mmio-v3.c | 19 +++
> >> virt/kvm/arm/vgic/vgic-sys-reg-v3.c | 324 ++++++++++++++++++++++++++++++++++++
> >> virt/kvm/arm/vgic/vgic-v3.c | 8 +
> >> virt/kvm/arm/vgic/vgic.h | 4 +
> >> 8 files changed, 395 insertions(+)
> >>
> >> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> >> index 56dc08d..91c7137 100644
> >> --- a/arch/arm64/include/uapi/asm/kvm.h
> >> +++ b/arch/arm64/include/uapi/asm/kvm.h
> >> @@ -206,9 +206,12 @@ struct kvm_arch_memory_slot {
> >> (0xffffffffULL << KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT)
> >> #define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
> >> #define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
> >> +#define KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK (0xffff)
> >> #define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
> >> #define KVM_DEV_ARM_VGIC_GRP_CTRL 4
> >> #define KVM_DEV_ARM_VGIC_GRP_REDIST_REGS 5
> >> +#define KVM_DEV_ARM_VGIC_CPU_SYSREGS 6
> >> +
> >> #define KVM_DEV_ARM_VGIC_CTRL_INIT 0
> >>
> >> /* Device Control API on vcpu fd */
> >> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> >> index d50a82a..1a14e29 100644
> >> --- a/arch/arm64/kvm/Makefile
> >> +++ b/arch/arm64/kvm/Makefile
> >> @@ -32,5 +32,6 @@ kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-mmio-v3.o
> >> kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-kvm-device.o
> >> kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-its.o
> >> kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/irqchip.o
> >> +kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/vgic/vgic-sys-reg-v3.o
> >
> > Thi is making me wonder: Are we properly handling GICv3 save/restore
> > for AArch32 now that we have GICv3 support for AArch32? By properly I
> > mean that either it is clearly only supported on AArch64 systems or it's
> > supported on both AArch64 and AArch32, but it shouldn't break randomly
> > on AArch32.
>
> It supports both AArch64 and AArch64 in handling of system registers
> save/restore.
> All system registers that we save/restore are 32-bit for both aarch64
> and aarch32.
> Though opcode op0 should be zero for aarch32, the remaining Op and CRn codes
> are same. However the codes sent by qemu is matched and register
> are handled properly irrespective of AArch32 or AArch64.
>
> I don't have platform which support AArch32 guests to verify.
Actually this is not about the guest, it's about an ARMv8 AArch32 host
that has a GICv3.
I just tried to do a v7 compile with your patches, and it results in an
epic failure, so there's something for you to look at.
> >
> >> kvm-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/arch_timer.o
> >> kvm-$(CONFIG_KVM_ARM_PMU) += $(KVM)/arm/pmu.o
> >> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> >> index 002f092..730a18a 100644
> >> --- a/include/kvm/arm_vgic.h
> >> +++ b/include/kvm/arm_vgic.h
> >> @@ -71,6 +71,9 @@ struct vgic_global {
> >>
> >> /* GIC system register CPU interface */
> >> struct static_key_false gicv3_cpuif;
> >> +
> >> + /* Cache ICH_VTR_EL2 reg value */
> >> + u32 ich_vtr_el2;
> >> };
> >>
> >> extern struct vgic_global kvm_vgic_global_state;
> >> @@ -269,6 +272,12 @@ struct vgic_cpu {
> >> u64 pendbaser;
> >>
> >> bool lpis_enabled;
> >> +
> >> + /* Cache guest priority bits */
> >> + u32 num_pri_bits;
> >> +
> >> + /* Cache guest interrupt ID bits */
> >> + u32 num_id_bits;
> >> };
> >>
> >> extern struct static_key_false vgic_v2_cpuif_trap;
> >> diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
> >> index 6c7d30c..da532d1 100644
> >> --- a/virt/kvm/arm/vgic/vgic-kvm-device.c
> >> +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
> >> @@ -504,6 +504,14 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
> >> if (!is_write)
> >> *reg = tmp32;
> >> break;
> >> + case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
> >> + u64 regid;
> >> +
> >> + regid = (attr->attr & KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK);
> >> + ret = vgic_v3_cpu_sysregs_uaccess(vcpu, is_write,
> >> + regid, reg);
> >> + break;
> >> + }
> >> default:
> >> ret = -EINVAL;
> >> break;
> >> @@ -537,6 +545,15 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
> >> reg = tmp32;
> >> return vgic_v3_attr_regs_access(dev, attr, ®, true);
> >> }
> >> + case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
> >> + u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> >> + u64 reg;
> >> +
> >> + if (get_user(reg, uaddr))
> >> + return -EFAULT;
> >> +
> >> + return vgic_v3_attr_regs_access(dev, attr, ®, true);
> >> + }
> >> }
> >> return -ENXIO;
> >> }
> >> @@ -563,6 +580,15 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
> >> tmp32 = reg;
> >> return put_user(tmp32, uaddr);
> >> }
> >> + case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
> >> + u64 __user *uaddr = (u64 __user *)(long)attr->addr;
> >> + u64 reg;
> >> +
> >> + ret = vgic_v3_attr_regs_access(dev, attr, ®, false);
> >> + if (ret)
> >> + return ret;
> >> + return put_user(reg, uaddr);
> >> + }
> >> }
> >>
> >> return -ENXIO;
> >> @@ -581,6 +607,7 @@ static int vgic_v3_has_attr(struct kvm_device *dev,
> >> break;
> >> case KVM_DEV_ARM_VGIC_GRP_DIST_REGS:
> >> case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
> >> + case KVM_DEV_ARM_VGIC_CPU_SYSREGS:
> >> return vgic_v3_has_attr_regs(dev, attr);
> >> case KVM_DEV_ARM_VGIC_GRP_NR_IRQS:
> >> return 0;
> >> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> >> index b35fb83..519b919 100644
> >> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
> >> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> >> @@ -23,6 +23,7 @@
> >>
> >> #include "vgic.h"
> >> #include "vgic-mmio.h"
> >> +#include "sys_regs.h"
> >>
> >> /* extract @num bytes at @offset bytes offset in data */
> >> unsigned long extract_bytes(u64 data, unsigned int offset,
> >> @@ -639,6 +640,24 @@ int vgic_v3_has_attr_regs(struct kvm_device *dev, struct kvm_device_attr *attr)
> >> nr_regions = ARRAY_SIZE(vgic_v3_rdbase_registers);
> >> break;
> >> }
> >> + case KVM_DEV_ARM_VGIC_CPU_SYSREGS: {
> >> + u64 reg, id;
> >> + unsigned long vgic_mpidr, mpidr_reg;
> >> + struct kvm_vcpu *vcpu;
> >> +
> >> + vgic_mpidr = (attr->attr & KVM_DEV_ARM_VGIC_V3_MPIDR_MASK) >>
> >> + KVM_DEV_ARM_VGIC_V3_MPIDR_SHIFT;
> >> +
> >> + /* Convert plain mpidr value to MPIDR reg format */
> >> + mpidr_reg = VGIC_TO_MPIDR(vgic_mpidr);
> >> +
> >> + vcpu = kvm_mpidr_to_vcpu(dev->kvm, mpidr_reg);
> >> + if (!vcpu)
> >> + return -EINVAL;
> >> +
> >> + id = (attr->attr & KVM_DEV_ARM_VGIC_SYSREG_INSTR_MASK);
> >> + return vgic_v3_has_cpu_sysregs_attr(vcpu, 0, id, ®);
> >> + }
> >> default:
> >> return -ENXIO;
> >> }
> >> diff --git a/virt/kvm/arm/vgic/vgic-sys-reg-v3.c b/virt/kvm/arm/vgic/vgic-sys-reg-v3.c
> >> new file mode 100644
> >> index 0000000..69d8597
> >> --- /dev/null
> >> +++ b/virt/kvm/arm/vgic/vgic-sys-reg-v3.c
> >
> > Shouldn't we have a GPL header here?
> >
> >> @@ -0,0 +1,324 @@
> >> +#include <linux/irqchip/arm-gic-v3.h>
> >> +#include <linux/kvm.h>
> >> +#include <linux/kvm_host.h>
> >> +#include <kvm/iodev.h>
> >> +#include <kvm/arm_vgic.h>
> >> +#include <asm/kvm_emulate.h>
> >> +#include <asm/kvm_arm.h>
> >> +#include <asm/kvm_mmu.h>
> >> +
> >> +#include "vgic.h"
> >> +#include "vgic-mmio.h"
> >> +#include "sys_regs.h"
> >> +
> >> +static bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> >> + const struct sys_reg_desc *r)
> >> +{
> >> + struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu;
> >> + struct vgic_vmcr vmcr;
> >> + u64 val;
> >> + u32 num_pri_bits, num_id_bits;
> >> +
> >> + vgic_get_vmcr(vcpu, &vmcr);
> >> + if (p->is_write) {
> >> + val = p->regval;
> >> +
> >> + /*
> >> + * Does not allow update of ICC_CTLR_EL1 if HW does not support
> >> + * guest programmed ID and PRI bits
> >> + */
> >
> > I would suggest rewording this comment:
> > Disallow restoring VM state not supported by this hardware.
> >
> >> + num_pri_bits = ((val & ICC_CTLR_EL1_PRI_BITS_MASK) >>
> >> + ICC_CTLR_EL1_PRI_BITS_SHIFT) + 1;
> >> + if (num_pri_bits > vgic_v3_cpu->num_pri_bits)
> >> + return false;
> >> +
> >> + vgic_v3_cpu->num_pri_bits = num_pri_bits;
> >
> > hmmm, this looks weird to me, because vgic_v3_cpu->num_pri_bits I don't
> > understand which effect this is intended to have?
> >
> > Sure, it may limit what you do with other registers later, but since
> > there's no ordering requirement that the ctlr be restored first, I'm not
> > sure it makes sense.
> >
> > Also, since this field is RO in the ICH_VTR, we'll have a strange
> > situation during runtime after a GICv3 restore where the
> > vgic_v3_cpu->num_pri_its differs from the hardware's ICH_VTR_EL2 field,
> > which is never the case if you didn't do a save/restore.
>
> Yes, but in any case, vgic_v3_cpu->num_pri_bits will be always less
> than HW supported
> value.
>
So answer my question: What is the intended effect of writing this
value? Is it just so that if you migrate this platform back again, then
you're checking compatibility with what the guest would potentially do,
or should you maintain the num_pri_bits limitation during runtime
somehow?
> >
> > Finally, should we somehow ensure that this field is set to the same
> > value across VCPUs or is that not an architectural requirement?
> >
> Yes it is nice to have it same across VCPUs. But should be ok as
> we are ensuring value is not greater than HW supported value.
Does the architecture allow having a different number of priority bits
supported across CPUs? If not, you shouldn't allow a VM programming
things that way either.
> There is no single point of place where we can make such a check
>
> >> +
> >> + num_id_bits = (val & ICC_CTLR_EL1_ID_BITS_MASK) >>
> >> + ICC_CTLR_EL1_ID_BITS_SHIFT;
> >> + if (num_id_bits > vgic_v3_cpu->num_id_bits)
> >> + return false;
> >> +
> >> + vgic_v3_cpu->num_id_bits = num_id_bits;
> >
> > same questions
> >
> >> +
> >> + vmcr.ctlr &= ~(ICH_VMCR_CBPR_MASK | ICH_VMCR_EOIM_MASK);
> >> + vmcr.ctlr |= ((val & ICC_CTLR_EL1_CBPR_MASK) >>
> >> + ICC_CTLR_EL1_CBPR_SHIFT) << ICH_VMCR_CBPR_SHIFT;
> >> + vmcr.ctlr |= ((val & ICC_CTLR_EL1_EOImode_MASK) >>
> >> + ICC_CTLR_EL1_EOImode_SHIFT) <<
> >> + ICH_VMCR_EOIM_SHIFT;
> >
> > I'm really confused here. Is the vmcr.ctlr field in the ICC_CTLR_EL1
> > format or in the VMCR format? I would assume the former, since
> > otherwise I don't get the point with this indirection, and for GICv2
> > vmcr.ctlr captures the GICC_CTLR value and git_set_vmcr transforms this
> > into VMCR values.
> >
> > Having a line that says "ctlr &= ~ICH_VMCR" should make some alarm bells
> > ring.
>
> I will check and fix it.
> >
> >> + vgic_set_vmcr(vcpu, &vmcr);
> >
> > Should we check compatibility between the source and destination for the
> > SEIS and A3V support here?
>
> Can be checked. But I feel A3V check makes more sense than checking for
> SEIS.
>
Please argue the *why* for whatever you end up doing with respect to
both bits in the commit message of your next patch revision.
> >
> >> + } else {
> >> + val = 0;
> >> + val |= (vgic_v3_cpu->num_pri_bits - 1) <<
> >> + ICC_CTLR_EL1_PRI_BITS_SHIFT;
> >> + val |= vgic_v3_cpu->num_id_bits <<
> >> + ICC_CTLR_EL1_ID_BITS_SHIFT;
> >> + val |= ((kvm_vgic_global_state.ich_vtr_el2 &
> >> + ICH_VTR_SEIS_MASK) >> ICH_VTR_SEIS_SHIFT) <<
> >> + ICC_CTLR_EL1_SEIS_SHIFT;
> >> + val |= ((kvm_vgic_global_state.ich_vtr_el2 &
> >> + ICH_VTR_A3V_MASK) >> ICH_VTR_A3V_SHIFT) <<
> >> + ICC_CTLR_EL1_A3V_SHIFT;
> >> + val |= ((vmcr.ctlr & ICH_VMCR_CBPR_MASK) >>
> >> + ICH_VMCR_CBPR_SHIFT) << ICC_CTLR_EL1_CBPR_SHIFT;
> >> + val |= ((vmcr.ctlr & ICH_VMCR_EOIM_MASK) >>
> >> + ICH_VMCR_EOIM_SHIFT) << ICC_CTLR_EL1_EOImode_SHIFT;
> >
> > again, these last two look weird to me.
> >
> >> +
> >> + p->regval = val;
> >> + }
> >> +
> >> + return true;
> >> +}
> >> +
> >> +static bool access_gic_pmr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> >> + const struct sys_reg_desc *r)
> >> +{
> >> + struct vgic_vmcr vmcr;
> >> +
> >> + vgic_get_vmcr(vcpu, &vmcr);
> >> + if (p->is_write) {
> >> + vmcr.pmr = (p->regval & ICC_PMR_EL1_MASK) >> ICC_PMR_EL1_SHIFT;
> >> + vgic_set_vmcr(vcpu, &vmcr);
> >> + } else {
> >> + p->regval = (vmcr.pmr << ICC_PMR_EL1_SHIFT) & ICC_PMR_EL1_MASK;
> >> + }
> >> +
> >> + return true;
> >> +}
> >> +
> >> +static bool access_gic_bpr0(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> >> + const struct sys_reg_desc *r)
> >> +{
> >> + struct vgic_vmcr vmcr;
> >> +
> >> + vgic_get_vmcr(vcpu, &vmcr);
> >> + if (p->is_write) {
> >> + vmcr.bpr = (p->regval & ICC_BPR0_EL1_MASK) >>
> >> + ICC_BPR0_EL1_SHIFT;
> >> + vgic_set_vmcr(vcpu, &vmcr);
> >> + } else {
> >> + p->regval = (vmcr.bpr << ICC_BPR0_EL1_SHIFT) &
> >> + ICC_BPR0_EL1_MASK;
> >> + }
> >> +
> >> + return true;
> >> +}
> >> +
> >> +static bool access_gic_bpr1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> >> + const struct sys_reg_desc *r)
> >> +{
> >> + struct vgic_vmcr vmcr;
> >> +
> >> + if (!p->is_write)
> >> + p->regval = 0;
> >> +
> >> + vgic_get_vmcr(vcpu, &vmcr);
> >> + if (!((vmcr.ctlr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT)) {
> >> + if (p->is_write) {
> >> + vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >>
> >> + ICC_BPR1_EL1_SHIFT;
> >> + vgic_set_vmcr(vcpu, &vmcr);
> >> + } else {
> >> + p->regval = (vmcr.abpr << ICC_BPR1_EL1_SHIFT) &
> >> + ICC_BPR1_EL1_MASK;
> >> + }
> >> + } else {
> >> + if (!p->is_write)
> >> + p->regval = min((vmcr.bpr + 1), 7U);
> >> + }
> >> +
> >> + return true;
> >> +}
> >> +
> >> +static bool access_gic_grpen0(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> >> + const struct sys_reg_desc *r)
> >> +{
> >> + struct vgic_vmcr vmcr;
> >> +
> >> + vgic_get_vmcr(vcpu, &vmcr);
> >> + if (p->is_write) {
> >> + vmcr.grpen0 = (p->regval & ICC_IGRPEN0_EL1_MASK) >>
> >> + ICC_IGRPEN0_EL1_SHIFT;
> >> + vgic_set_vmcr(vcpu, &vmcr);
> >> + } else {
> >> + p->regval = (vmcr.grpen0 << ICC_IGRPEN0_EL1_SHIFT) &
> >> + ICC_IGRPEN0_EL1_MASK;
> >> + }
> >> +
> >> + return true;
> >> +}
> >> +
> >> +static bool access_gic_grpen1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> >> + const struct sys_reg_desc *r)
> >> +{
> >> + struct vgic_vmcr vmcr;
> >> +
> >> + vgic_get_vmcr(vcpu, &vmcr);
> >> + if (p->is_write) {
> >> + vmcr.grpen1 = (p->regval & ICC_IGRPEN1_EL1_MASK) >>
> >> + ICC_IGRPEN1_EL1_SHIFT;
> >> + vgic_set_vmcr(vcpu, &vmcr);
> >> + } else {
> >> + p->regval = (vmcr.grpen1 << ICC_IGRPEN1_EL1_SHIFT) &
> >> + ICC_IGRPEN1_EL1_MASK;
> >> + }
> >> +
> >> + return true;
> >> +}
> >> +
> >> +static void vgic_v3_access_apr_reg(struct kvm_vcpu *vcpu,
> >> + struct sys_reg_params *p, u8 apr, u8 idx)
> >> +{
> >> + struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
> >> + uint32_t *ap_reg;
> >> +
> >> + if (apr)
> >> + ap_reg = &vgicv3->vgic_ap1r[idx];
> >> + else
> >> + ap_reg = &vgicv3->vgic_ap0r[idx];
> >> +
> >> + if (p->is_write)
> >> + *ap_reg = p->regval;
> >> + else
> >> + p->regval = *ap_reg;
> >> +}
> >> +
> >> +static void access_gic_aprn(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> >> + const struct sys_reg_desc *r, u8 apr)
> >> +{
> >> + struct vgic_cpu *vgic_v3_cpu = &vcpu->arch.vgic_cpu;
> >> + u8 idx = r->Op2 & 3;
> >> +
> >> + switch (vgic_v3_cpu->num_pri_bits) {
> >> + case 7:
> >> + if (idx > 3)
> >> + goto err;
> >
> > idx cannot be higher than three given the mask above, right?
> >
> >> + vgic_v3_access_apr_reg(vcpu, p, apr, idx);
> >> + break;
> >> + case 6:
> >> + if (idx > 1)
> >> + goto err;
> >> + vgic_v3_access_apr_reg(vcpu, p, apr, idx);
> >> + break;
> >> + default:
> >> + if (idx > 0)
> >> + goto err;
> >> + vgic_v3_access_apr_reg(vcpu, p, apr, idx);
> >> + }
> >
> > what's the rationale behind ignoring the case where userspace is using
> > unsupported priorities? Is it that this will be checked during
> > save/restore of the ctlr?
> >
> > This sort of thing just looks like the case that's impossible to debug,
> > because userspace could be scratching its head trying to understand why
> > the value it wrote isn't recorded anywhere...
> >
> > If there's a good rationale for doing it this way, then could we have a
> > comment to that effect?
>
> Accessing umplemented priority registers raised UNDEF exception.
> So userspace accesing should be ignored instead of recording unsupported
> values.
>
That's not what I asked.
I asked why it's silently ignored as opposed to raising an error visible
to user space?
> >
> >> +
> >> + return;
> >> +err:
> >> + if (!p->is_write)
> >> + p->regval = 0;
> >> +}
> >> +
> >> +static bool access_gic_ap0r(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> >> + const struct sys_reg_desc *r)
> >> +{
> >> + access_gic_aprn(vcpu, p, r, 0);
> >> +
> >> + return true;
> >> +}
> >> +
> >> +static bool access_gic_ap1r(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> >> + const struct sys_reg_desc *r)
> >> +{
> >> + access_gic_aprn(vcpu, p, r, 1);
> >> +
> >> + return true;
> >> +}
> >> +
> >> +static bool access_gic_sre(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
> >> + const struct sys_reg_desc *r)
> >> +{
> >> + struct vgic_v3_cpu_if *vgicv3 = &vcpu->arch.vgic_cpu.vgic_v3;
> >> +
> >> + /* Validate SRE bit */
> >> + if (p->is_write) {
> >> + if (!(p->regval & ICC_SRE_EL1_SRE))
> >> + return false;
> >> + } else {
> >> + p->regval = vgicv3->vgic_sre;
> >> + }
> >> +
> >> + return true;
> >> +}
> >> +
> >> +static const struct sys_reg_desc gic_v3_icc_reg_descs[] = {
> >> + /* ICC_PMR_EL1 */
> >> + { Op0(3), Op1(0), CRn(4), CRm(6), Op2(0), access_gic_pmr },
> >> + /* ICC_BPR0_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(8), Op2(3), access_gic_bpr0 },
> >> + /* ICC_AP0R0_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(8), Op2(4), access_gic_ap0r },
> >> + /* ICC_AP0R1_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(8), Op2(5), access_gic_ap0r },
> >> + /* ICC_AP0R2_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(8), Op2(6), access_gic_ap0r },
> >> + /* ICC_AP0R3_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(8), Op2(7), access_gic_ap0r },
> >> + /* ICC_AP1R0_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(9), Op2(0), access_gic_ap1r },
> >> + /* ICC_AP1R1_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(9), Op2(1), access_gic_ap1r },
> >> + /* ICC_AP1R2_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(9), Op2(2), access_gic_ap1r },
> >> + /* ICC_AP1R3_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(9), Op2(3), access_gic_ap1r },
> >> + /* ICC_BPR1_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(12), Op2(3), access_gic_bpr1 },
> >> + /* ICC_CTLR_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(12), Op2(4), access_gic_ctlr },
> >> + /* ICC_SRE_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(12), Op2(5), access_gic_sre },
> >> + /* ICC_IGRPEN0_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(12), Op2(6), access_gic_grpen0 },
> >> + /* ICC_GRPEN1_EL1 */
> >> + { Op0(3), Op1(0), CRn(12), CRm(12), Op2(7), access_gic_grpen1 },
> >> +};
> >> +
> >> +int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id,
> >> + u64 *reg)
> >> +{
> >> + struct sys_reg_params params;
> >> + u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
> >> +
> >> + params.regval = *reg;
> >> + params.is_write = is_write;
> >> + params.is_aarch32 = false;
> >> + params.is_32bit = false;
> >> +
> >> + if (find_reg_by_id(sysreg, ¶ms, gic_v3_icc_reg_descs,
> >> + ARRAY_SIZE(gic_v3_icc_reg_descs)))
> >> + return 0;
> >> +
> >> + return -ENXIO;
> >> +}
> >> +
> >> +int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write, u64 id,
> >> + u64 *reg)
> >> +{
> >> + struct sys_reg_params params;
> >> + const struct sys_reg_desc *r;
> >> + u64 sysreg = (id & KVM_DEV_ARM_VGIC_SYSREG_MASK) | KVM_REG_SIZE_U64;
> >> +
> >> + if (is_write)
> >> + params.regval = *reg;
> >> + params.is_write = is_write;
> >> + params.is_aarch32 = false;
> >> + params.is_32bit = false;
> >> +
> >> + r = find_reg_by_id(sysreg, ¶ms, gic_v3_icc_reg_descs,
> >> + ARRAY_SIZE(gic_v3_icc_reg_descs));
> >> + if (!r)
> >> + return -ENXIO;
> >> +
> >> + if (!r->access(vcpu, ¶ms, r))
> >> + return -EINVAL;
> >
> > According to the API, EINVAL meansinvalid mpidr. Should we expand on
> > how it can be used or allocate a new error code?
> How abt EACCES error code?
>
That would mean permission denied, which is a bit weird.
> >
> >> +
> >> + if (!is_write)
> >> + *reg = params.regval;
> >> +
> >> + return 0;
> >> +}
> >> diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
> >> index 967c295..1139971 100644
> >> --- a/virt/kvm/arm/vgic/vgic-v3.c
> >> +++ b/virt/kvm/arm/vgic/vgic-v3.c
> >> @@ -228,6 +228,13 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu)
> >> vgic_v3->vgic_sre = 0;
> >> }
> >>
> >> + vcpu->arch.vgic_cpu.num_id_bits = (kvm_vgic_global_state.ich_vtr_el2 &
> >> + ICH_VTR_ID_BITS_MASK) >>
> >> + ICH_VTR_ID_BITS_SHIFT;
> >> + vcpu->arch.vgic_cpu.num_pri_bits = ((kvm_vgic_global_state.ich_vtr_el2 &
> >> + ICH_VTR_PRI_BITS_MASK) >>
> >> + ICH_VTR_PRI_BITS_SHIFT) + 1;
> >> +
> >> /* Get the show on the road... */
> >> vgic_v3->vgic_hcr = ICH_HCR_EN;
> >> }
> >> @@ -328,6 +335,7 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
> >> */
> >> kvm_vgic_global_state.nr_lr = (ich_vtr_el2 & 0xf) + 1;
> >> kvm_vgic_global_state.can_emulate_gicv2 = false;
> >> + kvm_vgic_global_state.ich_vtr_el2 = ich_vtr_el2;
> >>
> >> if (!info->vcpu.start) {
> >> kvm_info("GICv3: no GICV resource entry\n");
> >> diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
> >> index c461f6b..0e632d0 100644
> >> --- a/virt/kvm/arm/vgic/vgic.h
> >> +++ b/virt/kvm/arm/vgic/vgic.h
> >> @@ -126,6 +126,10 @@ int vgic_v3_dist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
> >> int offset, u32 *val);
> >> int vgic_v3_redist_uaccess(struct kvm_vcpu *vcpu, bool is_write,
> >> int offset, u32 *val);
> >> +int vgic_v3_cpu_sysregs_uaccess(struct kvm_vcpu *vcpu, bool is_write,
> >> + u64 id, u64 *val);
> >> +int vgic_v3_has_cpu_sysregs_attr(struct kvm_vcpu *vcpu, bool is_write, u64 id,
> >> + u64 *reg);
> >> #else
> >> static inline int vgic_register_its_iodevs(struct kvm *kvm)
> >> {
> >> --
Thanks,
-Christoffer
^ permalink raw reply
* Boot failures in -next due to 'ARM: dts: imx: Remove skeleton.dtsi'
From: Guenter Roeck @ 2016-11-17 16:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161117150551.GA21742@leverpostej>
On 11/17/2016 07:05 AM, Mark Rutland wrote:
> On Thu, Nov 17, 2016 at 06:44:55AM -0800, Guenter Roeck wrote:
>> On 11/17/2016 02:55 AM, Mark Rutland wrote:
>>> On Wed, Nov 16, 2016 at 02:40:24PM -0800, Guenter Roeck wrote:
>>>> On Wed, Nov 16, 2016 at 08:27:09PM -0200, Fabio Estevam wrote:
>>>>> Hi Guenter,
>>>>>
>>>>> On Wed, Nov 16, 2016 at 8:10 PM, Guenter Roeck <linux@roeck-us.net> wrote:
>>>>>>
>>>>>> Anyway, I guess the problem is that the "official" dtb files no longer provide
>>>>>> the skeleton /chosen and /memory nodes (and maybe others), and qemu seems to
>>>>>> expect that they are provided. Is that correct ?
>>>>>
>>>>> imx6qdl-sabrelite.dtsi provides chosen and memory nodes.
>>>>
>>>> Yes, but not the 'device_type' property, which the kernel seems to expect.
>>>
>>> Memory nodes require this property per ePAPR and the devicetree.org
>>> spec, so the bug is that we didn't add those when removing the
>>> skeleton.dtsi include.
>>
>> The downside from qemu perspective is that the real hardware seems
>> to add the property unconditionally, or the boot failure would have
>> been seen there as well.
>>
>> I submitted https://patchwork.ozlabs.org/patch/695951/; we'll see how it goes.
>
> Sure, the firmare/bootlaoder you're using may add this automatically.
>
> My worry is that adding this to a generic file in QEMU only serves to
> mask this class of bug for other boards (i.e. they'll work fine in QEMU,
> but not on real HW using whatever bootlaoder happens ot be there).
>
Good point.
What would be the correct behavior for qemu ? Adding a chosen node if it does
not exist is one detail we already established. Also, I think a check if
/memory/device_type exists (and to bail out if it doesn't) would make sense.
What about the memory node ? Does it have to exist, or should it be added
(including the device_type property) if not ?
Thanks,
Guenter
^ permalink raw reply
* [PATCH 1/2] drm/i2c: tda998x: allow interrupt to be shared
From: Russell King - ARM Linux @ 2016-11-17 16:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161117122457.GC21156@e106950-lin.cambridge.arm.com>
On Thu, Nov 17, 2016 at 12:24:57PM +0000, Brian Starkey wrote:
> I tested these two and the power-down one on mali-dp and hdlcd. The
> output, hotplugging and EDID continued to work; so you can have my
> tested-by and reviewed-by for all 3.
Thanks!
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* Boot failures in -next due to 'ARM: dts: imx: Remove skeleton.dtsi'
From: Mark Rutland @ 2016-11-17 16:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2eaf84f9-ea00-d331-1875-56adafb62378@roeck-us.net>
On Thu, Nov 17, 2016 at 08:17:00AM -0800, Guenter Roeck wrote:
> On 11/17/2016 07:05 AM, Mark Rutland wrote:
> >On Thu, Nov 17, 2016 at 06:44:55AM -0800, Guenter Roeck wrote:
> >>On 11/17/2016 02:55 AM, Mark Rutland wrote:
> >>>Memory nodes require this property per ePAPR and the devicetree.org
> >>>spec, so the bug is that we didn't add those when removing the
> >>>skeleton.dtsi include.
> >>
> >>The downside from qemu perspective is that the real hardware seems
> >>to add the property unconditionally, or the boot failure would have
> >>been seen there as well.
> >>
> >>I submitted https://patchwork.ozlabs.org/patch/695951/; we'll see how it goes.
> >
> >Sure, the firmare/bootlaoder you're using may add this automatically.
> >
> >My worry is that adding this to a generic file in QEMU only serves to
> >mask this class of bug for other boards (i.e. they'll work fine in QEMU,
> >but not on real HW using whatever bootlaoder happens ot be there).
> >
> Good point.
>
> What would be the correct behavior for qemu ? Adding a chosen node if it does
> not exist is one detail we already established. Also, I think a check if
> /memory/device_type exists (and to bail out if it doesn't) would make sense.
We'd also need to check for /memory@<n> nodes, as they can validly have
unit-addresses (and many do).
Generally, the "correct" way to find them is to iterate over all ndoes
with device_type = "memory", so one could do that and give up if none
are found, ignoring the naming entirely.
> What about the memory node ? Does it have to exist, or should it be added
> (including the device_type property) if not ?
I'm not sure what QEMU does in this area. I suspect it may expect a node
in some cases, or may generate one in others.
There's no point generating one when we don't have the information to
hand, certainly.
Thanks,
Mark.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox