All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: "Radim Krčmář" <rkrcmar@redhat.com>
Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
	bsd@redhat.com, guangrong.xiao@linux.intel.com,
	Yang Zhang <yang.z.zhang@intel.com>,
	wanpeng.li@linux.intel.com
Subject: Re: [PATCH 12/13] KVM: x86: add KVM_MEM_X86_SMRAM memory slot flag
Date: Wed, 06 May 2015 11:47:35 +0200	[thread overview]
Message-ID: <5549E337.1090606@redhat.com> (raw)
In-Reply-To: <20150505171747.GB17198@potion.brq.redhat.com>



On 05/05/2015 19:17, Radim Krčmář wrote:
> 2015-04-30 13:36+0200, Paolo Bonzini:
>> This adds an arch-specific memslot flag that hides slots unless the
>> VCPU is in system management mode.
>>
>> Some care is needed in order to limit the overhead of x86_gfn_to_memslot
>> when compared with gfn_to_memslot.  Thankfully, we have __gfn_to_memslot
>> and search_memslots which are the same, so we can add some extra output
>> to search_memslots.  The compiler will optimize it as dead code in
>> __gfn_to_memslot, and will use it to thread jumps in x86_gfn_to_memslot.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
>> @@ -19,10 +19,23 @@
>>  
>>  #include <linux/module.h>
>>  #include <linux/kvm_host.h>
>> +#include "kvm_cache_regs.h"
>>  
>>  struct kvm_memory_slot *x86_gfn_to_memslot(struct kvm_vcpu *vcpu, gfn_t gfn)
>>  {
>> -	struct kvm_memory_slot *slot = gfn_to_memslot(vcpu->kvm, gfn);
>> +	/* By using search_memslots directly the compiler can optimize away
>> +	 * the "if (found)" check below.
>> +         *
>> +	 * It cannot do the same for gfn_to_memslot because it is not inlined,
>> +	 * and it also cannot do the same for __gfn_to_memslot because the
>> +	 * kernel is compiled with -fno-delete-null-pointer-checks.
>> +	 */
>> +	bool found;
>> +	struct kvm_memslots *memslots = kvm_memslots(vcpu->kvm);
>> +	struct kvm_memory_slot *slot = search_memslots(memslots, gfn, &found);
>> +
>> +	if (found && unlikely(slot->flags & KVM_MEM_X86_SMRAM) && !is_smm(vcpu))
>> +		return NULL;
> 
> Patch [10/13] made me sad and IIUIC, the line above is the only reason
> for it ...

Yes, all the differences trickle down to using x86_gfn_to_memslot.

On the other hand, there are already cut-and-pasted loops for guest 
memory access, see kvm_write_guest_virt_system or 
kvm_read_guest_virt_helper.

We could add __-prefixed macros like

#define __kvm_write_guest(fn_page, gpa, data, len, args...)	\
	({							\
		gpa_t _gpa = (gpa);				\
		void *_data = (data);				\
		int _len = (len);				\
		gfn_t _gfn = _gpa >> PAGE_SHIFT;		\
		int _offset = offset_in_page(_gpa);		\
		int _seg, _ret;					\
	        while ((_seg = next_segment(_len, _offset)) != 0) { \
	                _ret = (fn_page)(args##, _gfn, _data, _offset, _seg); \
	                if (_ret < 0)				\
	                        break;				\
	                _offset = 0;				\
	                _len -= _seg;				\
	                _data += _seg;				\
	                ++_gfn;					\
	        }						\
		_ret;						\
	})

...

int x86_write_guest_page(struct kvm_vcpu *vcpu, gfn_t gfn, const void *data,
                    int offset, unsigned long len)
{
	return __kvm_write_guest_page(x86_gfn_to_memslot, gfn, data, offset, len, vcpu);
}

int x86_write_guest_cached(struct kvm_vcpu *vcpu, struct gfn_to_hva_cache *ghc,
                    const void *data, unsigned long len)
{
	return __kvm_write_guest_cached(x86_gfn_to_hva_cache_init,
					x86_write_guest, ghc, data, len, vcpu);
}

int x86_write_guest(struct kvm_vcpu *vcpu, gpa_t gpa, const void *data,
                    unsigned long len)
{
	return __kvm_write_guest(x86_write_guest_page, gpa, data, len, vcpu);
}

but frankly it seems worse than the disease.

 what about renaming and changing kvm_* memory function to
> vcpu_* and create 
>   bool kvm_arch_vcpu_can_access_slot(vcpu, slot)
> which could also be inline in arch/*/include/asm/kvm_host.h thanks to
> the way we build.
> We could be passing both kvm and vcpu in internal memslot operations and
> not checking if vcpu is NULL.  This should allow all possible operations
> with little code duplication and the compiler could also optimize the
> case where vcpu is NULL.

That would be a huge patch, and most architectures do not (yet) need it.

I can change the functions to kvm_vcpu_read_* and when a second architecture
needs it, we move it from arch/x86/kvm/ to virt/kvm.  I named it x86_ just
because it was the same length as kvm_ and thus hardly needed reindentation.

> Another option is adding something like "vcpu kvm_arch_fake_vcpu(kvm)"
> for cases where the access doesn't have an associated vcpu, so it would
> always succeed.  (Might not be generic enough.)

That's ugly...

The question is also how often the copied code is changed, and the answer is
that most of it was never changed since it was introduced in 2007
(commit 195aefde9cc2, "KVM: Add general accessors to read and write guest
memory").  Before then, KVM used kmap_atomic directly!

Only the cache code is more recent, but that also has only been changed a
couple of times after introducing it in 2010 (commit 49c7754ce570, "KVM:
Add memory slot versioning and use it to provide fast guest write interface").
It is very stable code.

Paolo

  reply	other threads:[~2015-05-06  9:47 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-30 11:35 [RFC PATCH 00/13] KVM: x86: SMM support Paolo Bonzini
2015-04-30 11:36 ` [PATCH 01/13] KVM: MMU: fix for CR4.SMEP=1, CR0.WP=0? Paolo Bonzini
2015-05-08  2:52   ` Xiao Guangrong
2015-04-30 11:36 ` [PATCH 02/13] KVM: reuse memslot in kvm_write_guest_page Paolo Bonzini
2015-05-05 15:03   ` Bandan Das
2015-05-05 16:29     ` Radim Krčmář
2015-04-30 11:36 ` [PATCH 03/13] KVM: export __gfn_to_pfn_memslot, drop gfn_to_pfn_async Paolo Bonzini
2015-04-30 11:36 ` [PATCH 04/13] KVM: remove unnecessary arg from mark_page_dirty_in_slot, export it Paolo Bonzini
2015-04-30 11:36 ` [PATCH 05/13] KVM: x86: pass host_initiated to functions that read MSRs Paolo Bonzini
2015-05-04 14:01   ` Radim Krčmář
2015-05-04 16:04     ` Paolo Bonzini
2015-04-30 11:36 ` [PATCH 06/13] KVM: x86: pass the whole hflags field to emulator and back Paolo Bonzini
2015-05-05 15:47   ` Bandan Das
2015-05-05 16:16     ` Paolo Bonzini
2015-05-06 16:49       ` Bandan Das
2015-04-30 11:36 ` [PATCH 07/13] KVM: x86: API changes for SMM support Paolo Bonzini
2015-05-04 15:37   ` Radim Krčmář
2015-05-04 16:02     ` Paolo Bonzini
2015-05-05 16:36   ` Bandan Das
2015-05-05 16:45     ` Paolo Bonzini
2015-04-30 11:36 ` [PATCH 08/13] KVM: x86: stubs " Paolo Bonzini
2015-05-04 17:51   ` Radim Krčmář
2015-05-05  9:37     ` Paolo Bonzini
2015-05-05 18:38     ` Bandan Das
2015-05-05 18:48       ` Radim Krčmář
2015-04-30 11:36 ` [PATCH 09/13] KVM: x86: save/load state on SMM switch Paolo Bonzini
2015-05-04 19:59   ` Radim Krčmář
2015-05-05  9:37     ` Paolo Bonzini
2015-05-05 12:48       ` Radim Krčmář
2015-05-05 13:18         ` Paolo Bonzini
2015-05-05 20:44   ` Bandan Das
2015-05-06 10:39     ` Paolo Bonzini
2015-05-06 17:55       ` Bandan Das
2015-05-06 19:38         ` Paolo Bonzini
2015-05-12 23:56           ` Bandan Das
2015-05-13  6:58             ` Paolo Bonzini
2015-04-30 11:36 ` [PATCH 10/13] KVM: x86: add vcpu-specific functions to read/write/translate GFNs Paolo Bonzini
2015-04-30 11:36 ` [PATCH 11/13] KVM: x86: add SMM to the MMU role Paolo Bonzini
2015-04-30 11:36 ` [PATCH 12/13] KVM: x86: add KVM_MEM_X86_SMRAM memory slot flag Paolo Bonzini
2015-05-05 17:17   ` Radim Krčmář
2015-05-06  9:47     ` Paolo Bonzini [this message]
2015-05-06 16:24       ` Radim Krčmář
2015-05-06 18:15         ` Bandan Das
2015-05-06 19:43         ` Paolo Bonzini
2015-05-15 20:32   ` Avi Kivity
2015-05-18  8:31     ` Paolo Bonzini
2015-04-30 11:36 ` [PATCH 13/13] KVM: x86: advertise KVM_CAP_X86_SMM Paolo Bonzini
2015-05-05 18:40 ` [RFC PATCH 00/13] KVM: x86: SMM support Radim Krčmář
2015-05-06 11:18   ` Paolo Bonzini
2015-05-06 17:14     ` Radim Krčmář
2015-05-19 14:25 ` Zhang, Yang Z
2015-05-19 14:25   ` Zhang, Yang Z
2015-05-19 14:27   ` Paolo Bonzini
2015-05-20  1:03     ` Zhang, Yang Z
2015-05-20  1:03       ` Zhang, Yang Z
2015-05-20 15:22     ` Andi Kleen

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=5549E337.1090606@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=bsd@redhat.com \
    --cc=guangrong.xiao@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rkrcmar@redhat.com \
    --cc=wanpeng.li@linux.intel.com \
    --cc=yang.z.zhang@intel.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.