2019-09-28 17:26:06

by Andrea Arcangeli

[permalink] [raw]
Subject: [PATCH 00/14] KVM monolithic v2

Hello,

as usual the last 4 patches could be splitted off but I did more
measurements in that area and I altered the commit headers. They're
fairly small commits compared to the previous part so I kept it
considering they're needed to benchmark the previous part.

The KVM monolithic enhancement is easy to identify checking the word
"monolithic" in the subject so there's no confusion about where that
work stops.

This renames all functions in place mixed up in whatever location they
existed in svm.c or vmx.c. If they require an inline call they're
defined now as extern before the kvm_x86_ops structure.

Converting those small kvm_x86 functions to inlines requires more
Makefile work and header restructuring so it's left for later.

The removal of kvm_x86_ops is also left for later because that
requires lots of logic changes in the code scattered all over the
place in KVM code. This patchset tries to do the conversion with as
few logic changes as possible, so the code works the same and this
only improves the implementation and the performance.

Doing the conversion plus the logic changes at the same time would
pose the risk of not being able to identify through bisection if any
regression is caused by a bug in the conversion or in one small commit
to alter the logic and to remove the need of one more pointer to
function.

It's best if each single removal of any pointer to functional change
is done through a separate small commit. After all those small commits
done incrementally with this patchset, the kvm_x86_ops structure can
be deleted.

https://git.kernel.org/pub/scm/linux/kernel/git/andrea/aa.git/log/?h=kvm-mono2

Thanks,
Andrea

Andrea Arcangeli (14):
KVM: monolithic: x86: remove kvm.ko
KVM: monolithic: x86: disable linking vmx and svm at the same time
into the kernel
KVM: monolithic: x86: convert the kvm_x86_ops and kvm_pmu_ops methods
to external functions
KVM: monolithic: x86: handle the request_immediate_exit variation
KVM: monolithic: add more section prefixes in the KVM common code
KVM: monolithic: x86: remove __exit section prefix from
machine_unsetup
KVM: monolithic: x86: remove __init section prefix from
kvm_x86_cpu_has_kvm_support
KVM: monolithic: x86: remove exports
KVM: monolithic: remove exports from KVM common code
KVM: monolithic: x86: drop the kvm_pmu_ops structure
KVM: x86: optimize more exit handlers in vmx.c
KVM: retpolines: x86: eliminate retpoline from vmx.c exit handlers
KVM: retpolines: x86: eliminate retpoline from svm.c exit handlers
x86: retpolines: eliminate retpoline from msr event handlers

arch/x86/events/intel/core.c | 11 +
arch/x86/include/asm/kvm_host.h | 205 +++++++-
arch/x86/kvm/Kconfig | 24 +-
arch/x86/kvm/Makefile | 5 +-
arch/x86/kvm/cpuid.c | 27 +-
arch/x86/kvm/hyperv.c | 8 +-
arch/x86/kvm/irq.c | 4 -
arch/x86/kvm/irq_comm.c | 2 -
arch/x86/kvm/kvm_cache_regs.h | 10 +-
arch/x86/kvm/lapic.c | 46 +-
arch/x86/kvm/mmu.c | 50 +-
arch/x86/kvm/mmu.h | 4 +-
arch/x86/kvm/mtrr.c | 2 -
arch/x86/kvm/pmu.c | 27 +-
arch/x86/kvm/pmu.h | 37 +-
arch/x86/kvm/pmu_amd.c | 43 +-
arch/x86/kvm/svm.c | 682 ++++++++++++++++-----------
arch/x86/kvm/trace.h | 4 +-
arch/x86/kvm/vmx/nested.c | 84 ++--
arch/x86/kvm/vmx/pmu_intel.c | 46 +-
arch/x86/kvm/vmx/vmx.c | 795 ++++++++++++++++++--------------
arch/x86/kvm/vmx/vmx.h | 39 +-
arch/x86/kvm/x86.c | 418 +++++++----------
arch/x86/kvm/x86.h | 2 +-
include/linux/kvm_host.h | 4 +-
virt/kvm/eventfd.c | 1 -
virt/kvm/kvm_main.c | 71 +--
27 files changed, 1413 insertions(+), 1238 deletions(-)


