Re: [PATCH v2 2/2] drivers: gpio: add virtio-gpio guest driver

2021-04-13 Thread Alex Bennée


"Enrico Weigelt, metux IT consult"  writes:

> On 04.12.20 04:35, Jason Wang wrote:
>
> Hi,
>
>> Is the plan to keep this doc synced with the one in the virtio
>> specification?
>
> Yes, of course. I'm still in progress of doing the beaurocratic stuff w/
> virtio-tc folks (ID registration, ...) - yet have to see whether they
> wanna add it to their spec documents ...
>
> BTW: if you feel, sometings not good w/ the current spec, please raise
> your voice now.
>
>> I think it's better to use u8 ot uint8_t here.Git grep told me the
>> former is more popular under Documentation/.
>
> thx, I'll fix that
>
>>> +- for version field currently only value 1 supported.
>>> +- the line names block holds a stream of zero-terminated strings,
>>> +  holding the individual line names.
>> 
>> I'm not sure but does this mean we don't have a fixed length of config
>> space? Need to check whether it can bring any trouble to
>> migration(compatibility).
>
> Yes, it depends on how many gpio lines are present and how much space
> their names take up.
>
> A fixed size would either put unpleasent limits on the max number of
> lines or waste a lot space when only few lines present.
>
> Not that virtio-gpio is also meant for small embedded workloads running
> under some hypervisor.
>
>>> +- unspecified fields are reserved for future use and should be zero.
>>> +
>>> +
>>> +Virtqueues and messages:
>>> +
>>> +
>>> +- Queue #0: transmission from host to guest
>>> +- Queue #1: transmission from guest to host
>> 
>> 
>> Virtio became more a popular in the area without virtualization. So I
>> think it's better to use "device/driver" instead of "host/guest" here.
>
> Good point. But I'd prefer "cpu" instead of "driver" in that case.

I think you are going to tie yourself up in knots if you don't move this
to the OASIS spec. The reason being the VirtIO spec has definitions for
what a "Device" and a "Driver" is that are clear and unambiguous. The
upstream spec should be considered the canonical source of truth for any
implementation (Linux or otherwise).

By all means have the distilled documentation for the driver in the
kernel source tree but trying to upstream an implementation before
starting the definition in the standard is a little back to front IMHO*.

* that's not to say these things can't be done in parallel as the spec
  is reviewed and worked on and the kinks worked out but you want the
  final order of upstreaming to start with the spec.

-- 
Alex Bennée


Re: [RFC PATCH 1/5] rpmb: add Replay Protected Memory Block (RPMB) subsystem

2021-03-11 Thread Alex Bennée


Hector Martin  writes:

> On 11/03/2021 23.31, Linus Walleij wrote:
>> I understand your argument, is your position such that the nature
>> of the hardware is such that community should leave this hardware
>> alone and not try to make use of RPMB  for say ordinary (self-installed)
>> Linux distributions?
>
> It's not really that the community should leave this hardware alone, so 
> much that I think there is a very small subset of users who will be able 
> to benefit from it, and that subset will be happy with a usable 
> kernel/userspace interface and some userspace tooling for this purpose, 
> including provisioning and such.
>
> Consider the prerequisites for using RPMB usefully here:
>
> * You need (user-controlled) secureboot
> * You need secret key storage - so either some kind of CPU-fused key, or 
> one protected by a TPM paired with the secureboot (key sealed to PCR 
> values and such)
> * But if you have a TPM, that can handle secure counters for you already 
> AIUI, so you don't need RPMB
> * So this means you must be running a non-TPM secureboot system
>
> And so we're back to embedded platforms like Android phones and other 
> SoC stuff... user-controlled secureboot is already somewhat rare here, 
> and even rarer are the cases where the user controls the whole chain 
> including the TEE if any (otherwise it'll be using RPMB already); this 
> pretty much excludes all production Android phones except for a few 
> designed as completely open systems; we're left with those and a subset 
> of dev boards (e.g. the Jetson TX1 I did fuse experiments on). In the 
> end, those systems will probably end up with fairly bespoke set-ups for 
> any given device or SoC family, for using RPMB.
>
> But then again, if you have a full secureboot system where you control 
> the TEE level, wouldn't you want to put the RPMB shenanigans there and 
> get some semblance of secure TPM/keystore/attempt throttling 
> functionality that is robust against Linux exploits and has a smaller 
> attack surface? Systems without EL3 are rare (Apple M1 :-)) so it makes 
> more sense to do this on those that do have it. If you're paranoid 
> enough to be getting into building your own secure system with 
> anti-rollback for retry counters, you should be heading in that directly 
> anyway.
>
> And now Linux's RPMB code is useless because you're running the stack in 
> the secure monitor instead :-)

Well quiet - the principle use-case of virtio-rpmb is to provide a RPMB
like device emulation for things like OPTEE when running under QEMU's
full-system emulation. However when it came to testing it out I went for
Thomas' patches because that was the only virtio FE implementation
available.

When I finished the implementation and Ilias started on the uBoot
front-end for virtio-rpmb. uBoot being firmware could very well be
running in the secure world so would have a valid use case accessing an
RPMB device. We ran into API dissonance because uboot's driver model is
roughly modelled on the kernel so expects to be talking to eMMC devices
which lead to requirements to fake something up to keep the driver
stacks happy.

I guess what we are saying is that real secure monitors should come up
with their own common API for interfacing with RPMB devices without
looking to the Linux kernel for inspiration?

-- 
Alex Bennée


Re: [RFC PATCH 0/5] RPMB internal and user-space API + WIP virtio-rpmb frontend

2021-03-10 Thread Alex Bennée


Avri Altman  writes:

> The mmc driver has some hooks to support rpmb access, but access is
> mainly facilitated from user space, e.g. mmc-utils.
>
> The ufs driver has no concept of rpmb access - it is facilitated via
> user space, e.g. ufs-utils and similar.
>
> Both for ufs and mmc, rpmb access is defined in their applicable jedec
> specs. This is the case for few years now - AFAIK No new rpmb-related
> stuff is expected to be introduced in the near future.
>
> What problems, as far as mmc and ufs, are you trying to solve by this
> new subsystem?

Well in my case the addition of virtio-rpmb. As yet another RPMB device
which only supports RPMB transactions and isn't part of a wider block
device. The API dissonance comes into play when looking to implement it
as part of wider block device stacks and then having to do things like
fake 0 length eMMC devices with just an RPMB partition to use existing
tools.

I guess that was the original attraction of having a common kernel
subsystem to interact with RPMB functionality regardless of the
underlying HW. However from the other comments it seems the preference
is just to leave it to user-space and domain specific tools for each
device type.

>
> Thanks,
> Avri


-- 
Alex Bennée


Re: [RFC PATCH 2/5] char: rpmb: provide a user space interface

2021-03-04 Thread Alex Bennée


Winkler, Tomas  writes:

>> "Winkler, Tomas"  writes:
>> 
>> >> The user space API is achieved via a number of synchronous IOCTLs.
>> >>
>> >>   * RPMB_IOC_VER_CMD - simple versioning API
>> >>   * RPMB_IOC_CAP_CMD - query of underlying capabilities
>> >>   * RPMB_IOC_PKEY_CMD - one time programming of access key
>> >>   * RPMB_IOC_COUNTER_CMD - query the write counter
>> >>   * RPMB_IOC_WBLOCKS_CMD - write blocks to device
>> >>   * RPMB_IOC_RBLOCKS_CMD - read blocks from device
>> >>
>> >> The keys used for programming and writing blocks to the device are
>> >> key_serial_t handles as provided by the keyctl() interface.
>> >>
>> >> [AJB: here there are two key differences between this and the
>> >> original proposal. The first is the dropping of the sequence of
>> >> preformated frames in favour of explicit actions. The second is the
>> >> introduction of key_serial_t and the keyring API for referencing the
>> >> key to use]
>> >
>> > Putting it gently I'm not sure this is good idea, from the security point 
>> > of
>> view.
>> > The key has to be possession of the one that signs the frames as they are,
>> it doesn't mean it is linux kernel keyring, it can be other party on 
>> different
>> system.
>> > With this approach you will make the other usecases not applicable. It
>> > is less then trivial to move key securely from one system to another.
>> 
>> OK I can understand the desire for such a use-case but it does constrain the
>> interface on the kernel with access to the hardware to purely providing a
>> pipe to the raw hardware while also having to expose the details of the HW
>> to userspace. 
> This is the use case in Android. The key is in the "trusty" which
> different os running in a virtual environment. The file storage
> abstraction is implemented there. I'm not sure the point of
> constraining the kernel, can you please elaborate on that.

Well the kernel is all about abstracting differences not baking in
assumptions. However can I ask a bit more about this security model?

Is the secure enclave just a separate userspace process or is it in a
separate virtual machine? Is it accessible at all by the kernel running
the driver?

The fact that key id is passed down into the kernel doesn't have to
imply the kernel does the final cryptographic operation. In the ARM
world you could make a call to the secure world to do the operation for
you. I note the keyctl() interface already has support for going to
userspace to make queries of the keyring. Maybe what is really needed is
an abstraction for the kernel to delegate the MAC calculation to some other
trusted process that also understands the keyid.

>
> Also doesn't this break down after a PROGRAM_KEY event as
>> the key will have had to traverse into the "untrusted" kernel?
>
> This is one in a life event of the card happening on the manufacturing
> floor, maybe even not performed on Linux.

In an off list conversation it was suggested that maybe the PROGRAM_KEY
ioctl should be disabled for locked down kernels to dissuade production
use of the facility (it is handy for testing though!).

>> I wonder if virtio-rpmb may be of help here? You could wrap up up the front-
>> end in the security domain that has the keys although I don't know how easy
>> it would be for a backend to work with real hardware?
>
> I'm open to see any proposal, not sure I can wrap may head about it right 
> now. 
>
> Anyway I was about to send the new round of my code,  but let's come to 
> common ground first. 
>

OK - I'll see what the others say.

-- 
Alex Bennée


Re: [RFC PATCH 2/5] char: rpmb: provide a user space interface

2021-03-04 Thread Alex Bennée
"Winkler, Tomas"  writes:

>> The user space API is achieved via a number of synchronous IOCTLs.
>> 
>>   * RPMB_IOC_VER_CMD - simple versioning API
>>   * RPMB_IOC_CAP_CMD - query of underlying capabilities
>>   * RPMB_IOC_PKEY_CMD - one time programming of access key
>>   * RPMB_IOC_COUNTER_CMD - query the write counter
>>   * RPMB_IOC_WBLOCKS_CMD - write blocks to device
>>   * RPMB_IOC_RBLOCKS_CMD - read blocks from device
>> 
>> The keys used for programming and writing blocks to the device are
>> key_serial_t handles as provided by the keyctl() interface.
>> 
>> [AJB: here there are two key differences between this and the original
>> proposal. The first is the dropping of the sequence of preformated frames in
>> favour of explicit actions. The second is the introduction of key_serial_t 
>> and
>> the keyring API for referencing the key to use]
>
> Putting it gently I'm not sure this is good idea, from the security point of 
> view.
> The key has to be possession of the one that signs the frames as they are, it 
> doesn't mean it is linux kernel keyring, it can be other party on different 
> system.
> With this approach you will make the other usecases not applicable. It
> is less then trivial to move key securely from one system to another.

OK I can understand the desire for such a use-case but it does constrain
the interface on the kernel with access to the hardware to purely
providing a pipe to the raw hardware while also having to expose the
details of the HW to userspace. Also doesn't this break down after a
PROGRAM_KEY event as the key will have had to traverse into the
"untrusted" kernel?

I wonder if virtio-rpmb may be of help here? You could wrap up up the
front-end in the security domain that has the keys although I don't know
how easy it would be for a backend to work with real hardware?

