[Android-virt] [PATCH 6/8] ARM: KVM: table-driven coprocessor emulation.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Mar 13, 2012 at 4:47 AM, Peter Maydell <peter.maydell at linaro.org> wrote:
> On 13 March 2012 00:18, Rusty Russell <rusty at rustcorp.com.au> wrote:
>> + ? ? ? MCR(p15, 1, ANY, 9, 0, 2, ignore_write, 0),
>> + ? ? ? MRC(p15, 1, ANY, 9, 0, 2, read_l2ctlr, 0),
>
> Hmm. I'm generally a bit suspicious of anything that doesn't
> explicitly say which are crn/crm/op1/op2, because the various
> docs and tables in TRMs and manuals have no particular
> consistency about ordering and it's fantastically easy to get
> confused. However the MRC()/MCR() are quite cute.
>
> Are you going to want to encode "this is how this cp15 register
> is reset" in your tables at some point? Or "r/o for user mode
> but r/w for kernel" or other complicated permissions? One
> downside of these macros is that you've lost the ability to
> use named fields in the struct initialisers and are back to
> a plain list, which is fine when there are only 2 things other
> than the crn/crm/op1/op2 but might get ugly if we need to add
> more later.
>
the version in the v7 patch series does seem to address both items
(take a look at the snippet below), but it's a define mess. Let me
know what you think there.

+#define DF (-1UL) /* Default: If nothing else fits, use this one */
+#define CRn(_x)                .CRn = _x
+#define CRm(_x)        .CRm = _x
+#define Op1(_x)        .Op1 = _x
+#define Op2(_x)        .Op2 = _x
+#define is64           .is_64 = true
+#define is32           .is_64 = false
+#define READ           .is_w  = false
+#define WRITE          .is_w  = true
+#define RW             .is_w  = DF
+
+static const struct coproc_emulate coproc_emulate[] = {
+       /*
+        * L2CTLR access:
+        *
+        * Ignore writes completely.
+        *
+        * FIXME: Hack Alert: Read zero as default case.
+        */
+       { CRn( 9), CRm( 0), Op1( 1), Op2( 2), is32,  WRITE, ignore_write},
+       { CRn( 9), CRm( 0), Op1( 1), Op2( 2), is32,  READ,  read_l2ctlr},
+       { CRn( 9), CRm(DF), Op1(DF), Op2(DF), is32,  WRITE, ignore_write},
+       { CRn( 9), CRm(DF), Op1(DF), Op2(DF), is32,  READ,  read_zero},
+
+       /*
+        * These CRn == 10 entries may not need to exist - if we can
+        * ignore guest attempts to tamper with TLB lockdowns then it
+        * should be enough to store/restore the host/guest PRRR and
+        * NMRR memory remap registers and allow guest direct access
+        * to these registers.
+        *
+        * TLB Lockdown operations - ignored
+        */
+       { CRn(10), CRm( 0), Op1(DF), Op2(DF), is32,  WRITE, ignore_write},
+       { CRn(10), CRm( 2), Op1( 0), Op2( 0), is32,  RW,    access_cp15_reg,
+                                                           c10_PRRR},
+       { CRn(10), CRm( 2), Op1( 0), Op2( 1), is32,  RW,    access_cp15_reg,
+                                                           c10_NMRR},
+
+       /*
+        * The CP15 c15 register is architecturally implementation
+        * defined, but some guest kernels attempt to read/write a
+        * diagnostics register here. We always return 0 and ignore
+        * writes and hope for the best.
+        */
+       { CRn(15), CRm(DF), Op1(DF), Op2(DF), is32,  WRITE, ignore_write, 1},
+       { CRn(15), CRm(DF), Op1(DF), Op2(DF), is32,  READ,  read_zero,    1},
+};
+
+#undef is64
+#undef is32
+#undef READ
+#undef WRITE
+#undef RW

-Christoffer



[Index of Archives]     [Linux KVM]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux