From: dave.martin@linaro.org (Dave Martin)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 14/15] KVM: ARM: Handle I/O aborts
Date: Mon, 1 Oct 2012 13:53:26 +0100 [thread overview]
Message-ID: <20121001125326.GA2100@linaro.org> (raw)
In-Reply-To: <CANM98qKFKU98EWNaOepjxab3h5vQypxdt_YoJbKV9kd31XUfaw@mail.gmail.com>
On Sun, Sep 30, 2012 at 05:49:21PM -0400, Christoffer Dall wrote:
> On Thu, Sep 27, 2012 at 11:11 AM, Will Deacon <will.deacon@arm.com> wrote:
> > On Sat, Sep 15, 2012 at 04:35:59PM +0100, Christoffer Dall wrote:
> >> When the guest accesses I/O memory this will create data abort
> >> exceptions and they are handled by decoding the HSR information
> >> (physical address, read/write, length, register) and forwarding reads
> >> and writes to QEMU which performs the device emulation.
> >>
> >> Certain classes of load/store operations do not support the syndrome
> >> information provided in the HSR and we therefore must be able to fetch
> >> the offending instruction from guest memory and decode it manually.
> >>
> >> We only support instruction decoding for valid reasonable MMIO operations
> >> where trapping them do not provide sufficient information in the HSR (no
> >> 16-bit Thumb instructions provide register writeback that we care about).
> >>
> >> The following instruciton types are NOT supported for MMIO operations
> >> despite the HSR not containing decode info:
> >> - any Load/Store multiple
> >> - any load/store exclusive
> >> - any load/store dual
> >> - anything with the PC as the dest register
> >
> > [...]
> >
> >> +
> >> +/******************************************************************************
> >> + * Load-Store instruction emulation
> >> + *****************************************************************************/
> >> +
> >> +/*
> >> + * Must be ordered with LOADS first and WRITES afterwards
> >> + * for easy distinction when doing MMIO.
> >> + */
> >> +#define NUM_LD_INSTR 9
> >> +enum INSTR_LS_INDEXES {
> >> + INSTR_LS_LDRBT, INSTR_LS_LDRT, INSTR_LS_LDR, INSTR_LS_LDRB,
> >> + INSTR_LS_LDRD, INSTR_LS_LDREX, INSTR_LS_LDRH, INSTR_LS_LDRSB,
> >> + INSTR_LS_LDRSH,
> >> + INSTR_LS_STRBT, INSTR_LS_STRT, INSTR_LS_STR, INSTR_LS_STRB,
> >> + INSTR_LS_STRD, INSTR_LS_STREX, INSTR_LS_STRH,
> >> + NUM_LS_INSTR
> >> +};
> >> +
> >> +static u32 ls_instr[NUM_LS_INSTR][2] = {
> >> + {0x04700000, 0x0d700000}, /* LDRBT */
> >> + {0x04300000, 0x0d700000}, /* LDRT */
> >> + {0x04100000, 0x0c500000}, /* LDR */
> >> + {0x04500000, 0x0c500000}, /* LDRB */
> >> + {0x000000d0, 0x0e1000f0}, /* LDRD */
> >> + {0x01900090, 0x0ff000f0}, /* LDREX */
> >> + {0x001000b0, 0x0e1000f0}, /* LDRH */
> >> + {0x001000d0, 0x0e1000f0}, /* LDRSB */
> >> + {0x001000f0, 0x0e1000f0}, /* LDRSH */
> >> + {0x04600000, 0x0d700000}, /* STRBT */
> >> + {0x04200000, 0x0d700000}, /* STRT */
> >> + {0x04000000, 0x0c500000}, /* STR */
> >> + {0x04400000, 0x0c500000}, /* STRB */
> >> + {0x000000f0, 0x0e1000f0}, /* STRD */
> >> + {0x01800090, 0x0ff000f0}, /* STREX */
> >> + {0x000000b0, 0x0e1000f0} /* STRH */
> >> +};
> >> +
> >> +static inline int get_arm_ls_instr_index(u32 instr)
> >> +{
> >> + return kvm_instr_index(instr, ls_instr, NUM_LS_INSTR);
> >> +}
> >> +
> >> +/*
> >> + * Load-Store instruction decoding
> >> + */
> >> +#define INSTR_LS_TYPE_BIT 26
> >> +#define INSTR_LS_RD_MASK 0x0000f000
> >> +#define INSTR_LS_RD_SHIFT 12
> >> +#define INSTR_LS_RN_MASK 0x000f0000
> >> +#define INSTR_LS_RN_SHIFT 16
> >> +#define INSTR_LS_RM_MASK 0x0000000f
> >> +#define INSTR_LS_OFFSET12_MASK 0x00000fff
> >
> > I'm afraid you're not going to thank me much for this, but it's high time we
> > unified the various instruction decoding functions we have under arch/arm/
> > and this seems like a good opportunity for that. For example, look at the
> > following snippets (there is much more in the files I list) in addition to
> > what you have:
> >
>
> I think it would be great if we had a set of unified decoding functions!
>
> However, I think it's a shame if we can't merge KVM because we want to
> clean up this code. There would be nothing in the way of breaking API
> or anything like that preventing us from cleaning this up after the
> code has been merged.
>
> Please consider reviewing the code for correctness and consider if the
> code could be merged as is.
>
> On the other hand, if you or Dave or anyone else wants to create a set
> of patches that cleans this up in a timely manner, I will be happy to
> merge them for my code as well ;)
The time I would have available to put into this is rather limited, but
I have some initial ideas, as outlined below.
Tixy (who did the kprobes implementation, which is probably the most
sophisticated opcode handling we have in the kernel right now) may have
ideas too. I would hope that any common framework could reuse a fair
chunk of his implementation and test coverage.
I think that a common framework would have to start out a lot more
generic that the special-purpose code in current subsystems, at least
initially. We should try to move all the knowledge about how
instructions are encoded out of subsystems and into the common
framework, so far as possible.
We might end up with an interface like this:
Instruction data in memory <-> __arm_mem_to_opcode*() and friends <-> canonical form
canonical form -> __arm_opcode_decode() -> decoded form
decoded form -> __arm_opcode_encode() -> canonical form
The decoded form might look something like this:
struct arm_insn {
u32 opcode;
u32 flags; /* common flags */
enum arm_insn_type type;
u32 insn_flags; /* insn specific flags */
enum arm_reg Rd;
enum arm_reg Rn;
enum arm_reg Rm;
enum arm_reg Rs;
enum arm_reg Rt;
enum arm_reg Ra;
/* ... */
};
... and so on. This just a sketch, and deliberately very incomplete.
The basic principle here is that the client gets the architectural,
encoding-independent view of the instruction: as far as possible, client
code should never need to know anything about how the encoding works.
The client code should not even need to know for most purposes whether
the instruction is ARM or Thumb, once decoded.
Identifying instruction classes (i.e., is this a VFP/NEON instruction,
does this access memory, does this change the PC) etc. should all be
abstracted as helper functions / macros.
All cleverness involving tables and hashes to accelerate decode and
identify instruction classes should move into the framework, but
we can start out with something stupid and simple: if we only need
to distinguish a few instruction types to begin with, a simple switch
statement for decode may be enough to get started. However, as
things mature, a more sophisticated table-driven approach could be
A good starting point would be load/store emulation as this seems to be a
common theme, and we would need a credible deployment for any new
framework so that we know it's fit for purpose.
So just refactoring the code that appears in the KVM patches could be a
good way of getting such a framework off the ground.
Subsystems could be migrated to the new framework incrementally after
its initial creation, while extending the framework as needed. This
means that the initial that the initial framework could be pretty simple
-- we don't need all the functionality all at once.
[...]
Cheers
---Dave
next prev parent reply other threads:[~2012-10-01 12:53 UTC|newest]
Thread overview: 82+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-15 15:34 [PATCH 00/15] KVM/ARM Implementation Christoffer Dall
2012-09-15 15:34 ` [PATCH 01/15] ARM: add mem_type prot_pte accessor Christoffer Dall
2012-09-18 12:23 ` Will Deacon
2012-09-18 19:18 ` Christoffer Dall
2012-09-18 21:04 ` Russell King - ARM Linux
2012-09-18 21:53 ` Christoffer Dall
2012-09-20 10:01 ` Marc Zyngier
2012-09-20 13:21 ` Christoffer Dall
2012-09-15 15:34 ` [PATCH 02/15] ARM: Add page table and page defines needed by KVM Christoffer Dall
2012-09-18 12:47 ` Will Deacon
2012-09-18 14:06 ` Catalin Marinas
2012-09-18 15:05 ` Christoffer Dall
2012-09-18 15:07 ` Catalin Marinas
2012-09-18 15:10 ` Christoffer Dall
2012-09-18 22:01 ` Christoffer Dall
2012-09-19 9:21 ` Will Deacon
2012-09-20 0:10 ` Christoffer Dall
2012-09-15 15:34 ` [PATCH 03/15] ARM: Section based HYP idmap Christoffer Dall
2012-09-18 13:00 ` Will Deacon
2012-10-01 2:19 ` Christoffer Dall
2012-09-15 15:34 ` [PATCH 04/15] ARM: idmap: only initialize HYP idmap when HYP mode is available Christoffer Dall
2012-09-18 13:03 ` Will Deacon
2012-09-20 0:11 ` Christoffer Dall
2012-09-15 15:35 ` [PATCH 05/15] ARM: Expose PMNC bitfields for KVM use Christoffer Dall
2012-09-18 13:08 ` Will Deacon
2012-09-18 22:13 ` Christoffer Dall
2012-09-19 4:09 ` [kvmarm] " Rusty Russell
2012-09-19 9:30 ` Will Deacon
2012-09-15 15:35 ` [PATCH 06/15] KVM: ARM: Initial skeleton to compile KVM support Christoffer Dall
2012-09-25 15:20 ` Will Deacon
2012-09-26 1:43 ` Christoffer Dall
2012-09-27 14:13 ` Will Deacon
2012-09-27 14:39 ` Marc Zyngier
2012-09-27 14:45 ` [kvmarm] " Peter Maydell
2012-09-27 15:20 ` Will Deacon
2012-09-30 19:21 ` Christoffer Dall
2012-10-01 13:03 ` [kvmarm] " Marc Zyngier
2012-10-04 13:02 ` Min-gyu Kim
2012-10-04 13:35 ` Christoffer Dall
2012-10-05 6:28 ` Rusty Russell
2012-10-04 13:44 ` [kvmarm] " Avi Kivity
2012-09-15 15:35 ` [PATCH 07/15] KVM: ARM: Hypervisor inititalization Christoffer Dall
2012-09-15 15:35 ` [PATCH 08/15] KVM: ARM: Memory virtualization setup Christoffer Dall
2012-09-15 15:35 ` [PATCH 09/15] KVM: ARM: Inject IRQs and FIQs from userspace Christoffer Dall
2012-09-25 15:55 ` Will Deacon
2012-09-29 15:50 ` Christoffer Dall
2012-09-30 12:48 ` Will Deacon
2012-09-30 14:34 ` Christoffer Dall
2012-09-15 15:35 ` [PATCH 10/15] KVM: ARM: World-switch implementation Christoffer Dall
2012-09-25 17:00 ` Will Deacon
2012-09-25 17:15 ` [kvmarm] " Peter Maydell
2012-09-25 17:42 ` Marc Zyngier
2012-09-30 0:33 ` Christoffer Dall
2012-09-30 9:48 ` Peter Maydell
2012-09-30 14:31 ` Christoffer Dall
2012-09-30 17:47 ` Christoffer Dall
2012-09-15 15:35 ` [PATCH 11/15] KVM: ARM: Emulation framework and CP15 emulation Christoffer Dall
2012-09-15 15:35 ` [PATCH 12/15] KVM: ARM: User space API for getting/setting co-proc registers Christoffer Dall
2012-09-15 15:35 ` [PATCH 13/15] KVM: ARM: Handle guest faults in KVM Christoffer Dall
2012-09-25 11:11 ` Min-gyu Kim
2012-09-25 12:38 ` Christoffer Dall
2012-09-27 3:11 ` Min-gyu Kim
2012-09-27 5:35 ` Christoffer Dall
2012-09-27 15:26 ` [kvmarm] " Marc Zyngier
2012-09-27 12:39 ` Catalin Marinas
2012-09-27 17:15 ` Christoffer Dall
2012-09-27 17:21 ` Catalin Marinas
2012-09-15 15:35 ` [PATCH 14/15] KVM: ARM: Handle I/O aborts Christoffer Dall
2012-09-27 15:11 ` Will Deacon
2012-09-30 21:49 ` Christoffer Dall
2012-10-01 12:53 ` Dave Martin [this message]
2012-10-01 15:12 ` Jon Medhurst (Tixy)
2012-10-01 16:07 ` Dave Martin
2012-10-05 9:00 ` Russell King - ARM Linux
2012-10-08 10:04 ` Dave Martin
2012-10-08 21:52 ` Christoffer Dall
2012-09-15 15:36 ` [PATCH 15/15] KVM: ARM: Guest wait-for-interrupts (WFI) support Christoffer Dall
2012-09-25 17:04 ` Will Deacon
2012-09-29 23:00 ` Christoffer Dall
2012-09-18 12:21 ` [PATCH 00/15] KVM/ARM Implementation Will Deacon
2012-09-18 12:32 ` Christoffer Dall
2012-09-19 12:44 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20121001125326.GA2100@linaro.org \
--to=dave.martin@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).