> We all wished it can be abstracted more but the frames has to come already 
> signed, and the key material is inside the frame. 
> Thanks
> Tomas
>
>
>> 
>> Signed-off-by: Alex Bennée 
>> Cc: Ulf Hansson 
>> Cc: Linus  Walleij 
>> Cc: Arnd Bergmann 
>> Cc: Ilias Apalodimas 
>> Cc: Tomas Winkler 
>> Cc: Alexander Usyskin 
>> Cc: Avri Altman 
>> ---
>>  .../userspace-api/ioctl/ioctl-number.rst  |   1 +
>>  MAINTAINERS   |   1 +
>>  drivers/char/rpmb/Kconfig |   7 +
>>  drivers/char/rpmb/Makefile|   1 +
>>  drivers/char/rpmb/cdev.c  | 246 ++
>>  drivers/char/rpmb/core.c  |  10 +-
>>  drivers/char/rpmb/rpmb-cdev.h |  17 ++
>>  include/linux/rpmb.h  |  10 +
>>  include/uapi/linux/rpmb.h |  68 +
>>  9 files changed, 357 insertions(+), 4 deletions(-)  create mode 100644
>> drivers/char/rpmb/cdev.c  create mode 100644 drivers/char/rpmb/rpmb-
>> cdev.h  create mode 100644 include/uapi/linux/rpmb.h
>> 
>> diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst
>> b/Documentation/userspace-api/ioctl/ioctl-number.rst
>> index a4c75a28c839..0ff2d4d81bb0 100644
>> --- a/Documentation/userspace-api/ioctl/ioctl-number.rst
>> +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
>> @@ -344,6 +344,7 @@ Code  Seq#Include File
>> Comments
>>  0xB5  00-0F  uapi/linux/rpmsg.h  
>> <mailto:linux-
>> remotep...@vger.kernel.org>
>>  0xB6  alllinux/fpga-dfl.h
>>  0xB7  alluapi/linux/remoteproc_cdev.h
>> <mailto:linux-
>> remotep...@vger.kernel.org>
>> +0xB8  80-8F  uapi/linux/rpmb.h   
>> <mailto:linux-
>> m...@vger.kernel.org>
>>  0xC0  00-0F  linux/usb/iowarrior.h
>>  0xCA  00-0F  uapi/misc/cxl.h
>>  0xCA  10-2F  uapi/misc/ocxl.h
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 076f3983526c..c60b41b6e6bd 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -15374,6 +15374,7 @@ M:   ?
>>  L:  linux-kernel@vger.kernel.org
>>  S:  Supported
>>  F:  drivers/char/rpmb/*
>> +F:  include/uapi/linux/rpmb.h
>>  F:  include/linux/rpmb.h
>> 
>>  RTL2830 MEDIA DRIVER
>> diff --git a/drivers/char/rpmb/Kconfig b/drivers/char/rpmb/Kconfig index
>> 431c2823cf70..9068664a399a 100644
>> --- a/drivers/char/rpmb/Kconfig
>> +++ b/drivers/char/rpmb/Kconfig
>> @@ -9,3 +9,10 @@ config RPMB
>>access RPMB partition.
>> 
>>If unsure, select N.

Re: [RFC PATCH 1/5] rpmb: add Replay Protected Memory Block (RPMB) subsystem

2021-03-03 Thread Alex Bennée
Foolishly I'd missed you out of the series Cc so you only got those
two patches. You should find the rest @

Subject: [RFC PATCH  0/5] RPMB internal and user-space API + WIP
virtio-rpmb frontend
Date: Wed,  3 Mar 2021 13:54:55 +
Message-Id: <20210303135500.24673-1-alex.ben...@linaro.org>

assuming you are subscribed to one of the Cc'd lists.

On Wed, 3 Mar 2021 at 15:29, Ulf Hansson  wrote:
>
> On Wed, 3 Mar 2021 at 14:55, Alex Bennée  wrote:
> >
> > A number of storage technologies support a specialised hardware
> > partition designed to be resistant to replay attacks. The underlying
> > HW protocols differ but the operations are common. The RPMB partition
> > cannot be accessed via standard block layer, but by a set of specific
> > commands: WRITE, READ, GET_WRITE_COUNTER, and PROGRAM_KEY. Such a
> > partition provides authenticated and replay protected access, hence
> > suitable as a secure storage.
> >
> > The RPMB layer aims to provide in-kernel API for Trusted Execution
> > Environment (TEE) devices that are capable to securely compute block
> > frame signature. In case a TEE device wishes to store a replay
> > protected data, requests the storage device via RPMB layer to store
> > the data.
> >
> > A TEE device driver can claim the RPMB interface, for example, via
> > class_interface_register(). The RPMB layer provides a series of
> > operations for interacting with the device.
> >
> >   * program_key - a one time operation for setting up a new device
> >   * get_capacity - introspect the device capacity
> >   * get_write_count - check the write counter
> >   * write_blocks - write a series of blocks to the RPMB device
> >   * read_blocks - read a series of blocks from the RPMB device
> >
> > The detailed operation of implementing the access is left to the TEE
> > device driver itself.
> >
> > [This is based-on Thomas Winkler's proposed API from:
> >
> >   
> > https://lore.kernel.org/linux-mmc/1478548394-8184-2-git-send-email-tomas.wink...@intel.com/
> >
> > The principle difference is the framing details and HW specific
> > bits (JDEC vs NVME frames) are left to the lower level TEE driver to
> > worry about. The eventual userspace ioctl interface will aim to be
> > similarly generic. This is an RFC to follow up on:
> >
> >   Subject: RPMB user space ABI
> >   Date: Thu, 11 Feb 2021 14:07:00 +
> >   Message-ID: <87mtwashi4@linaro.org>]
> >
> > Signed-off-by: Alex Bennée 
> > Cc: Tomas Winkler 
> > Cc: Ulf Hansson 
> > Cc: Linus  Walleij 
> > Cc: Arnd Bergmann 
> > Cc: Ilias Apalodimas 
>
> Alex, I promise to have a closer look at this and provide my opinions.
>
> However, it looks like you have posted patch 1 and patch2, but the
> remainder 3, 4, 5 I can't find. Was this perhaps intentional?
>
> Moreover, I think these kinds of changes deserve a proper
> cover-letter, describing the overall goal with the series. Can you
> perhaps re-submit, so clarify things.
>
> Kind regards
> Uffe
>
> > ---
> >  MAINTAINERS|   7 +
> >  drivers/char/Kconfig   |   2 +
> >  drivers/char/Makefile  |   1 +
> >  drivers/char/rpmb/Kconfig  |  11 +
> >  drivers/char/rpmb/Makefile |   7 +
> >  drivers/char/rpmb/core.c   | 429 +
> >  include/linux/rpmb.h   | 163 ++
> >  7 files changed, 620 insertions(+)
> >  create mode 100644 drivers/char/rpmb/Kconfig
> >  create mode 100644 drivers/char/rpmb/Makefile
> >  create mode 100644 drivers/char/rpmb/core.c
> >  create mode 100644 include/linux/rpmb.h
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index bfc1b86e3e73..076f3983526c 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -15369,6 +15369,13 @@ T: git git://linuxtv.org/media_tree.git
> >  F: 
> > Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml
> >  F: drivers/media/platform/sunxi/sun8i-rotate/
> >
> > +RPMB SUBSYSTEM
> > +M: ?
> > +L: linux-kernel@vger.kernel.org
> > +S: Supported
> > +F: drivers/char/rpmb/*
> > +F: include/linux/rpmb.h
> > +
> >  RTL2830 MEDIA DRIVER
> >  M: Antti Palosaari 
> >  L: linux-me...@vger.kernel.org
> > diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
> > index d229a2d0c017..a7834cc3e0ea 100644
> > --- a/drivers/char/Kconfig
> > +++ b/drivers/char/Kconfig
> > @@ -471,6 +471,8 @@ config ADI
> >   and SSM (Silicon 

[RFC PATCH 4/5] rpmb: create virtio rpmb frontend driver [WIP]

2021-03-03 Thread Alex Bennée
This implements a virtio rpmb frontend driver for the RPMB subsystem.

[AJB: the principle difference is all the MAC calculation and
validation is now done in the driver]

Signed-off-by: Alex Bennée 
Cc: Tomas Winkler 

---
ajb:
  - add include linux/slab.h for kzalloc
  - include standardised VIRTIO_ID_RPMB
  - remove extra frames when sending commands down virtqueue
  - clean up out/in sgs - hopefully more conforming
  - remove cmd_cap code
---
 drivers/char/rpmb/Kconfig|  10 +
 drivers/char/rpmb/Makefile   |   1 +
 drivers/char/rpmb/virtio_rpmb.c  | 366 +++
 include/uapi/linux/virtio_ids.h  |   1 +
 include/uapi/linux/virtio_rpmb.h |  54 +
 5 files changed, 432 insertions(+)
 create mode 100644 drivers/char/rpmb/virtio_rpmb.c
 create mode 100644 include/uapi/linux/virtio_rpmb.h

diff --git a/drivers/char/rpmb/Kconfig b/drivers/char/rpmb/Kconfig
index 9068664a399a..845f458452a5 100644
--- a/drivers/char/rpmb/Kconfig
+++ b/drivers/char/rpmb/Kconfig
@@ -16,3 +16,13 @@ config RPMB_INTF_DEV
help
  Say yes here if you want to access RPMB from user space
  via character device interface /dev/rpmb%d
+
+config VIRTIO_RPMB
+   tristate "Virtio RPMB character device interface /dev/vrpmb"
+   default n
+   depends on VIRTIO && KEYS
+   select RPMB
+   help
+ Say yes here if you want to access virtio RPMB from user space
+ via character device interface /dev/vrpmb.
+ This device interface is only for guest/frontend virtio driver.
diff --git a/drivers/char/rpmb/Makefile b/drivers/char/rpmb/Makefile
index f54b3f30514b..4b397b50a42c 100644
--- a/drivers/char/rpmb/Makefile
+++ b/drivers/char/rpmb/Makefile
@@ -4,5 +4,6 @@
 obj-$(CONFIG_RPMB) += rpmb.o
 rpmb-objs += core.o
 rpmb-$(CONFIG_RPMB_INTF_DEV) += cdev.o
+obj-$(CONFIG_VIRTIO_RPMB) += virtio_rpmb.o
 
 ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/char/rpmb/virtio_rpmb.c b/drivers/char/rpmb/virtio_rpmb.c
new file mode 100644
index ..6ade26874a4e
--- /dev/null
+++ b/drivers/char/rpmb/virtio_rpmb.c
@@ -0,0 +1,366 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Virtio RPMB Front End Driver
+ *
+ * Copyright (c) 2018-2019 Intel Corporation.
+ * Copyright (c) 2021 Linaro Ltd.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RPMB_MAC_SIZE 32
+
+static const char id[] = "RPMB:VIRTIO";
+
+struct virtio_rpmb_info {
+   struct virtqueue *vq;
+   struct mutex lock; /* info lock */
+   wait_queue_head_t have_data;
+   struct rpmb_dev *rdev;
+};
+
+static void virtio_rpmb_recv_done(struct virtqueue *vq)
+{
+   struct virtio_rpmb_info *vi;
+   struct virtio_device *vdev = vq->vdev;
+
+   vi = vq->vdev->priv;
+   if (!vi) {
+   dev_err(&vdev->dev, "Error: no found vi data.\n");
+   return;
+   }
+
+   wake_up(&vi->have_data);
+}
+
+/* static int rpmb_virtio_cmd_seq(struct device *dev, u8 target, */
+/*struct rpmb_cmd *cmds, u32 ncmds) */
+/* { */
+/* struct virtio_device *vdev = dev_to_virtio(dev); */
+/* struct virtio_rpmb_info *vi = vdev->priv; */
+/* unsigned int i; */
+/* struct scatterlist out_frames[3]; */
+/* struct scatterlist in_frames[3]; */
+/* struct scatterlist *sgs[3]; */
+/* unsigned int num_out = 0, num_in = 0; */
+/* size_t sz; */
+/* int ret; */
+/* unsigned int len; */
+
+/* if (ncmds > RPMB_SEQ_CMD_MAX) */
+/* return -EINVAL; */
+
+/* mutex_lock(&vi->lock); */
+
+/* /\* */
+/*  * Process the frames - putting in the appropriate out_frames */
+/*  * and in_frames before we build our final ordered sgs[] out */
+/*  * array. */
+/*  *\/ */
+/* for (i = 0; i < ncmds; i++) { */
+/* struct rpmb_cmd *cmd = &cmds[i]; */
+/* sz = sizeof(struct rpmb_frame_jdec) * (cmd->nframes ?: 1); */
+/* if (cmd->flags) { */
+/* sg_init_one(&out_frames[num_out++], cmd->frames, sz); */
+/* } else { */
+/* sg_init_one(&in_frames[num_in++], cmd->frames, sz); */
+/* } */
+/* } */
+
+/* for (i = 0; i < num_out; i++) { */
+/* sgs[i] = &out_frames[i]; */
+/* } */
+/* for (i = 0; i < num_in; i++) { */
+/* sgs[num_out + i] = &in_frames[i]; */
+/* } */
+
+/* dev_warn(dev, "out = %d, in = %d\n", num_out, num_in); */
+
+/* virtqueue_add_sgs(vi->vq, sgs, num_out, num_in, vi, GFP_KERNEL); */
+/* virtqueue_kick(vi->vq); */
+
+/* wait_event(vi->have_data, virtqueue_get_buf(vi->vq, &len)); */
+
+/* ret = 0; */
+
+/* /\

[RFC PATCH 0/5] RPMB internal and user-space API + WIP virtio-rpmb frontend

2021-03-03 Thread Alex Bennée
Hi,

This is a follow-up to the email I sent last month:

  Subject: RPMB user space ABI
  Date: Thu, 11 Feb 2021 14:07:00 +
  Message-ID: <87mtwashi4@linaro.org>

which attempts to put some concrete flesh on the bones of the proposal
for a new internal kernel API for dealing with RPMB partitions and the
resultant exposed user-space character device API.

It became apparent while implementing a virtio-rpmb backend that the
initial proposed API didn't sit well with a device like virtio-rpmb
which isn't part of a greater device (like eMMC or UFS). It also
exposed the gritty details of the frame format to userspace leaving it
to deal with the complications of creating JDEC frames and calculating
MACs.

The series is based on Thomas' last posting with a bunch of
functionality dropped:

  - no FS/RPMB integration
  - dropped the simulator
  - dropped the sysfs patches

There is a start of a WIP virtio-rpmb front-end however as the initial
discussion should be focused on the proposed APIs I thought it would
be worth posting as an RFC before getting too deep into the weeds of
implementation. The principle changes to the original proposal:

  - frame construction left to device driver

  The differences between UFS/JEDEC/VirtioRPMB are left for the driver
  itself to deal with. This means things like MAC calculation and
  validation also remain the preserve of the low level implementation
  details. This doesn't mean there can't be shared code where
  implementation details are common across several device types.

  - key management uses keyctl()

  This means in theory userspace could interact with the RPMB device
  without having to manage the key itself. This also means you don't
  need to pass as much data about as the kernel internals can just use
  the keyring id with the API to fetch the key when required.

  - user-space interface split across several ioctls

  Now we no longer have multiple command frames going back and forth
  we can have a single structure per ioctl which just contains what is
  needed for the operation in question.

So what do people think? Is it worth pursuing this approach?

I'm certainly intended to complete the virtio-rpmb driver and test it
with my QEMU based vhost-user backend. However I've no direct interest
in implementing the interfaces to real hardware. I leave that to
people who have access to such things and are willing to take up the
maintainer burden if this is merged.


Alex Bennée (5):
  rpmb: add Replay Protected Memory Block (RPMB) subsystem
  char: rpmb: provide a user space interface
  tools rpmb: add RPBM access tool
  rpmb: create virtio rpmb frontend driver [WIP]
  tools/rpmb: simple test sequence

 .../userspace-api/ioctl/ioctl-number.rst  |   1 +
 MAINTAINERS   |   9 +
 drivers/char/Kconfig  |   2 +
 drivers/char/Makefile |   1 +
 drivers/char/rpmb/Kconfig |  28 +
 drivers/char/rpmb/Makefile|   9 +
 drivers/char/rpmb/cdev.c  | 246 +++
 drivers/char/rpmb/core.c  | 431 
 drivers/char/rpmb/rpmb-cdev.h |  17 +
 drivers/char/rpmb/virtio_rpmb.c   | 366 ++
 include/linux/rpmb.h  | 173 +
 include/uapi/linux/rpmb.h |  68 ++
 include/uapi/linux/virtio_ids.h   |   1 +
 include/uapi/linux/virtio_rpmb.h  |  54 ++
 tools/Makefile|  14 +-
 tools/rpmb/.gitignore |   2 +
 tools/rpmb/Makefile   |  41 ++
 tools/rpmb/key|   1 +
 tools/rpmb/rpmb.c | 649 ++
 tools/rpmb/test.sh|  13 +
 20 files changed, 2121 insertions(+), 5 deletions(-)
 create mode 100644 drivers/char/rpmb/Kconfig
 create mode 100644 drivers/char/rpmb/Makefile
 create mode 100644 drivers/char/rpmb/cdev.c
 create mode 100644 drivers/char/rpmb/core.c
 create mode 100644 drivers/char/rpmb/rpmb-cdev.h
 create mode 100644 drivers/char/rpmb/virtio_rpmb.c
 create mode 100644 include/linux/rpmb.h
 create mode 100644 include/uapi/linux/rpmb.h
 create mode 100644 include/uapi/linux/virtio_rpmb.h
 create mode 100644 tools/rpmb/.gitignore
 create mode 100644 tools/rpmb/Makefile
 create mode 100644 tools/rpmb/key
 create mode 100644 tools/rpmb/rpmb.c
 create mode 100755 tools/rpmb/test.sh

-- 
2.20.1



[RFC PATCH 1/5] rpmb: add Replay Protected Memory Block (RPMB) subsystem

2021-03-03 Thread Alex Bennée
A number of storage technologies support a specialised hardware
partition designed to be resistant to replay attacks. The underlying
HW protocols differ but the operations are common. The RPMB partition
cannot be accessed via standard block layer, but by a set of specific
commands: WRITE, READ, GET_WRITE_COUNTER, and PROGRAM_KEY. Such a
partition provides authenticated and replay protected access, hence
suitable as a secure storage.

The RPMB layer aims to provide in-kernel API for Trusted Execution
Environment (TEE) devices that are capable to securely compute block
frame signature. In case a TEE device wishes to store a replay
protected data, requests the storage device via RPMB layer to store
the data.

A TEE device driver can claim the RPMB interface, for example, via
class_interface_register(). The RPMB layer provides a series of
operations for interacting with the device.

  * program_key - a one time operation for setting up a new device
  * get_capacity - introspect the device capacity
  * get_write_count - check the write counter
  * write_blocks - write a series of blocks to the RPMB device
  * read_blocks - read a series of blocks from the RPMB device

The detailed operation of implementing the access is left to the TEE
device driver itself.

[This is based-on Thomas Winkler's proposed API from:

  
https://lore.kernel.org/linux-mmc/1478548394-8184-2-git-send-email-tomas.wink...@intel.com/

The principle difference is the framing details and HW specific
bits (JDEC vs NVME frames) are left to the lower level TEE driver to
worry about. The eventual userspace ioctl interface will aim to be
similarly generic. This is an RFC to follow up on:

  Subject: RPMB user space ABI
  Date: Thu, 11 Feb 2021 14:07:00 +
  Message-ID: <87mtwashi4@linaro.org>]

Signed-off-by: Alex Bennée 
Cc: Tomas Winkler 
Cc: Ulf Hansson 
Cc: Linus  Walleij 
Cc: Arnd Bergmann 
Cc: Ilias Apalodimas 
---
 MAINTAINERS|   7 +
 drivers/char/Kconfig   |   2 +
 drivers/char/Makefile  |   1 +
 drivers/char/rpmb/Kconfig  |  11 +
 drivers/char/rpmb/Makefile |   7 +
 drivers/char/rpmb/core.c   | 429 +
 include/linux/rpmb.h   | 163 ++
 7 files changed, 620 insertions(+)
 create mode 100644 drivers/char/rpmb/Kconfig
 create mode 100644 drivers/char/rpmb/Makefile
 create mode 100644 drivers/char/rpmb/core.c
 create mode 100644 include/linux/rpmb.h

diff --git a/MAINTAINERS b/MAINTAINERS
index bfc1b86e3e73..076f3983526c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15369,6 +15369,13 @@ T: git git://linuxtv.org/media_tree.git
 F: 
Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml
 F: drivers/media/platform/sunxi/sun8i-rotate/
 
+RPMB SUBSYSTEM
+M: ?
+L: linux-kernel@vger.kernel.org
+S: Supported
+F: drivers/char/rpmb/*
+F: include/linux/rpmb.h
+
 RTL2830 MEDIA DRIVER
 M: Antti Palosaari 
 L: linux-me...@vger.kernel.org
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index d229a2d0c017..a7834cc3e0ea 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -471,6 +471,8 @@ config ADI
  and SSM (Silicon Secured Memory).  Intended consumers of this
  driver include crash and makedumpfile.
 
+source "drivers/char/rpmb/Kconfig"
+
 endmenu
 
 config RANDOM_TRUST_CPU
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index ffce287ef415..0eed6e21a7a7 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_PS3_FLASH)   += ps3flash.o
 obj-$(CONFIG_XILLYBUS) += xillybus/
 obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o
 obj-$(CONFIG_ADI)  += adi.o
+obj-$(CONFIG_RPMB) += rpmb/
diff --git a/drivers/char/rpmb/Kconfig b/drivers/char/rpmb/Kconfig
new file mode 100644
index ..431c2823cf70
--- /dev/null
+++ b/drivers/char/rpmb/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2015-2019, Intel Corporation.
+
+config RPMB
+   tristate "RPMB partition interface"
+   help
+ Unified RPMB partition interface for eMMC and UFS.
+ Provides interface for in kernel security controllers to
+ access RPMB partition.
+
+ If unsure, select N.
diff --git a/drivers/char/rpmb/Makefile b/drivers/char/rpmb/Makefile
new file mode 100644
index ..24d4752a9a53
--- /dev/null
+++ b/drivers/char/rpmb/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2015-2019, Intel Corporation.
+
+obj-$(CONFIG_RPMB) += rpmb.o
+rpmb-objs += core.o
+
+ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/char/rpmb/core.c b/drivers/char/rpmb/core.c
new file mode 100644
index ..a2e21c14986a
--- /dev/null
+++ b/drivers/char/rpmb/core.c
@@ -0,0 +1,429 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(c) 2015 - 2019 Intel Corporation. All rights reserved.
+ *

[RFC PATCH 2/5] char: rpmb: provide a user space interface

2021-03-03 Thread Alex Bennée
The user space API is achieved via a number of synchronous IOCTLs.

  * RPMB_IOC_VER_CMD - simple versioning API
  * RPMB_IOC_CAP_CMD - query of underlying capabilities
  * RPMB_IOC_PKEY_CMD - one time programming of access key
  * RPMB_IOC_COUNTER_CMD - query the write counter
  * RPMB_IOC_WBLOCKS_CMD - write blocks to device
  * RPMB_IOC_RBLOCKS_CMD - read blocks from device

The keys used for programming and writing blocks to the device are
key_serial_t handles as provided by the keyctl() interface.

[AJB: here there are two key differences between this and the original
proposal. The first is the dropping of the sequence of preformated
frames in favour of explicit actions. The second is the introduction
of key_serial_t and the keyring API for referencing the key to use]

Signed-off-by: Alex Bennée 
Cc: Ulf Hansson 
Cc: Linus  Walleij 
Cc: Arnd Bergmann 
Cc: Ilias Apalodimas 
Cc: Tomas Winkler 
Cc: Alexander Usyskin 
Cc: Avri Altman 
---
 .../userspace-api/ioctl/ioctl-number.rst  |   1 +
 MAINTAINERS   |   1 +
 drivers/char/rpmb/Kconfig |   7 +
 drivers/char/rpmb/Makefile|   1 +
 drivers/char/rpmb/cdev.c  | 246 ++
 drivers/char/rpmb/core.c  |  10 +-
 drivers/char/rpmb/rpmb-cdev.h |  17 ++
 include/linux/rpmb.h  |  10 +
 include/uapi/linux/rpmb.h |  68 +
 9 files changed, 357 insertions(+), 4 deletions(-)
 create mode 100644 drivers/char/rpmb/cdev.c
 create mode 100644 drivers/char/rpmb/rpmb-cdev.h
 create mode 100644 include/uapi/linux/rpmb.h

diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst 
b/Documentation/userspace-api/ioctl/ioctl-number.rst
index a4c75a28c839..0ff2d4d81bb0 100644
--- a/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ b/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -344,6 +344,7 @@ Code  Seq#Include File  
 Comments
 0xB5  00-0F  uapi/linux/rpmsg.h  
<mailto:linux-remotep...@vger.kernel.org>
 0xB6  alllinux/fpga-dfl.h
 0xB7  alluapi/linux/remoteproc_cdev.h
<mailto:linux-remotep...@vger.kernel.org>
+0xB8  80-8F  uapi/linux/rpmb.h   
<mailto:linux-...@vger.kernel.org>
 0xC0  00-0F  linux/usb/iowarrior.h
 0xCA  00-0F  uapi/misc/cxl.h
 0xCA  10-2F  uapi/misc/ocxl.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 076f3983526c..c60b41b6e6bd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15374,6 +15374,7 @@ M:  ?
 L: linux-kernel@vger.kernel.org
 S: Supported
 F: drivers/char/rpmb/*
+F: include/uapi/linux/rpmb.h
 F: include/linux/rpmb.h
 
 RTL2830 MEDIA DRIVER
diff --git a/drivers/char/rpmb/Kconfig b/drivers/char/rpmb/Kconfig
index 431c2823cf70..9068664a399a 100644
--- a/drivers/char/rpmb/Kconfig
+++ b/drivers/char/rpmb/Kconfig
@@ -9,3 +9,10 @@ config RPMB
  access RPMB partition.
 
  If unsure, select N.
+
+config RPMB_INTF_DEV
+   bool "RPMB character device interface /dev/rpmbN"
+   depends on RPMB && KEYS
+   help
+ Say yes here if you want to access RPMB from user space
+ via character device interface /dev/rpmb%d
diff --git a/drivers/char/rpmb/Makefile b/drivers/char/rpmb/Makefile
index 24d4752a9a53..f54b3f30514b 100644
--- a/drivers/char/rpmb/Makefile
+++ b/drivers/char/rpmb/Makefile
@@ -3,5 +3,6 @@
 
 obj-$(CONFIG_RPMB) += rpmb.o
 rpmb-objs += core.o
+rpmb-$(CONFIG_RPMB_INTF_DEV) += cdev.o
 
 ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/char/rpmb/cdev.c b/drivers/char/rpmb/cdev.c
new file mode 100644
index ..55f66720fd03
--- /dev/null
+++ b/drivers/char/rpmb/cdev.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright(c) 2015 - 2019 Intel Corporation.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "rpmb-cdev.h"
+
+static dev_t rpmb_devt;
+#define RPMB_MAX_DEVS  MINORMASK
+
+#define RPMB_DEV_OPEN0  /** single open bit (position) */
+
+/**
+ * rpmb_open - the open function
+ *
+ * @inode: pointer to inode structure
+ * @fp: pointer to file structure
+ *
+ * Return: 0 on success, <0 on error
+ */
+static int rpmb_open(struct inode *inode, struct file *fp)
+{
+   struct rpmb_dev *rdev;
+
+   rdev = container_of(inode->i_cdev, struct rpmb_dev, cdev);
+   if (!rdev)
+   return -ENODEV;
+
+   /* the rpmb is single open! */
+   if (test_and_set_bit(RPMB_DEV_OPEN, &rdev->status))
+   return -EBUSY;
+
+   mutex_lock(&rdev->lock);
+
+   fp->private_data = rdev;
+
+   mutex_unlock(&rdev->lock);
+
+   return nonseekable_open(inode, fp);
+}
+
+/**
+ * rpmb_release - the cdev release 

[RFC PATCH 5/5] tools/rpmb: simple test sequence

2021-03-03 Thread Alex Bennée
A simple test script to exercise the rpmb interface.

Signed-off-by: Alex Bennée 
---
 tools/rpmb/key |  1 +
 tools/rpmb/test.sh | 13 +
 2 files changed, 14 insertions(+)
 create mode 100644 tools/rpmb/key
 create mode 100755 tools/rpmb/test.sh

diff --git a/tools/rpmb/key b/tools/rpmb/key
new file mode 100644
index ..2b6bd3bc3fe6
--- /dev/null
+++ b/tools/rpmb/key
@@ -0,0 +1 @@
+h�#ע�pRT࿮��\r|O� �mo�
\ No newline at end of file
diff --git a/tools/rpmb/test.sh b/tools/rpmb/test.sh
new file mode 100755
index ..ae5ce49a412f
--- /dev/null
+++ b/tools/rpmb/test.sh
@@ -0,0 +1,13 @@
+#!/bin/sh -e
+echo "get info"
+./rpmb -v get-info /dev/rpmb0
+echo "program key"
+./rpmb -v program-key /dev/rpmb0 key
+echo "get write counter"
+./rpmb -v write-counter /dev/rpmb0
+echo "generating data"
+dd if=/dev/urandom of=data.in count=1 bs=256
+echo "write data"
+./rpmb -v write-blocks /dev/rpmb0 0 1 data.in
+echo "read data back"
+./rpmb -v read-blocks /dev/rpmb0 0 1 data.out
-- 
2.20.1



[RFC PATCH 3/5] tools rpmb: add RPBM access tool

2021-03-03 Thread Alex Bennée
Add simple RPMB host testing tool. It can be used to program key,
write and read data block, and retrieve write counter.

[AJB: the principle differences are a simpler ioctl API which doesn't
need to do the low level frame construction itself. It also uses the
kernel keychain API for managing the keys]

Signed-off-by: Alex Bennée 
Cc: Tomas Winkler 
Cc: Alexander Usyskin 
---
 MAINTAINERS   |   1 +
 tools/Makefile|  14 +-
 tools/rpmb/.gitignore |   2 +
 tools/rpmb/Makefile   |  41 +++
 tools/rpmb/rpmb.c | 649 ++
 5 files changed, 702 insertions(+), 5 deletions(-)
 create mode 100644 tools/rpmb/.gitignore
 create mode 100644 tools/rpmb/Makefile
 create mode 100644 tools/rpmb/rpmb.c

diff --git a/MAINTAINERS b/MAINTAINERS
index c60b41b6e6bd..8b0768b16eae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15376,6 +15376,7 @@ S:  Supported
 F: drivers/char/rpmb/*
 F: include/uapi/linux/rpmb.h
 F: include/linux/rpmb.h
+F: tools/rpmb/
 
 RTL2830 MEDIA DRIVER
 M: Antti Palosaari 
diff --git a/tools/Makefile b/tools/Makefile
index 85af6ebbce91..916ab8f8cefc 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -27,6 +27,7 @@ help:
@echo '  objtool- an ELF object analysis tool'
@echo '  pci- PCI tools'
@echo '  perf   - Linux performance measurement and 
analysis tool'
+   @echo '  rpmb   - Replay protected memory block access 
tool'
@echo '  selftests  - various kernel selftests'
@echo '  bootconfig - boot config tool'
@echo '  spi- spi tools'
@@ -64,7 +65,7 @@ acpi: FORCE
 cpupower: FORCE
$(call descend,power/$@)
 
-cgroup firewire hv guest bootconfig spi usb virtio vm bpf iio gpio objtool 
leds wmi pci firmware debugging: FORCE
+cgroup firewire hv guest bootconfig rpmb spi usb virtio vm bpf iio gpio 
objtool leds wmi pci firmware debugging: FORCE
$(call descend,$@)
 
 bpf/%: FORCE
@@ -100,7 +101,7 @@ kvm_stat: FORCE
$(call descend,kvm/$@)
 
 all: acpi cgroup cpupower gpio hv firewire liblockdep \
-   perf selftests bootconfig spi turbostat usb \
+   perf rpmb selftests bootconfig spi turbostat usb \
virtio vm bpf x86_energy_perf_policy \
tmon freefall iio objtool kvm_stat wmi \
pci debugging
@@ -111,7 +112,7 @@ acpi_install:
 cpupower_install:
$(call descend,power/$(@:_install=),install)
 
-cgroup_install firewire_install gpio_install hv_install iio_install 
perf_install bootconfig_install spi_install usb_install virtio_install 
vm_install bpf_install objtool_install wmi_install pci_install 
debugging_install:
+cgroup_install firewire_install gpio_install hv_install iio_install 
rpmb_install perf_install bootconfig_install spi_install usb_install 
virtio_install vm_install bpf_install objtool_install wmi_install pci_install 
debugging_install:
$(call descend,$(@:_install=),install)
 
 liblockdep_install:
@@ -134,7 +135,7 @@ kvm_stat_install:
 
 install: acpi_install cgroup_install cpupower_install gpio_install \
hv_install firewire_install iio_install liblockdep_install \
-   perf_install selftests_install turbostat_install usb_install \
+   perf_install rpmb_install selftests_install turbostat_install 
usb_install \
virtio_install vm_install bpf_install 
x86_energy_perf_policy_install \
tmon_install freefall_install objtool_install kvm_stat_install \
wmi_install pci_install debugging_install 
intel-speed-select_install
@@ -164,6 +165,9 @@ perf_clean:
$(Q)mkdir -p $(PERF_O) .
$(Q)$(MAKE) --no-print-directory -C perf O=$(PERF_O) subdir= clean
 
+rpmb_clean:
+   $(call descend,$(@:_clean=),clean)
+
 selftests_clean:
$(call descend,testing/$(@:_clean=),clean)
 
@@ -180,7 +184,7 @@ build_clean:
$(call descend,build,clean)
 
 clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \
-   perf_clean selftests_clean turbostat_clean bootconfig_clean 
spi_clean usb_clean virtio_clean \
+   perf_clean rpmb_clean selftests_clean turbostat_clean 
bootconfig_clean spi_clean usb_clean virtio_clean \
vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean 
tmon_clean \
freefall_clean build_clean libbpf_clean libsubcmd_clean 
liblockdep_clean \
gpio_clean objtool_clean leds_clean wmi_clean pci_clean 
firmware_clean debugging_clean \
diff --git a/tools/rpmb/.gitignore b/tools/rpmb/.gitignore
new file mode 100644
index ..218f680548e6
--- /dev/null
+++ b/tools/rpmb/.gitignore
@@ -0,0 +1,2 @@
+*.o
+rpmb
diff --git a/tools/rpmb/Makefile b/tools/rpmb/Makefile
new file mode 100644
index 0

RPMB user space ABI

2021-02-15 Thread Alex Bennée
Hi,

Last year while I was implementing a virtio-rpmb backend for QEMU I
ended up using patches from the ACRN tree which was based on Thomas'
patches last posted in 2016:

  
https://lore.kernel.org/lkml/1478548394-8184-1-git-send-email-tomas.wink...@intel.com/

which I bastardised into a testing tree on a more recent kernel:

  https://git.linaro.org/people/alex.bennee/linux.git/log/?h=testing/virtio-rpmb

The main reason I hacked them around was because the VirtIO spec had
since been finalised and had a very different framing structure. The
original proposed ABI provided for an ioctl which sent JDEC frames to
the underlying device. This was later expanded to support NVME style
frames. Neither of these frame sequences matched the final VirtIO
specification.

It seems to me having the ioctl ABI at this level exposes too many
underlying HW details to user space. With the number of HW devices that
providing RPMB features likely to grow from the current 3 (eMMC/JDEC,
NVME, VirtIO) it seems this ABI should operate at a higher level, e.g.:

  PROGRAM_KEY
  GET_WRITE_COUNTER
  WRITE_DATA
  READ_DATA

and I guess some sort of asynchronous result check?

It would then be for the kernel to take the higher level concepts and
translate them to the final frames required to talk to the actual HW (if
indeed there is some).

Does this seem reasonable? Is this orthogonal to any access to RPMB
partitions that file-systems might want to do?

-- 
Alex Bennée


Re: [PATCH v1 3/3] kernel/configs: don't include PCI_QUIRKS in KVM guest configs

2020-08-04 Thread Alex Bennée


Marc Zyngier  writes:

> On 2020-08-04 15:44, Alex Bennée wrote:
>> Marc Zyngier  writes:
>> 
>>> On 2020-08-04 13:44, Alex Bennée wrote:
>>>> The VIRTIO_PCI support is an idealised PCI bus, we don't need a bunch
>>>> of bloat for real world hardware for a VirtIO guest.
>>> 
>>> Who says this guest will only have virtio devices?
>> 
>> This is true - although what is the point of kvm_guest.config? We
>> certainly turn on a whole bunch of virt optimised pathways with 
>> PARAVIRT
>> and HYPERVISOR_GUEST along with the rest of VirtIO.
>
> Most of which actually qualifies as bloat itself as far as KVM/arm64
> is concerned...

So here is the question - does the kernel care about having a blessed
config for a minimal viable guest? They are certainly used in the cloud
but I understand the kernel is trying to get away from having a zoo of
configs. What is the actual point of kvm_guest.config? Just an easy
enabling for developers?

>
>   M.


-- 
Alex Bennée


Re: [RFC PATCH v1 0/3] put arm64 kvm_config on a diet

2020-08-04 Thread Alex Bennée


Ard Biesheuvel  writes:

> On Tue, 4 Aug 2020 at 14:45, Alex Bennée  wrote:
>>
>> Hi,
>>
>> When building guest kernels for virtualisation we were bringing in a
>> bunch of stuff from physical hardware which we don't need for our
>> idealised fixable virtual PCI devices. This series makes some Kconfig
>> changes to allow the ThunderX and XGene PCI drivers to be compiled
>> out. It also drops PCI_QUIRKS from the KVM guest build as a virtual
>> PCI device should be quirk free.
>>
>
> What about PCI passthrough?

That is a good point - how much of the host PCI controller is visible to
a pass-through guest?

AIUI in passthrough the driver only interacts with the particular cards
IO window. How many quirks are visible just at the device level (rather
than the bus itself)?

That said I think the last patch might get dropped as long as the user
has the option to slim down their kernel with the first two.

>
>> This is my first time hacking around Kconfig so I hope I've got the
>> balance between depends and selects right but please let be know if it
>> could be specified in a cleaner way.
>>
>> Alex Bennée (3):
>>   arm64: allow de-selection of ThunderX PCI controllers
>>   arm64: gate the whole of pci-xgene on CONFIG_PCI_XGENE
>>   kernel/configs: don't include PCI_QUIRKS in KVM guest configs
>>
>>  arch/arm64/Kconfig.platforms| 2 ++
>>  arch/arm64/configs/defconfig| 1 +
>>  drivers/pci/controller/Kconfig  | 7 +++
>>  drivers/pci/controller/Makefile | 8 +++-
>>  kernel/configs/kvm_guest.config | 1 +
>>  5 files changed, 14 insertions(+), 5 deletions(-)
>>
>> --
>> 2.20.1
>>
>>
>> ___
>> linux-arm-kernel mailing list
>> linux-arm-ker...@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


-- 
Alex Bennée


Re: [PATCH v1 3/3] kernel/configs: don't include PCI_QUIRKS in KVM guest configs

2020-08-04 Thread Alex Bennée


Marc Zyngier  writes:

> On 2020-08-04 13:44, Alex Bennée wrote:
>> The VIRTIO_PCI support is an idealised PCI bus, we don't need a bunch
>> of bloat for real world hardware for a VirtIO guest.
>
> Who says this guest will only have virtio devices?

This is true - although what is the point of kvm_guest.config? We
certainly turn on a whole bunch of virt optimised pathways with PARAVIRT
and HYPERVISOR_GUEST along with the rest of VirtIO.

> Or even, virtio devices without bugs? Given that said device can
> come from any VMM, I'm not sure this is the right thing to do.

Perhaps this patch is one too far. I don't mind dropping it as long as I
can still slim down the kernels I know don't need the extra bloat.

>
> Thanks,
>
>  M.
>
>> 
>> Signed-off-by: Alex Bennée 
>> ---
>>  kernel/configs/kvm_guest.config | 1 +
>>  1 file changed, 1 insertion(+)
>> 
>> diff --git a/kernel/configs/kvm_guest.config 
>> b/kernel/configs/kvm_guest.config
>> index 208481d91090..672863a2fdf1 100644
>> --- a/kernel/configs/kvm_guest.config
>> +++ b/kernel/configs/kvm_guest.config
>> @@ -13,6 +13,7 @@ CONFIG_IP_PNP_DHCP=y
>>  CONFIG_BINFMT_ELF=y
>>  CONFIG_PCI=y
>>  CONFIG_PCI_MSI=y
>> +CONFIG_PCI_QUIRKS=n
>>  CONFIG_DEBUG_KERNEL=y
>>  CONFIG_VIRTUALIZATION=y
>>  CONFIG_HYPERVISOR_GUEST=y


-- 
Alex Bennée


[RFC PATCH v1 0/3] put arm64 kvm_config on a diet

2020-08-04 Thread Alex Bennée
Hi,

When building guest kernels for virtualisation we were bringing in a
bunch of stuff from physical hardware which we don't need for our
idealised fixable virtual PCI devices. This series makes some Kconfig
changes to allow the ThunderX and XGene PCI drivers to be compiled
out. It also drops PCI_QUIRKS from the KVM guest build as a virtual
PCI device should be quirk free.

This is my first time hacking around Kconfig so I hope I've got the
balance between depends and selects right but please let be know if it
could be specified in a cleaner way.

Alex Bennée (3):
  arm64: allow de-selection of ThunderX PCI controllers
  arm64: gate the whole of pci-xgene on CONFIG_PCI_XGENE
  kernel/configs: don't include PCI_QUIRKS in KVM guest configs

 arch/arm64/Kconfig.platforms| 2 ++
 arch/arm64/configs/defconfig| 1 +
 drivers/pci/controller/Kconfig  | 7 +++
 drivers/pci/controller/Makefile | 8 +++-
 kernel/configs/kvm_guest.config | 1 +
 5 files changed, 14 insertions(+), 5 deletions(-)

-- 
2.20.1



[PATCH v1 1/3] arm64: allow de-selection of ThunderX PCI controllers

2020-08-04 Thread Alex Bennée
For a pure VirtIO guest bringing in all the PCI quirk handling adds a
significant amount of bloat to kernel we don't need. Solve this by
adding a CONFIG symbol for the ThunderX PCI devices and allowing it to
be turned off. Saving over 300k from the uncompressed vmlinux:

  -rwxr-xr-x 1 alex alex  85652472 Aug  3 16:48 vmlinux*
  -rwxr-xr-x 1 alex alex  86033880 Aug  3 16:39 vmlinux.orig*

Signed-off-by: Alex Bennée 
Cc: Robert Richter 
Cc: linux-...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
---
 arch/arm64/Kconfig.platforms| 2 ++
 arch/arm64/configs/defconfig| 1 +
 drivers/pci/controller/Kconfig  | 7 +++
 drivers/pci/controller/Makefile | 4 ++--
 4 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 8dd05b2a925c..a328eebdaa59 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -253,12 +253,14 @@ config ARCH_SPRD
 
 config ARCH_THUNDER
bool "Cavium Inc. Thunder SoC Family"
+select PCI_THUNDER
help
  This enables support for Cavium's Thunder Family of SoCs.
 
 config ARCH_THUNDER2
bool "Cavium ThunderX2 Server Processors"
select GPIOLIB
+select PCI_THUNDER
help
  This enables support for Cavium's ThunderX2 CN99XX family of
  server processors.
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 2ca7ba69c318..d840cba99941 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -199,6 +199,7 @@ CONFIG_PCI_HOST_GENERIC=y
 CONFIG_PCI_XGENE=y
 CONFIG_PCIE_ALTERA=y
 CONFIG_PCIE_ALTERA_MSI=y
+CONFIG_PCI_THUNDER=y
 CONFIG_PCI_HOST_THUNDER_PEM=y
 CONFIG_PCI_HOST_THUNDER_ECAM=y
 CONFIG_PCIE_ROCKCHIP_HOST=m
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index adddf21fa381..28335ffa5d48 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -286,6 +286,13 @@ config PCI_LOONGSON
  Say Y here if you want to enable PCI controller support on
  Loongson systems.
 
+config PCI_THUNDER
+   bool "Thunder X PCIE controllers"
+   depends on ARM64
+   select PCI_QUIRKS
+   help
+  Say Y here to enable ThunderX ECAM and PEM PCI controllers.
+
 source "drivers/pci/controller/dwc/Kconfig"
 source "drivers/pci/controller/mobiveil/Kconfig"
 source "drivers/pci/controller/cadence/Kconfig"
diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index efd9733ead26..8fad4781a5d3 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -45,8 +45,8 @@ obj-y += mobiveil/
 # ARM64 and use internal ifdefs to only build the pieces we need
 # depending on whether ACPI, the DT driver, or both are enabled.
 
+obj-$(CONFIG_PCI_THUNDER) += pci-thunder-ecam.o
+obj-$(CONFIG_PCI_THUNDER) += pci-thunder-pem.o
 ifdef CONFIG_PCI
-obj-$(CONFIG_ARM64) += pci-thunder-ecam.o
-obj-$(CONFIG_ARM64) += pci-thunder-pem.o
 obj-$(CONFIG_ARM64) += pci-xgene.o
 endif
-- 
2.20.1



[PATCH v1 2/3] arm64: gate the whole of pci-xgene on CONFIG_PCI_XGENE

2020-08-04 Thread Alex Bennée
This is a little weirder as bits of the file are already conditioned
on the exiting symbol. Either way they are not actually needed for
non-xgene machines saving another 12k:

-rwxr-xr-x 1 alex alex  86033880 Aug  3 16:39 vmlinux.orig*
-rwxr-xr-x 1 alex alex  85652472 Aug  3 16:54 vmlinux.rm-thunder*
-rwxr-xr-x 1 alex alex  85639808 Aug  3 17:12 vmlinux*

Signed-off-by: Alex Bennée 
---
 drivers/pci/controller/Makefile | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile
index 8fad4781a5d3..3b9b72f5773a 100644
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -47,6 +47,4 @@ obj-y += mobiveil/
 
 obj-$(CONFIG_PCI_THUNDER) += pci-thunder-ecam.o
 obj-$(CONFIG_PCI_THUNDER) += pci-thunder-pem.o
-ifdef CONFIG_PCI
-obj-$(CONFIG_ARM64) += pci-xgene.o
-endif
+obj-$(CONFIG_PCI_XGENE) += pci-xgene.o
-- 
2.20.1



[PATCH v1 3/3] kernel/configs: don't include PCI_QUIRKS in KVM guest configs

2020-08-04 Thread Alex Bennée
The VIRTIO_PCI support is an idealised PCI bus, we don't need a bunch
of bloat for real world hardware for a VirtIO guest.

Signed-off-by: Alex Bennée 
---
 kernel/configs/kvm_guest.config | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/configs/kvm_guest.config b/kernel/configs/kvm_guest.config
index 208481d91090..672863a2fdf1 100644
--- a/kernel/configs/kvm_guest.config
+++ b/kernel/configs/kvm_guest.config
@@ -13,6 +13,7 @@ CONFIG_IP_PNP_DHCP=y
 CONFIG_BINFMT_ELF=y
 CONFIG_PCI=y
 CONFIG_PCI_MSI=y
+CONFIG_PCI_QUIRKS=n
 CONFIG_DEBUG_KERNEL=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_HYPERVISOR_GUEST=y
-- 
2.20.1



Re: [PATCH v2 0/5] virtio mmio specification enhancement

2020-08-03 Thread Alex Bennée


Alex Bennée  writes:

> Pincus, Josh  writes:
>
>> Hi,
>>
>>  
>>
>> We were looking into a similar enhancement for the Virt I/O MMIO transport 
>> and came across this project.
>>
>> This enhancement would be perfect for us.
>
> So there is certainly an interest in optimising MMIO based virtio and
> the current read/ack cycle adds additional round trip time for any trap
> and emulate hypervisor. However I think there is some resistance to
> making MMIO a re-implementation of what PCI already gives us for "free".

>
>   - Quantifying the memory foot-print difference between PCI/MMIO
>
> PCI gives a lot for free including a discovery and IRQ model already
> designed to handle MSI/MSI-X. There is a claim that this brings in a
> lot of bloat but I think there was some debate around the numbers.
> My rough initial experiment with a PCI and non-PCI build with
> otherwise identical VIRTIO configs results in the following:
>
> 16:40:15 c.282% [alex@zen:~/l/l/builds] review/rpmb|… + ls -l 
> arm64/vmlinux arm64.nopci/vmlinux
> -rwxr-xr-x 1 alex alex 83914728 Jul 31 16:39 arm64.nopci/vmlinux*
> -rwxr-xr-x 1 alex alex 86368080 Jul 31 16:33 arm64/vmlinux*
>
> which certainly implies there could be a fair amount of headroom for
> an MMIO version to implement some features. However I don't know if
> it's fully apples to apples as there maybe unneeded PCI bloat that a
> virtio-only kernel doesn't need.

Just following up after cutting the Xgene and ThunderX PCI bloat from
the kernel the margin is a little smaller:

  -rwxr-xr-x 1 alex alex 83914728 Jul 31 16:39 arm64.nopci/vmlinux*
  -rwxr-xr-x 1 alex alex 85639808 Aug  3 17:12 arm64/vmlinux*

-- 
Alex Bennée


Re: [PATCH v2 0/5] virtio mmio specification enhancement

2020-07-31 Thread Alex Bennée


Pincus, Josh  writes:

> Hi,
>
>  
>
> We were looking into a similar enhancement for the Virt I/O MMIO transport 
> and came across this project.
>
> This enhancement would be perfect for us.

So there is certainly an interest in optimising MMIO based virtio and
the current read/ack cycle adds additional round trip time for any trap
and emulate hypervisor. However I think there is some resistance to
making MMIO a re-implementation of what PCI already gives us for "free".

I believe the current questions that need to be addressed are:

  - Clear definitions in the spec on doorbells/notifications

The current virtio spec uses different terms in some places so it
would be nice to clarify the language and formalise what the
standard expects from transports w.r.t the capabilities of
notifications and doorbells.

  - Quantifying the memory foot-print difference between PCI/MMIO

PCI gives a lot for free including a discovery and IRQ model already
designed to handle MSI/MSI-X. There is a claim that this brings in a
lot of bloat but I think there was some debate around the numbers.
My rough initial experiment with a PCI and non-PCI build with
otherwise identical VIRTIO configs results in the following:

16:40:15 c.282% [alex@zen:~/l/l/builds] review/rpmb|… + ls -l arm64/vmlinux 
arm64.nopci/vmlinux
-rwxr-xr-x 1 alex alex 83914728 Jul 31 16:39 arm64.nopci/vmlinux*
-rwxr-xr-x 1 alex alex 86368080 Jul 31 16:33 arm64/vmlinux*

which certainly implies there could be a fair amount of headroom for
an MMIO version to implement some features. However I don't know if
it's fully apples to apples as there maybe unneeded PCI bloat that a
virtio-only kernel doesn't need.


What are the features you are most interested in?

> Has there been any progress since Feb, 2020?  It looks like the effort
> might have stalled?

I can't speak to the OP's but there is certainly interest from others
that are not the original posters.


-- 
Alex Bennée


Re: [PATCH v2 04/12] arm64: docs: cpu-feature-registers: Document ID_AA64PFR1_EL1

2019-10-11 Thread Alex Bennée


Dave Martin  writes:

> Commit d71be2b6c0e1 ("arm64: cpufeature: Detect SSBS and advertise
> to userspace") exposes ID_AA64PFR1_EL1 to userspace, but didn't
> update the documentation to match.
>
> Add it.
>
> Signed-off-by: Dave Martin 
>
> ---
>
> Note to maintainers:
>
>  * This patch has been racing with various other attempts to fix
>the same documentation in the meantime.
>
>Since this patch only fixes the documenting for pre-existing
>features, it can safely be dropped if appropriate.
>
>The _new_ documentation relating to BTI feature reporting
>is in a subsequent patch, and needs to be retained.
> ---
>  Documentation/arm64/cpu-feature-registers.rst | 15 +++
>  1 file changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/arm64/cpu-feature-registers.rst 
> b/Documentation/arm64/cpu-feature-registers.rst
> index 2955287..b86828f 100644
> --- a/Documentation/arm64/cpu-feature-registers.rst
> +++ b/Documentation/arm64/cpu-feature-registers.rst
> @@ -168,8 +168,15 @@ infrastructure:
>   +--+-+-+
>
>
> -  3) MIDR_EL1 - Main ID Register
> +  3) ID_AA64PFR1_EL1 - Processor Feature Register 1
> + +--+-+-+
> + | Name |  bits   | visible |
> + +--+-+-+
> + | SSBS | [7-4]   |y|
> + +--+-+-+
> +
>
> +  4) MIDR_EL1 - Main ID Register
>   +--+-+-+
>   | Name |  bits   | visible |
>   +--+-+-+
> @@ -188,7 +195,7 @@ infrastructure:
> as available on the CPU where it is fetched and is not a system
> wide safe value.
>
> -  4) ID_AA64ISAR1_EL1 - Instruction set attribute register 1
> +  5) ID_AA64ISAR1_EL1 - Instruction set attribute register 1

If I'm not mistaken .rst has support for auto-enumeration if the #
character is used. That might reduce the pain of re-numbering in future.

>
>   +--+-+-+
>   | Name |  bits   | visible |
> @@ -210,7 +217,7 @@ infrastructure:
>   | DPB  | [3-0]   |y|
>   +--+-+-+
>
> -  5) ID_AA64MMFR2_EL1 - Memory model feature register 2
> +  6) ID_AA64MMFR2_EL1 - Memory model feature register 2
>
>   +--+-+-+
>   | Name |  bits   | visible |
> @@ -218,7 +225,7 @@ infrastructure:
>   | AT   | [35-32] |y|
>   +--+-+-+
>
> -  6) ID_AA64ZFR0_EL1 - SVE feature ID register 0
> +  7) ID_AA64ZFR0_EL1 - SVE feature ID register 0
>
>   +--+-+-+
>   | Name |  bits   | visible |


--
Alex Bennée


Re: [PATCH] arm64/sve: fix genksyms generation

2019-06-17 Thread Alex Bennée


Arnd Bergmann  writes:

> On Mon, Jun 17, 2019 at 1:26 PM Will Deacon  wrote:
>>
>> Hi Arnd,
>>
>> On Mon, Jun 17, 2019 at 12:42:11PM +0200, Arnd Bergmann wrote:
>> > genksyms does not understand __uint128_t, so we get a build failure
>> > in the fpsimd module when it cannot export a symbol right:
>>
>> The fpsimd code is builtin, so which module is actually failing? My
>> allmodconfig build succeeds, so I must be missing something.
>
> It happened for me on randconfig builds, you can find one such configuration
> at https://pastebin.com/cU8iQ4ta now. I was building this with clang
> rather than gcc, which may affect the issue, but I assumed not.
>
>> > WARNING: EXPORT symbol "kernel_neon_begin" [vmlinux] version generation 
>> > failed, symbol will not be versioned.
>> > /home/arnd/cross/x86_64/gcc-8.1.0-nolibc/aarch64-linux/bin/aarch64-linux-ld:
>> >  arch/arm64/kernel/fpsimd.o: relocation R_AARCH64_ABS32 against 
>> > `__crc_kernel_neon_begin' can not be used when making a shared object
>> > arch/arm64/kernel/fpsimd.o:(.data+0x0): dangerous relocation: unsupported 
>> > relocation
>> > arch/arm64/kernel/fpsimd.o:(".discard.addressable"+0x0): dangerous 
>> > relocation: unsupported relocation
>> > arch/arm64/kernel/fpsimd.o:(".discard.addressable"+0x8): dangerous 
>> > relocation: unsupported relocation
>> >
>> > We could teach genksyms about the type, but it's easier to just
>> > work around it by defining that type locally in a way that genksyms
>> > understands.
>> >
>> > Fixes: 41040cf7c5f0 ("arm64/sve: Fix missing SVE/FPSIMD endianness 
>> > conversions")
>>
>> I can't see which part of that patch causes the problem, so I'm a bit wary
>> of the fix. We've been using __uint128_t for a while now, and I see there's
>> one in the x86 kvm code as well, so it would be nice to understand what's
>> happening here so that we can avoid running into it in future as well.
>
> The problem is only in files that export a symbol. This is also the
> case in arch/x86/kernel/kvm.c, but it may be lucky because the
> type only appears /after/ the last export in that file.
>
>> > Signed-off-by: Arnd Bergmann 
>> > ---
>> >  arch/arm64/kernel/fpsimd.c | 3 +++
>> >  1 file changed, 3 insertions(+)
>> >
>> > diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
>> > index 07f238ef47ae..2aba07cccf50 100644
>> > --- a/arch/arm64/kernel/fpsimd.c
>> > +++ b/arch/arm64/kernel/fpsimd.c
>> > @@ -400,6 +400,9 @@ static int __init sve_sysctl_init(void) { return 0; }
>> >  #define ZREG(sve_state, vq, n) ((char *)(sve_state) +\
>> >   (SVE_SIG_ZREG_OFFSET(vq, n) - SVE_SIG_REGS_OFFSET))
>> >
>> > +#ifdef __GENKSYMS__
>> > +typedef __u64 __uint128_t[2];
>> > +#endif
>>
>> I suspect I need to figure out what genksyms is doing, but I'm nervous
>> about exposing this as an array type without understanding whether or
>> not that has consequences for its operation.
>
> The entire point is genksyms is to ensure that types of exported symbols
> are compatible. To do this, it has a limited parser for C source code that
> understands the basic types (char, int, long, _Bool, etc) and how to
> aggregate them into structs and function arguments. This process has
> always been fragile, and it clearly breaks when it fails to understand a
> particular type.

Shouldn't the solution for this be to fix genksyms to be less fragile
and more understanding? The code base doesn't seem to be full of these
sorts of ifdef workarounds.

>
>   Arnd


--
Alex Bennée


[PATCH v1 1/2] kvm: arm64: handle single-step during SError exceptions

2017-11-23 Thread Alex Bennée
When an SError arrives during single-step it may be delivered before
the step completes. In that case the DBG_SPSR_SS bit will have flipped
as the instruction executed. After handling the abort in handle_exit()
we test to see if the bit is clear and we were single-stepping before
deciding if we need to exit to user space.

Signed-off-by: Alex Bennée 
---
 arch/arm64/kvm/handle_exit.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 3e645ec9e751..3ba8c4a3bcff 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
@@ -250,7 +251,12 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
return 1;
case ARM_EXCEPTION_EL1_SERROR:
kvm_inject_vabt(vcpu);
-   return 1;
+   /* We may still need to return for single-step */
+   if (!(*vcpu_cpsr(vcpu) & DBG_SPSR_SS)
+   && kvm_arm_handle_step_debug(vcpu, run))
+   return 0;
+   else
+   return 1;
case ARM_EXCEPTION_TRAP:
return handle_trap_exceptions(vcpu, run);
case ARM_EXCEPTION_HYP_GONE:
-- 
2.15.0



[PATCH v1 2/2] kvm: arm64: handle single-step of hyp emulated mmio instructions

2017-11-23 Thread Alex Bennée
There is a fast-path of MMIO emulation inside hyp mode. The handling
of single-step is broadly the same as kvm_arm_handle_step_debug()
except we just setup ESR/HSR so handle_exit() does the correct thing
as we exit.

For the case of an emulated illegal access causing an SError we will
exit via the ARM_EXCEPTION_EL1_SERROR path in handle_exit(). We behave
as we would during a real SError and clear the DBG_SPSR_SS bit for the
emulated instruction.

Signed-off-by: Alex Bennée 
---
 arch/arm64/kvm/hyp/switch.c | 37 ++---
 1 file changed, 30 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 525c01f48867..f7c651f3a8c0 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static bool __hyp_text __fpsimd_enabled_nvhe(void)
 {
@@ -269,7 +270,11 @@ static bool __hyp_text __populate_fault_info(struct 
kvm_vcpu *vcpu)
return true;
 }
 
-static void __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
+/* Skip an instruction which has been emulated. Returns true if
+ * execution can continue or false if we need to exit hyp mode because
+ * single-step was in effect.
+ */
+static bool __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
 {
*vcpu_pc(vcpu) = read_sysreg_el2(elr);
 
@@ -282,6 +287,14 @@ static void __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
}
 
write_sysreg_el2(*vcpu_pc(vcpu), elr);
+
+   if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
+   vcpu->arch.fault.esr_el2 =
+   (ESR_ELx_EC_SOFTSTP_LOW << ESR_ELx_EC_SHIFT) | 0x22;
+   return false;
+   } else {
+   return true;
+   }
 }
 
 int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
@@ -342,13 +355,21 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
int ret = __vgic_v2_perform_cpuif_access(vcpu);
 
if (ret == 1) {
-   __skip_instr(vcpu);
-   goto again;
+   if (__skip_instr(vcpu))
+   goto again;
+   else
+   exit_code = ARM_EXCEPTION_TRAP;
}
 
if (ret == -1) {
-   /* Promote an illegal access to an SError */
-   __skip_instr(vcpu);
+   /* Promote an illegal access to an
+* SError. If we would be returning
+* due to single-step clear the SS
+* bit so handle_exit knows what to
+* do after dealing with the error.
+*/
+   if (!__skip_instr(vcpu))
+   *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
exit_code = ARM_EXCEPTION_EL1_SERROR;
}
 
@@ -363,8 +384,10 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
int ret = __vgic_v3_perform_cpuif_access(vcpu);
 
if (ret == 1) {
-   __skip_instr(vcpu);
-   goto again;
+   if (__skip_instr(vcpu))
+   goto again;
+   else
+   exit_code = ARM_EXCEPTION_TRAP;
}
 
/* 0 falls through to be handled out of EL2 */
-- 
2.15.0



[RFC PATCH] kvm: arm64: handle single-step of hyp emulated mmio instructions

2017-11-22 Thread Alex Bennée
There is a fast-path of MMIO emulation inside hyp mode. The handling
of single-step is broadly the same as kvm_arm_handle_step_debug()
except we just setup ESR/HSR so handle_exit() does the correct thing
as we exit.

For the case of an emulated illegal access causing an SError we signal
to handle_exit() by clearing the DBG_SPSR_SS bit as would have
actually happened had the hardware really single-stepped the
instruction.

[AJB: currently compile tested only]

Signed-off-by: Alex Bennée 
---
 arch/arm64/kvm/handle_exit.c |  8 +++-
 arch/arm64/kvm/hyp/switch.c  | 37 ++---
 2 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index af1c804742f6..128120f04e0e 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
@@ -242,7 +243,12 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
return 1;
case ARM_EXCEPTION_EL1_SERROR:
kvm_inject_vabt(vcpu);
-   return 1;
+   /* We may still need to return for single-step */
+   if (!(*vcpu_cpsr(vcpu) & DBG_SPSR_SS)
+   && kvm_arm_handle_step_debug(vcpu, run))
+   return 0;
+   else
+   return 1;
case ARM_EXCEPTION_TRAP:
return handle_trap_exceptions(vcpu, run);
case ARM_EXCEPTION_HYP_GONE:
diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 945e79c641c4..a6712f179b52 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -22,6 +22,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static bool __hyp_text __fpsimd_enabled_nvhe(void)
 {
@@ -263,7 +264,11 @@ static bool __hyp_text __populate_fault_info(struct 
kvm_vcpu *vcpu)
return true;
 }
 
-static void __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
+/* Skip an instruction which has been emulated. Returns true if
+ * execution can continue or false if we need to exit hyp mode because
+ * single-step was in effect.
+ */
+static bool __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
 {
*vcpu_pc(vcpu) = read_sysreg_el2(elr);
 
@@ -276,6 +281,14 @@ static void __hyp_text __skip_instr(struct kvm_vcpu *vcpu)
}
 
write_sysreg_el2(*vcpu_pc(vcpu), elr);
+
+   if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
+   vcpu->arch.fault.esr_el2 =
+   (ESR_ELx_EC_SOFTSTP_LOW << ESR_ELx_EC_SHIFT) | 0x22;
+   return false;
+   } else {
+   return true;
+   }
 }
 
 int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
@@ -336,13 +349,21 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
int ret = __vgic_v2_perform_cpuif_access(vcpu);
 
if (ret == 1) {
-   __skip_instr(vcpu);
-   goto again;
+   if (__skip_instr(vcpu))
+   goto again;
+   else
+   exit_code = ARM_EXCEPTION_TRAP;
}
 
if (ret == -1) {
-   /* Promote an illegal access to an SError */
-   __skip_instr(vcpu);
+   /* Promote an illegal access to an
+* SError. If we would be returning
+* due to single-step clear the SS
+* bit so handle_exit knows what to
+* do after dealing with the error.
+*/
+   if (!__skip_instr(vcpu))
+   *vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
exit_code = ARM_EXCEPTION_EL1_SERROR;
}
 
@@ -357,8 +378,10 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
int ret = __vgic_v3_perform_cpuif_access(vcpu);
 
if (ret == 1) {
-   __skip_instr(vcpu);
-   goto again;
+   if (__skip_instr(vcpu))
+   goto again;
+   else
+   exit_code = ARM_EXCEPTION_TRAP;
}
 
/* 0 falls through to be handled out of EL2 */
-- 
2.15.0



[PATCH v3 2/3] kvm: arm64: handle single-stepping trapped instructions

2017-11-16 Thread Alex Bennée
If we are using guest debug to single-step the guest we need to ensure
we exit after emulating the instruction. This only affects
instructions completely emulated by the kernel. For userspace emulated
instructions we need to exit and return to complete the emulation.

The kvm_arm_handle_step_debug() helper sets up the necessary exit
state if needed.

Signed-off-by: Alex Bennée 
Reviewed-by: Julien Thierry 
---
v2
  - use helper from patch 1
  - if (handled > 0) instead of if (handled) so errors propagate
---
 arch/arm64/kvm/handle_exit.c | 47 +++-
 1 file changed, 33 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 7debb74843a0..af1c804742f6 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -178,6 +178,38 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu 
*vcpu)
return arm_exit_handlers[hsr_ec];
 }
 