2019-09-28 17:26:10

by Andrea Arcangeli

[permalink] [raw]
Subject: [PATCH 06/14] KVM: monolithic: x86: remove __exit section prefix from machine_unsetup

Adjusts the section prefixes of some KVM x86 code function because
with the monolithic KVM model the section checker can now do a more
accurate static analysis at build time and it found a potentially
kernel crashing bug. This also allows to build without
CONFIG_SECTION_MISMATCH_WARN_ONLY=n.

The __exit removed from machine_unsetup is because
kvm_arch_hardware_unsetup() is called by kvm_init() which is in the
__init section. It's not allowed to call a function located in the
__exit section and dropped during the kernel link from the __init
section or the kernel will crash if that call is made.

Signed-off-by: Andrea Arcangeli <[email protected]>
---
arch/x86/include/asm/kvm_host.h | 4 ++--
arch/x86/kvm/svm.c | 2 +-
arch/x86/kvm/vmx/vmx.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 47eeb92d4b4a..0ae65148e5ed 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1008,7 +1008,7 @@ extern int kvm_x86_hardware_enable(void);
extern void kvm_x86_hardware_disable(void);
extern __init int kvm_x86_check_processor_compatibility(void);
extern __init int kvm_x86_hardware_setup(void);
-extern __exit void kvm_x86_hardware_unsetup(void);
+extern void kvm_x86_hardware_unsetup(void);
extern bool kvm_x86_cpu_has_accelerated_tpr(void);
extern bool kvm_x86_has_emulated_msr(int index);
extern void kvm_x86_cpuid_update(struct kvm_vcpu *vcpu);
@@ -1199,7 +1199,7 @@ struct kvm_x86_ops {
void (*hardware_disable)(void);
int (*check_processor_compatibility)(void);/* __init */
int (*hardware_setup)(void); /* __init */
- void (*hardware_unsetup)(void); /* __exit */
+ void (*hardware_unsetup)(void);
bool (*cpu_has_accelerated_tpr)(void);
bool (*has_emulated_msr)(int index);
void (*cpuid_update)(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index aa8c0efdc441..057ba1f8d7b3 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1405,7 +1405,7 @@ __init int kvm_x86_hardware_setup(void)
return r;
}

-__exit void kvm_x86_hardware_unsetup(void)
+void kvm_x86_hardware_unsetup(void)
{
int cpu;

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index aad44e62b20a..2ae162eb082e 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7645,7 +7645,7 @@ __init int kvm_x86_hardware_setup(void)
return r;
}

-__exit void kvm_x86_hardware_unsetup(void)
+void kvm_x86_hardware_unsetup(void)
{
if (nested)
nested_vmx_hardware_unsetup();

2019-09-28 17:26:16

by Andrea Arcangeli

[permalink] [raw]
Subject: [PATCH 07/14] KVM: monolithic: x86: remove __init section prefix from kvm_x86_cpu_has_kvm_support

Adjusts the section prefixes of some KVM x86 code function because
with the monolithic KVM model the section checker can now do a more
accurate static analysis at build time. This also allows to build
without CONFIG_SECTION_MISMATCH_WARN_ONLY=n.

The __init needs to be removed on vmx despite it's only svm calling it
from kvm_x86_hardware_enable which is eventually called by
hardware_enable_nolock() or there's a (potentially false positive)
warning (false positive because this function isn't called in the vmx
case). If this isn't needed the right cleanup isn't to put it in the
__init section, but to drop it. As long as it's defined in vmx as a
kvm_x86 operation, it's expectable that might eventually be called at
runtime while hot plugging new CPUs.

Signed-off-by: Andrea Arcangeli <[email protected]>
---
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/kvm/vmx/vmx.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 0ae65148e5ed..75affbf7861b 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1002,7 +1002,7 @@ struct kvm_lapic_irq {
bool msi_redir_hint;
};

-extern __init int kvm_x86_cpu_has_kvm_support(void);
+extern int kvm_x86_cpu_has_kvm_support(void);
extern __init int kvm_x86_disabled_by_bios(void);
extern int kvm_x86_hardware_enable(void);
extern void kvm_x86_hardware_disable(void);
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 2ae162eb082e..faccffc4709e 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -2094,7 +2094,7 @@ void kvm_x86_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
}
}

