[PATCH] KVM: arm64: Handle CMOs on Read Only memslots

Marc Zyngier maz at kernel.org
Fri Feb 12 13:18:04 EST 2021


Hi Alex,

On 2021-02-12 17:12, Alexandru Elisei wrote:
> Hi Marc,
> 
> I've been trying to get my head around what the architecture says about 
> CMOs, so
> please bare with me if I misunderstood some things.

No worries. I've had this patch for a few weeks now, and can't
make up my mind about it. It does address an actual issue though,
so I couldn't just discard it... ;-)

> On 2/11/21 2:27 PM, Marc Zyngier wrote:
>> It appears that when a guest traps into KVM because it is
>> performing a CMO on a Read Only memslot, our handling of
>> this operation is "slightly suboptimal", as we treat it as
>> an MMIO access without a valid syndrome.
>> 
>> The chances that userspace is adequately equiped to deal
>> with such an exception being slim, it would be better to
>> handle it in the kernel.
>> 
>> What we need to provide is roughly as follows:
>> 
>> (a) if a CMO hits writeable memory, handle it as a normal memory acess
>> (b) if a CMO hits non-memory, skip it
>> (c) if a CMO hits R/O memory, that's where things become fun:
>>   (1) if the CMO is DC IVAC, the architecture says this should result
>>       in a permission fault
>>   (2) if the CMO is DC CIVAC, it should work similarly to (a)
> 
> When you say it should work similarly to (a), you mean it should be 
> handled as a
> normal memory access, without the "CMO hits writeable memory" part, 
> right?

What I mean is that the cache invalidation should take place,
preferably without involving KVM at all (other than populating
S2 if required).

> 
>> 
>> We already perform (a) and (b) correctly, but (c) is a total mess.
>> Hence we need to distinguish between IVAC (c.1) and CIVAC (c.2).
>> 
>> One way to do it is to treat CMOs generating a translation fault as
>> a *read*, even when they are on a RW memslot. This allows us to
>> further triage things:
>> 
>> If they come back with a permission fault, that is because this is
>> a DC IVAC instruction:
>> - inside a RW memslot: no problem, treat it as a write (a)(c.2)
>> - inside a RO memslot: inject a data abort in the guest (c.1)
>> 
>> The only drawback is that DC IVAC on a yet unmapped page faults
>> twice: one for the initial translation fault that result in a RO
>> mapping, and once for the permission fault. I think we can live with
>> that.
> 
> I'm trying to make sure I understand what the problem is.
> 
> gfn_to_pfn_prot() returnsKVM_HVA_ERR_RO_BAD if the write is to a RO 
> memslot.
> KVM_HVA_ERR_RO_BAD is PAGE_OFFSET + PAGE_SIZE, which means that
> is_error_noslot_pfn() return true. In that case we exit to userspace
> with -EFAULT
> for DC IVAC and DC CIVAC. But what we should be doing is this:
> 
> - For DC IVAC, inject a dabt with ISS = 0x10, meaning an external abort 
> (that's
> what kvm_inject_dabt_does()).
> 
> - For DC CIVAC, exit to userspace with -EFAULT.
> 
> Did I get that right?

Not quite. What I *think* we should do is:

- DC CIVAC should just work, without going to userspace. I can't imagine
   a reason why we'd involve userspace for this, and we currently don't
   really have a good way to describe this to userspace.

- DC IVAC is more nuanced: we could either inject an exception (which
   is what this patch does), or perform the CMO ourselves as a DC CIVAC
   (consistent with the IVA->CIVA upgrade caused by having a S2 
translation).
   This second approach is comparable to what we do when the guest
   issues a CMO on an emulated MMIO address (we don't inject a fault).

Thanks,

         M.
-- 
Jazz is not dead. It just smells funny...



More information about the linux-arm-kernel mailing list