+/*
+ * We may be single-stepping an emulated instruction. If the emulation
+ * has been completed in-kernel we can return to userspace with a
+ * KVM_EXIT_DEBUG, otherwise the userspace needs to complete its
+ * emulation first.
+ */
+
+static int handle_trap_exceptions(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   int handled;
+
+   /*
+* See ARM ARM B1.14.1: "Hyp traps on instructions
+* that fail their condition code check"
+*/
+   if (!kvm_condition_valid(vcpu)) {
+   kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+   handled = 1;
+   } else {
+   exit_handle_fn exit_handler;
+
+   exit_handler = kvm_get_exit_handler(vcpu);
+   handled = exit_handler(vcpu, run);
+   }
+
+   /* helper sets exit_reason if we need to return to userspace */
+   if (handled > 0 && kvm_arm_handle_step_debug(vcpu, run))
+   handled = 0;
+
+   return handled;
+}
+
 /*
  * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on
  * proper exit to userspace.
@@ -185,8 +217,6 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu 
*vcpu)
 int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
   int exception_index)
 {
-   exit_handle_fn exit_handler;
-
if (ARM_SERROR_PENDING(exception_index)) {
u8 hsr_ec = ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu));
 
@@ -214,18 +244,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
kvm_inject_vabt(vcpu);
return 1;
case ARM_EXCEPTION_TRAP:
-   /*
-* See ARM ARM B1.14.1: "Hyp traps on instructions
-* that fail their condition code check"
-*/
-   if (!kvm_condition_valid(vcpu)) {
-   kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
-   return 1;
-   }
-
-   exit_handler = kvm_get_exit_handler(vcpu);
-
-   return exit_handler(vcpu, run);
+   return handle_trap_exceptions(vcpu, run);
case ARM_EXCEPTION_HYP_GONE:
/*
 * EL2 has been reset to the hyp-stub. This happens when a guest
-- 
2.15.0



[PATCH v3 1/3] kvm: arm debug: introduce helper for single-step

2017-11-16 Thread Alex Bennée
After emulating instructions we may want return to user-space to
handle a single-step. If single-step is enabled the helper set the run
structure for return and returns true.

Signed-off-by: Alex Bennée 
Reviewed-by: Julien Thierry 
---
v2
  - kvm_arm_maybe_return_debug -> kvm_arm_handle_step_debug
  - return bool, true if return to userspace is required
---
 arch/arm/include/asm/kvm_host.h   |  5 +
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/kvm/debug.c| 22 ++
 3 files changed, 28 insertions(+)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 4a879f6ff13b..26a1ea6c6542 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -285,6 +285,11 @@ static inline void kvm_arm_init_debug(void) {}
 static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
+static inline bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu,
+struct kvm_run *run)
+{
+   return false;
+}
 
 int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
   struct kvm_device_attr *attr);
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index e923b58606e2..bbfd6a2adb2b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -369,6 +369,7 @@ void kvm_arm_init_debug(void);
 void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
+bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
   struct kvm_device_attr *attr);
 int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index dbadfaf850a7..95afd22a4634 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -221,3 +221,25 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
}
}
 }
+
+
+/*
+ * When KVM has successfully emulated the instruction we might want to
+ * return to user space with a KVM_EXIT_DEBUG. We can only do this
+ * once the emulation is complete though so for userspace emulations
+ * we have to wait until we have re-entered KVM before calling this
+ * helper.
+ *
+ * Return true (and set exit_reason) to return to userspace or false
+ * if no further action required.
+ */
+
+bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
+   run->exit_reason = KVM_EXIT_DEBUG;
+   run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << 
ESR_ELx_EC_SHIFT;
+   return true;
+   }
+   return false;
+}
-- 
2.15.0



[PATCH v3 3/3] kvm: arm64: handle single-step of userspace mmio instructions

2017-11-16 Thread Alex Bennée
The system state of KVM when using userspace emulation is not complete
until we return into KVM_RUN. To handle mmio related updates we wait
until they have been committed and then schedule our KVM_EXIT_DEBUG.

The kvm_arm_handle_step_debug() helper tells us if we need to return
and sets up the exit_reason for us.

Signed-off-by: Alex Bennée 

---
v2
  - call helper directly from kvm_arch_vcpu_ioctl_run
v3
  - return 0 (ioctl success) instead of 1
---
 virt/kvm/arm/arm.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 95cba0799828..b40440defca1 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -625,6 +625,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
ret = kvm_handle_mmio_return(vcpu, vcpu->run);
if (ret)
return ret;
+   if (kvm_arm_handle_step_debug(vcpu, vcpu->run))
+   return 0;
+
}
 
if (run->immediate_exit)
-- 
2.15.0



Re: [PATCH v2 3/3] kvm: arm64: handle single-step of userspace mmio instructions

2017-11-13 Thread Alex Bennée

Julien Thierry  writes:

> Hi Alex,
>
> On 09/11/17 17:00, Alex Bennée wrote:
>> The system state of KVM when using userspace emulation is not complete
>> until we return into KVM_RUN. To handle mmio related updates we wait
>> until they have been committed and then schedule our KVM_EXIT_DEBUG.
>>
>> The kvm_arm_handle_step_debug() helper tells us if we need to return
>> and sets up the exit_reason for us.
>>
>> Signed-off-by: Alex Bennée 
>>
>> ---
>> v2
>>- call helper directly from kvm_arch_vcpu_ioctl_run
>> ---
>>   virt/kvm/arm/arm.c | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
>> index 95cba0799828..2991adfaca9d 100644
>> --- a/virt/kvm/arm/arm.c
>> +++ b/virt/kvm/arm/arm.c
>> @@ -625,6 +625,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, 
>> struct kvm_run *run)
>>  ret = kvm_handle_mmio_return(vcpu, vcpu->run);
>>  if (ret)
>>  return ret;
>> +if (kvm_arm_handle_step_debug(vcpu, vcpu->run))
>> +return 1;
>> +
>
> In the previous patch, kvm_arch_vcpu_ioctl_run return 0 when telling
> userspace about a debug exception. Shouldn't this branch return 0
> instead of 1?

Probably - although in practice it makes no difference. In QEMU for
example the test is if (run_ret < 0) to handle errors. Otherwise success
is assumed.

> Returning on non-zero for kvm_handle_mmio_return is done because it
> means there was an error. This is not the case for
> kvm_arm_handle_step_debug.
>
> The description in the comment of kvm_arch_vcpu_ioctl_run is not very
> clear whether non-zero result should be used for errors or if only the
> negative values are treated as such, and positive values seems to be
> generally used to keep the vcpu going. So, I thought it might make
> sense to always return the same value upon debug exceptions.

There is a subtle mis-match between what gets passed back to the ioctl
and what terminates the while() loop later on. As far as the ioctl is
concerned it's 0 success and - error. Once you get to the while loop
you'll only ever exit once ret is no longer > 0.

Anyway for consistency we should certainly return 0, I'll fix it on the
next iteration.

>
> Cheers,


--
Alex Bennée


[PATCH] fixup! kvm: arm debug: introduce helper for single-step

2017-11-09 Thread Alex Bennée
---
 arch/arm/include/asm/kvm_host.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index a2e881d6108e..26a1ea6c6542 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -286,7 +286,10 @@ static inline void kvm_arm_setup_debug(struct kvm_vcpu 
*vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
 static inline bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu,
-struct kvm_run *run) {}
+struct kvm_run *run)
+{
+   return false;
+}
 
 int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
   struct kvm_device_attr *attr);
-- 
2.14.2



[PATCH v2 1/3] kvm: arm debug: introduce helper for single-step

2017-11-09 Thread Alex Bennée
After emulating instructions we may want return to user-space to
handle a single-step. If single-step is enabled the helper set the run
structure for return and returns true.

Signed-off-by: Alex Bennée 

---
v2
  - kvm_arm_maybe_return_debug -> kvm_arm_handle_step_debug
  - return bool, true if return to userspace is required
---
 arch/arm/include/asm/kvm_host.h   |  2 ++
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/kvm/debug.c| 22 ++
 3 files changed, 25 insertions(+)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 4a879f6ff13b..a2e881d6108e 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -285,6 +285,8 @@ static inline void kvm_arm_init_debug(void) {}
 static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
+static inline bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu,
+struct kvm_run *run) {}
 
 int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
   struct kvm_device_attr *attr);
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index e923b58606e2..bbfd6a2adb2b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -369,6 +369,7 @@ void kvm_arm_init_debug(void);
 void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
+bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
   struct kvm_device_attr *attr);
 int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index dbadfaf850a7..95afd22a4634 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -221,3 +221,25 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
}
}
 }
+
+
+/*
+ * When KVM has successfully emulated the instruction we might want to
+ * return to user space with a KVM_EXIT_DEBUG. We can only do this
+ * once the emulation is complete though so for userspace emulations
+ * we have to wait until we have re-entered KVM before calling this
+ * helper.
+ *
+ * Return true (and set exit_reason) to return to userspace or false
+ * if no further action required.
+ */
+
+bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
+   run->exit_reason = KVM_EXIT_DEBUG;
+   run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << 
ESR_ELx_EC_SHIFT;
+   return true;
+   }
+   return false;
+}
-- 
2.14.2



[PATCH v2 3/3] kvm: arm64: handle single-step of userspace mmio instructions

2017-11-09 Thread Alex Bennée
The system state of KVM when using userspace emulation is not complete
until we return into KVM_RUN. To handle mmio related updates we wait
until they have been committed and then schedule our KVM_EXIT_DEBUG.

The kvm_arm_handle_step_debug() helper tells us if we need to return
and sets up the exit_reason for us.

Signed-off-by: Alex Bennée 

---
v2
  - call helper directly from kvm_arch_vcpu_ioctl_run
---
 virt/kvm/arm/arm.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index 95cba0799828..2991adfaca9d 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -625,6 +625,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
ret = kvm_handle_mmio_return(vcpu, vcpu->run);
if (ret)
return ret;
+   if (kvm_arm_handle_step_debug(vcpu, vcpu->run))
+   return 1;
+
}
 
if (run->immediate_exit)
-- 
2.14.2



[PATCH v2 2/3] kvm: arm64: handle single-stepping trapped instructions

2017-11-09 Thread Alex Bennée
If we are using guest debug to single-step the guest we need to ensure
we exit after emulating the instruction. This only affects
instructions completely emulated by the kernel. For userspace emulated
instructions we need to exit and return to complete the emulation.

The kvm_arm_handle_step_debug() helper sets up the necessary exit
state if needed.

Signed-off-by: Alex Bennée 

---
v2
  - use helper from patch 1
  - if (handled > 0) instead of if (handled) so errors propagate
---
 arch/arm64/kvm/handle_exit.c | 47 +++-
 1 file changed, 33 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 7debb74843a0..af1c804742f6 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -178,6 +178,38 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu 
*vcpu)
return arm_exit_handlers[hsr_ec];
 }
 
+/*
+ * We may be single-stepping an emulated instruction. If the emulation
+ * has been completed in-kernel we can return to userspace with a
+ * KVM_EXIT_DEBUG, otherwise the userspace needs to complete its
+ * emulation first.
+ */
+
+static int handle_trap_exceptions(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   int handled;
+
+   /*
+* See ARM ARM B1.14.1: "Hyp traps on instructions
+* that fail their condition code check"
+*/
+   if (!kvm_condition_valid(vcpu)) {
+   kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+   handled = 1;
+   } else {
+   exit_handle_fn exit_handler;
+
+   exit_handler = kvm_get_exit_handler(vcpu);
+   handled = exit_handler(vcpu, run);
+   }
+
+   /* helper sets exit_reason if we need to return to userspace */
+   if (handled > 0 && kvm_arm_handle_step_debug(vcpu, run))
+   handled = 0;
+
+   return handled;
+}
+
 /*
  * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on
  * proper exit to userspace.
@@ -185,8 +217,6 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu 
*vcpu)
 int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
   int exception_index)
 {
-   exit_handle_fn exit_handler;
-
if (ARM_SERROR_PENDING(exception_index)) {
u8 hsr_ec = ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu));
 
@@ -214,18 +244,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
kvm_inject_vabt(vcpu);
return 1;
case ARM_EXCEPTION_TRAP:
-   /*
-* See ARM ARM B1.14.1: "Hyp traps on instructions
-* that fail their condition code check"
-*/
-   if (!kvm_condition_valid(vcpu)) {
-   kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
-   return 1;
-   }
-
-   exit_handler = kvm_get_exit_handler(vcpu);
-
-   return exit_handler(vcpu, run);
+   return handle_trap_exceptions(vcpu, run);
case ARM_EXCEPTION_HYP_GONE:
/*
 * EL2 has been reset to the hyp-stub. This happens when a guest
-- 
2.14.2



Re: [PATCH v1 2/2] kvm: arm64: handle single-step of userspace mmio instructions

2017-10-13 Thread Alex Bennée

Christoffer Dall  writes:

> On Fri, Oct 06, 2017 at 12:39:21PM +0100, Alex Bennée wrote:
>> The system state of KVM when using userspace emulation is not complete
>> until we return into KVM_RUN. To handle mmio related updates we wait
>> until they have been committed and then schedule our KVM_EXIT_DEBUG.
>>
>> I've introduced a new function kvm_arm_maybe_return_debug() to wrap up
>> the differences between arm/arm64 which is currently null for arm.
>>
>> Signed-off-by: Alex Bennée 
>> ---
>>  arch/arm/include/asm/kvm_host.h   |  2 ++
>>  arch/arm64/include/asm/kvm_host.h |  1 +
>>  arch/arm64/kvm/debug.c| 21 +
>>  arch/arm64/kvm/handle_exit.c  |  9 +++--
>>  virt/kvm/arm/arm.c|  2 +-
>>  virt/kvm/arm/mmio.c   |  3 ++-
>>  6 files changed, 30 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_host.h 
>> b/arch/arm/include/asm/kvm_host.h
>> index 4a879f6ff13b..aec943f6d123 100644
>> --- a/arch/arm/include/asm/kvm_host.h
>> +++ b/arch/arm/include/asm/kvm_host.h
>> @@ -285,6 +285,8 @@ static inline void kvm_arm_init_debug(void) {}
>>  static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
>>  static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
>>  static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
>> +static inline int  kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu,
>> +struct kvm_run *run) {}
>>
>>  int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
>> struct kvm_device_attr *attr);
>> diff --git a/arch/arm64/include/asm/kvm_host.h 
>> b/arch/arm64/include/asm/kvm_host.h
>> index e923b58606e2..fa67d21662f6 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -369,6 +369,7 @@ void kvm_arm_init_debug(void);
>>  void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
>>  void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
>>  void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
>> +int  kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu, struct kvm_run *run);
>>  int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
>> struct kvm_device_attr *attr);
>>  int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
>> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
>> index dbadfaf850a7..a10a18c55c87 100644
>> --- a/arch/arm64/kvm/debug.c
>> +++ b/arch/arm64/kvm/debug.c
>> @@ -221,3 +221,24 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
>>  }
>>  }
>>  }
>> +
>> +
>> +/*
>> + * When KVM has successfully emulated the instruction we might want to
>> + * return we a KVM_EXIT_DEBUG. We can only do this once the emulation
>> + * is complete though so for userspace emulations we have to wait
>> + * until we have re-entered KVM.
>> + *
>> + * Return > 0 to return to guest, 0 (and set exit_reason) on proper
>> + * exit to userspace.
>> + */
>> +
>> +int kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> +{
>> +if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
>> +run->exit_reason = KVM_EXIT_DEBUG;
>> +run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << 
>> ESR_ELx_EC_SHIFT;
>> +return 0;
>> +}
>> +return 1;
>> +}
>> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
>> index c918d291cb58..7b04f59217bf 100644
>> --- a/arch/arm64/kvm/handle_exit.c
>> +++ b/arch/arm64/kvm/handle_exit.c
>> @@ -202,13 +202,10 @@ static int handle_trap_exceptions(struct kvm_vcpu 
>> *vcpu, struct kvm_run *run)
>>  handled = exit_handler(vcpu, run);
>>  }
>>
>> -if (handled && (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)) {
>> -handled = 0;
>> -run->exit_reason = KVM_EXIT_DEBUG;
>> -run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << 
>> ESR_ELx_EC_SHIFT;
>> -}
>> +if (handled)
>> +return kvm_arm_maybe_return_debug(vcpu, run);
>
> Again, this seems to override the return value of exit_handler, which
> may be something negative.
>
> Just so I'm clear: There's no intended functionality change of this
> particular hunk, it's just to share the logic in
> kvm_arm_maybe_return_debug, right?

Yes, modulo the annoying semantics in the two places of the vcpu run
ioctl loo

Re: [PATCH v1 2/2] kvm: arm64: handle single-step of userspace mmio instructions

2017-10-13 Thread Alex Bennée

Christoffer Dall  writes:

> On Fri, Oct 06, 2017 at 02:45:35PM +0100, Alex Bennée wrote:
>>
>> Julien Thierry  writes:
>>
>> > On 06/10/17 12:39, Alex Bennée wrote:
>> >> The system state of KVM when using userspace emulation is not complete
>> >> until we return into KVM_RUN. To handle mmio related updates we wait
>> >> until they have been committed and then schedule our KVM_EXIT_DEBUG.
>> >>
>> >> I've introduced a new function kvm_arm_maybe_return_debug() to wrap up
>> >> the differences between arm/arm64 which is currently null for arm.
>> >>
>> >> Signed-off-by: Alex Bennée 
>> >> ---
>> >>   arch/arm/include/asm/kvm_host.h   |  2 ++
>> >>   arch/arm64/include/asm/kvm_host.h |  1 +
>> >>   arch/arm64/kvm/debug.c| 21 +
>> >>   arch/arm64/kvm/handle_exit.c  |  9 +++--
>> >>   virt/kvm/arm/arm.c|  2 +-
>> >>   virt/kvm/arm/mmio.c   |  3 ++-
>> >>   6 files changed, 30 insertions(+), 8 deletions(-)
>> >>
>> >> diff --git a/arch/arm/include/asm/kvm_host.h 
>> >> b/arch/arm/include/asm/kvm_host.h
>> >> index 4a879f6ff13b..aec943f6d123 100644
>> >> --- a/arch/arm/include/asm/kvm_host.h
>> >> +++ b/arch/arm/include/asm/kvm_host.h
>> >> @@ -285,6 +285,8 @@ static inline void kvm_arm_init_debug(void) {}
>> >>   static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
>> >>   static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
>> >>   static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
>> >> +static inline int  kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu,
>> >> + struct kvm_run *run) {}
>> >>
>> >
>> > This function should return 1.
>>
>> So I did ponder making this a bool, returning true if we need to exit
>> and testing in v/k/a/arm.c exit leg rather than in the mmio handler.
>>
>> At the moment it mirrors the existing exit logic which follows -1 err, 0
>> return, >0 handled. But as I mentioned in the cover letter this fell
>> down a bit when dealing with the mmio case.
>>
>> >
>> >>   int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
>> >>  struct kvm_device_attr *attr);
>> >> diff --git a/arch/arm64/include/asm/kvm_host.h 
>> >> b/arch/arm64/include/asm/kvm_host.h
>> >> index e923b58606e2..fa67d21662f6 100644
>> >> --- a/arch/arm64/include/asm/kvm_host.h
>> >> +++ b/arch/arm64/include/asm/kvm_host.h
>> >> @@ -369,6 +369,7 @@ void kvm_arm_init_debug(void);
>> >>   void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
>> >>   void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
>> >>   void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
>> >> +int  kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu, struct kvm_run 
>> >> *run);
>> >
>> > I feel the name could be a little bit more explicit:
>> >
>> > kvm_arm_trap_need_step_debug, kvm_arm_trap_step_return_debug,
>> > kvm_arm_trap_need_return_debug.
>>
>> I wanted to keep the debug suffix so that's fine although I'm not so
>> sure trap is correct because on the tail end of mmio emulation are we
>> still trapping?
>>
>> Maybe kvm_arm_step_emulated_debug?
>
> I think you should name it:
>
> kvm_arm_should_complete_emulated_instr_debug() - or something better -

Naming is hard :-/

> and call it directly from kvm_arch_vcpu_ioctl_run, so that it becomes:
>
>   ret = kvm_handle_mmio_return(vcpu, vcpu->run);
>   if (ret)
>   return ret;
>   ret = kvm_arm_should_complete_emulated_instr_debug(vcpu);
>   if (ret)
>   return ret;

This runs into the problem of slightly different ret semantics for here
and in handle_exit. Maybe just having a bool response and:

if (kvm_arm_should_complete_emulated_instr_debug(vcpu))
return 0;

And then in handle_exit:

if (handled == 1 && kvm_arm_should_complete_emulated_instr_debug(vcpu))
return 0;
else
return handled;

?
>
>>
>> > At least, I think it would be nice that the name reflect that this
>> > check is meant for emulated instructions.
>> >
>> > Otherwise:
>> >
>> > Reviewed-by: Julien Thierry 
>> >
>> > Thanks,
>>
>>
> Thanks,
> -Christoffer


--
Alex Bennée


Re: [PATCH v1 1/2] KVM: arm64: handle single-stepping trapped instructions

2017-10-13 Thread Alex Bennée

Christoffer Dall  writes:

> On Fri, Oct 06, 2017 at 12:39:20PM +0100, Alex Bennée wrote:
>> If we are using guest debug to single-step the guest we need to ensure
>> we exit after emulating the instruction. This only affects
>> instructions completely emulated by the kernel. For userspace emulated
>> instructions we need to exit and return to complete the emulation.
>>
>> We fake debug.arch.hsr to contain ESR_ELx_EC_SOFTSTP_LOW so QEMU knows
>> it was a single-step event (and without altering the userspace ABI).
>>
>> Signed-off-by: Alex Bennée 
>> ---
>>  arch/arm64/kvm/handle_exit.c | 48 
>> +++-
>>  1 file changed, 34 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
>> index 7debb74843a0..c918d291cb58 100644
>> --- a/arch/arm64/kvm/handle_exit.c
>> +++ b/arch/arm64/kvm/handle_exit.c
>> @@ -178,6 +178,39 @@ static exit_handle_fn kvm_get_exit_handler(struct 
>> kvm_vcpu *vcpu)
>>  return arm_exit_handlers[hsr_ec];
>>  }
>>
>> +/*
>> + * When handling traps we need to ensure exit the guest if we
>> + * completely emulated the instruction while single-stepping. Stuff to
>> + * be emulated in userspace needs to complete that first.
>> + */
>
> I really don't understand the first sentence here.  We are already out
> of the guest, so do you mean a return to userspace?
> I think the second sentence could be more clear as well.  Is 'stuff' not
> actually 'MMIO emulation' or 'emulation' more broadly?

Your right - it's sloppily worded how about:

 /*
  * We may be single-stepping an emulated instruction. If the emulation
  * has been completed in-kernel we can return to userspace with a
  * KVM_EXIT_DEBUG, otherwise the userspace needs to complete it's
  * emulation first.
  */

For x86 there is also IO emulation but in principle anything that might
be passed off to userspace to be completed should be done first.

>
>> +
>> +static int handle_trap_exceptions(struct kvm_vcpu *vcpu, struct kvm_run 
>> *run)
>> +{
>> +int handled;
>> +
>> +/*
>> + * See ARM ARM B1.14.1: "Hyp traps on instructions
>> + * that fail their condition code check"
>> + */
>> +if (!kvm_condition_valid(vcpu)) {
>> +kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
>> +handled = 1;
>> +} else {
>> +exit_handle_fn exit_handler;
>> +
>> +exit_handler = kvm_get_exit_handler(vcpu);
>> +handled = exit_handler(vcpu, run);
>> +}
>> +
>> +if (handled && (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)) {
>
> Don't you want if (handled == 1) or if (handled > 0) ?
>
> If there was an error I think we want to just return that to userspace
> and not override it and present single-stepping.

Yes, I'll fix it.

>
>> +handled = 0;
>> +run->exit_reason = KVM_EXIT_DEBUG;
>> +run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << 
>> ESR_ELx_EC_SHIFT;
>> +}
>> +
>> +return handled;
>> +}
>> +
>>  /*
>>   * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on
>>   * proper exit to userspace.
>> @@ -185,8 +218,6 @@ static exit_handle_fn kvm_get_exit_handler(struct 
>> kvm_vcpu *vcpu)
>>  int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
>> int exception_index)
>>  {
>> -exit_handle_fn exit_handler;
>> -
>>  if (ARM_SERROR_PENDING(exception_index)) {
>>  u8 hsr_ec = ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu));
>>
>> @@ -214,18 +245,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run 
>> *run,
>>  kvm_inject_vabt(vcpu);
>>  return 1;
>>  case ARM_EXCEPTION_TRAP:
>> -/*
>> - * See ARM ARM B1.14.1: "Hyp traps on instructions
>> -     * that fail their condition code check"
>> - */
>> -if (!kvm_condition_valid(vcpu)) {
>> -kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
>> -return 1;
>> -}
>> -
>> -exit_handler = kvm_get_exit_handler(vcpu);
>> -
>> -return exit_handler(vcpu, run);
>> +return handle_trap_exceptions(vcpu, run);
>>  case ARM_EXCEPTION_HYP_GONE:
>>  /*
>>   * EL2 has been reset to the hyp-stub. This happens when a guest
>> --
>> 2.14.1
>>
>
> Thanks,
> -Christoffer


--
Alex Bennée


Re: [PATCH v1 2/2] kvm: arm64: handle single-step of userspace mmio instructions

2017-10-06 Thread Alex Bennée

Marc Zyngier  writes:

> On 06/10/17 13:37, Marc Zyngier wrote:
>> On 06/10/17 12:39, Alex Bennée wrote:
>>> The system state of KVM when using userspace emulation is not complete
>>> until we return into KVM_RUN. To handle mmio related updates we wait
>>> until they have been committed and then schedule our KVM_EXIT_DEBUG.
>>>
>>> I've introduced a new function kvm_arm_maybe_return_debug() to wrap up
>>> the differences between arm/arm64 which is currently null for arm.
>>>
>>> Signed-off-by: Alex Bennée 
>>> ---
>>>  arch/arm/include/asm/kvm_host.h   |  2 ++
>>>  arch/arm64/include/asm/kvm_host.h |  1 +
>>>  arch/arm64/kvm/debug.c| 21 +
>>>  arch/arm64/kvm/handle_exit.c  |  9 +++--
>>>  virt/kvm/arm/arm.c|  2 +-
>>>  virt/kvm/arm/mmio.c   |  3 ++-
>>>  6 files changed, 30 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/arch/arm/include/asm/kvm_host.h 
>>> b/arch/arm/include/asm/kvm_host.h
>>> index 4a879f6ff13b..aec943f6d123 100644
>>> --- a/arch/arm/include/asm/kvm_host.h
>>> +++ b/arch/arm/include/asm/kvm_host.h
>>> @@ -285,6 +285,8 @@ static inline void kvm_arm_init_debug(void) {}
>>>  static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
>>>  static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
>>>  static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
>>> +static inline int  kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu,
>>> +   struct kvm_run *run) {}
>>>
>>>  int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
>>>struct kvm_device_attr *attr);
>>> diff --git a/arch/arm64/include/asm/kvm_host.h 
>>> b/arch/arm64/include/asm/kvm_host.h
>>> index e923b58606e2..fa67d21662f6 100644
>>> --- a/arch/arm64/include/asm/kvm_host.h
>>> +++ b/arch/arm64/include/asm/kvm_host.h
>>> @@ -369,6 +369,7 @@ void kvm_arm_init_debug(void);
>>>  void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
>>>  void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
>>>  void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
>>> +int  kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu, struct kvm_run 
>>> *run);
>>>  int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
>>>struct kvm_device_attr *attr);
>>>  int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
>>> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
>>> index dbadfaf850a7..a10a18c55c87 100644
>>> --- a/arch/arm64/kvm/debug.c
>>> +++ b/arch/arm64/kvm/debug.c
>>> @@ -221,3 +221,24 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
>>> }
>>> }
>>>  }
>>> +
>>> +
>>> +/*
>>> + * When KVM has successfully emulated the instruction we might want to
>>> + * return we a KVM_EXIT_DEBUG. We can only do this once the emulation
>>> + * is complete though so for userspace emulations we have to wait
>>> + * until we have re-entered KVM.
>>> + *
>>> + * Return > 0 to return to guest, 0 (and set exit_reason) on proper
>>> + * exit to userspace.
>>> + */
>>> +
>>> +int kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>> +{
>>> +   if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
>>> +   run->exit_reason = KVM_EXIT_DEBUG;
>>> +   run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << 
>>> ESR_ELx_EC_SHIFT;
>>> +   return 0;
>>> +   }
>>> +   return 1;
>>> +}
>>> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
>>> index c918d291cb58..7b04f59217bf 100644
>>> --- a/arch/arm64/kvm/handle_exit.c
>>> +++ b/arch/arm64/kvm/handle_exit.c
>>> @@ -202,13 +202,10 @@ static int handle_trap_exceptions(struct kvm_vcpu 
>>> *vcpu, struct kvm_run *run)
>>> handled = exit_handler(vcpu, run);
>>> }
>>>
>>> -   if (handled && (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)) {
>>> -   handled = 0;
>>> -   run->exit_reason = KVM_EXIT_DEBUG;
>>> -   run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << 
>>> ESR_ELx_EC_SHIFT;
>>> -   }
>>> +   if (handled)
>>> +   return kvm_arm_maybe_return_d

Re: [PATCH v1 2/2] kvm: arm64: handle single-step of userspace mmio instructions

2017-10-06 Thread Alex Bennée

Julien Thierry  writes:

> On 06/10/17 12:39, Alex Bennée wrote:
>> The system state of KVM when using userspace emulation is not complete
>> until we return into KVM_RUN. To handle mmio related updates we wait
>> until they have been committed and then schedule our KVM_EXIT_DEBUG.
>>
>> I've introduced a new function kvm_arm_maybe_return_debug() to wrap up
>> the differences between arm/arm64 which is currently null for arm.
>>
>> Signed-off-by: Alex Bennée 
>> ---
>>   arch/arm/include/asm/kvm_host.h   |  2 ++
>>   arch/arm64/include/asm/kvm_host.h |  1 +
>>   arch/arm64/kvm/debug.c| 21 +
>>   arch/arm64/kvm/handle_exit.c  |  9 +++--
>>   virt/kvm/arm/arm.c|  2 +-
>>   virt/kvm/arm/mmio.c   |  3 ++-
>>   6 files changed, 30 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_host.h 
>> b/arch/arm/include/asm/kvm_host.h
>> index 4a879f6ff13b..aec943f6d123 100644
>> --- a/arch/arm/include/asm/kvm_host.h
>> +++ b/arch/arm/include/asm/kvm_host.h
>> @@ -285,6 +285,8 @@ static inline void kvm_arm_init_debug(void) {}
>>   static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
>>   static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
>>   static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
>> +static inline int  kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu,
>> +struct kvm_run *run) {}
>>
>
> This function should return 1.

So I did ponder making this a bool, returning true if we need to exit
and testing in v/k/a/arm.c exit leg rather than in the mmio handler.

At the moment it mirrors the existing exit logic which follows -1 err, 0
return, >0 handled. But as I mentioned in the cover letter this fell
down a bit when dealing with the mmio case.

>
>>   int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
>> struct kvm_device_attr *attr);
>> diff --git a/arch/arm64/include/asm/kvm_host.h 
>> b/arch/arm64/include/asm/kvm_host.h
>> index e923b58606e2..fa67d21662f6 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -369,6 +369,7 @@ void kvm_arm_init_debug(void);
>>   void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
>>   void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
>>   void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
>> +int  kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu, struct kvm_run *run);
>
> I feel the name could be a little bit more explicit:
>
> kvm_arm_trap_need_step_debug, kvm_arm_trap_step_return_debug,
> kvm_arm_trap_need_return_debug.

I wanted to keep the debug suffix so that's fine although I'm not so
sure trap is correct because on the tail end of mmio emulation are we
still trapping?

Maybe kvm_arm_step_emulated_debug?

> At least, I think it would be nice that the name reflect that this
> check is meant for emulated instructions.
>
> Otherwise:
>
> Reviewed-by: Julien Thierry 
>
> Thanks,


--
Alex Bennée


[PATCH v1 1/2] KVM: arm64: handle single-stepping trapped instructions

2017-10-06 Thread Alex Bennée
If we are using guest debug to single-step the guest we need to ensure
we exit after emulating the instruction. This only affects
instructions completely emulated by the kernel. For userspace emulated
instructions we need to exit and return to complete the emulation.

We fake debug.arch.hsr to contain ESR_ELx_EC_SOFTSTP_LOW so QEMU knows
it was a single-step event (and without altering the userspace ABI).

Signed-off-by: Alex Bennée 
---
 arch/arm64/kvm/handle_exit.c | 48 +++-
 1 file changed, 34 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 7debb74843a0..c918d291cb58 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -178,6 +178,39 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu 
*vcpu)
return arm_exit_handlers[hsr_ec];
 }
 
+/*
+ * When handling traps we need to ensure exit the guest if we
+ * completely emulated the instruction while single-stepping. Stuff to
+ * be emulated in userspace needs to complete that first.
+ */
+
+static int handle_trap_exceptions(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   int handled;
+
+   /*
+* See ARM ARM B1.14.1: "Hyp traps on instructions
+* that fail their condition code check"
+*/
+   if (!kvm_condition_valid(vcpu)) {
+   kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+   handled = 1;
+   } else {
+   exit_handle_fn exit_handler;
+
+   exit_handler = kvm_get_exit_handler(vcpu);
+   handled = exit_handler(vcpu, run);
+   }
+
+   if (handled && (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)) {
+   handled = 0;
+   run->exit_reason = KVM_EXIT_DEBUG;
+   run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << 
ESR_ELx_EC_SHIFT;
+   }
+
+   return handled;
+}
+
 /*
  * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on
  * proper exit to userspace.
@@ -185,8 +218,6 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu 
*vcpu)
 int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
   int exception_index)
 {
-   exit_handle_fn exit_handler;
-
if (ARM_SERROR_PENDING(exception_index)) {
u8 hsr_ec = ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu));
 
@@ -214,18 +245,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
kvm_inject_vabt(vcpu);
return 1;
case ARM_EXCEPTION_TRAP:
-   /*
-* See ARM ARM B1.14.1: "Hyp traps on instructions
-* that fail their condition code check"
-*/
-   if (!kvm_condition_valid(vcpu)) {
-   kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
-   return 1;
-   }
-
-   exit_handler = kvm_get_exit_handler(vcpu);
-
-   return exit_handler(vcpu, run);
+   return handle_trap_exceptions(vcpu, run);
case ARM_EXCEPTION_HYP_GONE:
/*
 * EL2 has been reset to the hyp-stub. This happens when a guest
-- 
2.14.1



[PATCH v1 2/2] kvm: arm64: handle single-step of userspace mmio instructions

2017-10-06 Thread Alex Bennée
The system state of KVM when using userspace emulation is not complete
until we return into KVM_RUN. To handle mmio related updates we wait
until they have been committed and then schedule our KVM_EXIT_DEBUG.

I've introduced a new function kvm_arm_maybe_return_debug() to wrap up
the differences between arm/arm64 which is currently null for arm.

Signed-off-by: Alex Bennée 
---
 arch/arm/include/asm/kvm_host.h   |  2 ++
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/kvm/debug.c| 21 +
 arch/arm64/kvm/handle_exit.c  |  9 +++--
 virt/kvm/arm/arm.c|  2 +-
 virt/kvm/arm/mmio.c   |  3 ++-
 6 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 4a879f6ff13b..aec943f6d123 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -285,6 +285,8 @@ static inline void kvm_arm_init_debug(void) {}
 static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
+static inline int  kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu,
+   struct kvm_run *run) {}
 
 int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
   struct kvm_device_attr *attr);
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index e923b58606e2..fa67d21662f6 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -369,6 +369,7 @@ void kvm_arm_init_debug(void);
 void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
 void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu);
+int  kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
   struct kvm_device_attr *attr);
 int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index dbadfaf850a7..a10a18c55c87 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -221,3 +221,24 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
}
}
 }
+
+
+/*
+ * When KVM has successfully emulated the instruction we might want to
+ * return we a KVM_EXIT_DEBUG. We can only do this once the emulation
+ * is complete though so for userspace emulations we have to wait
+ * until we have re-entered KVM.
+ *
+ * Return > 0 to return to guest, 0 (and set exit_reason) on proper
+ * exit to userspace.
+ */
+
+int kvm_arm_maybe_return_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
+   run->exit_reason = KVM_EXIT_DEBUG;
+   run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << 
ESR_ELx_EC_SHIFT;
+   return 0;
+   }
+   return 1;
+}
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index c918d291cb58..7b04f59217bf 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -202,13 +202,10 @@ static int handle_trap_exceptions(struct kvm_vcpu *vcpu, 
struct kvm_run *run)
handled = exit_handler(vcpu, run);
}
 
-   if (handled && (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)) {
-   handled = 0;
-   run->exit_reason = KVM_EXIT_DEBUG;
-   run->debug.arch.hsr = ESR_ELx_EC_SOFTSTP_LOW << 
ESR_ELx_EC_SHIFT;
-   }
+   if (handled)
+   return kvm_arm_maybe_return_debug(vcpu, run);
 
-   return handled;
+   return 0;
 }
 
 /*
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c
index b9f68e4add71..3d28fe2daa26 100644
--- a/virt/kvm/arm/arm.c
+++ b/virt/kvm/arm/arm.c
@@ -623,7 +623,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
 
if (run->exit_reason == KVM_EXIT_MMIO) {
ret = kvm_handle_mmio_return(vcpu, vcpu->run);
-   if (ret)
+   if (ret < 1)
return ret;
}
 
diff --git a/virt/kvm/arm/mmio.c b/virt/kvm/arm/mmio.c
index b6e715fd3c90..e43e3bd6222f 100644
--- a/virt/kvm/arm/mmio.c
+++ b/virt/kvm/arm/mmio.c
@@ -117,7 +117,8 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
vcpu_set_reg(vcpu, vcpu->arch.mmio_decode.rt, data);
}
 
-   return 0;
+   /* If debugging in effect we may need to return now */
+   return kvm_arm_maybe_return_debug(vcpu, run);
 }
 
 static int decode_hsr(struct kvm_vcpu *vcpu, bool *is_write, int *len)
-- 
2.14.1



[PATCH v2 2/2] KVM: arm: rename pm_fake handler to trap_raz_wi

2017-05-11 Thread Alex Bennée
From: Zhichao Huang 

pm_fake doesn't quite describe what the handler does (ignoring writes
and returning 0 for reads).

As we're about to use it (a lot) in a different context, rename it
with a (admitedly cryptic) name that make sense for all users.

Signed-off-by: Zhichao Huang 
Reviewed-by: Alex Bennee 
Acked-by: Christoffer Dall 
Acked-by: Marc Zyngier 
Signed-off-by: Alex Bennée 

---
v2:
  - fix minor merge conflicts
  - add maz a-b