-__init int kvm_x86_cpu_has_kvm_support(void)
+int kvm_x86_cpu_has_kvm_support(void)
{
return cpu_has_vmx();
}

2019-09-28 17:28:03

by Andrea Arcangeli

[permalink] [raw]
Subject: [PATCH 01/14] KVM: monolithic: x86: remove kvm.ko

This is the first commit of a patch series that aims to replace the
modular kvm.ko kernel module with a monolithic kvm-intel/kvm-amd
model. This change has the only possible cons of wasting some disk
space in /lib/modules/. The pros are that it saves CPUS and some minor
RAM which are more scarse resources than disk space.

The pointer to function virtual template model cannot provide any
runtime benefit because kvm-intel and kvm-amd can't be loaded at the
same time.

This removes kvm.ko and it links and duplicates all kvm.ko objects to
both kvm-amd and kvm-intel.

Signed-off-by: Andrea Arcangeli <[email protected]>
---
arch/x86/kvm/Makefile | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index 31ecf7a76d5a..68b81f381369 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -12,9 +12,8 @@ kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
hyperv.o page_track.o debugfs.o

-kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o vmx/evmcs.o vmx/nested.o
-kvm-amd-y += svm.o pmu_amd.o
+kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o vmx/evmcs.o vmx/nested.o $(kvm-y)
+kvm-amd-y += svm.o pmu_amd.o $(kvm-y)

-obj-$(CONFIG_KVM) += kvm.o
obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
obj-$(CONFIG_KVM_AMD) += kvm-amd.o

2019-09-28 17:28:13

by Andrea Arcangeli

[permalink] [raw]
Subject: [PATCH 04/14] KVM: monolithic: x86: handle the request_immediate_exit variation

request_immediate_exit is one of those few cases where the pointer to
function of the method isn't fixed at build time and it requires
special handling because hardware_setup() may override it at runtime.

Signed-off-by: Andrea Arcangeli <[email protected]>
---
arch/x86/kvm/vmx/vmx.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index bb122ab4b96c..aad44e62b20a 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -7022,7 +7022,10 @@ void kvm_x86_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry)

void kvm_x86_request_immediate_exit(struct kvm_vcpu *vcpu)
{
- to_vmx(vcpu)->req_immediate_exit = true;
+ if (likely(enable_preemption_timer))
+ to_vmx(vcpu)->req_immediate_exit = true;
+ else
+ __kvm_request_immediate_exit(vcpu);
}

int kvm_x86_check_intercept(struct kvm_vcpu *vcpu,

2019-10-15 05:35:03

by Sean Christopherson

[permalink] [raw]
Subject: Re: [PATCH 01/14] KVM: monolithic: x86: remove kvm.ko

On Sat, Sep 28, 2019 at 01:23:10PM -0400, Andrea Arcangeli wrote:
> This is the first commit of a patch series that aims to replace the
> modular kvm.ko kernel module with a monolithic kvm-intel/kvm-amd
> model. This change has the only possible cons of wasting some disk
> space in /lib/modules/. The pros are that it saves CPUS and some minor
> RAM which are more scarse resources than disk space.
>
> The pointer to function virtual template model cannot provide any
> runtime benefit because kvm-intel and kvm-amd can't be loaded at the
> same time.
>
> This removes kvm.ko and it links and duplicates all kvm.ko objects to
> both kvm-amd and kvm-intel.

The KVM config option should be changed to a bool and its help text
updated. Maybe something similar to the help for VIRTUALIZATION to make
it clear that enabling KVM on its own does nothing.

>
> Signed-off-by: Andrea Arcangeli <[email protected]>
> ---
> arch/x86/kvm/Makefile | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
> index 31ecf7a76d5a..68b81f381369 100644
> --- a/arch/x86/kvm/Makefile
> +++ b/arch/x86/kvm/Makefile
> @@ -12,9 +12,8 @@ kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
> i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
> hyperv.o page_track.o debugfs.o
>
> -kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o vmx/evmcs.o vmx/nested.o
> -kvm-amd-y += svm.o pmu_amd.o
> +kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o vmx/evmcs.o vmx/nested.o $(kvm-y)
> +kvm-amd-y += svm.o pmu_amd.o $(kvm-y)
>
> -obj-$(CONFIG_KVM) += kvm.o
> obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
> obj-$(CONFIG_KVM_AMD) += kvm-amd.o

2019-10-15 05:36:33

by Sean Christopherson

[permalink] [raw]
Subject: Re: [PATCH 01/14] KVM: monolithic: x86: remove kvm.ko

On Mon, Oct 14, 2019 at 06:31:44PM -0700, Sean Christopherson wrote:
> On Sat, Sep 28, 2019 at 01:23:10PM -0400, Andrea Arcangeli wrote:
> > This is the first commit of a patch series that aims to replace the
> > modular kvm.ko kernel module with a monolithic kvm-intel/kvm-amd
> > model. This change has the only possible cons of wasting some disk
> > space in /lib/modules/. The pros are that it saves CPUS and some minor
> > RAM which are more scarse resources than disk space.
> >
> > The pointer to function virtual template model cannot provide any
> > runtime benefit because kvm-intel and kvm-amd can't be loaded at the
> > same time.
> >
> > This removes kvm.ko and it links and duplicates all kvm.ko objects to
> > both kvm-amd and kvm-intel.
>
> The KVM config option should be changed to a bool and its help text
> updated. Maybe something similar to the help for VIRTUALIZATION to make
> it clear that enabling KVM on its own does nothing.

Making KVM a bool doesn't work well, keeping it a tristate and keying off
KVM=y to force Intel or AMD (as done in the next patch) looks like the
cleanest implementation.

The help text should still be updated though.

> >
> > Signed-off-by: Andrea Arcangeli <[email protected]>
> > ---
> > arch/x86/kvm/Makefile | 5 ++---
> > 1 file changed, 2 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
> > index 31ecf7a76d5a..68b81f381369 100644
> > --- a/arch/x86/kvm/Makefile
> > +++ b/arch/x86/kvm/Makefile
> > @@ -12,9 +12,8 @@ kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
> > i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
> > hyperv.o page_track.o debugfs.o
> >
> > -kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o vmx/evmcs.o vmx/nested.o
> > -kvm-amd-y += svm.o pmu_amd.o
> > +kvm-intel-y += vmx/vmx.o vmx/vmenter.o vmx/pmu_intel.o vmx/vmcs12.o vmx/evmcs.o vmx/nested.o $(kvm-y)
> > +kvm-amd-y += svm.o pmu_amd.o $(kvm-y)
> >
> > -obj-$(CONFIG_KVM) += kvm.o
> > obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
> > obj-$(CONFIG_KVM_AMD) += kvm-amd.o

2019-10-15 11:13:02

by Paolo Bonzini

[permalink] [raw]
Subject: Re: [PATCH 01/14] KVM: monolithic: x86: remove kvm.ko

On 15/10/19 05:18, Sean Christopherson wrote:
>> The KVM config option should be changed to a bool and its help text
>> updated. Maybe something similar to the help for VIRTUALIZATION to make
>> it clear that enabling KVM on its own does nothing.
> Making KVM a bool doesn't work well, keeping it a tristate and keying off
> KVM=y to force Intel or AMD (as done in the next patch) looks like the
> cleanest implementation.

Indeed, keeping the KVM option as tristate helps showing the right
suboptions, similar to what Andrea did in patch 2. However, this patch
already breaks the CONFIG_KVM_INTEL=y && CONFIG_KVM_AMD=y case I think,
so it should be squashed with "KVM: monolithic: x86: disable linking vmx
and svm at the same time into the kernel".

> The help text should still be updated though.

The patch doesn't change the fact that enabling KVM on its own does
nothing, so the help text can be updated independently (patch welcome :)).

Thanks,

Paolo