---
 arch/arm/kvm/coproc.c | 32 
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index c3ed6bd5ddf3..31bd9bb0b765 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -260,7 +260,7 @@ static bool access_gic_sre(struct kvm_vcpu *vcpu,
  * must always support PMCCNTR (the cycle counter): we just RAZ/WI for
  * all PM registers, which doesn't crash the guest kernel at least.
  */
-static bool pm_fake(struct kvm_vcpu *vcpu,
+static bool trap_raz_wi(struct kvm_vcpu *vcpu,
const struct coproc_params *p,
const struct coproc_reg *r)
 {
@@ -270,19 +270,19 @@ static bool pm_fake(struct kvm_vcpu *vcpu,
return read_zero(vcpu, p);
 }
 
-#define access_pmcr pm_fake
-#define access_pmcntenset pm_fake
-#define access_pmcntenclr pm_fake
-#define access_pmovsr pm_fake
-#define access_pmselr pm_fake
-#define access_pmceid0 pm_fake
-#define access_pmceid1 pm_fake
-#define access_pmccntr pm_fake
-#define access_pmxevtyper pm_fake
-#define access_pmxevcntr pm_fake
-#define access_pmuserenr pm_fake
-#define access_pmintenset pm_fake
-#define access_pmintenclr pm_fake
+#define access_pmcr trap_raz_wi
+#define access_pmcntenset trap_raz_wi
+#define access_pmcntenclr trap_raz_wi
+#define access_pmovsr trap_raz_wi
+#define access_pmselr trap_raz_wi
+#define access_pmceid0 trap_raz_wi
+#define access_pmceid1 trap_raz_wi
+#define access_pmccntr trap_raz_wi
+#define access_pmxevtyper trap_raz_wi
+#define access_pmxevcntr trap_raz_wi
+#define access_pmuserenr trap_raz_wi
+#define access_pmintenset trap_raz_wi
+#define access_pmintenclr trap_raz_wi
 
 /* Architected CP15 registers.
  * CRn denotes the primary register number, but is copied to the CRm in the
@@ -547,7 +547,7 @@ int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
struct coproc_params params = decode_64bit_hsr(vcpu);
 
/* raz_wi cp14 */
-   pm_fake(vcpu, ¶ms, NULL);
+   trap_raz_wi(vcpu, ¶ms, NULL);
 
/* handled */
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
@@ -602,7 +602,7 @@ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
struct coproc_params params = decode_32bit_hsr(vcpu);
 
/* raz_wi cp14 */
-   pm_fake(vcpu, ¶ms, NULL);
+   trap_raz_wi(vcpu, ¶ms, NULL);
 
/* handled */
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
-- 
2.11.0



[PATCH v2 1/2] KVM: arm: plug potential guest hardware debug leakage

2017-05-11 Thread Alex Bennée
From: Zhichao Huang 

Hardware debugging in guests is not intercepted currently, it means
that a malicious guest can bring down the entire machine by writing
to the debug registers.

This patch enable trapping of all debug registers, preventing the
guests to access the debug registers. This includes access to the
debug mode(DBGDSCR) in the guest world all the time which could
otherwise mess with the host state. Reads return 0 and writes are
ignored (RAZ_WI).

The result is the guest cannot detect any working hardware based debug
support. As debug exceptions are still routed to the guest normal
debug using software based breakpoints still works.

To support debugging using hardware registers we need to implement a
debug register aware world switch as well as special trapping for
registers that may affect the host state.

Signed-off-by: Zhichao Huang 
Signed-off-by: Alex Bennée 

---
ajb v2:
 - don't (void) unused return value
 - fix some 0/1 bool usage
 - further re-factor to avoid hacky if (cp15) in trap path
ajb v1:
  - convert to C world switch
  - reword commit message
---
 arch/arm/include/asm/kvm_coproc.h |  3 +-
 arch/arm/kvm/coproc.c | 77 ++-
 arch/arm/kvm/handle_exit.c|  4 +-
 arch/arm/kvm/hyp/switch.c |  4 +-
 4 files changed, 66 insertions(+), 22 deletions(-)

diff --git a/arch/arm/include/asm/kvm_coproc.h 
b/arch/arm/include/asm/kvm_coproc.h
index 4917c2f7e459..e74ab0fbab79 100644
--- a/arch/arm/include/asm/kvm_coproc.h
+++ b/arch/arm/include/asm/kvm_coproc.h
@@ -31,7 +31,8 @@ void kvm_register_target_coproc_table(struct 
kvm_coproc_target_table *table);
 int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run);
-int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 3e5e4194ef86..c3ed6bd5ddf3 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -93,12 +93,6 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
return 1;
 }
 
-int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
-{
-   kvm_inject_undefined(vcpu);
-   return 1;
-}
-
 static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
 {
/*
@@ -514,12 +508,7 @@ static int emulate_cp15(struct kvm_vcpu *vcpu,
return 1;
 }
 
-/**
- * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
- * @vcpu: The VCPU pointer
- * @run:  The kvm_run struct
- */
-int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+static struct coproc_params decode_64bit_hsr(struct kvm_vcpu *vcpu)
 {
struct coproc_params params;
 
@@ -533,9 +522,38 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
params.CRm = 0;
 
+   return params;
+}
+
+/**
+ * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   struct coproc_params params = decode_64bit_hsr(vcpu);
+
return emulate_cp15(vcpu, ¶ms);
 }
 
+/**
+ * kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   struct coproc_params params = decode_64bit_hsr(vcpu);
+
+   /* raz_wi cp14 */
+   pm_fake(vcpu, ¶ms, NULL);
+
+   /* handled */
+   kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+   return 1;
+}
+
 static void reset_coproc_regs(struct kvm_vcpu *vcpu,
  const struct coproc_reg *table, size_t num)
 {
@@ -546,12 +564,7 @@ static void reset_coproc_regs(struct kvm_vcpu *vcpu,
table[i].reset(vcpu, &table[i]);
 }
 
-/**
- * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
- * @vcpu: The VCPU pointer
- * @run:  The kvm_run struct
- */
-int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+static struct coproc_params decode_32bit_hsr(struct kvm_vcpu *vcpu)
 {
struct coproc_params params;
 
@@ -565,9 +578,37 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7;
params.Rt2 = 0;
 
+   return params;
+}
+
+/**
+ * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP

Re: [PATCH v1 1/2] KVM: arm: plug guest debug exploit

2017-05-11 Thread Alex Bennée

Marc Zyngier  writes:

> Hi Alex,
>
> On 10/05/17 18:01, Alex Bennée wrote:
>> From: Zhichao Huang 
>>
>> Hardware debugging in guests is not intercepted currently, it means
>> that a malicious guest can bring down the entire machine by writing
>> to the debug registers.
>>
>> This patch enable trapping of all debug registers, preventing the
>> guests to access the debug registers. This includes access to the
>> debug mode(DBGDSCR) in the guest world all the time which could
>> otherwise mess with the host state. Reads return 0 and writes are
>> ignored.
>>
>> The result is the guest cannot detect any working hardware based debug
>> support. As debug exceptions are still routed to the guest normal
>> debug using software based breakpoints still works.
>>
>> To support debugging using hardware registers we need to implement a
>> debug register aware world switch as well as special trapping for
>> registers that may affect the host state.
>>
>> Signed-off-by: Zhichao Huang 
>> Signed-off-by: Alex Bennée 
>>
>> ---
>> ajb:
>>   - convert to C world switch
>>   - reword commit message
>> ---
>>  arch/arm/include/asm/kvm_coproc.h |  3 +-
>>  arch/arm/kvm/coproc.c | 82 
>> +--
>>  arch/arm/kvm/handle_exit.c|  4 +-
>>  arch/arm/kvm/hyp/switch.c |  4 +-
>>  4 files changed, 69 insertions(+), 24 deletions(-)
>>
>> diff --git a/arch/arm/include/asm/kvm_coproc.h 
>> b/arch/arm/include/asm/kvm_coproc.h
>> index 4917c2f7e459..e74ab0fbab79 100644
>> --- a/arch/arm/include/asm/kvm_coproc.h
>> +++ b/arch/arm/include/asm/kvm_coproc.h
>> @@ -31,7 +31,8 @@ void kvm_register_target_coproc_table(struct 
>> kvm_coproc_target_table *table);
>>  int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run);
>>  int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
>>  int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run);
>> -int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
>> +int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
>> +int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
>>  int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
>>  int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
>>
>> diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
>> index 3e5e4194ef86..b2053393bb1f 100644
>> --- a/arch/arm/kvm/coproc.c
>> +++ b/arch/arm/kvm/coproc.c
>> @@ -93,12 +93,6 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, 
>> struct kvm_run *run)
>>  return 1;
>>  }
>>
>> -int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> -{
>> -kvm_inject_undefined(vcpu);
>> -return 1;
>> -}
>> -
>>  static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
>>  {
>>  /*
>> @@ -514,12 +508,8 @@ static int emulate_cp15(struct kvm_vcpu *vcpu,
>>  return 1;
>>  }
>>
>> -/**
>> - * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
>> - * @vcpu: The VCPU pointer
>> - * @run:  The kvm_run struct
>> - */
>> -int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> +static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, struct kvm_run *run,
>> +bool cp15)
>>  {
>>  struct coproc_params params;
>>
>> @@ -533,7 +523,35 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct 
>> kvm_run *run)
>>  params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
>>  params.CRm = 0;
>>
>> -return emulate_cp15(vcpu, ¶ms);
>> +if (cp15)
>> +return emulate_cp15(vcpu, ¶ms);
>> +
>> +/* raz_wi cp14 */
>> +(void)pm_fake(vcpu, ¶ms, NULL);
>
> Why this (void) cast?

I guess a super picky compiler could complain about throwing away a
return value? Mine didn't do I've removed it.

>
>> +
>> +/* handled */
>> +kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
>> +return 1;
>> +}
>> +
>> +/**
>> + * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
>> + * @vcpu: The VCPU pointer
>> + * @run:  The kvm_run struct
>> + */
>> +int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> +{
>> +return kvm_handle_cp_64(vcpu, run, 1);
>
> true instead of 1?

fixed

>
>> +}
>> +
&

[PATCH v1 2/2] KVM: arm: rename pm_fake handler to trap_raz_wi

2017-05-10 Thread Alex Bennée
From: Zhichao Huang 

pm_fake doesn't quite describe what the handler does (ignoring writes
and returning 0 for reads).

As we're about to use it (a lot) in a different context, rename it
with a (admitedly cryptic) name that make sense for all users.

Signed-off-by: Zhichao Huang 
Reviewed-by: Alex Bennee 
Acked-by: Christoffer Dall 
Signed-off-by: Alex Bennée 
---
 arch/arm/kvm/coproc.c | 32 
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index b2053393bb1f..6919363ce7cc 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -260,7 +260,7 @@ static bool access_gic_sre(struct kvm_vcpu *vcpu,
  * must always support PMCCNTR (the cycle counter): we just RAZ/WI for
  * all PM registers, which doesn't crash the guest kernel at least.
  */
-static bool pm_fake(struct kvm_vcpu *vcpu,
+static bool trap_raz_wi(struct kvm_vcpu *vcpu,
const struct coproc_params *p,
const struct coproc_reg *r)
 {
@@ -270,19 +270,19 @@ static bool pm_fake(struct kvm_vcpu *vcpu,
return read_zero(vcpu, p);
 }
 
-#define access_pmcr pm_fake
-#define access_pmcntenset pm_fake
-#define access_pmcntenclr pm_fake
-#define access_pmovsr pm_fake
-#define access_pmselr pm_fake
-#define access_pmceid0 pm_fake
-#define access_pmceid1 pm_fake
-#define access_pmccntr pm_fake
-#define access_pmxevtyper pm_fake
-#define access_pmxevcntr pm_fake
-#define access_pmuserenr pm_fake
-#define access_pmintenset pm_fake
-#define access_pmintenclr pm_fake
+#define access_pmcr trap_raz_wi
+#define access_pmcntenset trap_raz_wi
+#define access_pmcntenclr trap_raz_wi
+#define access_pmovsr trap_raz_wi
+#define access_pmselr trap_raz_wi
+#define access_pmceid0 trap_raz_wi
+#define access_pmceid1 trap_raz_wi
+#define access_pmccntr trap_raz_wi
+#define access_pmxevtyper trap_raz_wi
+#define access_pmxevcntr trap_raz_wi
+#define access_pmuserenr trap_raz_wi
+#define access_pmintenset trap_raz_wi
+#define access_pmintenclr trap_raz_wi
 
 /* Architected CP15 registers.
  * CRn denotes the primary register number, but is copied to the CRm in the
@@ -527,7 +527,7 @@ static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, struct 
kvm_run *run,
return emulate_cp15(vcpu, ¶ms);
 
/* raz_wi cp14 */
-   (void)pm_fake(vcpu, ¶ms, NULL);
+   (void)trap_raz_wi(vcpu, ¶ms, NULL);
 
/* handled */
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
@@ -583,7 +583,7 @@ static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, struct 
kvm_run *run,
return emulate_cp15(vcpu, ¶ms);
 
/* raz_wi cp14 */
-   (void)pm_fake(vcpu, ¶ms, NULL);
+   (void)trap_raz_wi(vcpu, ¶ms, NULL);
 
/* handled */
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
-- 
2.11.0



[PATCH v1 1/2] KVM: arm: plug guest debug exploit

2017-05-10 Thread Alex Bennée
From: Zhichao Huang 

Hardware debugging in guests is not intercepted currently, it means
that a malicious guest can bring down the entire machine by writing
to the debug registers.

This patch enable trapping of all debug registers, preventing the
guests to access the debug registers. This includes access to the
debug mode(DBGDSCR) in the guest world all the time which could
otherwise mess with the host state. Reads return 0 and writes are
ignored.

The result is the guest cannot detect any working hardware based debug
support. As debug exceptions are still routed to the guest normal
debug using software based breakpoints still works.

To support debugging using hardware registers we need to implement a
debug register aware world switch as well as special trapping for
registers that may affect the host state.

Signed-off-by: Zhichao Huang 
Signed-off-by: Alex Bennée 

---
ajb:
  - convert to C world switch
  - reword commit message
---
 arch/arm/include/asm/kvm_coproc.h |  3 +-
 arch/arm/kvm/coproc.c | 82 +--
 arch/arm/kvm/handle_exit.c|  4 +-
 arch/arm/kvm/hyp/switch.c |  4 +-
 4 files changed, 69 insertions(+), 24 deletions(-)

diff --git a/arch/arm/include/asm/kvm_coproc.h 
b/arch/arm/include/asm/kvm_coproc.h
index 4917c2f7e459..e74ab0fbab79 100644
--- a/arch/arm/include/asm/kvm_coproc.h
+++ b/arch/arm/include/asm/kvm_coproc.h
@@ -31,7 +31,8 @@ void kvm_register_target_coproc_table(struct 
kvm_coproc_target_table *table);
 int kvm_handle_cp10_id(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp_0_13_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct kvm_run *run);
-int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp14_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
+int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run);
 int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run);
 
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 3e5e4194ef86..b2053393bb1f 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -93,12 +93,6 @@ int kvm_handle_cp14_load_store(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
return 1;
 }
 
-int kvm_handle_cp14_access(struct kvm_vcpu *vcpu, struct kvm_run *run)
-{
-   kvm_inject_undefined(vcpu);
-   return 1;
-}
-
 static void reset_mpidr(struct kvm_vcpu *vcpu, const struct coproc_reg *r)
 {
/*
@@ -514,12 +508,8 @@ static int emulate_cp15(struct kvm_vcpu *vcpu,
return 1;
 }
 
-/**
- * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
- * @vcpu: The VCPU pointer
- * @run:  The kvm_run struct
- */
-int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+static int kvm_handle_cp_64(struct kvm_vcpu *vcpu, struct kvm_run *run,
+   bool cp15)
 {
struct coproc_params params;
 
@@ -533,7 +523,35 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
params.Rt2 = (kvm_vcpu_get_hsr(vcpu) >> 10) & 0xf;
params.CRm = 0;
 
-   return emulate_cp15(vcpu, ¶ms);
+   if (cp15)
+   return emulate_cp15(vcpu, ¶ms);
+
+   /* raz_wi cp14 */
+   (void)pm_fake(vcpu, ¶ms, NULL);
+
+   /* handled */
+   kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
+   return 1;
+}
+
+/**
+ * kvm_handle_cp15_64 -- handles a mrrc/mcrr trap on a guest CP15 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp15_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   return kvm_handle_cp_64(vcpu, run, 1);
+}
+
+/**
+ * kvm_handle_cp14_64 -- handles a mrrc/mcrr trap on a guest CP14 access
+ * @vcpu: The VCPU pointer
+ * @run:  The kvm_run struct
+ */
+int kvm_handle_cp14_64(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   return kvm_handle_cp_64(vcpu, run, 0);
 }
 
 static void reset_coproc_regs(struct kvm_vcpu *vcpu,
@@ -546,12 +564,8 @@ static void reset_coproc_regs(struct kvm_vcpu *vcpu,
table[i].reset(vcpu, &table[i]);
 }
 
-/**
- * kvm_handle_cp15_32 -- handles a mrc/mcr trap on a guest CP15 access
- * @vcpu: The VCPU pointer
- * @run:  The kvm_run struct
- */
-int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct kvm_run *run)
+static int kvm_handle_cp_32(struct kvm_vcpu *vcpu, struct kvm_run *run,
+ bool cp15)
 {
struct coproc_params params;
 
@@ -565,7 +579,35 @@ int kvm_handle_cp15_32(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
params.Op2 = (kvm_vcpu_get_hsr(vcpu) >> 17) & 0x7;
params.Rt2 = 0;
 
-   return emulate_cp15(vcpu, ¶ms);
+   if (cp15)
+   return emulate_cp15(vcpu, ¶ms);
+
+   /* raz_wi cp14 */
+   (void)pm_fake(vcpu, ¶ms, NULL);
+
+   /* handled */
+  

Re: [PATCH] binfmt_misc: allow selecting the interpreter based on xattr keywords

2016-11-11 Thread Alex Bennée

Carlos O'Donell  writes:

> On 08/26/2016 10:55 AM, Florian Weimer wrote:
>> On 08/25/2016 06:15 PM, James Bottomley wrote:
>>> On Sun, 2016-08-21 at 21:01 -0700, Josh Max wrote:

>
> This ignores the fact that the alternate loader also needs to have
> it's own ldconfig cache, implementation-dependent lookup paths etc,
> all of which have to be keyed off the xattr keyword specified dynamic
> loader. All of that is tractable though and can be done in userspace
> keyed from the selected dynamic loader. Buy why? Why not use a mount
> namespace and different loader e.g. lxc, docker, etc, or specify a
> loader that is a wrapper and does this for you?

Is binfmt_misc actually containerise-able yet? At the moment when using
qemu-user inside a docker container I still have to ensure the root
binfmt_misc points to the same location as I place qemu-user in the
docker container.

>
> I'm not convinced this is a good idea, but I'm open to learning about
> more use cases.


--
Alex Bennée


Re: [PATCH v15 00/10] arm64: Add kernel probes (kprobes) support

2016-07-15 Thread Alex Bennée

Marc Zyngier  writes:

> On 15/07/16 08:50, Catalin Marinas wrote:
>> On Thu, Jul 14, 2016 at 01:09:08PM -0400, William Cohen wrote:
>>> On 07/14/2016 12:22 PM, Catalin Marinas wrote:
>>>> On Fri, Jul 08, 2016 at 12:35:44PM -0400, David Long wrote:
>>>>> David A. Long (3):
>>>>>   arm64: Add HAVE_REGS_AND_STACK_ACCESS_API feature
>>>>>   arm64: Add more test functions to insn.c
>>>>>   arm64: add conditional instruction simulation support
>>>>>
>>>>> Pratyush Anand (2):
>>>>>   arm64: Blacklist non-kprobe-able symbol
>>>>>   arm64: Treat all entry code as non-kprobe-able
>>>>>
>>>>> Sandeepa Prabhu (4):
>>>>>   arm64: Kprobes with single stepping support
>>>>>   arm64: kprobes instruction simulation support
>>>>>   arm64: Add kernel return probes support (kretprobes)
>>>>>   kprobes: Add arm64 case in kprobe example module
>>>>>
>>>>> William Cohen (1):
>>>>>   arm64: Add trampoline code for kretprobes
>>>>
>>>> I applied these patches on top of the arm64 for-next/core branch an
>>>> tried to run the resulting kernel in a guest (on a Juno platform using
>>>> both kvmtool and qemu) with KPROBES_SANITY_TEST enabled. Unfortunately,
>>>> the kernel fails to boot with lots of "Unexpected kernel single-step
>>>> exception at EL1".
>>>>
>>>> Did you manage to run Kprobes in a guest before?
>>>
>>> I ran the systemtap testsuite several times on a physical machine
>>> running a kernel with the kprobe v15 patches without problem.
>>> Shouldn't the guest machine behave in the same manner as a host
>>> machine for single stepping and exception handling?  If the guest
>>> machine is failing, wouldn't that suggest there is a problem with the
>>> KVM handling of single stepping for guests?
>>
>> It didn't fail for me on the host either. What's strange is that on some
>> occasions even the guest managed to get to a prompt. I'll do more tests
>> today on different CPU configurations, just to rule out potential
>> hardware issues. If not hardware related, it's possible that the
>> interaction with KVM doesn't work as expected, maybe the
>> saving/restoring of the guest debug state loses information.
>
> Could well be the latter. I'll try to have a look, but Alex Bennée (on
> cc) is our man when it comes to the KVM debug infrastructure.
>
> Alex, any chance you could try this and shed some light on it?

Sure I'll have a look. There are problems with running gdb inside a
guest while trying to debug from outside associated with single-stepping
but none of this should get in the way if your not debugging the guest.

Let me get my system spun up and see if I can reproduce.

Shall I just apply this series on top of the current master?

--
Alex Bennée


Re: [PATCH v4 00/23] arm64: Virtualization Host Extension support

2016-02-29 Thread Alex Bennée

Marc Zyngier  writes:

> ARMv8.1 comes with the "Virtualization Host Extension" (VHE for
> short), which enables simpler support of Type-2 hypervisors.
>
> This extension allows the kernel to directly run at EL2, and
> significantly reduces the number of system registers shared between
> host and guest, reducing the overhead of virtualization.
>
> In order to have the same kernel binary running on all versions of the
> architecture, this series makes heavy use of runtime code patching.
>
> The first 22 patches massage the KVM code to deal with VHE and enable
> Linux to run at EL2. The last patch catches an ugly case when VHE
> capable CPUs are paired with some of their less capable siblings. This
> should never happen, but hey...
>
> I have deliberately left out some of the more "advanced"
> optimizations, as they are likely to distract the reviewer from the
> core infrastructure, which is what I care about at the moment.
>
> Note: GDB is currently busted on VHE systems, as it checks for version
>   6 on the debug architecture, while VHE is version 7. The
>   binutils people are on the case.

I assume you are talking about ptrace debug here rather than guest
debug?

Anyway from a cursory inspection I didn't see anything to worry about
from the guest debug side which is unchanged.

Acked-by: Alex Bennée 

>
> This has been tested on the FVP_Base_SLV-V8-A model, and based on
> v4.5-rc3 + kvmarm/master. I've put a branch out on:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git 
> kvm-arm64/vhe
>
> * From v3:
>   - Cleaned debug handling after comments from Catalin
>   - Added missing barriers in the panic patch
>   - Collected Rb and Acks from Christoffer and Catalin
>
> * From v2:
>   - Added support for perf to count kernel events in EL2
>   - Added support for EL2 breakpoints
>   - Moved the VTCR_EL2 setup from assembly to C
>   - Made the fault handling easier to understand (hopefuly)
>   - Plenty of smaller fixups
>
> * From v1:
>   - Full rewrite now that the World Switch is written in C code.
>   - Dropped the "early IRQ handling" for the moment.
>
> Marc Zyngier (23):
>   arm/arm64: KVM: Add hook for C-based stage2 init
>   arm64: KVM: Switch to C-based stage2 init
>   arm/arm64: Add new is_kernel_in_hyp_mode predicate
>   arm64: Allow the arch timer to use the HYP timer
>   arm64: Add ARM64_HAS_VIRT_HOST_EXTN feature
>   arm64: KVM: Skip HYP setup when already running in HYP
>   arm64: KVM: VHE: Patch out use of HVC
>   arm64: KVM: VHE: Patch out kern_hyp_va
>   arm64: KVM: VHE: Introduce unified system register accessors
>   arm64: KVM: VHE: Differenciate host/guest sysreg save/restore
>   arm64: KVM: VHE: Split save/restore of registers shared between guest
> and host
>   arm64: KVM: VHE: Use unified system register accessors
>   arm64: KVM: VHE: Enable minimal sysreg save/restore
>   arm64: KVM: VHE: Make __fpsimd_enabled VHE aware
>   arm64: KVM: VHE: Implement VHE activate/deactivate_traps
>   arm64: KVM: VHE: Use unified sysreg accessors for timer
>   arm64: KVM: VHE: Add fpsimd enabling on guest access
>   arm64: KVM: VHE: Add alternative panic handling
>   arm64: KVM: Move most of the fault decoding to C
>   arm64: perf: Count EL2 events if the kernel is running in HYP
>   arm64: hw_breakpoint: Allow EL2 breakpoints if running in HYP
>   arm64: VHE: Add support for running Linux in EL2 mode
>   arm64: Panic when VHE and non VHE CPUs coexist
>
>  arch/arm/include/asm/kvm_host.h|   4 +
>  arch/arm/include/asm/virt.h|   5 +
>  arch/arm/kvm/arm.c | 174 ++--
>  arch/arm/kvm/mmu.c |   7 ++
>  arch/arm64/Kconfig |  13 +++
>  arch/arm64/include/asm/cpufeature.h|   3 +-
>  arch/arm64/include/asm/hw_breakpoint.h |  49 +---
>  arch/arm64/include/asm/kvm_arm.h   |   6 +-
>  arch/arm64/include/asm/kvm_asm.h   |   2 +
>  arch/arm64/include/asm/kvm_emulate.h   |   3 +
>  arch/arm64/include/asm/kvm_host.h  |   6 +
>  arch/arm64/include/asm/kvm_mmu.h   |  12 +-
>  arch/arm64/include/asm/virt.h  |  27 +
>  arch/arm64/kernel/asm-offsets.c|   3 -
>  arch/arm64/kernel/cpufeature.c |  11 ++
>  arch/arm64/kernel/head.S   |  50 +++-
>  arch/arm64/kernel/perf_event.c |  14 ++-
>  arch/arm64/kernel/smp.c|   3 +
>  arch/arm64/kvm/hyp-init.S  |  18 ---
>  arch/arm64/kvm/hyp.S   |   7 ++
>  arch/arm64/kvm/hyp/Makefile|   1 +
>  arch/arm64/kvm/hyp/entry.S |   6 +
>  arch/arm64/kvm/hyp/hyp-entry.S | 109 ++

Re: [PATCH 1/8] goldfish: refactor goldfish platform configs

2015-11-25 Thread Alex Bennée

Jin Qian  writes:

> From: Greg Hackmann 
>
> On new virtual devices, the goldfish virtual bus can be replaced with
> autoprobing infrastructure like Device Tree.  Refactor the goldfish
> kernel configs to better accommodate this.

Should there be a header for this series? Does Google want to upstream
the android pipe into mainline while we are still examining VirtIO
alternatives?

>
> Move the goldfish platform into a menuconfig in the style of the chrome
> platform, and separate the goldfish bus into its own config option.
>
> Signed-off-by: Greg Hackmann 
> (cherry picked from commit 711910868190ee3645c1c52701bdde87783f)
> Signed-off-by: Jin Qian 
> ---
>  drivers/platform/Kconfig   |  3 +--
>  drivers/platform/goldfish/Kconfig  | 18 ++
>  drivers/platform/goldfish/Makefile |  2 +-
>  3 files changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
> index 0adccbf..c11db8b 100644
> --- a/drivers/platform/Kconfig
> +++ b/drivers/platform/Kconfig
> @@ -4,8 +4,7 @@ endif
>  if MIPS
>  source "drivers/platform/mips/Kconfig"
>  endif
> -if GOLDFISH
> +
>  source "drivers/platform/goldfish/Kconfig"
> -endif
>
>  source "drivers/platform/chrome/Kconfig"
> diff --git a/drivers/platform/goldfish/Kconfig 
> b/drivers/platform/goldfish/Kconfig
> index 635ef25..1ae3690 100644
> --- a/drivers/platform/goldfish/Kconfig
> +++ b/drivers/platform/goldfish/Kconfig
> @@ -1,5 +1,23 @@
> +menuconfig GOLDFISH
> + bool "Platform support for Goldfish virtual devices"
> + depends on X86_32 || X86_64 || ARM || ARM64
> + ---help---
> +   Say Y here to get to see options for the Goldfish virtual platform.
> +   This option alone does not add any kernel code.
> +
> +   Unless you are building for the Android Goldfish emulator say N here.
> +
> +if GOLDFISH
> +
> +config GOLDFISH_BUS
> + tristate "Goldfish platform bus"
> + ---help---
> +   This is a virtual bus to host Goldfish Android Virtual Devices.
> +
>  config GOLDFISH_PIPE
>   tristate "Goldfish virtual device for QEMU pipes"
>   ---help---
> This is a virtual device to drive the QEMU pipe interface used by
> the Goldfish Android Virtual Device.
> +
> +endif # GOLDFISH
> diff --git a/drivers/platform/goldfish/Makefile 
> b/drivers/platform/goldfish/Makefile
> index a002239..d348712 100644
> --- a/drivers/platform/goldfish/Makefile
> +++ b/drivers/platform/goldfish/Makefile
> @@ -1,5 +1,5 @@
>  #
>  # Makefile for Goldfish platform specific drivers
>  #
> -obj-$(CONFIG_GOLDFISH)   +=  pdev_bus.o
> +obj-$(CONFIG_GOLDFISH_BUS)   += pdev_bus.o
>  obj-$(CONFIG_GOLDFISH_PIPE)  += goldfish_pipe.o
> --
> 2.6.0.rc2.230.g3dd15c0


--
Alex Bennée
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH v4 1/3] tracing/events: Fix wrong sample output by storing array length instead of size

2015-07-23 Thread Alex Bennée

Steven Rostedt  writes:

> On Fri, 17 Jul 2015 10:32:15 -0400
> Steven Rostedt  wrote:
>
>
>> This change affects all callers of dymanic_array, not just bitmasks.
>> 
>> >__data_size += __item_length;
>> >  
>> >  #undef __string
>> 
>> BTW, if I revert commit ac01ce1410fc2 "tracing: Make
>> ftrace_print_array_seq compute buf_len" it works again.
>> 
>> I'm going to look into this some more, and maybe the answer is to go
>> back and just pass in buffer length here. I can't see what was broken
>> before that change.
>
> OK, the print_array() code is already being used by the thermal events
> and can't be changed. But we can't make the proposed change because
> that changes the user interface.
>
> What we can change is the sample code!
>
> -- Steve
>
> From 95de1e9721a2f9d05831a53d228e181a33001c55 Mon Sep 17 00:00:00 2001
> From: "Steven Rostedt (Red Hat)" 
> Date: Fri, 17 Jul 2015 14:03:26 -0400
> Subject: [PATCH] tracing: Fix sample output of dynamic arrays
>
> He Kuang noticed that the trace event samples for arrays was broken:
>
> "The output result of trace_foo_bar event in traceevent samples is
>  wrong. This problem can be reproduced as following:
>
>   (Build kernel with SAMPLE_TRACE_EVENTS=m)
>
>   $ insmod trace-events-sample.ko
>
>   $ echo 1 > /sys/kernel/debug/tracing/events/sample-trace/foo_bar/enable
>
>   $ cat /sys/kernel/debug/tracing/trace
>
>   event-sample-980 [000]   43.649559: foo_bar: foo hello 21 0x15
>   BIT1|BIT3|0x10 {0x1,0x6f6f6e53,0xff007970,0x} Snoopy
>  ^^
>  The array length is not right, should be {0x1}.
>   (,)
>
>   event-sample-980 [000]   44.653827: foo_bar: foo hello 22 0x16
>   BIT2|BIT3|0x10
>   {0x1,0x2,0x646e6147,0x666c61,0x,0x,0x750aeffe,0x7}
>   ^^
>  The array length is not right, should be {0x1,0x2}.
>   Gandalf (,)"
>
> This was caused by an update to have __print_array()'s second parameter
> be the count of items in the array and not the size of the array.
>
> As there is already users of __print_array(), it can not change. But
> the sample code can and we can also improve on the documentation about
> __print_array() and __get_dynamic_array_len().
>
> Link: 
> http://lkml.kernel.org/r/1436839171-31527-2-git-send-email-heku...@huawei.com
>
> Fixes: ac01ce1410fc2 ("tracing: Make ftrace_print_array_seq compute buf_len")
> Reported-by: He Kuang 
> Signed-off-by: Steven Rostedt 
> ---
>  samples/trace_events/trace-events-sample.h | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/samples/trace_events/trace-events-sample.h 
> b/samples/trace_events/trace-events-sample.h
> index 8965d1bb8811..125d6402f64f 100644
> --- a/samples/trace_events/trace-events-sample.h
> +++ b/samples/trace_events/trace-events-sample.h
> @@ -168,7 +168,10 @@
>   *
>   *  For __dynamic_array(int, foo, bar) use __get_dynamic_array(foo)
>   *Use __get_dynamic_array_len(foo) to get the length of the array
> - *saved.
> + *saved. Note, __get_dynamic_array_len() returns the total 
> allocated
> + *length of the dynamic array; __print_array() expects the second
> + *parameter to be the number of elements. To get that, the array 
> length
> + *needs to be divided by the element size.
>   *
>   *  For __string(foo, bar) use __get_str(foo)
>   *
> @@ -288,7 +291,7 @@ TRACE_EVENT(foo_bar,
>   *This prints out the array that is defined by __array in a nice format.
>   */
> __print_array(__get_dynamic_array(list),
> - __get_dynamic_array_len(list),
> + __get_dynamic_array_len(list) / sizeof(int),
>   sizeof(int)),
> __get_str(str), __get_bitmask(cpus))
>  );

Reviewed-by: Alex Bennée 

-- 
Alex Bennée
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v8 02/11] KVM: arm64: guest debug, define API headers

2015-07-07 Thread Alex Bennée
This commit defines the API headers for guest debugging. There are two
architecture specific debug structures:

  - kvm_guest_debug_arch, allows us to pass in HW debug registers
  - kvm_debug_exit_arch, signals exception and possible faulting address

The type of debugging being used is controlled by the architecture
specific control bits of the kvm_guest_debug->control flags in the ioctl
structure.

Signed-off-by: Alex Bennée 
Reviewed-by: David Hildenbrand 
Reviewed-by: Andrew Jones 
Acked-by: Christoffer Dall 

---
v2
   - expose hsr and pc directly to user-space
v3
   - s/control/controlled/ in commit message
   - add v8 to ARM ARM comment (ARM Architecture Reference Manual)
   - add rb tag
   - rm pc, add far
   - re-word comments on alignment
   - rename KVM_ARM_NDBG_REGS -> KVM_ARM_MAX_DBG_REGS
v4
   - now uses common HW/SW BP define
   - add a-b-tag
   - use u32 for control regs
v5
   - revert to have arch specific KVM_GUESTDBG_USE_SW/HW_BP
   - rm stale comments dbgctrl was stored as u64
v6
   - mv far comment from later patch
   - KVM_GUESTDBG_USE_HW_BP -> KVM_GUESTDBG_USE_HW
   - revert control regs to u64 (parity with GET/SET_ONE_REG)
---
 arch/arm64/include/uapi/asm/kvm.h | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/kvm.h 
b/arch/arm64/include/uapi/asm/kvm.h
index d268320..d82f3f3 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -100,12 +100,39 @@ struct kvm_sregs {
 struct kvm_fpu {
 };
 
+/*
+ * See v8 ARM ARM D7.3: Debug Registers
+ *
+ * The architectural limit is 16 debug registers of each type although
+ * in practice there are usually less (see ID_AA64DFR0_EL1).
+ *
+ * Although the control registers are architecturally defined as 32
+ * bits wide we use a 64 bit structure here to keep parity with
+ * KVM_GET/SET_ONE_REG behaviour which treats all system registers as
+ * 64 bit values. It also allows for the possibility of the
+ * architecture expanding the control registers without having to
+ * change the userspace ABI.
+ */
+#define KVM_ARM_MAX_DBG_REGS 16
 struct kvm_guest_debug_arch {
+   __u64 dbg_bcr[KVM_ARM_MAX_DBG_REGS];
+   __u64 dbg_bvr[KVM_ARM_MAX_DBG_REGS];
+   __u64 dbg_wcr[KVM_ARM_MAX_DBG_REGS];
+   __u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS];
 };
 
 struct kvm_debug_exit_arch {
+   __u32 hsr;
+   __u64 far;  /* used for watchpoints */
 };
 
+/*
+ * Architecture specific defines for kvm_guest_debug->control
+ */
+
+#define KVM_GUESTDBG_USE_SW_BP (1 << 16)
+#define KVM_GUESTDBG_USE_HW(1 << 17)
+
 struct kvm_sync_regs {
 };
 
-- 
2.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v8 08/11] KVM: arm64: introduce vcpu->arch.debug_ptr

2015-07-07 Thread Alex Bennée
This introduces a level of indirection for the debug registers. Instead
of using the sys_regs[] directly we store registers in a structure in
the vcpu. The new kvm_arm_reset_debug_ptr() sets the debug ptr to the
guest context.

Because we no longer give the sys_regs offset for the sys_reg_desc->reg
field, but instead the index into a debug-specific struct we need to
add a number of additional trap functions for each register. Also as the
generic generic user-space access code no longer works we have
introduced a new pair of function pointers to the sys_reg_desc structure
to override the generic code when needed.

Signed-off-by: Alex Bennée 

---
v6:
  - fix up some ws issues
  - correct clobber info
  - re-word commentary in kvm_host.h
  - fix endian access issues for aarch32 fields
  - revert all KVM_GET/SET_ONE_REG to 64bit (also see ABI update)
v7
  - new fn kvm_arm_reset_debug_ptr(), stubbed for arm
  - split trap fns into bcr,bvr,bcr,wvr and wxvr
  - add set/get fns to sys_regs_desc
  - reg_to_dbg/dbg_to_reg helpers for 32bit support
v8
  - rm #if 0 left over from re-factor
  - re-word reset_ptr comment
  - fix inadvertent whitespace changes
  - rename get/set to get_user/set_user
  - update commit wording
  - re-factor dbg_to_reg/reg_to_dbg
  - add newlines to keep checkpatch happy
  - ensure 63:32 of debug registers untouched by aarch32
---
 arch/arm/include/asm/kvm_host.h   |   1 +
 arch/arm/kvm/arm.c|   2 +
 arch/arm64/include/asm/kvm_asm.h  |  24 ++--
 arch/arm64/include/asm/kvm_host.h |  17 ++-
 arch/arm64/kernel/asm-offsets.c   |   6 +
 arch/arm64/kvm/debug.c|   9 ++
 arch/arm64/kvm/hyp.S  |  24 ++--
 arch/arm64/kvm/sys_regs.c | 274 +++---
 arch/arm64/kvm/sys_regs.h |   6 +
 9 files changed, 316 insertions(+), 47 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 746c0c69..825c337 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -239,5 +239,6 @@ static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, 
int cpu) {}
 static inline void kvm_arm_init_debug(void) {}
 static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
 
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index af60e6f..525473f 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -279,6 +279,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
/* Set up the timer */
kvm_timer_vcpu_init(vcpu);
 
+   kvm_arm_reset_debug_ptr(vcpu);
+
return 0;
 }
 
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index d6b507e..e997404 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -46,24 +46,16 @@
 #defineCNTKCTL_EL1 20  /* Timer Control Register (EL1) */
 #definePAR_EL1 21  /* Physical Address Register */
 #define MDSCR_EL1  22  /* Monitor Debug System Control Register */
-#define DBGBCR0_EL123  /* Debug Breakpoint Control Registers (0-15) */
-#define DBGBCR15_EL1   38
-#define DBGBVR0_EL139  /* Debug Breakpoint Value Registers (0-15) */
-#define DBGBVR15_EL1   54
-#define DBGWCR0_EL155  /* Debug Watchpoint Control Registers (0-15) */
-#define DBGWCR15_EL1   70
-#define DBGWVR0_EL171  /* Debug Watchpoint Value Registers (0-15) */
-#define DBGWVR15_EL1   86
-#define MDCCINT_EL187  /* Monitor Debug Comms Channel Interrupt Enable 
Reg */
+#define MDCCINT_EL123  /* Monitor Debug Comms Channel Interrupt Enable 
Reg */
 
 /* 32bit specific registers. Keep them at the end of the range */
-#defineDACR32_EL2  88  /* Domain Access Control Register */
-#defineIFSR32_EL2  89  /* Instruction Fault Status Register */
-#defineFPEXC32_EL2 90  /* Floating-Point Exception Control 
Register */
-#defineDBGVCR32_EL291  /* Debug Vector Catch Register */
-#defineTEECR32_EL1 92  /* ThumbEE Configuration Register */
-#defineTEEHBR32_EL193  /* ThumbEE Handler Base Register */
-#defineNR_SYS_REGS 94
+#defineDACR32_EL2  24  /* Domain Access Control Register */
+#defineIFSR32_EL2  25  /* Instruction Fault Status Register */
+#defineFPEXC32_EL2 26  /* Floating-Point Exception Control 
Register */
+#defineDBGVCR32_EL227  /* Debug Vector Catch Register */
+#defineTEECR32_EL1 28  /* ThumbEE Configuration Register */
+#defineTEEHBR32_EL129  /* ThumbEE Handler Base Register */
+#defineNR_SYS_REGS 30
 
 /* 32bit mapping */
 #define c0_MPIDR   (MPIDR_EL1 * 2) /* MultiProcessor ID Register */
diff --git a/arch/arm64/incl

[PATCH v8 05/11] KVM: arm64: guest debug, add SW break point support

2015-07-07 Thread Alex Bennée
This adds support for SW breakpoints inserted by userspace.

We do this by trapping all guest software debug exceptions to the
hypervisor (MDCR_EL2.TDE). The exit handler sets an exit reason of
KVM_EXIT_DEBUG with the kvm_debug_exit_arch structure holding the
exception syndrome information.

It will be up to userspace to extract the PC (via GET_ONE_REG) and
determine if the debug event was for a breakpoint it inserted. If not
userspace will need to re-inject the correct exception restart the
hypervisor to deliver the debug exception to the guest.

Any other guest software debug exception (e.g. single step or HW
assisted breakpoints) will cause an error and the VM to be killed. This
is addressed by later patches which add support for the other debug
types.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v2
  - update to use new exit struct
  - tweak for C setup
  - do our setup in debug_setup/clear code
  - fixed up comments
v3:
  - fix spacing in KVM_GUESTDBG_VALID_MASK
  - fix and clarify wording on kvm_handle_guest_debug
  - handle error case in kvm_handle_guest_debug
  - re-word the commit message
v4
  - rm else leg
  - add r-b-tag
v7
  - moved ioctl to guest
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/arm64/kvm/debug.c|  3 +++
 arch/arm64/kvm/guest.c|  2 +-
 arch/arm64/kvm/handle_exit.c  | 36 
 4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index ba635c7..33c8143 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2667,7 +2667,7 @@ when running. Common control bits are:
 The top 16 bits of the control field are architecture specific control
 flags which can include the following:
 
-  - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86]
+  - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64]
   - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
   - KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
   - KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index faf0e1f..8d1bfa4 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -73,6 +73,9 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
if (trap_debug)
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 
+   /* Trap breakpoints? */
+   if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+   vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
 }
 
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 0ba8677..22d22c5 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -332,7 +332,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
return -EINVAL;
 }
 
-#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE)
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
 
 /**
  * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 524fa25..27f38a9 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -82,6 +82,40 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
return 1;
 }
 
+/**
+ * kvm_handle_guest_debug - handle a debug exception instruction
+ *
+ * @vcpu:  the vcpu pointer
+ * @run:   access to the kvm_run structure for results
+ *
+ * We route all debug exceptions through the same handler. If both the
+ * guest and host are using the same debug facilities it will be up to
+ * userspace to re-inject the correct exception for guest delivery.
+ *
+ * @return: 0 (while setting run->exit_reason), -1 for error
+ */
+static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   u32 hsr = kvm_vcpu_get_hsr(vcpu);
+   int ret = 0;
+
+   run->exit_reason = KVM_EXIT_DEBUG;
+   run->debug.arch.hsr = hsr;
+
+   switch (hsr >> ESR_ELx_EC_SHIFT) {
+   case ESR_ELx_EC_BKPT32:
+   case ESR_ELx_EC_BRK64:
+   break;
+   default:
+   kvm_err("%s: un-handled case hsr: %#08x\n",
+   __func__, (unsigned int) hsr);
+   ret = -1;
+   break;
+   }
+
+   return ret;
+}
+
 static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_WFx]= kvm_handle_wfx,
[ESR_ELx_EC_CP15_32]= kvm_handle_cp15_32,
@@ -96,6 +130,8 @@ static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_SYS64]  = kvm_handle_sys_reg,
[ESR_ELx_EC_IABT_LOW]   = kvm_handle_guest_abort,
[ESR_ELx_EC_DABT_LOW]   = kvm_handle_guest_abort,
+   [ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug,
+   [ESR_ELx_EC_BRK64]  = kvm_handle_guest_debug,
 };
 
 static exit

[PATCH v8 06/11] KVM: arm64: guest debug, add support for single-step

2015-07-07 Thread Alex Bennée
This adds support for single-stepping the guest. To do this we need to
manipulate the guests PSTATE.SS and MDSCR_EL1.SS bits to trigger
stepping. We take care to preserve MDSCR_EL1 and trap access to it to
ensure we don't affect the apparent state of the guest.

As we have to enable trapping of all software debug exceptions we
suppress the ability of the guest to single-step itself. If we didn't we
would have to deal with the exception arriving while the guest was in
kernelspace when the guest is expecting to single-step userspace. This
is something we don't want to unwind in the kernel. Once the host is no
longer debugging the guest its ability to single-step userspace is
restored.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v2
  - Move pstate/mdscr manipulation into C
  - don't export guest_debug to assembly
  - add accessor for saved_debug regs
  - tweak save/restore of mdscr_el1
v3
  - don't save PC in debug information struct
  - rename debug_saved_regs->guest_debug_state
  - save whole value, only use bits in restore
  - add save/restore_guest-debug_regs helper functions
  - simplify commit message for clarity
  - rm vcpu_debug_saved_reg access fn
v4
  - added more comments based on suggestions
  - guest_debug_state->guest_debug_preserved
  - no point masking restore, we will trap out
v5
  - more comments
  - don't bother preserving pstate.ss (guest never sees change)
v6
  - reword comments on guest SS suppression
  - simplify comment for save regs, SS explained in detail later on
  - add r-b-t (code)
  - expanded commit description
v7
  - merge fix for ioctl move to guest.c
---
 arch/arm64/include/asm/kvm_host.h | 11 +++
 arch/arm64/kvm/debug.c| 68 ---
 arch/arm64/kvm/guest.c|  4 ++-
 arch/arm64/kvm/handle_exit.c  |  2 ++
 4 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 7cb99b5..e2db6a6 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -123,6 +123,17 @@ struct kvm_vcpu_arch {
 * here.
 */
 
+   /*
+* Guest registers we preserve during guest debugging.
+*
+* These shadow registers are updated by the kvm_handle_sys_reg
+* trap handler if the guest accesses or updates them while we
+* are using guest debug.
+*/
+   struct {
+   u32 mdscr_el1;
+   } guest_debug_preserved;
+
/* Don't run the guest */
bool pause;
 
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 8d1bfa4..d439eb8 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -19,11 +19,39 @@
 
 #include 
 
+#include 
+#include 
 #include 
+#include 
+
+/* These are the bits of MDSCR_EL1 we may manipulate */
+#define MDSCR_EL1_DEBUG_MASK   (DBG_MDSCR_SS | \
+   DBG_MDSCR_KDE | \
+   DBG_MDSCR_MDE)
 
 static DEFINE_PER_CPU(u32, mdcr_el2);
 
 /**
+ * save/restore_guest_debug_regs
+ *
+ * For some debug operations we need to tweak some guest registers. As
+ * a result we need to save the state of those registers before we
+ * make those modifications.
+ *
+ * Guest access to MDSCR_EL1 is trapped by the hypervisor and handled
+ * after we have restored the preserved value to the main context.
+ */
+static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
+{
+   vcpu->arch.guest_debug_preserved.mdscr_el1 = vcpu_sys_reg(vcpu, 
MDSCR_EL1);
+}
+
+static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
+{
+   vcpu_sys_reg(vcpu, MDSCR_EL1) = 
vcpu->arch.guest_debug_preserved.mdscr_el1;
+}
+
+/**
  * kvm_arm_init_debug - grab what we need for debug
  *
  * Currently the sole task of this function is to retrieve the initial
@@ -38,7 +66,6 @@ void kvm_arm_init_debug(void)
__this_cpu_write(mdcr_el2, kvm_call_hyp(__kvm_get_mdcr_el2));
 }
 
-
 /**
  * kvm_arm_setup_debug - set up debug related stuff
  *
@@ -73,12 +100,45 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
if (trap_debug)
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 
-   /* Trap breakpoints? */
-   if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+   /* Is Guest debugging in effect? */
+   if (vcpu->guest_debug) {
+   /* Route all software debug exceptions to EL2 */
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
+
+   /* Save guest debug state */
+   save_guest_debug_regs(vcpu);
+
+   /*
+* Single Step (ARM ARM D2.12.3 The software step state
+* machine)
+*
+* If we are doing Single Step we need to manipulate
+* the guest's MDSCR_EL1.SS and PSTATE.SS. Once the
+* step has occurred the hypervisor will tr

[PATCH v8 11/11] KVM: arm64: add trace points for guest_debug debug

2015-07-07 Thread Alex Bennée
This includes trace points for:
  kvm_arch_setup_guest_debug
  kvm_arch_clear_guest_debug

I've also added some generic register setting trace events and also a
trace point to dump the array of hardware registers.

Signed-off-by: Alex Bennée 

---
v3
  - add trace event for debug access.
  - remove short trace #define, rename trace events
  - use __print_array with fixed array instead of own func
  - rationalise trace points (only one per register changed)
  - add vcpu ptr to the debug_setup trace
  - remove :: in prints
v4
  - u32/u64 split on debug registers
  - fix for renames
  - add tracing of traps/set_guest_debug
  - remove handle_guest_debug trace
v5
  - minor print fmt fix
  - rm pstate traces
v6
  - fix merge conflicts
  - update control reg tracking to u64 (abi change)
v7
  - fix merge conflicts from ioctl move
  - fix other minor merge conflicts
  - fixes for the re-factored sys_regs code
v8
  - updates for sys_regs re-factor
---
 arch/arm64/kvm/debug.c|  36 +-
 arch/arm64/kvm/guest.c|   4 ++
 arch/arm64/kvm/sys_regs.c |  17 +++
 arch/arm64/kvm/trace.h| 123 ++
 4 files changed, 179 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 4a99e54..47e5f0f 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -18,12 +18,15 @@
  */
 
 #include 
+#include 
 
 #include 
 #include 
 #include 
 #include 
 
+#include "trace.h"
+
 /* These are the bits of MDSCR_EL1 we may manipulate */
 #define MDSCR_EL1_DEBUG_MASK   (DBG_MDSCR_SS | \
DBG_MDSCR_KDE | \
@@ -44,11 +47,17 @@ static DEFINE_PER_CPU(u32, mdcr_el2);
 static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
 {
vcpu->arch.guest_debug_preserved.mdscr_el1 = vcpu_sys_reg(vcpu, 
MDSCR_EL1);
+
+   trace_kvm_arm_set_dreg32("Saved MDSCR_EL1",
+   vcpu->arch.guest_debug_preserved.mdscr_el1);
 }
 
 static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
 {
vcpu_sys_reg(vcpu, MDSCR_EL1) = 
vcpu->arch.guest_debug_preserved.mdscr_el1;
+
+   trace_kvm_arm_set_dreg32("Restored MDSCR_EL1",
+   vcpu_sys_reg(vcpu, MDSCR_EL1));
 }
 
 /**
@@ -99,6 +108,8 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 {
bool trap_debug = !(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY);
 
+   trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug);
+
vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
MDCR_EL2_TPMCR |
@@ -140,6 +151,8 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS;
}
 
+   trace_kvm_arm_set_dreg32("SPSR_EL2", *vcpu_cpsr(vcpu));
+
/*
 * HW Breakpoints and watchpoints
 *
@@ -156,6 +169,14 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state;
vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
trap_debug = true;
+
+   trace_kvm_arm_set_regset("BKPTS", get_num_brps(),
+   
&vcpu->arch.debug_ptr->dbg_bcr[0],
+   
&vcpu->arch.debug_ptr->dbg_bvr[0]);
+
+   trace_kvm_arm_set_regset("WAPTS", get_num_wrps(),
+   
&vcpu->arch.debug_ptr->dbg_wcr[0],
+   
&vcpu->arch.debug_ptr->dbg_wvr[0]);
}
}
 
@@ -165,10 +186,15 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
/* Trap debug register access */
if (trap_debug)
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
+
+   trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2);
+   trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_sys_reg(vcpu, MDSCR_EL1));
 }
 
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
 {
+   trace_kvm_arm_clear_debug(vcpu->guest_debug);
+
if (vcpu->guest_debug) {
restore_guest_debug_regs(vcpu);
 
@@ -176,8 +202,16 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
 * If we were using HW debug we need to restore the
 * debug_ptr to the guest debug state.
 */
-   if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW)
+   if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
kvm_arm_reset_debug_ptr(vcpu);
 
+   trace_kvm_arm_set_regset("BKPTS", get_num_brps(),
+ 

[PATCH v8 10/11] KVM: arm64: enable KVM_CAP_SET_GUEST_DEBUG

2015-07-07 Thread Alex Bennée
Finally advertise the KVM capability for SET_GUEST_DEBUG. Once arm
support is added this check can be moved to the common
kvm_vm_ioctl_check_extension() code.

Signed-off-by: Alex Bennée 
Acked-by: Christoffer Dall 

---

v3:
 - separated capability check from previous patches
 - moved into arm64 specific ioctl handler.
v4:
 - add a-b-tag
---
 arch/arm64/kvm/reset.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 8620926..b4af618 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -77,6 +77,9 @@ int kvm_arch_dev_ioctl_check_extension(long ext)
case KVM_CAP_GUEST_DEBUG_HW_WPS:
r = get_num_wrps();
break;
+   case KVM_CAP_SET_GUEST_DEBUG:
+   r = 1;
+   break;
default:
r = 0;
}
-- 
2.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v8 07/11] KVM: arm64: re-factor hyp.S debug register code

2015-07-07 Thread Alex Bennée
This is a pre-cursor to sharing the code with the guest debug support.
This replaces the big macro that fishes data out of a fixed location
with a more general helper macro to restore a set of debug registers. It
uses macro substitution so it can be re-used for debug control and value
registers. It does however rely on the debug registers being 64 bit
aligned (as they happen to be in the hyp ABI).

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v3:
  - return to the patch series
  - add save and restore targets
  - change register use and document
v4:
  - keep original setup/restore names
  - don't use split u32/u64 structure yet
v6:
  - fix ws and clobber info in hyp.S
v7:
  - fix whitespace
  - add r-b-tag
---
 arch/arm64/kvm/hyp.S | 517 ++-
 1 file changed, 138 insertions(+), 379 deletions(-)

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 2c67a14..77c08df 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -228,199 +228,52 @@
stp x24, x25, [x3, #160]
 .endm
 
-.macro save_debug
-   // x2: base address for cpu context
-   // x3: tmp register
-
-   mrs x26, id_aa64dfr0_el1
-   ubfxx24, x26, #12, #4   // Extract BRPs
-   ubfxx25, x26, #20, #4   // Extract WRPs
-   mov w26, #15
-   sub w24, w26, w24   // How many BPs to skip
-   sub w25, w26, w25   // How many WPs to skip
-
-   add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-1:
-   mrs x20, dbgbcr15_el1
-   mrs x19, dbgbcr14_el1
-   mrs x18, dbgbcr13_el1
-   mrs x17, dbgbcr12_el1
-   mrs x16, dbgbcr11_el1
-   mrs x15, dbgbcr10_el1
-   mrs x14, dbgbcr9_el1
-   mrs x13, dbgbcr8_el1
-   mrs x12, dbgbcr7_el1
-   mrs x11, dbgbcr6_el1
-   mrs x10, dbgbcr5_el1
-   mrs x9, dbgbcr4_el1
-   mrs x8, dbgbcr3_el1
-   mrs x7, dbgbcr2_el1
-   mrs x6, dbgbcr1_el1
-   mrs x5, dbgbcr0_el1
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-
-1:
-   str x20, [x3, #(15 * 8)]
-   str x19, [x3, #(14 * 8)]
-   str x18, [x3, #(13 * 8)]
-   str x17, [x3, #(12 * 8)]
-   str x16, [x3, #(11 * 8)]
-   str x15, [x3, #(10 * 8)]
-   str x14, [x3, #(9 * 8)]
-   str x13, [x3, #(8 * 8)]
-   str x12, [x3, #(7 * 8)]
-   str x11, [x3, #(6 * 8)]
-   str x10, [x3, #(5 * 8)]
-   str x9, [x3, #(4 * 8)]
-   str x8, [x3, #(3 * 8)]
-   str x7, [x3, #(2 * 8)]
-   str x6, [x3, #(1 * 8)]
-   str x5, [x3, #(0 * 8)]
-
-   add x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-1:
-   mrs x20, dbgbvr15_el1
-   mrs x19, dbgbvr14_el1
-   mrs x18, dbgbvr13_el1
-   mrs x17, dbgbvr12_el1
-   mrs x16, dbgbvr11_el1
-   mrs x15, dbgbvr10_el1
-   mrs x14, dbgbvr9_el1
-   mrs x13, dbgbvr8_el1
-   mrs x12, dbgbvr7_el1
-   mrs x11, dbgbvr6_el1
-   mrs x10, dbgbvr5_el1
-   mrs x9, dbgbvr4_el1
-   mrs x8, dbgbvr3_el1
-   mrs x7, dbgbvr2_el1
-   mrs x6, dbgbvr1_el1
-   mrs x5, dbgbvr0_el1
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-
-1:
-   str x20, [x3, #(15 * 8)]
-   str x19, [x3, #(14 * 8)]
-   str x18, [x3, #(13 * 8)]
-   str x17, [x3, #(12 * 8)]
-   str x16, [x3, #(11 * 8)]
-   str x15, [x3, #(10 * 8)]
-   str x14, [x3, #(9 * 8)]
-   str x13, [x3, #(8 * 8)]
-   str x12, [x3, #(7 * 8)]
-   str x11, [x3, #(6 * 8)]
-   str x10, [x3, #(5 * 8)]
-   str x9, [x3, #(4 * 8)]
-   str x8, [x3, #(3 * 8)]
-   str x7, [x3, #(2 * 8)]
-   str x6, [x3, #(1 * 8)]
-   str x5, [x3, #(0 * 8)]
-
-   add x3, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
-
-   adr x26, 1f
-   add x26, x26, x25, lsl #2
-   br  x26
+.macro save_debug type
+   // x4: pointer to register set
+   // x5: number of registers to skip
+   // x6..x22 trashed
+
+   adr x22, 1f
+   add x22, x22, x5, lsl #2
+   br  x22
 1:
-   mrs x20, dbgwcr15_el1
-   mrs x19, dbgwcr14_el1
-   mrs x18, dbgwcr13_el1
-   mrs x17, dbgwcr12_el1
-   mrs x16, dbgwcr11_el1
-   mrs x15, dbgwcr10_el1
-   mrs x14, dbgwcr9_el1
-   mrs x13, dbgwcr8_el1
-   mrs x12, dbgwcr7_el1
-   mrs x11, dbgwcr6_el1
-   mrs x10, dbgwcr5_el1
-   mrs x9, dbgwcr4_el1
-   mrs x8, dbgwcr3_el1
-   mrs x7, dbgwcr

[PATCH v8 01/11] KVM: add comments for kvm_debug_exit_arch struct

2015-07-07 Thread Alex Bennée
Bring into line with the comments for the other structures and their
KVM_EXIT_* cases. Also update api.txt to reflect use in kvm_run
documentation.

Signed-off-by: Alex Bennée 
Reviewed-by: David Hildenbrand 
Reviewed-by: Andrew Jones 
Acked-by: Christoffer Dall 

---

v2
  - add comments for other exit types
v3
  - s/commentary/comments/
  - add rb tags
  - update api.txt kvm_run to include KVM_EXIT_DEBUG desc
v4
  - sp fixes
  - add a-b
---
 Documentation/virtual/kvm/api.txt | 4 +++-
 include/uapi/linux/kvm.h  | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 9fa2bf8..c34c32d 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3070,11 +3070,13 @@ data_offset describes where the data is located 
(KVM_EXIT_IO_OUT) or
 where kvm expects application code to place the data for the next
 KVM_RUN invocation (KVM_EXIT_IO_IN).  Data format is a packed array.
 
+   /* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
 
-Unused.
+If the exit_reason is KVM_EXIT_DEBUG, then a vcpu is processing a debug event
+for which architecture specific information is returned.
 
/* KVM_EXIT_MMIO */
struct {
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 4b60056..70ac641 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -237,6 +237,7 @@ struct kvm_run {
__u32 count;
__u64 data_offset; /* relative to kvm_run start */
} io;
+   /* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
@@ -285,6 +286,7 @@ struct kvm_run {
__u32 data;
__u8  is_write;
} dcr;
+   /* KVM_EXIT_INTERNAL_ERROR */
struct {
__u32 suberror;
/* Available with KVM_CAP_INTERNAL_ERROR_DATA: */
@@ -295,6 +297,7 @@ struct kvm_run {
struct {
__u64 gprs[32];
} osi;
+   /* KVM_EXIT_PAPR_HCALL */
struct {
__u64 nr;
__u64 ret;
-- 
2.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v8 09/11] KVM: arm64: guest debug, HW assisted debug support

2015-07-07 Thread Alex Bennée
This adds support for userspace to control the HW debug registers for
guest debug. In the debug ioctl we copy an IMPDEF registers into a new
register set called host_debug_state.

We use the recently introduced vcpu parameter debug_ptr to select which
register set is copied into the real registers when world switch occurs.

I've made some helper functions from hw_breakpoint.c more widely
available for re-use.

As with single step we need to tweak the guest registers to enable the
exceptions so we need to save and restore those bits.

Two new capabilities have been added to the KVM_EXTENSION ioctl to allow
userspace to query the number of hardware break and watch points
available on the host hardware.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v2
   - switched to C setup
   - replace host debug registers directly into context
   - minor tweak to api docs
   - setup right register for debug
   - add FAR_EL2 to debug exit structure
   - add support for trapping debug register access
v3
   - remove stray trace statement
   - fix spacing around operators (various)
   - clean-up usage of trap_debug
   - introduce debug_ptr, replace excessive memcpy stuff
   - don't use memcpy in ioctl, just assign
   - update cap ioctl documentation
   - reword a number comments
   - rename host_debug_state->external_debug_state
v4
   - use the new u32/u64 split debug_ptr approach
   - fix some wording/comments
v5
   - don't set MDSCR_EL1.KDE (not needed)
v6
   - update wording given change in commentary
   - KVM_GUESTDBG_USE_HW_BP->KVM_GUESTDBG_USE_HW
v7
   - fix merge conflicts from ioctl move to guest.c
   - use kvm_arm_reset_debug_ptr to reset ptr
   - a BUG_ON() test has been added to trap failure to reset debug_ptr
   - debugging->debug in kvm_host.h comment
   - s/defined// s/to// in commit msg
   - rm ref to introducing debug_ptr in commit msg
   - add r-b tag
v8
   - add #include  to hw_breakpoint.h
---
 Documentation/virtual/kvm/api.txt  |  7 +-
 arch/arm64/include/asm/hw_breakpoint.h | 14 
 arch/arm64/include/asm/kvm_host.h  |  6 -
 arch/arm64/kernel/hw_breakpoint.c  | 12 --
 arch/arm64/kvm/debug.c | 40 +-
 arch/arm64/kvm/guest.c |  7 ++
 arch/arm64/kvm/handle_exit.c   |  6 +
 arch/arm64/kvm/reset.c | 13 +++
 include/uapi/linux/kvm.h   |  2 ++
 9 files changed, 88 insertions(+), 19 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 33c8143..ada57df 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2668,7 +2668,7 @@ The top 16 bits of the control field are architecture 
specific control
 flags which can include the following:
 
   - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64]
-  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
+  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390, arm64]
   - KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
   - KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
   - KVM_GUESTDBG_EXIT_PENDING:  trigger an immediate guest exit [s390]
@@ -2683,6 +2683,11 @@ updated to the correct (supplied) values.
 The second part of the structure is architecture specific and
 typically contains a set of debug registers.
 
+For arm64 the number of debug registers is implementation defined and
+can be determined by querying the KVM_CAP_GUEST_DEBUG_HW_BPS and
+KVM_CAP_GUEST_DEBUG_HW_WPS capabilities which return a positive number
+indicating the number of supported registers.
+
 When debug events exit the main run loop with the reason
 KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run
 structure containing architecture specific debug information.
diff --git a/arch/arm64/include/asm/hw_breakpoint.h 
b/arch/arm64/include/asm/hw_breakpoint.h
index 52b484b..4c47cb2 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -16,6 +16,8 @@
 #ifndef __ASM_HW_BREAKPOINT_H
 #define __ASM_HW_BREAKPOINT_H
 
+#include 
+
 #ifdef __KERNEL__
 
 struct arch_hw_breakpoint_ctrl {
@@ -132,5 +134,17 @@ static inline void ptrace_hw_copy_thread(struct 
task_struct *task)
 
 extern struct pmu perf_ops_bp;
 
+/* Determine number of BRP registers available. */
+static inline int get_num_brps(void)
+{
+   return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1;
+}
+
+/* Determine number of WRP registers available. */
+static inline int get_num_wrps(void)
+{
+   return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1;
+}
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_BREAKPOINT_H */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 461d288..6c745e0 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.

[PATCH v8 04/11] KVM: arm: introduce kvm_arm_init/setup/clear_debug

2015-07-07 Thread Alex Bennée
This is a precursor for later patches which will need to do more to
setup debug state before entering the hyp.S switch code. The existing
functionality for setting mdcr_el2 has been moved out of hyp.S and now
uses the value kept in vcpu->arch.mdcr_el2.

As the assembler used to previously mask and preserve MDCR_EL2.HPMN I've
had to add a mechanism to save the value of mdcr_el2 as a per-cpu
variable during the initialisation code. The kernel never sets this
number so we are assuming the bootcode has set up the correct value
here.

This also moves the conditional setting of the TDA bit from the hyp code
into the C code which is currently used for the lazy debug register
context switch code.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v3
  - rename fns from arch->arm
  - preserve MDCR_EL2.HPMN setting
  - re-word some of the comments
  - fix some minor grammar nits
  - merge setting of mdcr_el2
  - introduce trap_debug flag
  - move setup/clear within the irq lock section
v4
  - fix TDOSA desc
  - rm un-needed else leg
  - s/arch/arm/
v6
  - add s-o-b tag
---
 arch/arm/include/asm/kvm_host.h   |  4 ++
 arch/arm/kvm/arm.c|  9 -
 arch/arm64/include/asm/kvm_asm.h  |  2 +
 arch/arm64/include/asm/kvm_host.h |  5 +++
 arch/arm64/kernel/asm-offsets.c   |  1 +
 arch/arm64/kvm/Makefile   |  2 +-
 arch/arm64/kvm/debug.c| 81 +++
 arch/arm64/kvm/hyp.S  | 19 -
 8 files changed, 110 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm64/kvm/debug.c

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index d71607c..746c0c69 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -236,4 +236,8 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+static inline void kvm_arm_init_debug(void) {}
+static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
+
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 92b80bc..af60e6f 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -542,6 +542,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
continue;
}
 
+   kvm_arm_setup_debug(vcpu);
+
/**
 * Enter the guest
 */
@@ -554,7 +556,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
vcpu->mode = OUTSIDE_GUEST_MODE;
kvm_guest_exit();
trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
-   /*
+
+   kvm_arm_clear_debug(vcpu);
+
+/*
 * We may have taken a host interrupt in HYP mode (ie
 * while executing the guest). This interrupt is still
 * pending, as we haven't serviced it yet!
@@ -902,6 +907,8 @@ static void cpu_init_hyp_mode(void *dummy)
vector_ptr = (unsigned long)__kvm_hyp_vector;
 
__cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
+
+   kvm_arm_init_debug();
 }
 
 static int hyp_init_cpu_notify(struct notifier_block *self,
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 4f7310f..d6b507e 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -137,6 +137,8 @@ extern char __restore_vgic_v2_state[];
 extern char __save_vgic_v3_state[];
 extern char __restore_vgic_v3_state[];
 
+extern u32 __kvm_get_mdcr_el2(void);
+
 #endif
 
 #endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index f0f58c9..7cb99b5 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -103,6 +103,7 @@ struct kvm_vcpu_arch {
 
/* HYP configuration */
u64 hcr_el2;
+   u32 mdcr_el2;
 
/* Exception Information */
struct kvm_vcpu_fault_info fault;
@@ -250,4 +251,8 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+void kvm_arm_init_debug(void);
+void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
+void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index da675cc..dfb25a2 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -117,6 +117,7 @@ int main(void)
   DEFINE(VCPU_HPFAR_EL2,   offsetof(struct kvm_vcpu, 
a

[PATCH v8 03/11] KVM: arm: guest debug, add stub KVM_SET_GUEST_DEBUG ioctl

2015-07-07 Thread Alex Bennée
This commit adds a stub function to support the KVM_SET_GUEST_DEBUG
ioctl. Any unsupported flag will return -EINVAL. For now, only
KVM_GUESTDBG_ENABLE is supported, although it won't have any effects.

Signed-off-by: Alex Bennée .
Reviewed-by: Christoffer Dall 

---
v2
  - simplified form of the ioctl (stuff will go into setup_debug)
v3
 - KVM_GUESTDBG_VALID->KVM_GUESTDBG_VALID_MASK
 - move mask check to the top of function
 - add ioctl doc header
 - split capability into separate patch
 - tweaked commit wording w.r.t return of -EINVAL
v4
 - add r-b-tag
v7
 - moved ioctl to arm64/kvm/guest.c, stubbed arm/kvm/guest.c
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/arm/kvm/arm.c|  7 ---
 arch/arm/kvm/guest.c  |  6 ++
 arch/arm64/kvm/guest.c| 27 +++
 4 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index c34c32d..ba635c7 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2645,7 +2645,7 @@ handled.
 4.87 KVM_SET_GUEST_DEBUG
 
 Capability: KVM_CAP_SET_GUEST_DEBUG
-Architectures: x86, s390, ppc
+Architectures: x86, s390, ppc, arm64
 Type: vcpu ioctl
 Parameters: struct kvm_guest_debug (in)
 Returns: 0 on success; -1 on error
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index d9631ec..92b80bc 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -302,13 +302,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_arm_set_running_vcpu(NULL);
 }
 
-int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
-   struct kvm_guest_debug *dbg)
-{
-   return -EINVAL;
-}
-
-
 int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
struct kvm_mp_state *mp_state)
 {
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index d503fbb..96e935b 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -290,3 +290,9 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 {
return -EINVAL;
 }
+
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+   struct kvm_guest_debug *dbg)
+{
+   return -EINVAL;
+}
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 9535bd5..0ba8677 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -331,3 +331,30 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 {
return -EINVAL;
 }
+
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE)
+
+/**
+ * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
+ * @kvm:   pointer to the KVM struct
+ * @kvm_guest_debug: the ioctl data buffer
+ *
+ * This sets up and enables the VM for guest debugging. Userspace
+ * passes in a control flag to enable different debug types and
+ * potentially other architecture specific information in the rest of
+ * the structure.
+ */
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+   struct kvm_guest_debug *dbg)
+{
+   if (dbg->control & ~KVM_GUESTDBG_VALID_MASK)
+   return -EINVAL;
+
+   if (dbg->control & KVM_GUESTDBG_ENABLE) {
+   vcpu->guest_debug = dbg->control;
+   } else {
+   /* If not enabled clear all flags */
+   vcpu->guest_debug = 0;
+   }
+   return 0;
+}
-- 
2.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v7 09/11] KVM: arm64: guest debug, HW assisted debug support

2015-07-06 Thread Alex Bennée

Will Deacon  writes:

> On Fri, Jul 03, 2015 at 05:07:41PM +0100, Alex Bennée wrote:
>> Will Deacon  writes:
>> > On Thu, Jul 02, 2015 at 02:50:33PM +0100, Alex Bennée wrote:
>> >> Are you happy with this?:
>> >
>> > [...]
>> >
>> >> +/**
>> >> + * kvm_arch_dev_ioctl_check_extension
>> >> + *
>> >> + * We currently assume that the number of HW registers is uniform
>> >> + * across all CPUs (see cpuinfo_sanity_check).
>> >> + */
>> >>  int kvm_arch_dev_ioctl_check_extension(long ext)
>> >>  {
>> >> int r;
>> >> @@ -64,6 +71,12 @@ int kvm_arch_dev_ioctl_check_extension(long ext)
>> >> case KVM_CAP_ARM_EL1_32BIT:
>> >> r = cpu_has_32bit_el1();
>> >> break;
>> >> +   case KVM_CAP_GUEST_DEBUG_HW_BPS:
>> >> +   r = hw_breakpoint_slots(TYPE_INST);
>> >> +   break;
>> >> +   case KVM_CAP_GUEST_DEBUG_HW_WPS:
>> >> +   r  = hw_breakpoint_slots(TYPE_DATA);
>> >> +   break;
>> >
>> > Whilst I much prefer this code, it actually adds an unwanted dependency
>> > on PERF_EVENTS that I didn't think about to start with. Sorry to keep
>> > messing you about -- I guess your original patch is the best thing after
>> > all.
>> 
>> Everything looks to be in hw_breakpoint.[ch] which does depend on
>> CONFIG_HAVE_HW_BREAKPOINT which depends on PERF_EVENTS to be built.
>> However the previous code depended on this behaviour as well.
>
> I think your original approach (of sticking stuff in the header file) works
> regardless of the CONFIG option, no?

Ahh yeah I reverted that to an extern due to random compile breakage:

http://storage.kernelci.org/alex/v4.1-12-gd38574dba3ec/arm64-allmodconfig/build.log

I'll see if I can fix that up.

>> It would seem weird to enable guest debug using HW debug registers to
>> debug the guest yet not allowing the host kernel to use them? Of course
>> this is the only code they would share as all the magic of guest
>> debugging is already mostly there for dirty guest handling.
>> 
>> I'm not familiar with Kconfig but it looks like this is all part of
>> arm64 defconfig. Are people really going to want to disable PERF_EVENTS
>> but still debug their guests with HW support?
>
> Then it's your call. I just find the host dependency on perf a bit weird
> to get guest debug working (especially as the dependency is completely
> "fake" because we don't use any perf infrastructure at all).
>
> Will

-- 
Alex Bennée
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v7 09/11] KVM: arm64: guest debug, HW assisted debug support

2015-07-03 Thread Alex Bennée

Will Deacon  writes:

> Hi Alex,
>
> On Thu, Jul 02, 2015 at 02:50:33PM +0100, Alex Bennée wrote:
>> Are you happy with this?:
>
> [...]
>
>> +/**
>> + * kvm_arch_dev_ioctl_check_extension
>> + *
>> + * We currently assume that the number of HW registers is uniform
>> + * across all CPUs (see cpuinfo_sanity_check).
>> + */
>>  int kvm_arch_dev_ioctl_check_extension(long ext)
>>  {
>> int r;
>> @@ -64,6 +71,12 @@ int kvm_arch_dev_ioctl_check_extension(long ext)
>> case KVM_CAP_ARM_EL1_32BIT:
>> r = cpu_has_32bit_el1();
>> break;
>> +   case KVM_CAP_GUEST_DEBUG_HW_BPS:
>> +   r = hw_breakpoint_slots(TYPE_INST);
>> +   break;
>> +   case KVM_CAP_GUEST_DEBUG_HW_WPS:
>> +   r  = hw_breakpoint_slots(TYPE_DATA);
>> +   break;
>
> Whilst I much prefer this code, it actually adds an unwanted dependency
> on PERF_EVENTS that I didn't think about to start with. Sorry to keep
> messing you about -- I guess your original patch is the best thing after
> all.

Everything looks to be in hw_breakpoint.[ch] which does depend on
CONFIG_HAVE_HW_BREAKPOINT which depends on PERF_EVENTS to be built.
However the previous code depended on this behaviour as well.

It would seem weird to enable guest debug using HW debug registers to
debug the guest yet not allowing the host kernel to use them? Of course
this is the only code they would share as all the magic of guest
debugging is already mostly there for dirty guest handling.

I'm not familiar with Kconfig but it looks like this is all part of
arm64 defconfig. Are people really going to want to disable PERF_EVENTS
but still debug their guests with HW support?

>
> Will

-- 
Alex Bennée
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v7 08/11] KVM: arm64: introduce vcpu->arch.debug_ptr

2015-07-03 Thread Alex Bennée

Christoffer Dall  writes:

> On Wed, Jul 01, 2015 at 07:29:00PM +0100, Alex Bennée wrote:
>> This introduces a level of indirection for the debug registers. Instead
>> of using the sys_regs[] directly we store registers in a structure in
>> the vcpu. The new kvm_arm_reset_debug_ptr() sets the debug ptr to the
>> guest context.
>> 
>> This also entails updating the sys_regs code to access this new
>> structure. New access function have been added for each set of debug
>> registers. The generic functions are still used for the few registers
>> stored in the main context.
>> 
>> New access function pointers have been added to the sys_reg_desc
>> structure to support the GET/SET_ONE_REG ioctl operations.
>
> Why is this needed?

Previously I had a hacky:

if (r->access == trap_debug64)
return debug_get64(vcpu, r, reg, uaddr);

Which used the same offset information. Now we have a cleaner:

if (r->set)
return (r->set)(vcpu, r, reg, uaddr);

Which accesses the structure directly, as the trap functions do:

__u64 *r = &vcpu->arch.vcpu_debug_state.dbg_bvr[rd->reg];
if (copy_from_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
return -EFAULT;
return 0;


>> +#if 0
>> +static int debug_set64(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
>> +const struct kvm_one_reg *reg, void __user *uaddr)
>> +{
>> +__u64 *r = (__u64 *) ((void * )&vcpu->arch.vcpu_debug_state + rd->reg);
>> +if (copy_from_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
>> +return -EFAULT;
>> +return 0;
>> +}
>> +
>> +static int debug_get64(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
>> +const struct kvm_one_reg *reg, void __user *uaddr)
>> +{
>> +__u64 *r = (__u64 *) ((void * )&vcpu->arch.vcpu_debug_state + rd->reg);
>> +if (copy_to_user(uaddr, r, KVM_REG_SIZE(reg->id)) != 0)
>> +return -EFAULT;
>> +return 0;
>> +}
>> +#endif
>> +
>
> what is this ifdef'ed block of code doing here?

Oops. Yeah looks like I missed removing that after I finished the
re-factor. These where the old get/set functions I used.

>
>>  int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg 
>> *reg)
>>  {
>>  const struct sys_reg_desc *r;
>> @@ -1303,6 +1530,9 @@ int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, 
>> const struct kvm_one_reg *reg
>>  if (!r)
>>  return get_invariant_sys_reg(reg->id, uaddr);
>>  
>> +if (r->get)
>> +return (r->get)(vcpu, r, reg, uaddr);
>> +
>>  return reg_to_user(uaddr, &vcpu_sys_reg(vcpu, r->reg), reg->id);
>>  }
>>  
>> @@ -1321,6 +1551,9 @@ int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, 
>> const struct kvm_one_reg *reg
>>  if (!r)
>>  return set_invariant_sys_reg(reg->id, uaddr);
>>  
>> +if (r->set)
>> +return (r->set)(vcpu, r, reg, uaddr);
>> +
>>  return reg_from_user(&vcpu_sys_reg(vcpu, r->reg), uaddr, reg->id);
>>  }
>>  
>> diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
>> index d411e25..9265e7d 100644
>> --- a/arch/arm64/kvm/sys_regs.h
>> +++ b/arch/arm64/kvm/sys_regs.h
>> @@ -55,6 +55,12 @@ struct sys_reg_desc {
>>  
>>  /* Value (usually reset value) */
>>  u64 val;
>> +
>> +/* Get/Set functions, fallback if NULL */
>
> Is this only meant for usersapce access or when should one use these?

Yes for GET/SET

>
>> +int (*get)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
>> +   const struct kvm_one_reg *reg, void __user *uaddr);
>> +int (*set)(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
>> +   const struct kvm_one_reg *reg, void __user *uaddr);
>>  };
>>  
>>  static inline void print_sys_reg_instr(const struct sys_reg_params *p)
>> -- 
>> 2.4.5
>> 

-- 
Alex Bennée
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v7 09/11] KVM: arm64: guest debug, HW assisted debug support

2015-07-02 Thread Alex Bennée

Will Deacon  writes:

Are you happy with this?:

Subject: [PATCH v8 09/11] KVM: arm64: guest debug, HW assisted debug support

This adds support for userspace to control the HW debug registers for
guest debug. In the debug ioctl we copy an IMPDEF registers into a new
register set called host_debug_state.

We use the recently introduced vcpu parameter debug_ptr to select which
register set is copied into the real registers when world switch occurs.

I've made some helper functions from hw_breakpoint.c more widely
available for re-use.

As with single step we need to tweak the guest registers to enable the
exceptions so we need to save and restore those bits.

Two new capabilities have been added to the KVM_EXTENSION ioctl to allow
userspace to query the number of hardware break and watch points
available on the host hardware.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v2
   - switched to C setup
   - replace host debug registers directly into context
   - minor tweak to api docs
   - setup right register for debug
   - add FAR_EL2 to debug exit structure
   - add support for trapping debug register access
v3
   - remove stray trace statement
   - fix spacing around operators (various)
   - clean-up usage of trap_debug
   - introduce debug_ptr, replace excessive memcpy stuff
   - don't use memcpy in ioctl, just assign
   - update cap ioctl documentation
   - reword a number comments
   - rename host_debug_state->external_debug_state
v4
   - use the new u32/u64 split debug_ptr approach
   - fix some wording/comments
v5
   - don't set MDSCR_EL1.KDE (not needed)
v6
   - update wording given change in commentary
   - KVM_GUESTDBG_USE_HW_BP->KVM_GUESTDBG_USE_HW
v7
   - fix merge conflicts from ioctl move to guest.c
   - use kvm_arm_reset_debug_ptr to reset ptr
   - a BUG_ON() test has been added to trap failure to reset debug_ptr
   - debugging->debug in kvm_host.h comment
   - s/defined// s/to// in commit msg
   - rm ref to introducing debug_ptr in commit msg
   - add r-b tag
v8
   - use hw_breakpoint_slots() instead
---
 Documentation/virtual/kvm/api.txt |  7 ++-
 arch/arm64/include/asm/kvm_host.h |  6 +-
 arch/arm64/kvm/debug.c| 40 ++-
 arch/arm64/kvm/guest.c|  7 +++
 arch/arm64/kvm/handle_exit.c  |  6 ++
 arch/arm64/kvm/reset.c| 13 +
 arch/arm64/kvm/sys_regs.c |  3 ---
 include/uapi/linux/kvm.h  |  2 ++
 8 files changed, 74 insertions(+), 10 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 33c8143..ada57df 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2668,7 +2668,7 @@ The top 16 bits of the control field are architecture 
specific control
 flags which can include the following:
 
   - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64]
-  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
+  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390, arm64]
   - KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
   - KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
   - KVM_GUESTDBG_EXIT_PENDING:  trigger an immediate guest exit [s390]
@@ -2683,6 +2683,11 @@ updated to the correct (supplied) values.
 The second part of the structure is architecture specific and
 typically contains a set of debug registers.
 
+For arm64 the number of debug registers is implementation defined and
+can be determined by querying the KVM_CAP_GUEST_DEBUG_HW_BPS and
+KVM_CAP_GUEST_DEBUG_HW_WPS capabilities which return a positive number
+indicating the number of supported registers.
+
 When debug events exit the main run loop with the reason
 KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run
 structure containing architecture specific debug information.
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 461d288..6c745e0 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -116,13 +116,17 @@ struct kvm_vcpu_arch {
 * debugging the guest from the host and to maintain separate host and
 * guest state during world switches. vcpu_debug_state are the debug
 * registers of the vcpu as the guest sees them.  host_debug_state are
-* the host registers which are saved and restored during world 
switches.
+* the host registers which are saved and restored during
+* world switches. external_debug_state contains the debug
+* values we want to debug the guest. This is set via the
+* KVM_SET_GUEST_DEBUG ioctl.
 *
 * debug_ptr points to the set of debug registers that should be loaded
 * onto the hardware when running the guest.
 */
struct kvm_guest_debug_arch *debug_ptr;
struct kvm_guest_debug_arch vcpu_deb

[PATCH v7 01/11] KVM: add comments for kvm_debug_exit_arch struct

2015-07-01 Thread Alex Bennée
Bring into line with the comments for the other structures and their
KVM_EXIT_* cases. Also update api.txt to reflect use in kvm_run
documentation.

Signed-off-by: Alex Bennée 
Reviewed-by: David Hildenbrand 
Reviewed-by: Andrew Jones 
Acked-by: Christoffer Dall 

---

v2
  - add comments for other exit types
v3
  - s/commentary/comments/
  - add rb tags
  - update api.txt kvm_run to include KVM_EXIT_DEBUG desc
v4
  - sp fixes
  - add a-b
---
 Documentation/virtual/kvm/api.txt | 4 +++-
 include/uapi/linux/kvm.h  | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 9fa2bf8..c34c32d 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3070,11 +3070,13 @@ data_offset describes where the data is located 
(KVM_EXIT_IO_OUT) or
 where kvm expects application code to place the data for the next
 KVM_RUN invocation (KVM_EXIT_IO_IN).  Data format is a packed array.
 
+   /* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
 
-Unused.
+If the exit_reason is KVM_EXIT_DEBUG, then a vcpu is processing a debug event
+for which architecture specific information is returned.
 
/* KVM_EXIT_MMIO */
struct {
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 4b60056..70ac641 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -237,6 +237,7 @@ struct kvm_run {
__u32 count;
__u64 data_offset; /* relative to kvm_run start */
} io;
+   /* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
@@ -285,6 +286,7 @@ struct kvm_run {
__u32 data;
__u8  is_write;
} dcr;
+   /* KVM_EXIT_INTERNAL_ERROR */
struct {
__u32 suberror;
/* Available with KVM_CAP_INTERNAL_ERROR_DATA: */
@@ -295,6 +297,7 @@ struct kvm_run {
struct {
__u64 gprs[32];
} osi;
+   /* KVM_EXIT_PAPR_HCALL */
struct {
__u64 nr;
__u64 ret;
-- 
2.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v7 03/11] KVM: arm: guest debug, add stub KVM_SET_GUEST_DEBUG ioctl

2015-07-01 Thread Alex Bennée
This commit adds a stub function to support the KVM_SET_GUEST_DEBUG
ioctl. Any unsupported flag will return -EINVAL. For now, only
KVM_GUESTDBG_ENABLE is supported, although it won't have any effects.

Signed-off-by: Alex Bennée .
Reviewed-by: Christoffer Dall 

---
v2
  - simplified form of the ioctl (stuff will go into setup_debug)
v3
 - KVM_GUESTDBG_VALID->KVM_GUESTDBG_VALID_MASK
 - move mask check to the top of function
 - add ioctl doc header
 - split capability into separate patch
 - tweaked commit wording w.r.t return of -EINVAL
v4
 - add r-b-tag
v7
 - moved ioctl to arm64/kvm/guest.c, stubbed arm/kvm/guest.c
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/arm/kvm/arm.c|  7 ---
 arch/arm/kvm/guest.c  |  6 ++
 arch/arm64/kvm/guest.c| 27 +++
 4 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index c34c32d..ba635c7 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2645,7 +2645,7 @@ handled.
 4.87 KVM_SET_GUEST_DEBUG
 
 Capability: KVM_CAP_SET_GUEST_DEBUG
-Architectures: x86, s390, ppc
+Architectures: x86, s390, ppc, arm64
 Type: vcpu ioctl
 Parameters: struct kvm_guest_debug (in)
 Returns: 0 on success; -1 on error
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index d9631ec..92b80bc 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -302,13 +302,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_arm_set_running_vcpu(NULL);
 }
 
-int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
-   struct kvm_guest_debug *dbg)
-{
-   return -EINVAL;
-}
-
-
 int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
struct kvm_mp_state *mp_state)
 {
diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
index d503fbb..96e935b 100644
--- a/arch/arm/kvm/guest.c
+++ b/arch/arm/kvm/guest.c
@@ -290,3 +290,9 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 {
return -EINVAL;
 }
+
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+   struct kvm_guest_debug *dbg)
+{
+   return -EINVAL;
+}
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 9535bd5..0ba8677 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -331,3 +331,30 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
 {
return -EINVAL;
 }
+
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE)
+
+/**
+ * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
+ * @kvm:   pointer to the KVM struct
+ * @kvm_guest_debug: the ioctl data buffer
+ *
+ * This sets up and enables the VM for guest debugging. Userspace
+ * passes in a control flag to enable different debug types and
+ * potentially other architecture specific information in the rest of
+ * the structure.
+ */
+int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+   struct kvm_guest_debug *dbg)
+{
+   if (dbg->control & ~KVM_GUESTDBG_VALID_MASK)
+   return -EINVAL;
+
+   if (dbg->control & KVM_GUESTDBG_ENABLE) {
+   vcpu->guest_debug = dbg->control;
+   } else {
+   /* If not enabled clear all flags */
+   vcpu->guest_debug = 0;
+   }
+   return 0;
+}
-- 
2.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v7 08/11] KVM: arm64: introduce vcpu->arch.debug_ptr

2015-07-01 Thread Alex Bennée
This introduces a level of indirection for the debug registers. Instead
of using the sys_regs[] directly we store registers in a structure in
the vcpu. The new kvm_arm_reset_debug_ptr() sets the debug ptr to the
guest context.

This also entails updating the sys_regs code to access this new
structure. New access function have been added for each set of debug
registers. The generic functions are still used for the few registers
stored in the main context.

New access function pointers have been added to the sys_reg_desc
structure to support the GET/SET_ONE_REG ioctl operations.

Signed-off-by: Alex Bennée 

---
v6:
  - fix up some ws issues
  - correct clobber info
  - re-word commentary in kvm_host.h
  - fix endian access issues for aarch32 fields
  - revert all KVM_GET/SET_ONE_REG to 64bit (also see ABI update)
v7
  - new fn kvm_arm_reset_debug_ptr(), stubbed for arm
  - split trap fns into bcr,bvr,bcr,wvr and wxvr
  - add set/get fns to sys_regs_desc
  - reg_to_dbg/dbg_to_reg helpers for 32bit support
---
 arch/arm/include/asm/kvm_host.h   |   2 +-
 arch/arm/kvm/arm.c|   2 +
 arch/arm64/include/asm/kvm_asm.h  |  24 ++--
 arch/arm64/include/asm/kvm_host.h |  17 ++-
 arch/arm64/kernel/asm-offsets.c   |   6 +
 arch/arm64/kvm/debug.c|   9 ++
 arch/arm64/kvm/hyp.S  |  24 ++--
 arch/arm64/kvm/sys_regs.c | 281 ++
 arch/arm64/kvm/sys_regs.h |   6 +
 9 files changed, 321 insertions(+), 50 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 746c0c69..f42759b 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -239,5 +239,5 @@ static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, 
int cpu) {}
 static inline void kvm_arm_init_debug(void) {}
 static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
-
+static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index af60e6f..525473f 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -279,6 +279,8 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
/* Set up the timer */
kvm_timer_vcpu_init(vcpu);
 
+   kvm_arm_reset_debug_ptr(vcpu);
+
return 0;
 }
 
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index d6b507e..e997404 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -46,24 +46,16 @@
 #defineCNTKCTL_EL1 20  /* Timer Control Register (EL1) */
 #definePAR_EL1 21  /* Physical Address Register */
 #define MDSCR_EL1  22  /* Monitor Debug System Control Register */
-#define DBGBCR0_EL123  /* Debug Breakpoint Control Registers (0-15) */
-#define DBGBCR15_EL1   38
-#define DBGBVR0_EL139  /* Debug Breakpoint Value Registers (0-15) */
-#define DBGBVR15_EL1   54
-#define DBGWCR0_EL155  /* Debug Watchpoint Control Registers (0-15) */
-#define DBGWCR15_EL1   70
-#define DBGWVR0_EL171  /* Debug Watchpoint Value Registers (0-15) */
-#define DBGWVR15_EL1   86
-#define MDCCINT_EL187  /* Monitor Debug Comms Channel Interrupt Enable 
Reg */
+#define MDCCINT_EL123  /* Monitor Debug Comms Channel Interrupt Enable 
Reg */
 
 /* 32bit specific registers. Keep them at the end of the range */
-#defineDACR32_EL2  88  /* Domain Access Control Register */
-#defineIFSR32_EL2  89  /* Instruction Fault Status Register */
-#defineFPEXC32_EL2 90  /* Floating-Point Exception Control 
Register */
-#defineDBGVCR32_EL291  /* Debug Vector Catch Register */
-#defineTEECR32_EL1 92  /* ThumbEE Configuration Register */
-#defineTEEHBR32_EL193  /* ThumbEE Handler Base Register */
-#defineNR_SYS_REGS 94
+#defineDACR32_EL2  24  /* Domain Access Control Register */
+#defineIFSR32_EL2  25  /* Instruction Fault Status Register */
+#defineFPEXC32_EL2 26  /* Floating-Point Exception Control 
Register */
+#defineDBGVCR32_EL227  /* Debug Vector Catch Register */
+#defineTEECR32_EL1 28  /* ThumbEE Configuration Register */
+#defineTEEHBR32_EL129  /* ThumbEE Handler Base Register */
+#defineNR_SYS_REGS 30
 
 /* 32bit mapping */
 #define c0_MPIDR   (MPIDR_EL1 * 2) /* MultiProcessor ID Register */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index e2db6a6..461d288 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -108,11 +108,25 @@ struct kvm_vcpu_arch {
/* Exception Information */
struct kvm_vcpu_fault_info fault;
 
-   /* Debug state */
+   /* Guest debug state

[PATCH v7 10/11] KVM: arm64: enable KVM_CAP_SET_GUEST_DEBUG

2015-07-01 Thread Alex Bennée
Finally advertise the KVM capability for SET_GUEST_DEBUG. Once arm
support is added this check can be moved to the common
kvm_vm_ioctl_check_extension() code.

Signed-off-by: Alex Bennée 
Acked-by: Christoffer Dall 

---

v3:
 - separated capability check from previous patches
 - moved into arm64 specific ioctl handler.
v4:
 - add a-b-tag
---
 arch/arm64/kvm/reset.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 21d5a62..88e5331 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -76,6 +76,9 @@ int kvm_arch_dev_ioctl_check_extension(long ext)
case KVM_CAP_GUEST_DEBUG_HW_WPS:
r  = get_num_wrps();
break;
+   case KVM_CAP_SET_GUEST_DEBUG:
+   r = 1;
+   break;
default:
r = 0;
}
-- 
2.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v7 09/11] KVM: arm64: guest debug, HW assisted debug support

2015-07-01 Thread Alex Bennée
This adds support for userspace to control the HW debug registers for
guest debug. In the debug ioctl we copy an IMPDEF registers into a new
register set called host_debug_state.

We use the recently introduced vcpu parameter debug_ptr to select which
register set is copied into the real registers when world switch occurs.

I've made some helper functions from hw_breakpoint.c more widely
available for re-use.

As with single step we need to tweak the guest registers to enable the
exceptions so we need to save and restore those bits.

Two new capabilities have been added to the KVM_EXTENSION ioctl to allow
userspace to query the number of hardware break and watch points
available on the host hardware.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v2
   - switched to C setup
   - replace host debug registers directly into context
   - minor tweak to api docs
   - setup right register for debug
   - add FAR_EL2 to debug exit structure
   - add support for trapping debug register access
v3
   - remove stray trace statement
   - fix spacing around operators (various)
   - clean-up usage of trap_debug
   - introduce debug_ptr, replace excessive memcpy stuff
   - don't use memcpy in ioctl, just assign
   - update cap ioctl documentation
   - reword a number comments
   - rename host_debug_state->external_debug_state
v4
   - use the new u32/u64 split debug_ptr approach
   - fix some wording/comments
v5
   - don't set MDSCR_EL1.KDE (not needed)
v6
   - update wording given change in commentary
   - KVM_GUESTDBG_USE_HW_BP->KVM_GUESTDBG_USE_HW
v7
   - fix merge conflicts from ioctl move to guest.c
   - use kvm_arm_reset_debug_ptr to reset ptr
   - a BUG_ON() test has been added to trap failure to reset debug_ptr
   - debugging->debug in kvm_host.h comment
   - s/defined// s/to// in commit msg
   - rm ref to introducing debug_ptr in commit msg
   - add r-b tag
---
 Documentation/virtual/kvm/api.txt  |  7 +-
 arch/arm64/include/asm/hw_breakpoint.h |  4 
 arch/arm64/include/asm/kvm_host.h  |  6 -
 arch/arm64/kernel/hw_breakpoint.c  |  4 ++--
 arch/arm64/kvm/debug.c | 40 +-
 arch/arm64/kvm/guest.c |  7 ++
 arch/arm64/kvm/handle_exit.c   |  6 +
 arch/arm64/kvm/reset.c | 12 ++
 arch/arm64/kvm/sys_regs.c  |  3 ---
 include/uapi/linux/kvm.h   |  2 ++
 10 files changed, 79 insertions(+), 12 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 33c8143..ada57df 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2668,7 +2668,7 @@ The top 16 bits of the control field are architecture 
specific control
 flags which can include the following:
 
   - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64]
-  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
+  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390, arm64]
   - KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
   - KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
   - KVM_GUESTDBG_EXIT_PENDING:  trigger an immediate guest exit [s390]
@@ -2683,6 +2683,11 @@ updated to the correct (supplied) values.
 The second part of the structure is architecture specific and
 typically contains a set of debug registers.
 
+For arm64 the number of debug registers is implementation defined and
+can be determined by querying the KVM_CAP_GUEST_DEBUG_HW_BPS and
+KVM_CAP_GUEST_DEBUG_HW_WPS capabilities which return a positive number
+indicating the number of supported registers.
+
 When debug events exit the main run loop with the reason
 KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run
 structure containing architecture specific debug information.
diff --git a/arch/arm64/include/asm/hw_breakpoint.h 
b/arch/arm64/include/asm/hw_breakpoint.h
index 52b484b..9da2824 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -130,6 +130,10 @@ static inline void ptrace_hw_copy_thread(struct 
task_struct *task)
 }
 #endif
 
+/* Determine number of BRP/WRP registers available. */
+extern int get_num_brps(void);
+extern int get_num_wrps(void);
+
 extern struct pmu perf_ops_bp;
 
 #endif /* __KERNEL__ */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 461d288..6c745e0 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -116,13 +116,17 @@ struct kvm_vcpu_arch {
 * debugging the guest from the host and to maintain separate host and
 * guest state during world switches. vcpu_debug_state are the debug
 * registers of the vcpu as the guest sees them.  host_debug_state are
-* the host registers which are saved and restored during world 
switches.
+* the host registers which are s

[PATCH v7 11/11] KVM: arm64: add trace points for guest_debug debug

2015-07-01 Thread Alex Bennée
This includes trace points for:
  kvm_arch_setup_guest_debug
  kvm_arch_clear_guest_debug

I've also added some generic register setting trace events and also a
trace point to dump the array of hardware registers.

Signed-off-by: Alex Bennée 

---
v3
  - add trace event for debug access.
  - remove short trace #define, rename trace events
  - use __print_array with fixed array instead of own func
  - rationalise trace points (only one per register changed)
  - add vcpu ptr to the debug_setup trace
  - remove :: in prints
v4
  - u32/u64 split on debug registers
  - fix for renames
  - add tracing of traps/set_guest_debug
  - remove handle_guest_debug trace
v5
  - minor print fmt fix
  - rm pstate traces
v6
  - fix merge conflicts
  - update control reg tracking to u64 (abi change)
v7
  - fix merge conflicts from ioctl move
  - fix other minor merge conflicts
  - fixes for the re-factored sys_regs code
---
 arch/arm64/kvm/debug.c|  35 -
 arch/arm64/kvm/guest.c|   4 ++
 arch/arm64/kvm/sys_regs.c |  21 
 arch/arm64/kvm/trace.h| 123 ++
 4 files changed, 182 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 46b73d7..119107f 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -24,6 +24,8 @@
 #include 
 #include 
 
+#include "trace.h"
+
 /* These are the bits of MDSCR_EL1 we may manipulate */
 #define MDSCR_EL1_DEBUG_MASK   (DBG_MDSCR_SS | \
DBG_MDSCR_KDE | \
@@ -44,11 +46,17 @@ static DEFINE_PER_CPU(u32, mdcr_el2);
 static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
 {
vcpu->arch.guest_debug_preserved.mdscr_el1 = vcpu_sys_reg(vcpu, 
MDSCR_EL1);
+
+   trace_kvm_arm_set_dreg32("Saved MDSCR_EL1",
+   vcpu->arch.guest_debug_preserved.mdscr_el1);
 }
 
 static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
 {
vcpu_sys_reg(vcpu, MDSCR_EL1) = 
vcpu->arch.guest_debug_preserved.mdscr_el1;
+
+   trace_kvm_arm_set_dreg32("Restored MDSCR_EL1",
+   vcpu_sys_reg(vcpu, MDSCR_EL1));
 }
 
 /**
@@ -99,6 +107,8 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 {
bool trap_debug = !(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY);
 
+   trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug);
+
vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
MDCR_EL2_TPMCR |
@@ -140,6 +150,8 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS;
}
 
+   trace_kvm_arm_set_dreg32("SPSR_EL2", *vcpu_cpsr(vcpu));
+
/*
 * HW Breakpoints and watchpoints
 *
@@ -156,6 +168,14 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state;
vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
trap_debug = true;
+
+   trace_kvm_arm_set_regset("BKPTS", get_num_brps(),
+   
&vcpu->arch.debug_ptr->dbg_bcr[0],
+   
&vcpu->arch.debug_ptr->dbg_bvr[0]);
+
+   trace_kvm_arm_set_regset("WAPTS", get_num_wrps(),
+   
&vcpu->arch.debug_ptr->dbg_wcr[0],
+   
&vcpu->arch.debug_ptr->dbg_wvr[0]);
}
}
 
@@ -165,10 +185,15 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
/* Trap debug register access */
if (trap_debug)
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
+
+   trace_kvm_arm_set_dreg32("MDCR_EL2", vcpu->arch.mdcr_el2);
+   trace_kvm_arm_set_dreg32("MDSCR_EL1", vcpu_sys_reg(vcpu, MDSCR_EL1));
 }
 
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
 {
+   trace_kvm_arm_clear_debug(vcpu->guest_debug);
+
if (vcpu->guest_debug) {
restore_guest_debug_regs(vcpu);
 
@@ -176,8 +201,16 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
 * If we were using HW debug we need to restore the
 * debug_ptr to the guest debug state.
 */
-   if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW)
+   if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
kvm_arm_reset_debug_ptr(vcpu);
 
+   trace_kvm_arm_set_regset("BKPTS", get_num_brps(),
+   
&vcpu->arch.debug_ptr->dbg_bcr[0],
+

[PATCH v7 06/11] KVM: arm64: guest debug, add support for single-step

2015-07-01 Thread Alex Bennée
This adds support for single-stepping the guest. To do this we need to
manipulate the guests PSTATE.SS and MDSCR_EL1.SS bits to trigger
stepping. We take care to preserve MDSCR_EL1 and trap access to it to
ensure we don't affect the apparent state of the guest.

As we have to enable trapping of all software debug exceptions we
suppress the ability of the guest to single-step itself. If we didn't we
would have to deal with the exception arriving while the guest was in
kernelspace when the guest is expecting to single-step userspace. This
is something we don't want to unwind in the kernel. Once the host is no
longer debugging the guest its ability to single-step userspace is
restored.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v2
  - Move pstate/mdscr manipulation into C
  - don't export guest_debug to assembly
  - add accessor for saved_debug regs
  - tweak save/restore of mdscr_el1
v3
  - don't save PC in debug information struct
  - rename debug_saved_regs->guest_debug_state
  - save whole value, only use bits in restore
  - add save/restore_guest-debug_regs helper functions
  - simplify commit message for clarity
  - rm vcpu_debug_saved_reg access fn
v4
  - added more comments based on suggestions
  - guest_debug_state->guest_debug_preserved
  - no point masking restore, we will trap out
v5
  - more comments
  - don't bother preserving pstate.ss (guest never sees change)
v6
  - reword comments on guest SS suppression
  - simplify comment for save regs, SS explained in detail later on
  - add r-b-t (code)
  - expanded commit description
v7
  - merge fix for ioctl move to guest.c
---
 arch/arm64/include/asm/kvm_host.h | 11 +++
 arch/arm64/kvm/debug.c| 68 ---
 arch/arm64/kvm/guest.c|  4 ++-
 arch/arm64/kvm/handle_exit.c  |  2 ++
 4 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 7cb99b5..e2db6a6 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -123,6 +123,17 @@ struct kvm_vcpu_arch {
 * here.
 */
 
+   /*
+* Guest registers we preserve during guest debugging.
+*
+* These shadow registers are updated by the kvm_handle_sys_reg
+* trap handler if the guest accesses or updates them while we
+* are using guest debug.
+*/
+   struct {
+   u32 mdscr_el1;
+   } guest_debug_preserved;
+
/* Don't run the guest */
bool pause;
 
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 8d1bfa4..d439eb8 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -19,11 +19,39 @@
 
 #include 
 
+#include 
+#include 
 #include 
+#include 
+
+/* These are the bits of MDSCR_EL1 we may manipulate */
+#define MDSCR_EL1_DEBUG_MASK   (DBG_MDSCR_SS | \
+   DBG_MDSCR_KDE | \
+   DBG_MDSCR_MDE)
 
 static DEFINE_PER_CPU(u32, mdcr_el2);
 
 /**
+ * save/restore_guest_debug_regs
+ *
+ * For some debug operations we need to tweak some guest registers. As
+ * a result we need to save the state of those registers before we
+ * make those modifications.
+ *
+ * Guest access to MDSCR_EL1 is trapped by the hypervisor and handled
+ * after we have restored the preserved value to the main context.
+ */
+static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
+{
+   vcpu->arch.guest_debug_preserved.mdscr_el1 = vcpu_sys_reg(vcpu, 
MDSCR_EL1);
+}
+
+static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
+{
+   vcpu_sys_reg(vcpu, MDSCR_EL1) = 
vcpu->arch.guest_debug_preserved.mdscr_el1;
+}
+
+/**
  * kvm_arm_init_debug - grab what we need for debug
  *
  * Currently the sole task of this function is to retrieve the initial
@@ -38,7 +66,6 @@ void kvm_arm_init_debug(void)
__this_cpu_write(mdcr_el2, kvm_call_hyp(__kvm_get_mdcr_el2));
 }
 
-
 /**
  * kvm_arm_setup_debug - set up debug related stuff
  *
@@ -73,12 +100,45 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
if (trap_debug)
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 
-   /* Trap breakpoints? */
-   if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+   /* Is Guest debugging in effect? */
+   if (vcpu->guest_debug) {
+   /* Route all software debug exceptions to EL2 */
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
+
+   /* Save guest debug state */
+   save_guest_debug_regs(vcpu);
+
+   /*
+* Single Step (ARM ARM D2.12.3 The software step state
+* machine)
+*
+* If we are doing Single Step we need to manipulate
+* the guest's MDSCR_EL1.SS and PSTATE.SS. Once the
+* step has occurred the hypervisor will tr

[PATCH v7 05/11] KVM: arm64: guest debug, add SW break point support

2015-07-01 Thread Alex Bennée
This adds support for SW breakpoints inserted by userspace.

We do this by trapping all guest software debug exceptions to the
hypervisor (MDCR_EL2.TDE). The exit handler sets an exit reason of
KVM_EXIT_DEBUG with the kvm_debug_exit_arch structure holding the
exception syndrome information.

It will be up to userspace to extract the PC (via GET_ONE_REG) and
determine if the debug event was for a breakpoint it inserted. If not
userspace will need to re-inject the correct exception restart the
hypervisor to deliver the debug exception to the guest.

Any other guest software debug exception (e.g. single step or HW
assisted breakpoints) will cause an error and the VM to be killed. This
is addressed by later patches which add support for the other debug
types.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v2
  - update to use new exit struct
  - tweak for C setup
  - do our setup in debug_setup/clear code
  - fixed up comments
v3:
  - fix spacing in KVM_GUESTDBG_VALID_MASK
  - fix and clarify wording on kvm_handle_guest_debug
  - handle error case in kvm_handle_guest_debug
  - re-word the commit message
v4
  - rm else leg
  - add r-b-tag
v7
  - moved ioctl to guest
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/arm64/kvm/debug.c|  3 +++
 arch/arm64/kvm/guest.c|  2 +-
 arch/arm64/kvm/handle_exit.c  | 36 
 4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index ba635c7..33c8143 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2667,7 +2667,7 @@ when running. Common control bits are:
 The top 16 bits of the control field are architecture specific control
 flags which can include the following:
 
-  - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86]
+  - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64]
   - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
   - KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
   - KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index faf0e1f..8d1bfa4 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -73,6 +73,9 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
if (trap_debug)
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 
+   /* Trap breakpoints? */
+   if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+   vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
 }
 
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index 0ba8677..22d22c5 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -332,7 +332,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
return -EINVAL;
 }
 
-#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE)
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
 
 /**
  * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 524fa25..27f38a9 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -82,6 +82,40 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
return 1;
 }
 
+/**
+ * kvm_handle_guest_debug - handle a debug exception instruction
+ *
+ * @vcpu:  the vcpu pointer
+ * @run:   access to the kvm_run structure for results
+ *
+ * We route all debug exceptions through the same handler. If both the
+ * guest and host are using the same debug facilities it will be up to
+ * userspace to re-inject the correct exception for guest delivery.
+ *
+ * @return: 0 (while setting run->exit_reason), -1 for error
+ */
+static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   u32 hsr = kvm_vcpu_get_hsr(vcpu);
+   int ret = 0;
+
+   run->exit_reason = KVM_EXIT_DEBUG;
+   run->debug.arch.hsr = hsr;
+
+   switch (hsr >> ESR_ELx_EC_SHIFT) {
+   case ESR_ELx_EC_BKPT32:
+   case ESR_ELx_EC_BRK64:
+   break;
+   default:
+   kvm_err("%s: un-handled case hsr: %#08x\n",
+   __func__, (unsigned int) hsr);
+   ret = -1;
+   break;
+   }
+
+   return ret;
+}
+
 static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_WFx]= kvm_handle_wfx,
[ESR_ELx_EC_CP15_32]= kvm_handle_cp15_32,
@@ -96,6 +130,8 @@ static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_SYS64]  = kvm_handle_sys_reg,
[ESR_ELx_EC_IABT_LOW]   = kvm_handle_guest_abort,
[ESR_ELx_EC_DABT_LOW]   = kvm_handle_guest_abort,
+   [ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug,
+   [ESR_ELx_EC_BRK64]  = kvm_handle_guest_debug,
 };
 
 static exit

[PATCH v7 04/11] KVM: arm: introduce kvm_arm_init/setup/clear_debug

2015-07-01 Thread Alex Bennée
This is a precursor for later patches which will need to do more to
setup debug state before entering the hyp.S switch code. The existing
functionality for setting mdcr_el2 has been moved out of hyp.S and now
uses the value kept in vcpu->arch.mdcr_el2.

As the assembler used to previously mask and preserve MDCR_EL2.HPMN I've
had to add a mechanism to save the value of mdcr_el2 as a per-cpu
variable during the initialisation code. The kernel never sets this
number so we are assuming the bootcode has set up the correct value
here.

This also moves the conditional setting of the TDA bit from the hyp code
into the C code which is currently used for the lazy debug register
context switch code.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v3
  - rename fns from arch->arm
  - preserve MDCR_EL2.HPMN setting
  - re-word some of the comments
  - fix some minor grammar nits
  - merge setting of mdcr_el2
  - introduce trap_debug flag
  - move setup/clear within the irq lock section
v4
  - fix TDOSA desc
  - rm un-needed else leg
  - s/arch/arm/
v6
  - add s-o-b tag
---
 arch/arm/include/asm/kvm_host.h   |  4 ++
 arch/arm/kvm/arm.c|  9 -
 arch/arm64/include/asm/kvm_asm.h  |  2 +
 arch/arm64/include/asm/kvm_host.h |  5 +++
 arch/arm64/kernel/asm-offsets.c   |  1 +
 arch/arm64/kvm/Makefile   |  2 +-
 arch/arm64/kvm/debug.c| 81 +++
 arch/arm64/kvm/hyp.S  | 19 -
 8 files changed, 110 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm64/kvm/debug.c

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index d71607c..746c0c69 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -236,4 +236,8 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+static inline void kvm_arm_init_debug(void) {}
+static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
+
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 92b80bc..af60e6f 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -542,6 +542,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
continue;
}
 
+   kvm_arm_setup_debug(vcpu);
+
/**
 * Enter the guest
 */
@@ -554,7 +556,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
vcpu->mode = OUTSIDE_GUEST_MODE;
kvm_guest_exit();
trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
-   /*
+
+   kvm_arm_clear_debug(vcpu);
+
+/*
 * We may have taken a host interrupt in HYP mode (ie
 * while executing the guest). This interrupt is still
 * pending, as we haven't serviced it yet!
@@ -902,6 +907,8 @@ static void cpu_init_hyp_mode(void *dummy)
vector_ptr = (unsigned long)__kvm_hyp_vector;
 
__cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
+
+   kvm_arm_init_debug();
 }
 
 static int hyp_init_cpu_notify(struct notifier_block *self,
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 4f7310f..d6b507e 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -137,6 +137,8 @@ extern char __restore_vgic_v2_state[];
 extern char __save_vgic_v3_state[];
 extern char __restore_vgic_v3_state[];
 
+extern u32 __kvm_get_mdcr_el2(void);
+
 #endif
 
 #endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index f0f58c9..7cb99b5 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -103,6 +103,7 @@ struct kvm_vcpu_arch {
 
/* HYP configuration */
u64 hcr_el2;
+   u32 mdcr_el2;
 
/* Exception Information */
struct kvm_vcpu_fault_info fault;
@@ -250,4 +251,8 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+void kvm_arm_init_debug(void);
+void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
+void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index da675cc..dfb25a2 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -117,6 +117,7 @@ int main(void)
   DEFINE(VCPU_HPFAR_EL2,   offsetof(struct kvm_vcpu, 
a

[PATCH v7 07/11] KVM: arm64: re-factor hyp.S debug register code

2015-07-01 Thread Alex Bennée
This is a pre-cursor to sharing the code with the guest debug support.
This replaces the big macro that fishes data out of a fixed location
with a more general helper macro to restore a set of debug registers. It
uses macro substitution so it can be re-used for debug control and value
registers. It does however rely on the debug registers being 64 bit
aligned (as they happen to be in the hyp ABI).

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v3:
  - return to the patch series
  - add save and restore targets
  - change register use and document
v4:
  - keep original setup/restore names
  - don't use split u32/u64 structure yet
v6:
  - fix ws and clobber info in hyp.S
v7:
  - fix whitespace
  - add r-b-tag
---
 arch/arm64/kvm/hyp.S | 517 ++-
 1 file changed, 138 insertions(+), 379 deletions(-)

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 2c67a14..77c08df 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -228,199 +228,52 @@
stp x24, x25, [x3, #160]
 .endm
 
-.macro save_debug
-   // x2: base address for cpu context
-   // x3: tmp register
-
-   mrs x26, id_aa64dfr0_el1
-   ubfxx24, x26, #12, #4   // Extract BRPs
-   ubfxx25, x26, #20, #4   // Extract WRPs
-   mov w26, #15
-   sub w24, w26, w24   // How many BPs to skip
-   sub w25, w26, w25   // How many WPs to skip
-
-   add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-1:
-   mrs x20, dbgbcr15_el1
-   mrs x19, dbgbcr14_el1
-   mrs x18, dbgbcr13_el1
-   mrs x17, dbgbcr12_el1
-   mrs x16, dbgbcr11_el1
-   mrs x15, dbgbcr10_el1
-   mrs x14, dbgbcr9_el1
-   mrs x13, dbgbcr8_el1
-   mrs x12, dbgbcr7_el1
-   mrs x11, dbgbcr6_el1
-   mrs x10, dbgbcr5_el1
-   mrs x9, dbgbcr4_el1
-   mrs x8, dbgbcr3_el1
-   mrs x7, dbgbcr2_el1
-   mrs x6, dbgbcr1_el1
-   mrs x5, dbgbcr0_el1
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-
-1:
-   str x20, [x3, #(15 * 8)]
-   str x19, [x3, #(14 * 8)]
-   str x18, [x3, #(13 * 8)]
-   str x17, [x3, #(12 * 8)]
-   str x16, [x3, #(11 * 8)]
-   str x15, [x3, #(10 * 8)]
-   str x14, [x3, #(9 * 8)]
-   str x13, [x3, #(8 * 8)]
-   str x12, [x3, #(7 * 8)]
-   str x11, [x3, #(6 * 8)]
-   str x10, [x3, #(5 * 8)]
-   str x9, [x3, #(4 * 8)]
-   str x8, [x3, #(3 * 8)]
-   str x7, [x3, #(2 * 8)]
-   str x6, [x3, #(1 * 8)]
-   str x5, [x3, #(0 * 8)]
-
-   add x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-1:
-   mrs x20, dbgbvr15_el1
-   mrs x19, dbgbvr14_el1
-   mrs x18, dbgbvr13_el1
-   mrs x17, dbgbvr12_el1
-   mrs x16, dbgbvr11_el1
-   mrs x15, dbgbvr10_el1
-   mrs x14, dbgbvr9_el1
-   mrs x13, dbgbvr8_el1
-   mrs x12, dbgbvr7_el1
-   mrs x11, dbgbvr6_el1
-   mrs x10, dbgbvr5_el1
-   mrs x9, dbgbvr4_el1
-   mrs x8, dbgbvr3_el1
-   mrs x7, dbgbvr2_el1
-   mrs x6, dbgbvr1_el1
-   mrs x5, dbgbvr0_el1
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-
-1:
-   str x20, [x3, #(15 * 8)]
-   str x19, [x3, #(14 * 8)]
-   str x18, [x3, #(13 * 8)]
-   str x17, [x3, #(12 * 8)]
-   str x16, [x3, #(11 * 8)]
-   str x15, [x3, #(10 * 8)]
-   str x14, [x3, #(9 * 8)]
-   str x13, [x3, #(8 * 8)]
-   str x12, [x3, #(7 * 8)]
-   str x11, [x3, #(6 * 8)]
-   str x10, [x3, #(5 * 8)]
-   str x9, [x3, #(4 * 8)]
-   str x8, [x3, #(3 * 8)]
-   str x7, [x3, #(2 * 8)]
-   str x6, [x3, #(1 * 8)]
-   str x5, [x3, #(0 * 8)]
-
-   add x3, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
-
-   adr x26, 1f
-   add x26, x26, x25, lsl #2
-   br  x26
+.macro save_debug type
+   // x4: pointer to register set
+   // x5: number of registers to skip
+   // x6..x22 trashed
+
+   adr x22, 1f
+   add x22, x22, x5, lsl #2
+   br  x22
 1:
-   mrs x20, dbgwcr15_el1
-   mrs x19, dbgwcr14_el1
-   mrs x18, dbgwcr13_el1
-   mrs x17, dbgwcr12_el1
-   mrs x16, dbgwcr11_el1
-   mrs x15, dbgwcr10_el1
-   mrs x14, dbgwcr9_el1
-   mrs x13, dbgwcr8_el1
-   mrs x12, dbgwcr7_el1
-   mrs x11, dbgwcr6_el1
-   mrs x10, dbgwcr5_el1
-   mrs x9, dbgwcr4_el1
-   mrs x8, dbgwcr3_el1
-   mrs x7, dbgwcr

[PATCH v7 02/11] KVM: arm64: guest debug, define API headers

2015-07-01 Thread Alex Bennée
This commit defines the API headers for guest debugging. There are two
architecture specific debug structures:

  - kvm_guest_debug_arch, allows us to pass in HW debug registers
  - kvm_debug_exit_arch, signals exception and possible faulting address

The type of debugging being used is controlled by the architecture
specific control bits of the kvm_guest_debug->control flags in the ioctl
structure.

Signed-off-by: Alex Bennée 
Reviewed-by: David Hildenbrand 
Reviewed-by: Andrew Jones 
Acked-by: Christoffer Dall 

---
v2
   - expose hsr and pc directly to user-space
v3
   - s/control/controlled/ in commit message
   - add v8 to ARM ARM comment (ARM Architecture Reference Manual)
   - add rb tag
   - rm pc, add far
   - re-word comments on alignment
   - rename KVM_ARM_NDBG_REGS -> KVM_ARM_MAX_DBG_REGS
v4
   - now uses common HW/SW BP define
   - add a-b-tag
   - use u32 for control regs
v5
   - revert to have arch specific KVM_GUESTDBG_USE_SW/HW_BP
   - rm stale comments dbgctrl was stored as u64
v6
   - mv far comment from later patch
   - KVM_GUESTDBG_USE_HW_BP -> KVM_GUESTDBG_USE_HW
   - revert control regs to u64 (parity with GET/SET_ONE_REG)
---
 arch/arm64/include/uapi/asm/kvm.h | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/kvm.h 
b/arch/arm64/include/uapi/asm/kvm.h
index d268320..d82f3f3 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -100,12 +100,39 @@ struct kvm_sregs {
 struct kvm_fpu {
 };
 
+/*
+ * See v8 ARM ARM D7.3: Debug Registers
+ *
+ * The architectural limit is 16 debug registers of each type although
+ * in practice there are usually less (see ID_AA64DFR0_EL1).
+ *
+ * Although the control registers are architecturally defined as 32
+ * bits wide we use a 64 bit structure here to keep parity with
+ * KVM_GET/SET_ONE_REG behaviour which treats all system registers as
+ * 64 bit values. It also allows for the possibility of the
+ * architecture expanding the control registers without having to
+ * change the userspace ABI.
+ */
+#define KVM_ARM_MAX_DBG_REGS 16
 struct kvm_guest_debug_arch {
+   __u64 dbg_bcr[KVM_ARM_MAX_DBG_REGS];
+   __u64 dbg_bvr[KVM_ARM_MAX_DBG_REGS];
+   __u64 dbg_wcr[KVM_ARM_MAX_DBG_REGS];
+   __u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS];
 };
 
 struct kvm_debug_exit_arch {
+   __u32 hsr;
+   __u64 far;  /* used for watchpoints */
 };
 
+/*
+ * Architecture specific defines for kvm_guest_debug->control
+ */
+
+#define KVM_GUESTDBG_USE_SW_BP (1 << 16)
+#define KVM_GUESTDBG_USE_HW(1 << 17)
+
 struct kvm_sync_regs {
 };
 
-- 
2.4.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v6 10/12] KVM: arm64: guest debug, HW assisted debug support

2015-06-25 Thread Alex Bennée

Christoffer Dall  writes:

> On Thu, Jun 25, 2015 at 07:38:33AM +0100, Alex Bennée wrote:
>> 
>> Christoffer Dall  writes:
>> 
>> > On Fri, Jun 19, 2015 at 01:23:48PM +0100, Alex Bennée wrote:
>> >> This adds support for userspace to control the HW debug registers for
>> >> guest debug. In the debug ioctl we copy the IMPDEF defined number of

>> >>  void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
>> >>  {
>> >> - if (vcpu->guest_debug)
>> >> + if (vcpu->guest_debug) {
>> >>   restore_guest_debug_regs(vcpu);
>> >> +
>> >> + /*
>> >> +  * If we were using HW debug we need to restore the
>> >> +  * debug_ptr to the guest debug state.
>> >> +  */
>> >> + if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW)
>> >> + vcpu->arch.debug_ptr = &vcpu->arch.vcpu_debug_state;
>> >
>> > I still think this would be more cleanly done in the setup_debug
>> > function, but ok:
>> 
>> I don't follow, setup_debug is called before we enter KVM. It's pretty
>> light when no debugging is being done so this ensure we leave state how
>> we would like it when we stop debugging.
>> 
>> I can move it to an else leg in setup if you really want.
>> 
> I just feel like whenever you enter the guest you setup the state you
> want for your guest and then when reading the code you never have to
> worry about "did I set the pointer back correctly last time it exited",
> but thinking about your response, I guess that's an extra store on each
> world-switch, so theoretically that may be a bit more overhead (on top
> of the hundreds other stores and spinlocks we take and stuff).

The setup/clear() calls are tightly paired around the KVM_RUN ioctl code
without any obvious exit points.

Are there any cases you can escape the ioctl code flow? I notice irq's
are re-enabled so I guess a suitably determined irq function could
change the return address or mess around with guest_debug.

> If you prefer, leave it like this, but consider adding a
> BUG_ON(!guest_debugging && debug_ptr != &vcpu->arch.vcpu_debug_state) in
> the setup function...

The clear_debug() code would end up being a fairly sparse piece of code
without it ;-)

> I'm probably being paranoid.

A little paranoia goes a long way in kernel mode ;-)

>
> -Christoffer

-- 
Alex Bennée
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v6 10/12] KVM: arm64: guest debug, HW assisted debug support

2015-06-24 Thread Alex Bennée

Christoffer Dall  writes:

> On Fri, Jun 19, 2015 at 01:23:48PM +0100, Alex Bennée wrote:
>> This adds support for userspace to control the HW debug registers for
>> guest debug. In the debug ioctl we copy the IMPDEF defined number of
>
> s/defined//
>
>> registers into a new register set called host_debug_state. There is now
>> a new vcpu parameter called debug_ptr which selects which register set
>> is to copied into the real registers when world switch occurs.
>
> But this patch doesn't seem to add the debug_ptr field?

Oops, yes the comment belongs to the previous patch.

>
> s/to//
>
>> 
>> I've moved some helper functions into the hw_breakpoint.h header for
>> re-use.
>> 
>> As with single step we need to tweak the guest registers to enable the
>> exceptions so we need to save and restore those bits.
>> 
>> Two new capabilities have been added to the KVM_EXTENSION ioctl to allow
>> userspace to query the number of hardware break and watch points
>> available on the host hardware.
>> 
>> Signed-off-by: Alex Bennée 
>> 
>> ---
>> v2
>>- switched to C setup
>>- replace host debug registers directly into context
>>- minor tweak to api docs
>>- setup right register for debug
>>- add FAR_EL2 to debug exit structure
>>- add support for trapping debug register access
>> v3
>>- remove stray trace statement
>>- fix spacing around operators (various)
>>- clean-up usage of trap_debug
>>- introduce debug_ptr, replace excessive memcpy stuff
>>- don't use memcpy in ioctl, just assign
>>- update cap ioctl documentation
>>- reword a number comments
>>- rename host_debug_state->external_debug_state
>> v4
>>- use the new u32/u64 split debug_ptr approach
>>- fix some wording/comments
>> v5
>>- don't set MDSCR_EL1.KDE (not needed)
>> v6
>>- update wording given change in commentary
>>- KVM_GUESTDBG_USE_HW_BP->KVM_GUESTDBG_USE_HW
>> ---
>>  Documentation/virtual/kvm/api.txt  |  7 ++-
>>  arch/arm/kvm/arm.c |  7 +++
>>  arch/arm64/include/asm/hw_breakpoint.h | 12 +++
>>  arch/arm64/include/asm/kvm_host.h  |  6 +-
>>  arch/arm64/kernel/hw_breakpoint.c  | 12 ---
>>  arch/arm64/kvm/debug.c | 37 
>> +-
>>  arch/arm64/kvm/handle_exit.c   |  6 ++
>>  arch/arm64/kvm/reset.c | 12 +++
>>  include/uapi/linux/kvm.h   |  2 ++
>>  9 files changed, 82 insertions(+), 19 deletions(-)
>> 
>> diff --git a/Documentation/virtual/kvm/api.txt 
>> b/Documentation/virtual/kvm/api.txt
>> index 33c8143..ada57df 100644
>> --- a/Documentation/virtual/kvm/api.txt
>> +++ b/Documentation/virtual/kvm/api.txt
>> @@ -2668,7 +2668,7 @@ The top 16 bits of the control field are architecture 
>> specific control
>>  flags which can include the following:
>>  
>>- KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64]
>> -  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
>> +  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390, 
>> arm64]
>>- KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
>>- KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
>>- KVM_GUESTDBG_EXIT_PENDING:  trigger an immediate guest exit [s390]
>> @@ -2683,6 +2683,11 @@ updated to the correct (supplied) values.
>>  The second part of the structure is architecture specific and
>>  typically contains a set of debug registers.
>>  
>> +For arm64 the number of debug registers is implementation defined and
>> +can be determined by querying the KVM_CAP_GUEST_DEBUG_HW_BPS and
>> +KVM_CAP_GUEST_DEBUG_HW_WPS capabilities which return a positive number
>> +indicating the number of supported registers.
>> +
>>  When debug events exit the main run loop with the reason
>>  KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run
>>  structure containing architecture specific debug information.
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 0d17c7b..60c4045 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -307,6 +307,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>>  
>>  #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |\
>>  KVM_GUESTDBG_USE_SW_BP | \
>> +KVM_GUESTDBG_USE_HW | \
>> 

Re: [PATCH v6 08/12] KVM: arm64: re-factor hyp.S debug register code

2015-06-24 Thread Alex Bennée

Christoffer Dall  writes:

> On Fri, Jun 19, 2015 at 01:23:46PM +0100, Alex Bennée wrote:
>> This is a pre-cursor to sharing the code with the guest debug support.
>> This replaces the big macro that fishes data out of a fixed location
>> with a more general helper macro to restore a set of debug registers. It
>> uses macro substitution so it can be re-used for debug control and value
>> registers. It does however rely on the debug registers being 64 bit
>> aligned (as they happen to be in the hyp ABI).
>> 
>> Signed-off-by: Alex Bennée 
>> 
>> ---
>> v3:
>>   - return to the patch series
>>   - add save and restore targets
>>   - change register use and document
>> v4:
>>   - keep original setup/restore names
>>   - don't use split u32/u64 structure yet
>> v6:
>>   - fix ws and clobber info in hyp.S
>> ---
>>  arch/arm64/kvm/hyp.S | 517 
>> ++-
>>  1 file changed, 138 insertions(+), 379 deletions(-)
>> 
>> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
>> index 74e63d8..ee7f649 100644
>> --- a/arch/arm64/kvm/hyp.S
>> +++ b/arch/arm64/kvm/hyp.S
>> @@ -228,199 +228,52 @@
>>  stp x24, x25, [x3, #160]
>>  .endm
>>  
>> -.macro save_debug
>> -// x2: base address for cpu context
>> -// x3: tmp register
>> -
>> -mrs x26, id_aa64dfr0_el1
>> -ubfxx24, x26, #12, #4   // Extract BRPs
>> -ubfxx25, x26, #20, #4   // Extract WRPs
>> -mov w26, #15
>> -sub w24, w26, w24   // How many BPs to skip
>> -sub w25, w26, w25   // How many WPs to skip
>> -
>> -add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
>> -
>> -adr x26, 1f
>> -add x26, x26, x24, lsl #2
>> -br  x26
>> -1:
>> -mrs x20, dbgbcr15_el1
>> -mrs x19, dbgbcr14_el1
>> -mrs x18, dbgbcr13_el1
>> -mrs x17, dbgbcr12_el1
>> -mrs x16, dbgbcr11_el1
>> -mrs x15, dbgbcr10_el1
>> -mrs x14, dbgbcr9_el1
>> -mrs x13, dbgbcr8_el1
>> -mrs x12, dbgbcr7_el1
>> -mrs x11, dbgbcr6_el1
>> -mrs x10, dbgbcr5_el1
>> -mrs x9, dbgbcr4_el1
>> -mrs x8, dbgbcr3_el1
>> -mrs x7, dbgbcr2_el1
>> -mrs x6, dbgbcr1_el1
>> -mrs x5, dbgbcr0_el1
>> -
>> -adr x26, 1f
>> -add x26, x26, x24, lsl #2
>> -br  x26
>> -
>> -1:
>> -str x20, [x3, #(15 * 8)]
>> -str x19, [x3, #(14 * 8)]
>> -str x18, [x3, #(13 * 8)]
>> -str x17, [x3, #(12 * 8)]
>> -str x16, [x3, #(11 * 8)]
>> -str x15, [x3, #(10 * 8)]
>> -str x14, [x3, #(9 * 8)]
>> -str x13, [x3, #(8 * 8)]
>> -str x12, [x3, #(7 * 8)]
>> -str x11, [x3, #(6 * 8)]
>> -str x10, [x3, #(5 * 8)]
>> -str x9, [x3, #(4 * 8)]
>> -str x8, [x3, #(3 * 8)]
>> -str x7, [x3, #(2 * 8)]
>> -str x6, [x3, #(1 * 8)]
>> -str x5, [x3, #(0 * 8)]
>> -
>> -add x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
>> -
>> -adr x26, 1f
>> -add x26, x26, x24, lsl #2
>> -br  x26
>> -1:
>> -mrs x20, dbgbvr15_el1
>> -mrs x19, dbgbvr14_el1
>> -mrs x18, dbgbvr13_el1
>> -mrs x17, dbgbvr12_el1
>> -mrs x16, dbgbvr11_el1
>> -mrs x15, dbgbvr10_el1
>> -mrs x14, dbgbvr9_el1
>> -mrs x13, dbgbvr8_el1
>> -mrs x12, dbgbvr7_el1
>> -mrs x11, dbgbvr6_el1
>> -mrs x10, dbgbvr5_el1
>> -mrs x9, dbgbvr4_el1
>> -mrs x8, dbgbvr3_el1
>> -mrs x7, dbgbvr2_el1
>> -mrs x6, dbgbvr1_el1
>> -mrs x5, dbgbvr0_el1
>> -
>> -adr x26, 1f
>> -add x26, x26, x24, lsl #2
>> -br  x26
>> -
>> -1:
>> -str x20, [x3, #(15 * 8)]
>> -str x19, [x3, #(14 * 8)]
>> -str x18, [x3, #(13 * 8)]
>> -str x17, [x3, #(12 * 8)]
>> -str x16, [x3, #(11 * 8)]
>> -str x15, [x3, #(10 * 8)]
>> -str x14, [x3, #(9 * 8)]
>> -str x13, [x3, #(8 * 8)]
>> -str x12, [x3, #(7 * 8)]
>> -str x11, [x3, #(6 * 8)]
>> -str x10, [x3, #(5 * 8)]
>> -str x9, [x3, #(4 * 8)]
>> -str x8, [x3, #(3 * 8)]
&g

Re: [PATCH v6 09/12] KVM: arm64: introduce vcpu->arch.debug_ptr

2015-06-24 Thread Alex Bennée

Christoffer Dall  writes:

> On Fri, Jun 19, 2015 at 01:23:47PM +0100, Alex Bennée wrote:
>> This introduces a level of indirection for the debug registers. Instead
>> of using the sys_regs[] directly we store registers in a structure in
>> the vcpu. As we are no longer tied to the layout of the sys_regs[] we
>> can make the copies size appropriate for control and value registers.
>> 
>> This also entails updating the sys_regs code to access this new
>> structure. Instead of passing a register index we now pass an offset
>> into the kvm_guest_debug_arch structure.
>> 
>> We also need to ensure the GET/SET_ONE_REG ioctl operations store the
>> registers in their correct location.
>> 
>> Signed-off-by: Alex Bennée 
>> 
>> ---
>> v6:
>>   - fix up some ws issues
>>   - correct clobber info
>>   - re-word commentary in kvm_host.h
>>   - fix endian access issues for aarch32 fields
>>   - revert all KVM_GET/SET_ONE_REG to 64bit (also see ABI update)
>> ---

>>  
>> +/* Used when AArch32 kernels trap to mapped debug registers */
>> +static inline bool trap_debug32(struct kvm_vcpu *vcpu,
>> +const struct sys_reg_params *p,
>> +const struct sys_reg_desc *rd)
>> +{
>> +__u32 *r = (__u32 *) ((void * )&vcpu->arch.vcpu_debug_state + rd->reg);
>
> This still looks like something that's asking for BE trouble.  Why not
> access the register as a __u64 as it is and then only special-case it
> somehow for the XVR thingy...  Perhaps a separate function, see below.
>
>> +if (p->is_write) {
>> +*r = *vcpu_reg(vcpu, p->Rt);
>> +vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
>> +} else {
>> +*vcpu_reg(vcpu, p->Rt) = *r;
>> +}
>> +
>> +return true;
>> +}
>> +
>> +static inline bool trap_debug64(struct kvm_vcpu *vcpu,
>> +const struct sys_reg_params *p,
>> +const struct sys_reg_desc *rd)
>> +{
>> +__u64 *r = (__u64 *) ((void * )&vcpu->arch.vcpu_debug_state + rd->reg);
>> +if (p->is_write) {
>> +*r = *vcpu_reg(vcpu, p->Rt);
>> +vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
>> +} else {
>> +*vcpu_reg(vcpu, p->Rt) = *r;
>> +}
>> +
>> +return true;
>> +}
>> +
>> +static inline void reset_debug64(struct kvm_vcpu *vcpu, const struct 
>> sys_reg_desc *rd)
>> +{
>> +__u64 *r = (__u64 *) ((void * )&vcpu->arch.vcpu_debug_state + rd->reg);
>> +*r = rd->val;
>> +}
>> +
>>  static void reset_amair_el1(struct kvm_vcpu *vcpu, const struct 
>> sys_reg_desc *r)
>>  {
>>  u64 amair;
>> @@ -240,16 +277,20 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const 
>> struct sys_reg_desc *r)
>>  #define DBG_BCR_BVR_WCR_WVR_EL1(n)  \
>>  /* DBGBVRn_EL1 */   \
>>  { Op0(0b10), Op1(0b000), CRn(0b), CRm((n)), Op2(0b100), \
>> -  trap_debug_regs, reset_val, (DBGBVR0_EL1 + (n)), 0 }, \
>> +  trap_debug64, reset_debug64,  \
>> +  offsetof(struct kvm_guest_debug_arch, dbg_bvr[(n)]), 0 }, \
>>  /* DBGBCRn_EL1 */   \
>>  { Op0(0b10), Op1(0b000), CRn(0b), CRm((n)), Op2(0b101), \
>> -  trap_debug_regs, reset_val, (DBGBCR0_EL1 + (n)), 0 }, \
>> +  trap_debug64, reset_debug64,  \
>> +  offsetof(struct kvm_guest_debug_arch, dbg_bcr[(n)]), 0},  \
>>  /* DBGWVRn_EL1 */   \
>>  { Op0(0b10), Op1(0b000), CRn(0b), CRm((n)), Op2(0b110), \
>> -  trap_debug_regs, reset_val, (DBGWVR0_EL1 + (n)), 0 }, \
>> +  trap_debug64, reset_debug64,  \
>> +  offsetof(struct kvm_guest_debug_arch, dbg_wvr[(n)]), 0 }, \
>>  /* DBGWCRn_EL1 */   \
>>  { Op0(0b10), Op1(0b000), CRn(0b), CRm((n)), Op2(0b111), \
>> -  trap_debug_regs, reset_val, (DBGWCR0_EL1 + (n)), 0 }
>> +  trap_debug64, reset_debug64,  \
>> +  offsetof(struct kvm_guest_debug_arch, dbg_wcr[(n)]), 0}
>>  
>>  /*
>>   * Architected system registers.
>> @@ -502,42 +543,51 @@ static bool trap_dbgidr(s

[PATCH v6 11/12] KVM: arm64: enable KVM_CAP_SET_GUEST_DEBUG

2015-06-19 Thread Alex Bennée
Finally advertise the KVM capability for SET_GUEST_DEBUG. Once arm
support is added this check can be moved to the common
kvm_vm_ioctl_check_extension() code.

Signed-off-by: Alex Bennée 
Acked-by: Christoffer Dall 

---

v3:
 - separated capability check from previous patches
 - moved into arm64 specific ioctl handler.
v4:
 - add a-b-tag
---
 arch/arm64/kvm/reset.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 21d5a62..88e5331 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -76,6 +76,9 @@ int kvm_arch_dev_ioctl_check_extension(long ext)
case KVM_CAP_GUEST_DEBUG_HW_WPS:
r  = get_num_wrps();
break;
+   case KVM_CAP_SET_GUEST_DEBUG:
+   r = 1;
+   break;
default:
r = 0;
}
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v6 10/12] KVM: arm64: guest debug, HW assisted debug support

2015-06-19 Thread Alex Bennée
This adds support for userspace to control the HW debug registers for
guest debug. In the debug ioctl we copy the IMPDEF defined number of
registers into a new register set called host_debug_state. There is now
a new vcpu parameter called debug_ptr which selects which register set
is to copied into the real registers when world switch occurs.

I've moved some helper functions into the hw_breakpoint.h header for
re-use.

As with single step we need to tweak the guest registers to enable the
exceptions so we need to save and restore those bits.

Two new capabilities have been added to the KVM_EXTENSION ioctl to allow
userspace to query the number of hardware break and watch points
available on the host hardware.

Signed-off-by: Alex Bennée 

---
v2
   - switched to C setup
   - replace host debug registers directly into context
   - minor tweak to api docs
   - setup right register for debug
   - add FAR_EL2 to debug exit structure
   - add support for trapping debug register access
v3
   - remove stray trace statement
   - fix spacing around operators (various)
   - clean-up usage of trap_debug
   - introduce debug_ptr, replace excessive memcpy stuff
   - don't use memcpy in ioctl, just assign
   - update cap ioctl documentation
   - reword a number comments
   - rename host_debug_state->external_debug_state
v4
   - use the new u32/u64 split debug_ptr approach
   - fix some wording/comments
v5
   - don't set MDSCR_EL1.KDE (not needed)
v6
   - update wording given change in commentary
   - KVM_GUESTDBG_USE_HW_BP->KVM_GUESTDBG_USE_HW
---
 Documentation/virtual/kvm/api.txt  |  7 ++-
 arch/arm/kvm/arm.c |  7 +++
 arch/arm64/include/asm/hw_breakpoint.h | 12 +++
 arch/arm64/include/asm/kvm_host.h  |  6 +-
 arch/arm64/kernel/hw_breakpoint.c  | 12 ---
 arch/arm64/kvm/debug.c | 37 +-
 arch/arm64/kvm/handle_exit.c   |  6 ++
 arch/arm64/kvm/reset.c | 12 +++
 include/uapi/linux/kvm.h   |  2 ++
 9 files changed, 82 insertions(+), 19 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 33c8143..ada57df 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2668,7 +2668,7 @@ The top 16 bits of the control field are architecture 
specific control
 flags which can include the following:
 
   - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64]
-  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
+  - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390, arm64]
   - KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
   - KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
   - KVM_GUESTDBG_EXIT_PENDING:  trigger an immediate guest exit [s390]
@@ -2683,6 +2683,11 @@ updated to the correct (supplied) values.
 The second part of the structure is architecture specific and
 typically contains a set of debug registers.
 
+For arm64 the number of debug registers is implementation defined and
+can be determined by querying the KVM_CAP_GUEST_DEBUG_HW_BPS and
+KVM_CAP_GUEST_DEBUG_HW_WPS capabilities which return a positive number
+indicating the number of supported registers.
+
 When debug events exit the main run loop with the reason
 KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run
 structure containing architecture specific debug information.
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 0d17c7b..60c4045 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -307,6 +307,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 
 #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |\
KVM_GUESTDBG_USE_SW_BP | \
+   KVM_GUESTDBG_USE_HW | \
KVM_GUESTDBG_SINGLESTEP)
 
 /**
@@ -327,6 +328,12 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu 
*vcpu,
 
if (dbg->control & KVM_GUESTDBG_ENABLE) {
vcpu->guest_debug = dbg->control;
+
+   /* Hardware assisted Break and Watch points */
+   if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW) {
+   vcpu->arch.external_debug_state = dbg->arch;
+   }
+
} else {
/* If not enabled clear all flags */
vcpu->guest_debug = 0;
diff --git a/arch/arm64/include/asm/hw_breakpoint.h 
b/arch/arm64/include/asm/hw_breakpoint.h
index 52b484b..c450552 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -130,6 +130,18 @@ static inline void ptrace_hw_copy_thread(struct 
task_struct *task)
 }
 #endif
 
+/* Determine number of BRP registers available. */
+static inline int get_num_brps(void)
+{
+   return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1;
+}
+
+/* Determ

[PATCH v6 12/12] KVM: arm64: add trace points for guest_debug debug

2015-06-19 Thread Alex Bennée
This includes trace points for:
  kvm_arch_setup_guest_debug
  kvm_arch_clear_guest_debug

I've also added some generic register setting trace events and also a
trace point to dump the array of hardware registers.

Signed-off-by: Alex Bennée 

---
v3
  - add trace event for debug access.
  - remove short trace #define, rename trace events
  - use __print_array with fixed array instead of own func
  - rationalise trace points (only one per register changed)
  - add vcpu ptr to the debug_setup trace
  - remove :: in prints
v4
  - u32/u64 split on debug registers
  - fix for renames
  - add tracing of traps/set_guest_debug
  - remove handle_guest_debug trace
v5
  - minor print fmt fix
  - rm pstate traces
v6
  - fix merge conflicts
  - update control reg tracking to u64 (abi change)
---
 arch/arm/kvm/arm.c|   2 +
 arch/arm/kvm/trace.h  |  17 
 arch/arm64/kvm/debug.c|  35 +++-
 arch/arm64/kvm/sys_regs.c |  10 +
 arch/arm64/kvm/trace.h| 105 ++
 5 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 60c4045..d75c749 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -323,6 +323,8 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
struct kvm_guest_debug *dbg)
 {
+   trace_kvm_set_guest_debug(vcpu, dbg->control);
+
if (dbg->control & ~KVM_GUESTDBG_VALID_MASK)
return -EINVAL;
 
diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h
index 0ec3539..3e346a6 100644
--- a/arch/arm/kvm/trace.h
+++ b/arch/arm/kvm/trace.h
@@ -317,6 +317,23 @@ TRACE_EVENT(kvm_toggle_cache,
  __entry->now ? "on" : "off")
 );
 
+TRACE_EVENT(kvm_set_guest_debug,
+   TP_PROTO(struct kvm_vcpu *vcpu, __u32 guest_debug),
+   TP_ARGS(vcpu, guest_debug),
+
+   TP_STRUCT__entry(
+   __field(struct kvm_vcpu *, vcpu)
+   __field(__u32, guest_debug)
+   ),
+
+   TP_fast_assign(
+   __entry->vcpu = vcpu;
+   __entry->guest_debug = guest_debug;
+   ),
+
+   TP_printk("vcpu: %p, flags: 0x%08x", __entry->vcpu, 
__entry->guest_debug)
+);
+
 #endif /* _TRACE_KVM_H */
 
 #undef TRACE_INCLUDE_PATH
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index b287bbc..f69570a 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -24,6 +24,8 @@
 #include 
 #include 
 
+#include "trace.h"
+
 /* These are the bits of MDSCR_EL1 we may manipulate */
 #define MDSCR_EL1_DEBUG_MASK   (DBG_MDSCR_SS | \
DBG_MDSCR_KDE | \
@@ -44,11 +46,17 @@ static DEFINE_PER_CPU(u32, mdcr_el2);
 static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
 {
vcpu->arch.guest_debug_preserved.mdscr_el1 = vcpu_sys_reg(vcpu, 
MDSCR_EL1);
+
+   trace_kvm_arm_set_dreg32("Saved MDSCR_EL1",
+   vcpu->arch.guest_debug_preserved.mdscr_el1);
 }
 
 static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
 {
vcpu_sys_reg(vcpu, MDSCR_EL1) = 
vcpu->arch.guest_debug_preserved.mdscr_el1;
+
+   trace_kvm_arm_set_dreg32("Restored MDSCR_EL1",
+   vcpu_sys_reg(vcpu, MDSCR_EL1));
 }
 
 /**
@@ -90,6 +98,8 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
 {
bool trap_debug = !(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY);
 
+   trace_kvm_arm_setup_debug(vcpu, vcpu->guest_debug);
+
vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
MDCR_EL2_TPMCR |
@@ -131,6 +141,8 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS;
}
 
+   trace_kvm_arm_set_dreg32("SPSR_EL2", *vcpu_cpsr(vcpu));
+
/*
 * HW Breakpoints and watchpoints
 *
@@ -147,16 +159,29 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
vcpu->arch.debug_ptr = &vcpu->arch.external_debug_state;
vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
trap_debug = true;
+
+   trace_kvm_arm_set_regset("BKPTS", get_num_brps(),
+   
&vcpu->arch.debug_ptr->dbg_bcr[0],
+   
&vcpu->arch.debug_ptr->dbg_bvr[0]);
+
+   trace_kvm_arm_set_regset("WAPTS", get_num_wrps(),
+   
&vcpu->arch.debug_ptr->dbg_wcr[0],
+   
&vcpu->arch.deb

[PATCH v6 03/12] KVM: arm64: guest debug, define API headers

2015-06-19 Thread Alex Bennée
This commit defines the API headers for guest debugging. There are two
architecture specific debug structures:

  - kvm_guest_debug_arch, allows us to pass in HW debug registers
  - kvm_debug_exit_arch, signals exception and possible faulting address

The type of debugging being used is controlled by the architecture
specific control bits of the kvm_guest_debug->control flags in the ioctl
structure.

Signed-off-by: Alex Bennée 
Reviewed-by: David Hildenbrand 
Reviewed-by: Andrew Jones 
Acked-by: Christoffer Dall 

---
v2
   - expose hsr and pc directly to user-space
v3
   - s/control/controlled/ in commit message
   - add v8 to ARM ARM comment (ARM Architecture Reference Manual)
   - add rb tag
   - rm pc, add far
   - re-word comments on alignment
   - rename KVM_ARM_NDBG_REGS -> KVM_ARM_MAX_DBG_REGS
v4
   - now uses common HW/SW BP define
   - add a-b-tag
   - use u32 for control regs
v5
   - revert to have arch specific KVM_GUESTDBG_USE_SW/HW_BP
   - rm stale comments dbgctrl was stored as u64
v6
   - mv far comment from later patch
   - KVM_GUESTDBG_USE_HW_BP -> KVM_GUESTDBG_USE_HW
   - revert control regs to u64 (parity with GET/SET_ONE_REG)
---
 arch/arm64/include/uapi/asm/kvm.h | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/kvm.h 
b/arch/arm64/include/uapi/asm/kvm.h
index d268320..d82f3f3 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -100,12 +100,39 @@ struct kvm_sregs {
 struct kvm_fpu {
 };
 
+/*
+ * See v8 ARM ARM D7.3: Debug Registers
+ *
+ * The architectural limit is 16 debug registers of each type although
+ * in practice there are usually less (see ID_AA64DFR0_EL1).
+ *
+ * Although the control registers are architecturally defined as 32
+ * bits wide we use a 64 bit structure here to keep parity with
+ * KVM_GET/SET_ONE_REG behaviour which treats all system registers as
+ * 64 bit values. It also allows for the possibility of the
+ * architecture expanding the control registers without having to
+ * change the userspace ABI.
+ */
+#define KVM_ARM_MAX_DBG_REGS 16
 struct kvm_guest_debug_arch {
+   __u64 dbg_bcr[KVM_ARM_MAX_DBG_REGS];
+   __u64 dbg_bvr[KVM_ARM_MAX_DBG_REGS];
+   __u64 dbg_wcr[KVM_ARM_MAX_DBG_REGS];
+   __u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS];
 };
 
 struct kvm_debug_exit_arch {
+   __u32 hsr;
+   __u64 far;  /* used for watchpoints */
 };
 
+/*
+ * Architecture specific defines for kvm_guest_debug->control
+ */
+
+#define KVM_GUESTDBG_USE_SW_BP (1 << 16)
+#define KVM_GUESTDBG_USE_HW(1 << 17)
+
 struct kvm_sync_regs {
 };
 
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v6 06/12] KVM: arm64: guest debug, add SW break point support

2015-06-19 Thread Alex Bennée
This adds support for SW breakpoints inserted by userspace.

We do this by trapping all guest software debug exceptions to the
hypervisor (MDCR_EL2.TDE). The exit handler sets an exit reason of
KVM_EXIT_DEBUG with the kvm_debug_exit_arch structure holding the
exception syndrome information.

It will be up to userspace to extract the PC (via GET_ONE_REG) and
determine if the debug event was for a breakpoint it inserted. If not
userspace will need to re-inject the correct exception restart the
hypervisor to deliver the debug exception to the guest.

Any other guest software debug exception (e.g. single step or HW
assisted breakpoints) will cause an error and the VM to be killed. This
is addressed by later patches which add support for the other debug
types.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v2
  - update to use new exit struct
  - tweak for C setup
  - do our setup in debug_setup/clear code
  - fixed up comments
v3:
  - fix spacing in KVM_GUESTDBG_VALID_MASK
  - fix and clarify wording on kvm_handle_guest_debug
  - handle error case in kvm_handle_guest_debug
  - re-word the commit message
v4
  - rm else leg
  - add r-b-tag
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/arm/kvm/arm.c|  2 +-
 arch/arm64/kvm/debug.c|  3 +++
 arch/arm64/kvm/handle_exit.c  | 36 
 4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index ba635c7..33c8143 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2667,7 +2667,7 @@ when running. Common control bits are:
 The top 16 bits of the control field are architecture specific control
 flags which can include the following:
 
-  - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86]
+  - KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64]
   - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
   - KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
   - KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 4a274e1..064c105 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -302,7 +302,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_arm_set_running_vcpu(NULL);
 }
 
-#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE)
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
 
 /**
  * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index faf0e1f..8d1bfa4 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -73,6 +73,9 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
if (trap_debug)
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 
+   /* Trap breakpoints? */
+   if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+   vcpu->arch.mdcr_el2 |= MDCR_EL2_TDE;
 }
 
 void kvm_arm_clear_debug(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 524fa25..27f38a9 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -82,6 +82,40 @@ static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
return 1;
 }
 
+/**
+ * kvm_handle_guest_debug - handle a debug exception instruction
+ *
+ * @vcpu:  the vcpu pointer
+ * @run:   access to the kvm_run structure for results
+ *
+ * We route all debug exceptions through the same handler. If both the
+ * guest and host are using the same debug facilities it will be up to
+ * userspace to re-inject the correct exception for guest delivery.
+ *
+ * @return: 0 (while setting run->exit_reason), -1 for error
+ */
+static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
+{
+   u32 hsr = kvm_vcpu_get_hsr(vcpu);
+   int ret = 0;
+
+   run->exit_reason = KVM_EXIT_DEBUG;
+   run->debug.arch.hsr = hsr;
+
+   switch (hsr >> ESR_ELx_EC_SHIFT) {
+   case ESR_ELx_EC_BKPT32:
+   case ESR_ELx_EC_BRK64:
+   break;
+   default:
+   kvm_err("%s: un-handled case hsr: %#08x\n",
+   __func__, (unsigned int) hsr);
+   ret = -1;
+   break;
+   }
+
+   return ret;
+}
+
 static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_WFx]= kvm_handle_wfx,
[ESR_ELx_EC_CP15_32]= kvm_handle_cp15_32,
@@ -96,6 +130,8 @@ static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_SYS64]  = kvm_handle_sys_reg,
[ESR_ELx_EC_IABT_LOW]   = kvm_handle_guest_abort,
[ESR_ELx_EC_DABT_LOW]   = kvm_handle_guest_abort,
+   [ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug,
+   [ESR_ELx_EC_BRK64]  = kvm_handle_guest_debug,
 };
 
 static exit_handle_fn kvm_get_exit_handler(s

[PATCH v6 01/12] KVM: add comments for kvm_debug_exit_arch struct

2015-06-19 Thread Alex Bennée
Bring into line with the comments for the other structures and their
KVM_EXIT_* cases. Also update api.txt to reflect use in kvm_run
documentation.

Signed-off-by: Alex Bennée 
Reviewed-by: David Hildenbrand 
Reviewed-by: Andrew Jones 
Acked-by: Christoffer Dall 

---

v2
  - add comments for other exit types
v3
  - s/commentary/comments/
  - add rb tags
  - update api.txt kvm_run to include KVM_EXIT_DEBUG desc
v4
  - sp fixes
  - add a-b
---
 Documentation/virtual/kvm/api.txt | 4 +++-
 include/uapi/linux/kvm.h  | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index 9fa2bf8..c34c32d 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3070,11 +3070,13 @@ data_offset describes where the data is located 
(KVM_EXIT_IO_OUT) or
 where kvm expects application code to place the data for the next
 KVM_RUN invocation (KVM_EXIT_IO_IN).  Data format is a packed array.
 
+   /* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
 
-Unused.
+If the exit_reason is KVM_EXIT_DEBUG, then a vcpu is processing a debug event
+for which architecture specific information is returned.
 
/* KVM_EXIT_MMIO */
struct {
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 4b60056..70ac641 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -237,6 +237,7 @@ struct kvm_run {
__u32 count;
__u64 data_offset; /* relative to kvm_run start */
} io;
+   /* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
@@ -285,6 +286,7 @@ struct kvm_run {
__u32 data;
__u8  is_write;
} dcr;
+   /* KVM_EXIT_INTERNAL_ERROR */
struct {
__u32 suberror;
/* Available with KVM_CAP_INTERNAL_ERROR_DATA: */
@@ -295,6 +297,7 @@ struct kvm_run {
struct {
__u64 gprs[32];
} osi;
+   /* KVM_EXIT_PAPR_HCALL */
struct {
__u64 nr;
__u64 ret;
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v6 08/12] KVM: arm64: re-factor hyp.S debug register code

2015-06-19 Thread Alex Bennée
This is a pre-cursor to sharing the code with the guest debug support.
This replaces the big macro that fishes data out of a fixed location
with a more general helper macro to restore a set of debug registers. It
uses macro substitution so it can be re-used for debug control and value
registers. It does however rely on the debug registers being 64 bit
aligned (as they happen to be in the hyp ABI).

Signed-off-by: Alex Bennée 

---
v3:
  - return to the patch series
  - add save and restore targets
  - change register use and document
v4:
  - keep original setup/restore names
  - don't use split u32/u64 structure yet
v6:
  - fix ws and clobber info in hyp.S
---
 arch/arm64/kvm/hyp.S | 517 ++-
 1 file changed, 138 insertions(+), 379 deletions(-)

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 74e63d8..ee7f649 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -228,199 +228,52 @@
stp x24, x25, [x3, #160]
 .endm
 
-.macro save_debug
-   // x2: base address for cpu context
-   // x3: tmp register
-
-   mrs x26, id_aa64dfr0_el1
-   ubfxx24, x26, #12, #4   // Extract BRPs
-   ubfxx25, x26, #20, #4   // Extract WRPs
-   mov w26, #15
-   sub w24, w26, w24   // How many BPs to skip
-   sub w25, w26, w25   // How many WPs to skip
-
-   add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-1:
-   mrs x20, dbgbcr15_el1
-   mrs x19, dbgbcr14_el1
-   mrs x18, dbgbcr13_el1
-   mrs x17, dbgbcr12_el1
-   mrs x16, dbgbcr11_el1
-   mrs x15, dbgbcr10_el1
-   mrs x14, dbgbcr9_el1
-   mrs x13, dbgbcr8_el1
-   mrs x12, dbgbcr7_el1
-   mrs x11, dbgbcr6_el1
-   mrs x10, dbgbcr5_el1
-   mrs x9, dbgbcr4_el1
-   mrs x8, dbgbcr3_el1
-   mrs x7, dbgbcr2_el1
-   mrs x6, dbgbcr1_el1
-   mrs x5, dbgbcr0_el1
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-
-1:
-   str x20, [x3, #(15 * 8)]
-   str x19, [x3, #(14 * 8)]
-   str x18, [x3, #(13 * 8)]
-   str x17, [x3, #(12 * 8)]
-   str x16, [x3, #(11 * 8)]
-   str x15, [x3, #(10 * 8)]
-   str x14, [x3, #(9 * 8)]
-   str x13, [x3, #(8 * 8)]
-   str x12, [x3, #(7 * 8)]
-   str x11, [x3, #(6 * 8)]
-   str x10, [x3, #(5 * 8)]
-   str x9, [x3, #(4 * 8)]
-   str x8, [x3, #(3 * 8)]
-   str x7, [x3, #(2 * 8)]
-   str x6, [x3, #(1 * 8)]
-   str x5, [x3, #(0 * 8)]
-
-   add x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-1:
-   mrs x20, dbgbvr15_el1
-   mrs x19, dbgbvr14_el1
-   mrs x18, dbgbvr13_el1
-   mrs x17, dbgbvr12_el1
-   mrs x16, dbgbvr11_el1
-   mrs x15, dbgbvr10_el1
-   mrs x14, dbgbvr9_el1
-   mrs x13, dbgbvr8_el1
-   mrs x12, dbgbvr7_el1
-   mrs x11, dbgbvr6_el1
-   mrs x10, dbgbvr5_el1
-   mrs x9, dbgbvr4_el1
-   mrs x8, dbgbvr3_el1
-   mrs x7, dbgbvr2_el1
-   mrs x6, dbgbvr1_el1
-   mrs x5, dbgbvr0_el1
-
-   adr x26, 1f
-   add x26, x26, x24, lsl #2
-   br  x26
-
-1:
-   str x20, [x3, #(15 * 8)]
-   str x19, [x3, #(14 * 8)]
-   str x18, [x3, #(13 * 8)]
-   str x17, [x3, #(12 * 8)]
-   str x16, [x3, #(11 * 8)]
-   str x15, [x3, #(10 * 8)]
-   str x14, [x3, #(9 * 8)]
-   str x13, [x3, #(8 * 8)]
-   str x12, [x3, #(7 * 8)]
-   str x11, [x3, #(6 * 8)]
-   str x10, [x3, #(5 * 8)]
-   str x9, [x3, #(4 * 8)]
-   str x8, [x3, #(3 * 8)]
-   str x7, [x3, #(2 * 8)]
-   str x6, [x3, #(1 * 8)]
-   str x5, [x3, #(0 * 8)]
-
-   add x3, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
-
-   adr x26, 1f
-   add x26, x26, x25, lsl #2
-   br  x26
+.macro save_debug type
+   // x4: pointer to register set
+   // x5: number of registers to skip
+   // x6..x22 trashed
+
+   adr x22, 1f
+   add x22, x22, x5, lsl #2
+   br  x22
 1:
-   mrs x20, dbgwcr15_el1
-   mrs x19, dbgwcr14_el1
-   mrs x18, dbgwcr13_el1
-   mrs x17, dbgwcr12_el1
-   mrs x16, dbgwcr11_el1
-   mrs x15, dbgwcr10_el1
-   mrs x14, dbgwcr9_el1
-   mrs x13, dbgwcr8_el1
-   mrs x12, dbgwcr7_el1
-   mrs x11, dbgwcr6_el1
-   mrs x10, dbgwcr5_el1
-   mrs x9, dbgwcr4_el1
-   mrs x8, dbgwcr3_el1
-   mrs x7, dbgwcr2_el1
-   mrs x6, dbgwcr1_el1
-   mrs x5, dbgwcr0_el1
-
- 

[PATCH v6 05/12] KVM: arm: introduce kvm_arm_init/setup/clear_debug

2015-06-19 Thread Alex Bennée
This is a precursor for later patches which will need to do more to
setup debug state before entering the hyp.S switch code. The existing
functionality for setting mdcr_el2 has been moved out of hyp.S and now
uses the value kept in vcpu->arch.mdcr_el2.

As the assembler used to previously mask and preserve MDCR_EL2.HPMN I've
had to add a mechanism to save the value of mdcr_el2 as a per-cpu
variable during the initialisation code. The kernel never sets this
number so we are assuming the bootcode has set up the correct value
here.

This also moves the conditional setting of the TDA bit from the hyp code
into the C code which is currently used for the lazy debug register
context switch code.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v3
  - rename fns from arch->arm
  - preserve MDCR_EL2.HPMN setting
  - re-word some of the comments
  - fix some minor grammar nits
  - merge setting of mdcr_el2
  - introduce trap_debug flag
  - move setup/clear within the irq lock section
v4
  - fix TDOSA desc
  - rm un-needed else leg
  - s/arch/arm/
v6
  - add s-o-b tag
---
 arch/arm/include/asm/kvm_host.h   |  4 ++
 arch/arm/kvm/arm.c|  9 -
 arch/arm64/include/asm/kvm_asm.h  |  2 +
 arch/arm64/include/asm/kvm_host.h |  5 +++
 arch/arm64/kernel/asm-offsets.c   |  1 +
 arch/arm64/kvm/Makefile   |  2 +-
 arch/arm64/kvm/debug.c| 81 +++
 arch/arm64/kvm/hyp.S  | 19 -
 8 files changed, 110 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm64/kvm/debug.c

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index d71607c..746c0c69 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -236,4 +236,8 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+static inline void kvm_arm_init_debug(void) {}
+static inline void kvm_arm_setup_debug(struct kvm_vcpu *vcpu) {}
+static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
+
 #endif /* __ARM_KVM_HOST_H__ */
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 52a1d4d38..4a274e1 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -570,6 +570,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
continue;
}
 
+   kvm_arm_setup_debug(vcpu);
+
/**
 * Enter the guest
 */
@@ -582,7 +584,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct 
kvm_run *run)
vcpu->mode = OUTSIDE_GUEST_MODE;
kvm_guest_exit();
trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
-   /*
+
+   kvm_arm_clear_debug(vcpu);
+
+/*
 * We may have taken a host interrupt in HYP mode (ie
 * while executing the guest). This interrupt is still
 * pending, as we haven't serviced it yet!
@@ -930,6 +935,8 @@ static void cpu_init_hyp_mode(void *dummy)
vector_ptr = (unsigned long)__kvm_hyp_vector;
 
__cpu_init_hyp_mode(boot_pgd_ptr, pgd_ptr, hyp_stack_ptr, vector_ptr);
+
+   kvm_arm_init_debug();
 }
 
 static int hyp_init_cpu_notify(struct notifier_block *self,
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 4f7310f..d6b507e 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -137,6 +137,8 @@ extern char __restore_vgic_v2_state[];
 extern char __save_vgic_v3_state[];
 extern char __restore_vgic_v3_state[];
 
+extern u32 __kvm_get_mdcr_el2(void);
+
 #endif
 
 #endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index f0f58c9..7cb99b5 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -103,6 +103,7 @@ struct kvm_vcpu_arch {
 
/* HYP configuration */
u64 hcr_el2;
+   u32 mdcr_el2;
 
/* Exception Information */
struct kvm_vcpu_fault_info fault;
@@ -250,4 +251,8 @@ static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {}
 
+void kvm_arm_init_debug(void);
+void kvm_arm_setup_debug(struct kvm_vcpu *vcpu);
+void kvm_arm_clear_debug(struct kvm_vcpu *vcpu);
+
 #endif /* __ARM64_KVM_HOST_H__ */
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index da675cc..dfb25a2 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -117,6 +117,7 @@ int main(void)
   DEFINE(VCPU_HPFAR_EL2,   offsetof(struct kvm_vcpu, 
a

[PATCH v6 04/12] KVM: arm: guest debug, add stub KVM_SET_GUEST_DEBUG ioctl

2015-06-19 Thread Alex Bennée
This commit adds a stub function to support the KVM_SET_GUEST_DEBUG
ioctl. Any unsupported flag will return -EINVAL. For now, only
KVM_GUESTDBG_ENABLE is supported, although it won't have any effects.

Signed-off-by: Alex Bennée .
Reviewed-by: Christoffer Dall 

---
v2
  - simplified form of the ioctl (stuff will go into setup_debug)
v3
 - KVM_GUESTDBG_VALID->KVM_GUESTDBG_VALID_MASK
 - move mask check to the top of function
 - add ioctl doc header
 - split capability into separate patch
 - tweaked commit wording w.r.t return of -EINVAL
v4
 - add r-b-tag
---
 Documentation/virtual/kvm/api.txt |  2 +-
 arch/arm/kvm/arm.c| 23 ++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index c34c32d..ba635c7 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2645,7 +2645,7 @@ handled.
 4.87 KVM_SET_GUEST_DEBUG
 
 Capability: KVM_CAP_SET_GUEST_DEBUG
-Architectures: x86, s390, ppc
+Architectures: x86, s390, ppc, arm64
 Type: vcpu ioctl
 Parameters: struct kvm_guest_debug (in)
 Returns: 0 on success; -1 on error
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index d9631ec..52a1d4d38 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -302,10 +302,31 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_arm_set_running_vcpu(NULL);
 }
 
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE)
+
+/**
+ * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
+ * @kvm:   pointer to the KVM struct
+ * @kvm_guest_debug: the ioctl data buffer
+ *
+ * This sets up and enables the VM for guest debugging. Userspace
+ * passes in a control flag to enable different debug types and
+ * potentially other architecture specific information in the rest of
+ * the structure.
+ */
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
struct kvm_guest_debug *dbg)
 {
-   return -EINVAL;
+   if (dbg->control & ~KVM_GUESTDBG_VALID_MASK)
+   return -EINVAL;
+
+   if (dbg->control & KVM_GUESTDBG_ENABLE) {
+   vcpu->guest_debug = dbg->control;
+   } else {
+   /* If not enabled clear all flags */
+   vcpu->guest_debug = 0;
+   }
+   return 0;
 }
 
 
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v6 09/12] KVM: arm64: introduce vcpu->arch.debug_ptr

2015-06-19 Thread Alex Bennée
This introduces a level of indirection for the debug registers. Instead
of using the sys_regs[] directly we store registers in a structure in
the vcpu. As we are no longer tied to the layout of the sys_regs[] we
can make the copies size appropriate for control and value registers.

This also entails updating the sys_regs code to access this new
structure. Instead of passing a register index we now pass an offset
into the kvm_guest_debug_arch structure.

We also need to ensure the GET/SET_ONE_REG ioctl operations store the
registers in their correct location.

Signed-off-by: Alex Bennée 

---
v6:
  - fix up some ws issues
  - correct clobber info
  - re-word commentary in kvm_host.h
  - fix endian access issues for aarch32 fields
  - revert all KVM_GET/SET_ONE_REG to 64bit (also see ABI update)
---
 arch/arm/kvm/arm.c|   3 +
 arch/arm64/include/asm/kvm_asm.h  |  24 +++
 arch/arm64/include/asm/kvm_host.h |  16 -
 arch/arm64/kernel/asm-offsets.c   |   6 ++
 arch/arm64/kvm/hyp.S  |  24 ---
 arch/arm64/kvm/sys_regs.c | 148 +-
 6 files changed, 161 insertions(+), 60 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 9b3ed6d..0d17c7b 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -279,6 +279,9 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
/* Set up the timer */
kvm_timer_vcpu_init(vcpu);
 
+   /* Set the debug registers to be the guests */
+   vcpu->arch.debug_ptr = &vcpu->arch.vcpu_debug_state;
+
return 0;
 }
 
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index d6b507e..e997404 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -46,24 +46,16 @@
 #defineCNTKCTL_EL1 20  /* Timer Control Register (EL1) */
 #definePAR_EL1 21  /* Physical Address Register */
 #define MDSCR_EL1  22  /* Monitor Debug System Control Register */
-#define DBGBCR0_EL123  /* Debug Breakpoint Control Registers (0-15) */
-#define DBGBCR15_EL1   38
-#define DBGBVR0_EL139  /* Debug Breakpoint Value Registers (0-15) */
-#define DBGBVR15_EL1   54
-#define DBGWCR0_EL155  /* Debug Watchpoint Control Registers (0-15) */
-#define DBGWCR15_EL1   70
-#define DBGWVR0_EL171  /* Debug Watchpoint Value Registers (0-15) */
-#define DBGWVR15_EL1   86
-#define MDCCINT_EL187  /* Monitor Debug Comms Channel Interrupt Enable 
Reg */
+#define MDCCINT_EL123  /* Monitor Debug Comms Channel Interrupt Enable 
Reg */
 
 /* 32bit specific registers. Keep them at the end of the range */
-#defineDACR32_EL2  88  /* Domain Access Control Register */
-#defineIFSR32_EL2  89  /* Instruction Fault Status Register */
-#defineFPEXC32_EL2 90  /* Floating-Point Exception Control 
Register */
-#defineDBGVCR32_EL291  /* Debug Vector Catch Register */
-#defineTEECR32_EL1 92  /* ThumbEE Configuration Register */
-#defineTEEHBR32_EL193  /* ThumbEE Handler Base Register */
-#defineNR_SYS_REGS 94
+#defineDACR32_EL2  24  /* Domain Access Control Register */
+#defineIFSR32_EL2  25  /* Instruction Fault Status Register */
+#defineFPEXC32_EL2 26  /* Floating-Point Exception Control 
Register */
+#defineDBGVCR32_EL227  /* Debug Vector Catch Register */
+#defineTEECR32_EL1 28  /* ThumbEE Configuration Register */
+#defineTEEHBR32_EL129  /* ThumbEE Handler Base Register */
+#defineNR_SYS_REGS 30
 
 /* 32bit mapping */
 #define c0_MPIDR   (MPIDR_EL1 * 2) /* MultiProcessor ID Register */
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index e2db6a6..9697daf 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -108,11 +108,25 @@ struct kvm_vcpu_arch {
/* Exception Information */
struct kvm_vcpu_fault_info fault;
 
-   /* Debug state */
+   /* Guest debug state */
u64 debug_flags;
 
+   /*
+* We maintain more than a single set of debug registers to support
+* debugging the guest from the host and to maintain separate host and
+* guest state during world switches. vcpu_debug_state are the debug
+* registers of the vcpu as the guest sees them.  host_debug_state are
+* the host registers which are saved and restored during world 
switches.
+*
+* debug_ptr points to the set of debug registers that should be loaded
+* onto the hardware when running the guest.
+*/
+   struct kvm_guest_debug_arch *debug_ptr;
+   struct kvm_guest_debug_arch vcpu_debug_state;
+
/* Pointer to host CPU context */
kvm_cpu_context_t *host_cpu_context;
+   struct kvm_guest_

[PATCH v6 07/12] KVM: arm64: guest debug, add support for single-step

2015-06-19 Thread Alex Bennée
This adds support for single-stepping the guest. To do this we need to
manipulate the guests PSTATE.SS and MDSCR_EL1.SS bits to trigger
stepping. We take care to preserve MDSCR_EL1 and trap access to it to
ensure we don't affect the apparent state of the guest.

As we have to enable trapping of all software debug exceptions we
suppress the ability of the guest to single-step itself. If we didn't we
would have to deal with the exception arriving while the guest was in
kernelspace when the guest is expecting to single-step userspace. This
is something we don't want to unwind in the kernel. Once the host is no
longer debugging the guest its ability to single-step userspace is
restored.

Signed-off-by: Alex Bennée 
Reviewed-by: Christoffer Dall 

---
v2
  - Move pstate/mdscr manipulation into C
  - don't export guest_debug to assembly
  - add accessor for saved_debug regs
  - tweak save/restore of mdscr_el1
v3
  - don't save PC in debug information struct
  - rename debug_saved_regs->guest_debug_state
  - save whole value, only use bits in restore
  - add save/restore_guest-debug_regs helper functions
  - simplify commit message for clarity
  - rm vcpu_debug_saved_reg access fn
v4
  - added more comments based on suggestions
  - guest_debug_state->guest_debug_preserved
  - no point masking restore, we will trap out
v5
  - more comments
  - don't bother preserving pstate.ss (guest never sees change)
v6
  - reword comments on guest SS suppression
  - simplify comment for save regs, SS explained in detail later on
  - add r-b-t (code)
  - expanded commit description
---
 arch/arm/kvm/arm.c|  4 ++-
 arch/arm64/include/asm/kvm_host.h | 11 +++
 arch/arm64/kvm/debug.c| 68 ---
 arch/arm64/kvm/handle_exit.c  |  2 ++
 4 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 064c105..9b3ed6d 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -302,7 +302,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
kvm_arm_set_running_vcpu(NULL);
 }
 
-#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP)
+#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |\
+   KVM_GUESTDBG_USE_SW_BP | \
+   KVM_GUESTDBG_SINGLESTEP)
 
 /**
  * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
diff --git a/arch/arm64/include/asm/kvm_host.h 
b/arch/arm64/include/asm/kvm_host.h
index 7cb99b5..e2db6a6 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -123,6 +123,17 @@ struct kvm_vcpu_arch {
 * here.
 */
 
+   /*
+* Guest registers we preserve during guest debugging.
+*
+* These shadow registers are updated by the kvm_handle_sys_reg
+* trap handler if the guest accesses or updates them while we
+* are using guest debug.
+*/
+   struct {
+   u32 mdscr_el1;
+   } guest_debug_preserved;
+
/* Don't run the guest */
bool pause;
 
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index 8d1bfa4..d439eb8 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -19,11 +19,39 @@
 
 #include 
 
+#include 
+#include 
 #include 
+#include 
+
+/* These are the bits of MDSCR_EL1 we may manipulate */
+#define MDSCR_EL1_DEBUG_MASK   (DBG_MDSCR_SS | \
+   DBG_MDSCR_KDE | \
+   DBG_MDSCR_MDE)
 
 static DEFINE_PER_CPU(u32, mdcr_el2);
 
 /**
+ * save/restore_guest_debug_regs
+ *
+ * For some debug operations we need to tweak some guest registers. As
+ * a result we need to save the state of those registers before we
+ * make those modifications.
+ *
+ * Guest access to MDSCR_EL1 is trapped by the hypervisor and handled
+ * after we have restored the preserved value to the main context.
+ */
+static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
+{
+   vcpu->arch.guest_debug_preserved.mdscr_el1 = vcpu_sys_reg(vcpu, 
MDSCR_EL1);
+}
+
+static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
+{
+   vcpu_sys_reg(vcpu, MDSCR_EL1) = 
vcpu->arch.guest_debug_preserved.mdscr_el1;
+}
+
+/**
  * kvm_arm_init_debug - grab what we need for debug
  *
  * Currently the sole task of this function is to retrieve the initial
@@ -38,7 +66,6 @@ void kvm_arm_init_debug(void)
__this_cpu_write(mdcr_el2, kvm_call_hyp(__kvm_get_mdcr_el2));
 }
 
-
 /**
  * kvm_arm_setup_debug - set up debug related stuff
  *
@@ -73,12 +100,45 @@ void kvm_arm_setup_debug(struct kvm_vcpu *vcpu)
if (trap_debug)
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
 
-   /* Trap breakpoints? */
-   if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
+   /* Is Guest debugging in effect? */
+   if (vcpu->guest_debug) {
+   /* Route all software de

[PATCH v6 02/12] KVM: arm64: fix misleading comments in save/restore

2015-06-19 Thread Alex Bennée
The elr_el2 and spsr_el2 registers in fact contain the processor state
before entry into the hypervisor code. In the case of guest state it
could be in either el0 or el1.

Signed-off-by: Alex Bennée 
---
 arch/arm64/kvm/hyp.S | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 5befd01..cb9bdd8 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -50,8 +50,8 @@
stp x29, lr, [x3, #80]
 
mrs x19, sp_el0
-   mrs x20, elr_el2// EL1 PC
-   mrs x21, spsr_el2   // EL1 pstate
+   mrs x20, elr_el2// PC before hyp entry
+   mrs x21, spsr_el2   // pstate before hyp entry
 
stp x19, x20, [x3, #96]
str x21, [x3, #112]
@@ -82,8 +82,8 @@
ldr x21, [x3, #16]
 
msr sp_el0, x19
-   msr elr_el2, x20// EL1 PC
-   msr spsr_el2, x21   // EL1 pstate
+   msr elr_el2, x20// PC to restore
+   msr spsr_el2, x21   // pstate to restore
 
add x3, x2, #CPU_XREG_OFFSET(19)
ldp x19, x20, [x3]
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 001/003] Attempt to cope with device changes and delayed kobject deallocation

2015-06-09 Thread Alex Bennée

Richard Watts  writes:

> Expose kobject_get_unless_zero() which will shortly be
>   needed by get_device_parent().
>
> Signed-off-by: Richard Watts 
> ---
>   include/linux/kobject.h | 1 +
>   lib/kobject.c   | 2 +-
>   2 files changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/kobject.h b/include/linux/kobject.h
> index 2d61b90..662b136 100644
> --- a/include/linux/kobject.h
> +++ b/include/linux/kobject.h
> @@ -107,6 +107,7 @@ extern int __must_check kobject_rename(struct 
> kobject *, const char *new_name);
>   extern int __must_check kobject_move(struct kobject *, struct kobject *);
>
>   extern struct kobject *kobject_get(struct kobject *kobj);
> +extern struct kobject * __must_check kobject_get_unless_zero(struct 
> kobject *kobj);
>   extern void kobject_put(struct kobject *kobj);
>
>   extern const void *kobject_namespace(struct kobject *kobj);
> diff --git a/lib/kobject.c b/lib/kobject.c
> index 3b841b9..3ba1db4 100644
> --- a/lib/kobject.c
> +++ b/lib/kobject.c
> @@ -586,7 +586,7 @@ struct kobject *kobject_get(struct kobject *kobj)
>   return kobj;
>   }
>
> -static struct kobject * __must_check kobject_get_unless_zero(struct 
> kobject *kobj)
> +struct kobject * __must_check kobject_get_unless_zero(struct kobject *kobj)
>   {
>   if (!kref_get_unless_zero(&kobj->kref))
>   kobj = NULL;

Hi Richard,

checkpatch is complaining about some trailing whitespace in this patch.

> -- 
> 1.9.1

-- 
Alex Bennée
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 03/12] KVM: arm64: guest debug, define API headers

2015-06-04 Thread Alex Bennée

Christoffer Dall  writes:

> On Fri, May 29, 2015 at 10:30:19AM +0100, Alex Bennée wrote:
>> This commit defines the API headers for guest debugging. There are two
>> architecture specific debug structures:
>> 
>>   - kvm_guest_debug_arch, allows us to pass in HW debug registers
>>   - kvm_debug_exit_arch, signals exception and possible faulting address
>> 
>> The type of debugging being used is controlled by the architecture
>> specific control bits of the kvm_guest_debug->control flags in the ioctl
>> structure.
>> 
>> Signed-off-by: Alex Bennée 
>> Reviewed-by: David Hildenbrand 
>> Reviewed-by: Andrew Jones 
>> Acked-by: Christoffer Dall 
>
> I can re-confirm my ack despite the changes in v4, but this really is
> borderline to keep exiting r-b and a-b tags around from previous patches
> I would think, but ok.

I was wondering how much a patch has to change for the r-b tags to
become invalid. The meat of the API hasn't changed much though.

Drew/David,

Are you still happy with this patch?

>
> -Christoffer
>
>> 
>> ---
>> v2
>>- expose hsr and pc directly to user-space
>> v3
>>- s/control/controlled/ in commit message
>>- add v8 to ARM ARM comment (ARM Architecture Reference Manual)
>>- add rb tag
>>- rm pc, add far
>>- re-word comments on alignment
>>- rename KVM_ARM_NDBG_REGS -> KVM_ARM_MAX_DBG_REGS
>> v4
>>- now uses common HW/SW BP define
>>- add a-b-tag
>>- use u32 for control regs
>> v5
>>- revert to have arch specific KVM_GUESTDBG_USE_SW/HW_BP
>>- rm stale comments dbgctrl was stored as u64
>> ---
>>  arch/arm64/include/uapi/asm/kvm.h | 20 
>>  1 file changed, 20 insertions(+)
>> 
>> diff --git a/arch/arm64/include/uapi/asm/kvm.h 
>> b/arch/arm64/include/uapi/asm/kvm.h
>> index d268320..43758e7 100644
>> --- a/arch/arm64/include/uapi/asm/kvm.h
>> +++ b/arch/arm64/include/uapi/asm/kvm.h
>> @@ -100,12 +100,32 @@ struct kvm_sregs {
>>  struct kvm_fpu {
>>  };
>>  
>> +/*
>> + * See v8 ARM ARM D7.3: Debug Registers
>> + *
>> + * The architectural limit is 16 debug registers of each type although
>> + * in practice there are usually less (see ID_AA64DFR0_EL1).
>> + */
>> +#define KVM_ARM_MAX_DBG_REGS 16
>>  struct kvm_guest_debug_arch {
>> +__u32 dbg_bcr[KVM_ARM_MAX_DBG_REGS];
>> +__u64 dbg_bvr[KVM_ARM_MAX_DBG_REGS];
>> +__u32 dbg_wcr[KVM_ARM_MAX_DBG_REGS];
>> +__u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS];
>>  };
>>  
>>  struct kvm_debug_exit_arch {
>> +__u32 hsr;
>> +__u64 far;
>>  };
>>  
>> +/*
>> + * Architecture specific defines for kvm_guest_debug->control
>> + */
>> +
>> +#define KVM_GUESTDBG_USE_SW_BP  (1 << 16)
>> +#define KVM_GUESTDBG_USE_HW_BP  (1 << 17)
>> +
>>  struct kvm_sync_regs {
>>  };
>>  
>> -- 
>> 2.4.1
>> 

-- 
Alex Bennée
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 07/12] KVM: arm64: guest debug, add support for single-step

2015-06-04 Thread Alex Bennée

Christoffer Dall  writes:

> On Fri, May 29, 2015 at 10:30:23AM +0100, Alex Bennée wrote:
>> This adds support for single-stepping the guest. To do this we need to
>> manipulate the guests PSTATE.SS and MDSCR_EL1.SS bits which we do in the
>> kvm_arm_setup/clear_debug() so we don't affect the apparent state of the
>> guest. Additionally while the host is debugging the guest we suppress
>> the ability of the guest to single-step itself.
>
> I feel like there should be a slightly more elaborate explanation of
> exactly what works and what doesn't work when the guest is single
> stepping something and which choices we've made for supporting or not
> supporting this.

OK, I shall put bit more explanation. I was trying to avoid too much
exposition in the commit comments vs the code.

>
>> 
>> Signed-off-by: Alex Bennée 
>> 
>> ---
>> v2
>>   - Move pstate/mdscr manipulation into C
>>   - don't export guest_debug to assembly
>>   - add accessor for saved_debug regs
>>   - tweak save/restore of mdscr_el1
>> v3
>>   - don't save PC in debug information struct
>>   - rename debug_saved_regs->guest_debug_state
>>   - save whole value, only use bits in restore
>>   - add save/restore_guest-debug_regs helper functions
>>   - simplify commit message for clarity
>>   - rm vcpu_debug_saved_reg access fn
>> v4
>>   - added more comments based on suggestions
>>   - guest_debug_state->guest_debug_preserved
>>   - no point masking restore, we will trap out
>> v5
>>   - more comments
>>   - don't bother preserving pstate.ss
>
> it would have been good if there was some comment explaining the reason
> for this change.
>
>> ---
>>  arch/arm/kvm/arm.c|  4 ++-
>>  arch/arm64/include/asm/kvm_host.h | 11 
>>  arch/arm64/kvm/debug.c| 58 
>> ---
>>  arch/arm64/kvm/handle_exit.c  |  2 ++
>>  4 files changed, 70 insertions(+), 5 deletions(-)
>> 
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 064c105..9b3ed6d 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -302,7 +302,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>>  kvm_arm_set_running_vcpu(NULL);
>>  }
>>  
>> -#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | 
>> KVM_GUESTDBG_USE_SW_BP)
>> +#define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE |\
>> +KVM_GUESTDBG_USE_SW_BP | \
>> +KVM_GUESTDBG_SINGLESTEP)
>>  
>>  /**
>>   * kvm_arch_vcpu_ioctl_set_guest_debug - set up guest debugging
>> diff --git a/arch/arm64/include/asm/kvm_host.h 
>> b/arch/arm64/include/asm/kvm_host.h
>> index 7cb99b5..e2db6a6 100644
>> --- a/arch/arm64/include/asm/kvm_host.h
>> +++ b/arch/arm64/include/asm/kvm_host.h
>> @@ -123,6 +123,17 @@ struct kvm_vcpu_arch {
>>   * here.
>>   */
>>  
>> +/*
>> + * Guest registers we preserve during guest debugging.
>> + *
>> + * These shadow registers are updated by the kvm_handle_sys_reg
>> + * trap handler if the guest accesses or updates them while we
>> + * are using guest debug.
>> + */
>> +struct {
>> +u32 mdscr_el1;
>> +} guest_debug_preserved;
>> +
>>  /* Don't run the guest */
>>  bool pause;
>>  
>> diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
>> index 8d1bfa4..10a6baa 100644
>> --- a/arch/arm64/kvm/debug.c
>> +++ b/arch/arm64/kvm/debug.c
>> @@ -19,11 +19,41 @@
>>  
>>  #include 
>>  
>> +#include 
>> +#include 
>>  #include 
>> +#include 
>> +
>> +/* These are the bits of MDSCR_EL1 we may manipulate */
>> +#define MDSCR_EL1_DEBUG_MASK(DBG_MDSCR_SS | \
>> +DBG_MDSCR_KDE | \
>> +DBG_MDSCR_MDE)
>>  
>>  static DEFINE_PER_CPU(u32, mdcr_el2);
>>  
>>  /**
>> + * save/restore_guest_debug_regs
>> + *
>> + * For some debug operations we need to tweak some guest registers. As
>> + * a result we need to save the state of those registers before we
>> + * make those modifications. This does get confused if the guest
>> + * attempts to control single step while being debugged. It will start
>> + * working again once it is no longer being debugged by the host.
>
> What gets confused and what starts working?

Maybe I should cut from "This does get..." and pu

[PATCH v2] KVM: arm64: fix misleading comments in save/restore

2015-06-04 Thread Alex Bennée
The elr_el2 and spsr_el2 registers in fact contain the processor state
before entry into EL2. In the case of guest state it could be in either
el0 or el1.

Signed-off-by: Alex Bennée 

---
v2
  - s/hypervisor code/EL2/
  - comment: pc/pstate before entering/on return from el2
---
 arch/arm64/kvm/hyp.S | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 5befd01..519805f 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -50,8 +50,8 @@
stp x29, lr, [x3, #80]
 
mrs x19, sp_el0
-   mrs x20, elr_el2// EL1 PC
-   mrs x21, spsr_el2   // EL1 pstate
+   mrs x20, elr_el2// pc before entering el2
+   mrs x21, spsr_el2   // pstate before entering el2
 
stp x19, x20, [x3, #96]
str x21, [x3, #112]
@@ -82,8 +82,8 @@
ldr x21, [x3, #16]
 
msr sp_el0, x19
-   msr elr_el2, x20// EL1 PC
-   msr spsr_el2, x21   // EL1 pstate
+   msr elr_el2, x20// pc on return from el2
+   msr spsr_el2, x21   // pstate on return from el2
 
add x3, x2, #CPU_XREG_OFFSET(19)
ldp x19, x20, [x3]
-- 
2.4.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] KVM: arm64: fix misleading comments in save/restore

2015-06-04 Thread Alex Bennée

Marc Zyngier  writes:

> On 04/06/15 11:20, Alex Bennée wrote:
>> 
>> Marc Zyngier  writes:
>> 
>>> On 04/06/15 10:34, Christoffer Dall wrote:
>>>> On Thu, May 28, 2015 at 10:43:06AM +0100, Alex Bennée wrote:
>>>>> The elr_el2 and spsr_el2 registers in fact contain the processor state
>>>>> before entry into the hypervisor code.
>>>>
>>>> be careful with your use of the hypervisor, in the KVM design the
>>>> hypervisor is split across EL1 and EL2.
>> 
>> "before entry into EL2."
>> 
>>>>
>>>>> In the case of guest state it
>>>>> could be in either el0 or el1.
>>>>
>>>> true
>>>>
>>>>>
>>>>> Signed-off-by: Alex Bennée 
>>>>> ---
>>>>>  arch/arm64/kvm/hyp.S | 8 
>>>>>  1 file changed, 4 insertions(+), 4 deletions(-)
>>>>>
>>>>> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
>>>>> index d755922..1940a4c 100644
>>>>> --- a/arch/arm64/kvm/hyp.S
>>>>> +++ b/arch/arm64/kvm/hyp.S
>>>>> @@ -50,8 +50,8 @@
>>>>>   stp x29, lr, [x3, #80]
>>>>>  
>>>>>   mrs x19, sp_el0
>>>>> - mrs x20, elr_el2// EL1 PC
>>>>> - mrs x21, spsr_el2   // EL1 pstate
>>>>> + mrs x20, elr_el2// PC before hyp entry
>>>>> + mrs x21, spsr_el2   // pstate before hyp entry
>>>>>  
>>>>>   stp x19, x20, [x3, #96]
>>>>>   str x21, [x3, #112]
>>>>> @@ -82,8 +82,8 @@
>>>>>   ldr x21, [x3, #16]
>>>>>  
>>>>>   msr sp_el0, x19
>>>>> - msr elr_el2, x20// EL1 PC
>>>>> - msr spsr_el2, x21   // EL1 pstate
>>>>> + msr elr_el2, x20// PC to restore
>>>>> + msr spsr_el2, x21   // pstate to restore
>>>>
>>>> I don't feel like 'to restore' is much more meaningful here.
>>>>
>>>> I would actually vote for removin the comments all together, since one
>>>> should really understand the code as opposed to the comments when
>>>> reading this kind of stuff.
>>>>
>>>> Meh, I'm not sure.  Your patch is definitely better than doing nothing.
>>>>
>>>> Marc?
>>>
>>> While I definitely agree that people should pay more attention to the
>>> code rather than blindly trusting comments, I still think there is some
>>> value in disambiguating the exception entry/return, because this bit of
>>> code assumes some intimate knowledge of the ARMv8 exception model.
>>>
>>> As for the comments themselves, I'd rather have some wording that
>>> clearly indicate that we're dealing with guest information, i.e:
>>>
>>> mrs     x20, elr_el2// Guest PC
>>> mrs x21, spsr_el2   // Guest pstate
>>>
>>> (and the same for the exception return). The "before hyp entry" and "to
>>> restore" are not really useful (all the registers we are
>>> saving/restoring fall into these categories). What I wanted to convey
>>> here was that despite using an EL2 register, we are dealing with guest
>>> registers.
>> 
>> Which would be great it we were. However the code is used to
>> save/restore the host context as well as the guest context hence my
>> weasely words. 
>
> Gahhh. You're right. I'm spending too much time on the VHE code these
> days. Guess I'll stick to the weasel words then. Can you respin it with
> Christoffer's comment addressed?

Sure. Do you want it separated from the guest debug series or will you
be happy to take it with it when ready?

>
> Thanks,
>
>   M.

-- 
Alex Bennée
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 08/12] KVM: arm64: re-factor hyp.S debug register code

2015-06-04 Thread Alex Bennée

Christoffer Dall  writes:

> On Fri, May 29, 2015 at 10:30:24AM +0100, Alex Bennée wrote:
>> This is a pre-cursor to sharing the code with the guest debug support.
>> This replaces the big macro that fishes data out of a fixed location
>> with a more general helper macro to restore a set of debug registers. It
>> uses macro substitution so it can be re-used for debug control and value
>> registers. It does however rely on the debug registers being 64 bit
>> aligned (as they happen to be in the hyp ABI).

Oops I'd better fix that commit comment.

>> 
>> Signed-off-by: Alex Bennée 
>> 
>> ---
>> v3:
>>   - return to the patch series
>>   - add save and restore targets
>>   - change register use and document
>> v4:
>>   - keep original setup/restore names
>>   - don't use split u32/u64 structure yet
>> ---
>>  arch/arm64/kvm/hyp.S | 519 
>> ++-
>>  1 file changed, 140 insertions(+), 379 deletions(-)
>> 
>> diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
>> index 74e63d8..9c4897d 100644
>> --- a/arch/arm64/kvm/hyp.S
>> +++ b/arch/arm64/kvm/hyp.S
>
>
> [...]
>
>> @@ -465,195 +318,52 @@
>>  msr mdscr_el1,  x25
>>  .endm
>>  
>> -.macro restore_debug
>> -// x2: base address for cpu context
>> -// x3: tmp register
>> -
>> -mrs x26, id_aa64dfr0_el1
>> -ubfxx24, x26, #12, #4   // Extract BRPs
>> -ubfxx25, x26, #20, #4   // Extract WRPs
>> -mov w26, #15
>> -sub w24, w26, w24   // How many BPs to skip
>> -sub w25, w26, w25   // How many WPs to skip
>> -
>> -add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
>> +.macro restore_debug type
>> +// x4: pointer to register set
>> +// x5: number of registers to skip
>
> nit: use tabs instead of spaces here...
>
>> +// x6..x22 trashed
>>  
>
> [...]
>
>> @@ -887,12 +597,63 @@ __restore_sysregs:
>>  restore_sysregs
>>  ret
>>  
>> +/* Save debug state */
>>  __save_debug:
>> -save_debug
>> +// x0: base address for vcpu context
>> +// x2: ptr to current CPU context
>> +// x4/x5: trashed
>
> I had a bunch of questions here which I think you missed last time
> around:
>  1. why do we need the vcpu context?

We don't, I'll drop that

>  2. what does 'current' mean here?

Either the host or vcpu context depending which way we are currently going.

>  3. you're also trashing everything that save_debug trashes, so x4/5,
> x6-x22 trashed would be more correct

OK

>
>> +
>> +mrs x26, id_aa64dfr0_el1
>> +ubfxx24, x26, #12, #4   // Extract BRPs
>> +ubfxx25, x26, #20, #4   // Extract WRPs
>> +mov w26, #15
>> +sub w24, w26, w24   // How many BPs to skip
>> +sub w25, w26, w25   // How many WPs to skip
>> +
>> +mov x5, x24
>> +add x4, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
>> +save_debug dbgbcr
>> +add x4, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
>> +save_debug dbgbvr
>> +
>> +mov x5, x25
>> +add x4, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
>> +save_debug dbgwcr
>> +add x4, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1)
>> +save_debug dbgwvr
>> +
>> +mrs x21, mdccint_el1
>> +str x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)]
>>  ret
>>  
>> +/* Restore debug state */
>>  __restore_debug:
>> -restore_debug
>> +// x0: base address for cpu context
>> +// x2: ptr to current CPU context
>> +// x4/x5: trashed
>
> and you missed these comments too, basically same stuff, but why was it
> 'cpu' here and not 'vcpu' like above?

Again we use the functions both for restoring host and vcpu debug context.

>
> note again, that you're explicitly touching x24, xx25, and x26 here as
> well, so shouldn't they be listed as trashed?
>
>> +
>> +mrs x26, id_aa64dfr0_el1
>> +ubfxx24, x26, #12, #4   // Extract BRPs
>> +ubfxx25, x26, #20, #4   // Extract WRPs
>> +mov w26, #15
>> +    sub w24, w26, w24   // How many BPs to skip
>> +sub w25, w26, w25   // How many WPs to skip
>> +
>> +mov x5, x24
>> +add x4, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
>> +restore_debug dbgbcr
>> +add x4, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
>> +restore_debug dbgbvr
>> +
>> +mov x5, x25
>> +add x4, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
>> +restore_debug dbgwcr
>> +add x4, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1)
>> +restore_debug dbgwvr
>> +
>> +ldr x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)]
>> +msr mdccint_el1, x21
>> +
>>  ret
>>  
>>  __save_fpsimd:
>
> Thanks,
> -Christoffer

-- 
Alex Bennée
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


  1   2   3   >