From: Anthony Liguori <anthony@codemonkey.ws>
To: Hollis Blanchard <hollisb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
kvm-ppc-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
carsteno-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org,
Xiantao <xiantao.zhang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
Subject: Re: [kvm-ppc-devel] [kvm-devel] [PATCH 1 of 3] Use kvm_x86 to hold
Date: Wed, 28 Nov 2007 21:20:23 +0000 [thread overview]
Message-ID: <474DDB97.6090400@codemonkey.ws> (raw)
In-Reply-To: <e74d8a8e127c7347427e.1195577833@basalt>
Hollis Blanchard wrote:
> Signed-off-by: Zhang xiantao <xiantao.zhang@intel.com>
> Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
> ---
> Changes from Xiantao's patch:
> - Fix whitespace
> - Reorder variables to avoid stack padding
> - Leave descriptor_table relocation for another patch
>
> 8 files changed, 132 insertions(+), 85 deletions(-)
> drivers/kvm/ioapic.c | 7 ++-
> drivers/kvm/irq.h | 1
> drivers/kvm/kvm.h | 26 --------------
> drivers/kvm/kvm_main.c | 9 ++---
> drivers/kvm/mmu.c | 85 ++++++++++++++++++++++++++++--------------------
> drivers/kvm/vmx.c | 9 +++--
> drivers/kvm/x86.c | 37 ++++++++++++--------
> drivers/kvm/x86.h | 43 +++++++++++++++++++++++-
>
>
> diff --git a/drivers/kvm/ioapic.c b/drivers/kvm/ioapic.c
> --- a/drivers/kvm/ioapic.c
> +++ b/drivers/kvm/ioapic.c
> @@ -276,7 +276,9 @@ static int get_eoi_gsi(struct kvm_ioapic
>
> void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
> {
> - struct kvm_ioapic *ioapic = kvm->vioapic;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + struct kvm_ioapic *ioapic = kvm_x86->vioapic;
> union ioapic_redir_entry *ent;
> int gsi;
>
> @@ -386,11 +388,12 @@ int kvm_ioapic_init(struct kvm *kvm)
> int kvm_ioapic_init(struct kvm *kvm)
> {
> struct kvm_ioapic *ioapic;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
>
> ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL);
> if (!ioapic)
> return -ENOMEM;
> - kvm->vioapic = ioapic;
> + kvm_x86->vioapic = ioapic;
> kvm_ioapic_reset(ioapic);
> ioapic->dev.read = ioapic_mmio_read;
> ioapic->dev.write = ioapic_mmio_write;
>
If the ioapic depends on x86_specific information, why is it taking a
generic kvm structure instead of the x86 one?
> diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
> --- a/drivers/kvm/irq.h
> +++ b/drivers/kvm/irq.h
> @@ -23,6 +23,7 @@
> #define __IRQ_H
>
> #include "kvm.h"
> +#include "x86.h"
>
> typedef void irq_request_func(void *opaque, int level);
>
> diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
> --- a/drivers/kvm/kvm.h
> +++ b/drivers/kvm/kvm.h
> @@ -309,41 +309,15 @@ struct kvm {
> int nmemslots;
> struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS +
> KVM_PRIVATE_MEM_SLOTS];
> - /*
> - * Hash table of struct kvm_mmu_page.
> - */
> - struct list_head active_mmu_pages;
> - unsigned int n_free_mmu_pages;
> - unsigned int n_requested_mmu_pages;
> - unsigned int n_alloc_mmu_pages;
> - struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
> struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
> struct list_head vm_list;
> struct file *filp;
> struct kvm_io_bus mmio_bus;
> struct kvm_io_bus pio_bus;
> - struct kvm_pic *vpic;
> - struct kvm_ioapic *vioapic;
> int round_robin_prev_vcpu;
> - unsigned int tss_addr;
> struct page *apic_access_page;
> struct kvm_vm_stat stat;
> };
> -
> -static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
> -{
> - return kvm->vpic;
> -}
> -
> -static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm)
> -{
> - return kvm->vioapic;
> -}
> -
> -static inline int irqchip_in_kernel(struct kvm *kvm)
> -{
> - return pic_irqchip(kvm) != NULL;
> -}
>
> struct descriptor_table {
> u16 limit;
> diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
> --- a/drivers/kvm/kvm_main.c
> +++ b/drivers/kvm/kvm_main.c
> @@ -232,6 +232,7 @@ int __kvm_set_memory_region(struct kvm *
> unsigned long i;
> struct kvm_memory_slot *memslot;
> struct kvm_memory_slot old, new;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
>
> r = -EINVAL;
> /* General sanity checks */
> @@ -332,18 +333,18 @@ int __kvm_set_memory_region(struct kvm *
> if (mem->slot >= kvm->nmemslots)
> kvm->nmemslots = mem->slot + 1;
>
> - if (!kvm->n_requested_mmu_pages) {
> + if (!kvm_x86->n_requested_mmu_pages) {
>
Why is anything in kvm_main.c accessing a memory of kvm_x86? Something
is broken in the abstraction if that's the case.
> unsigned int n_pages;
>
> if (npages) {
> n_pages = npages * KVM_PERMILLE_MMU_PAGES / 1000;
> - kvm_mmu_change_mmu_pages(kvm, kvm->n_alloc_mmu_pages +
> - n_pages);
> + kvm_mmu_change_mmu_pages(kvm,
> + kvm_x86->n_alloc_mmu_pages + n_pages);
> } else {
> unsigned int nr_mmu_pages;
>
> n_pages = old.npages * KVM_PERMILLE_MMU_PAGES / 1000;
> - nr_mmu_pages = kvm->n_alloc_mmu_pages - n_pages;
> + nr_mmu_pages = kvm_x86->n_alloc_mmu_pages - n_pages;
> nr_mmu_pages = max(nr_mmu_pages,
> (unsigned int) KVM_MIN_ALLOC_MMU_PAGES);
> kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages);
> diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
> --- a/drivers/kvm/mmu.c
> +++ b/drivers/kvm/mmu.c
> @@ -526,12 +526,14 @@ static void kvm_mmu_free_page(struct kvm
> static void kvm_mmu_free_page(struct kvm *kvm,
> struct kvm_mmu_page *page_head)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> ASSERT(is_empty_shadow_page(page_head->spt));
> list_del(&page_head->link);
> __free_page(virt_to_page(page_head->spt));
> __free_page(virt_to_page(page_head->gfns));
> kfree(page_head);
> - ++kvm->n_free_mmu_pages;
> + ++kvm_x86->n_free_mmu_pages;
> }
The mmu functions should probably take kvm_x86 since this won't be
shared with any other architecture.
Regards,
Anthony Liguori
>
> static unsigned kvm_page_table_hashfn(gfn_t gfn)
> @@ -543,8 +545,9 @@ static struct kvm_mmu_page *kvm_mmu_allo
> u64 *parent_pte)
> {
> struct kvm_mmu_page *page;
> -
> - if (!vcpu->kvm->n_free_mmu_pages)
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> +
> + if (!kvm_x86->n_free_mmu_pages)
> return NULL;
>
> page = mmu_memory_cache_alloc(&vcpu->mmu_page_header_cache,
> @@ -552,12 +555,12 @@ static struct kvm_mmu_page *kvm_mmu_allo
> page->spt = mmu_memory_cache_alloc(&vcpu->mmu_page_cache, PAGE_SIZE);
> page->gfns = mmu_memory_cache_alloc(&vcpu->mmu_page_cache, PAGE_SIZE);
> set_page_private(virt_to_page(page->spt), (unsigned long)page);
> - list_add(&page->link, &vcpu->kvm->active_mmu_pages);
> + list_add(&page->link, &kvm_x86->active_mmu_pages);
> ASSERT(is_empty_shadow_page(page->spt));
> page->slot_bitmap = 0;
> page->multimapped = 0;
> page->parent_pte = parent_pte;
> - --vcpu->kvm->n_free_mmu_pages;
> + --kvm_x86->n_free_mmu_pages;
> return page;
> }
>
> @@ -643,10 +646,11 @@ static struct kvm_mmu_page *kvm_mmu_look
> struct hlist_head *bucket;
> struct kvm_mmu_page *page;
> struct hlist_node *node;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
>
> pgprintk("%s: looking for gfn %lx\n", __FUNCTION__, gfn);
> index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
> - bucket = &kvm->mmu_page_hash[index];
> + bucket = &kvm_x86->mmu_page_hash[index];
> hlist_for_each_entry(page, node, bucket, hash_link)
> if (page->gfn = gfn && !page->role.metaphysical) {
> pgprintk("%s: found role %x\n",
> @@ -670,6 +674,7 @@ static struct kvm_mmu_page *kvm_mmu_get_
> struct hlist_head *bucket;
> struct kvm_mmu_page *page;
> struct hlist_node *node;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
>
> role.word = 0;
> role.glevels = vcpu->mmu.root_level;
> @@ -684,7 +689,7 @@ static struct kvm_mmu_page *kvm_mmu_get_
> pgprintk("%s: looking gfn %lx role %x\n", __FUNCTION__,
> gfn, role.word);
> index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
> - bucket = &vcpu->kvm->mmu_page_hash[index];
> + bucket = &kvm_x86->mmu_page_hash[index];
> hlist_for_each_entry(page, node, bucket, hash_link)
> if (page->gfn = gfn && page->role.word = role.word) {
> mmu_page_add_parent_pte(vcpu, page, parent_pte);
> @@ -754,6 +759,7 @@ static void kvm_mmu_zap_page(struct kvm
> struct kvm_mmu_page *page)
> {
> u64 *parent_pte;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
>
> ++kvm->stat.mmu_shadow_zapped;
> while (page->multimapped || page->parent_pte) {
> @@ -775,7 +781,7 @@ static void kvm_mmu_zap_page(struct kvm
> hlist_del(&page->hash_link);
> kvm_mmu_free_page(kvm, page);
> } else
> - list_move(&page->link, &kvm->active_mmu_pages);
> + list_move(&page->link, &kvm_x86->active_mmu_pages);
> kvm_mmu_reset_last_pte_updated(kvm);
> }
>
> @@ -785,36 +791,39 @@ static void kvm_mmu_zap_page(struct kvm
> */
> void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> /*
> * If we set the number of mmu pages to be smaller be than the
> * number of actived pages , we must to free some mmu pages before we
> * change the value
> */
>
> - if ((kvm->n_alloc_mmu_pages - kvm->n_free_mmu_pages) >
> + if ((kvm_x86->n_alloc_mmu_pages - kvm_x86->n_free_mmu_pages) >
> kvm_nr_mmu_pages) {
> - int n_used_mmu_pages = kvm->n_alloc_mmu_pages
> - - kvm->n_free_mmu_pages;
> + int n_used_mmu_pages = kvm_x86->n_alloc_mmu_pages
> + - kvm_x86->n_free_mmu_pages;
>
> while (n_used_mmu_pages > kvm_nr_mmu_pages) {
> struct kvm_mmu_page *page;
>
> - page = container_of(kvm->active_mmu_pages.prev,
> + page = container_of(kvm_x86->active_mmu_pages.prev,
> struct kvm_mmu_page, link);
> kvm_mmu_zap_page(kvm, page);
> n_used_mmu_pages--;
> }
> - kvm->n_free_mmu_pages = 0;
> + kvm_x86->n_free_mmu_pages = 0;
> }
> else
> - kvm->n_free_mmu_pages += kvm_nr_mmu_pages
> - - kvm->n_alloc_mmu_pages;
> -
> - kvm->n_alloc_mmu_pages = kvm_nr_mmu_pages;
> + kvm_x86->n_free_mmu_pages += kvm_nr_mmu_pages
> + - kvm_x86->n_alloc_mmu_pages;
> +
> + kvm_x86->n_alloc_mmu_pages = kvm_nr_mmu_pages;
> }
>
> static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> unsigned index;
> struct hlist_head *bucket;
> struct kvm_mmu_page *page;
> @@ -824,7 +833,7 @@ static int kvm_mmu_unprotect_page(struct
> pgprintk("%s: looking for gfn %lx\n", __FUNCTION__, gfn);
> r = 0;
> index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
> - bucket = &kvm->mmu_page_hash[index];
> + bucket = &kvm_x86->mmu_page_hash[index];
> hlist_for_each_entry_safe(page, node, n, bucket, hash_link)
> if (page->gfn = gfn && !page->role.metaphysical) {
> pgprintk("%s: gfn %lx role %x\n", __FUNCTION__, gfn,
> @@ -1251,6 +1260,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *
> void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
> const u8 *new, int bytes)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> gfn_t gfn = gpa >> PAGE_SHIFT;
> struct kvm_mmu_page *page;
> struct hlist_node *node, *n;
> @@ -1280,7 +1290,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *
> vcpu->last_pte_updated = NULL;
> }
> index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
> - bucket = &vcpu->kvm->mmu_page_hash[index];
> + bucket = &kvm_x86->mmu_page_hash[index];
> hlist_for_each_entry_safe(page, node, n, bucket, hash_link) {
> if (page->gfn != gfn || page->role.metaphysical)
> continue;
> @@ -1344,10 +1354,12 @@ int kvm_mmu_unprotect_page_virt(struct k
>
> void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
> {
> - while (vcpu->kvm->n_free_mmu_pages < KVM_REFILL_PAGES) {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> +
> + while (kvm_x86->n_free_mmu_pages < KVM_REFILL_PAGES) {
> struct kvm_mmu_page *page;
>
> - page = container_of(vcpu->kvm->active_mmu_pages.prev,
> + page = container_of(kvm_x86->active_mmu_pages.prev,
> struct kvm_mmu_page, link);
> kvm_mmu_zap_page(vcpu->kvm, page);
> ++vcpu->kvm->stat.mmu_recycled;
> @@ -1397,9 +1409,10 @@ static void free_mmu_pages(struct kvm_vc
> static void free_mmu_pages(struct kvm_vcpu *vcpu)
> {
> struct kvm_mmu_page *page;
> -
> - while (!list_empty(&vcpu->kvm->active_mmu_pages)) {
> - page = container_of(vcpu->kvm->active_mmu_pages.next,
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> +
> + while (!list_empty(&kvm_x86->active_mmu_pages)) {
> + page = container_of(kvm_x86->active_mmu_pages.next,
> struct kvm_mmu_page, link);
> kvm_mmu_zap_page(vcpu->kvm, page);
> }
> @@ -1408,15 +1421,16 @@ static void free_mmu_pages(struct kvm_vc
>
> static int alloc_mmu_pages(struct kvm_vcpu *vcpu)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> struct page *page;
> int i;
>
> ASSERT(vcpu);
>
> - if (vcpu->kvm->n_requested_mmu_pages)
> - vcpu->kvm->n_free_mmu_pages = vcpu->kvm->n_requested_mmu_pages;
> + if (kvm_x86->n_requested_mmu_pages)
> + kvm_x86->n_free_mmu_pages = kvm_x86->n_requested_mmu_pages;
> else
> - vcpu->kvm->n_free_mmu_pages = vcpu->kvm->n_alloc_mmu_pages;
> + kvm_x86->n_free_mmu_pages = kvm_x86->n_alloc_mmu_pages;
> /*
> * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64.
> * Therefore we need to allocate shadow page tables in the first
> @@ -1464,8 +1478,9 @@ void kvm_mmu_slot_remove_write_access(st
> void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
> {
> struct kvm_mmu_page *page;
> -
> - list_for_each_entry(page, &kvm->active_mmu_pages, link) {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + list_for_each_entry(page, &kvm_x86->active_mmu_pages, link) {
> int i;
> u64 *pt;
>
> @@ -1483,8 +1498,9 @@ void kvm_mmu_zap_all(struct kvm *kvm)
> void kvm_mmu_zap_all(struct kvm *kvm)
> {
> struct kvm_mmu_page *page, *node;
> -
> - list_for_each_entry_safe(page, node, &kvm->active_mmu_pages, link)
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + list_for_each_entry_safe(page, node, &kvm_x86->active_mmu_pages, link)
> kvm_mmu_zap_page(kvm, page);
>
> kvm_flush_remote_tlbs(kvm);
> @@ -1637,7 +1653,7 @@ static int count_writable_mappings(struc
> struct kvm_mmu_page *page;
> int i;
>
> - list_for_each_entry(page, &vcpu->kvm->active_mmu_pages, link) {
> + list_for_each_entry(page, &kvm_x86->active_mmu_pages, link) {
> u64 *pt = page->spt;
>
> if (page->role.level != PT_PAGE_TABLE_LEVEL)
> @@ -1672,8 +1688,9 @@ static void audit_write_protection(struc
> struct kvm_memory_slot *slot;
> unsigned long *rmapp;
> gfn_t gfn;
> -
> - list_for_each_entry(page, &vcpu->kvm->active_mmu_pages, link) {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + list_for_each_entry(page, &kvm_x86->active_mmu_pages, link) {
> if (page->role.metaphysical)
> continue;
>
> diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
> --- a/drivers/kvm/vmx.c
> +++ b/drivers/kvm/vmx.c
> @@ -1141,12 +1141,14 @@ static void enter_pmode(struct kvm_vcpu
>
> static gva_t rmode_tss_base(struct kvm *kvm)
> {
> - if (!kvm->tss_addr) {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + if (!kvm_x86->tss_addr) {
> gfn_t base_gfn = kvm->memslots[0].base_gfn +
> kvm->memslots[0].npages - 3;
> return base_gfn << PAGE_SHIFT;
> }
> - return kvm->tss_addr;
> + return kvm_x86->tss_addr;
> }
>
> static void fix_rmode_seg(int seg, struct kvm_save_segment *save)
> @@ -1768,6 +1770,7 @@ static void do_interrupt_requests(struct
>
> static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> int ret;
> struct kvm_userspace_memory_region tss_mem = {
> .slot = 8,
> @@ -1779,7 +1782,7 @@ static int vmx_set_tss_addr(struct kvm *
> ret = kvm_set_memory_region(kvm, &tss_mem, 0);
> if (ret)
> return ret;
> - kvm->tss_addr = addr;
> + kvm_x86->tss_addr = addr;
> return 0;
> }
>
> diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c
> --- a/drivers/kvm/x86.c
> +++ b/drivers/kvm/x86.c
> @@ -815,13 +815,15 @@ static int kvm_vm_ioctl_set_nr_mmu_pages
> static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
> u32 kvm_nr_mmu_pages)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> if (kvm_nr_mmu_pages < KVM_MIN_ALLOC_MMU_PAGES)
> return -EINVAL;
>
> mutex_lock(&kvm->lock);
>
> kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages);
> - kvm->n_requested_mmu_pages = kvm_nr_mmu_pages;
> + kvm_x86->n_requested_mmu_pages = kvm_nr_mmu_pages;
>
> mutex_unlock(&kvm->lock);
> return 0;
> @@ -829,7 +831,9 @@ static int kvm_vm_ioctl_set_nr_mmu_pages
>
> static int kvm_vm_ioctl_get_nr_mmu_pages(struct kvm *kvm)
> {
> - return kvm->n_alloc_mmu_pages;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + return kvm_x86->n_alloc_mmu_pages;
> }
>
> /*
> @@ -972,6 +976,7 @@ long kvm_arch_vm_ioctl(struct file *filp
> unsigned int ioctl, unsigned long arg)
> {
> struct kvm *kvm = filp->private_data;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> void __user *argp = (void __user *)arg;
> int r = -EINVAL;
>
> @@ -1018,12 +1023,12 @@ long kvm_arch_vm_ioctl(struct file *filp
> }
> case KVM_CREATE_IRQCHIP:
> r = -ENOMEM;
> - kvm->vpic = kvm_create_pic(kvm);
> - if (kvm->vpic) {
> + kvm_x86->vpic = kvm_create_pic(kvm);
> + if (kvm_x86->vpic) {
> r = kvm_ioapic_init(kvm);
> if (r) {
> - kfree(kvm->vpic);
> - kvm->vpic = NULL;
> + kfree(kvm_x86->vpic);
> + kvm_x86->vpic = NULL;
> goto out;
> }
> } else
> @@ -1041,7 +1046,7 @@ long kvm_arch_vm_ioctl(struct file *filp
> kvm_pic_set_irq(pic_irqchip(kvm),
> irq_event.irq,
> irq_event.level);
> - kvm_ioapic_set_irq(kvm->vioapic,
> + kvm_ioapic_set_irq(kvm_x86->vioapic,
> irq_event.irq,
> irq_event.level);
> mutex_unlock(&kvm->lock);
> @@ -2603,14 +2608,14 @@ void kvm_arch_vcpu_uninit(struct kvm_vcp
>
> struct kvm *kvm_arch_create_vm(void)
> {
> - struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
> -
> - if (!kvm)
> + struct kvm_x86 *kvm_x86 = kzalloc(sizeof(struct kvm_x86), GFP_KERNEL);
> +
> + if (!kvm_x86)
> return ERR_PTR(-ENOMEM);
>
> - INIT_LIST_HEAD(&kvm->active_mmu_pages);
> -
> - return kvm;
> + INIT_LIST_HEAD(&kvm_x86->active_mmu_pages);
> +
> + return &kvm_x86->kvm;
> }
>
> static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu)
> @@ -2641,8 +2646,10 @@ static void kvm_free_vcpus(struct kvm *k
>
> void kvm_arch_destroy_vm(struct kvm *kvm)
> {
> - kfree(kvm->vpic);
> - kfree(kvm->vioapic);
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + kfree(kvm_x86->vpic);
> + kfree(kvm_x86->vioapic);
> kvm_free_vcpus(kvm);
> kvm_free_physmem(kvm);
> kfree(kvm);
> diff --git a/drivers/kvm/x86.h b/drivers/kvm/x86.h
> --- a/drivers/kvm/x86.h
> +++ b/drivers/kvm/x86.h
> @@ -155,6 +155,45 @@ struct kvm_vcpu {
>
> struct x86_emulate_ctxt emulate_ctxt;
> };
> +
> +struct kvm_x86 {
> + struct kvm kvm;
> + /*
> + * Hash table of struct kvm_mmu_page.
> + */
> + struct list_head active_mmu_pages;
> + unsigned int n_free_mmu_pages;
> + unsigned int n_requested_mmu_pages;
> + unsigned int n_alloc_mmu_pages;
> + struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
> + struct kvm_pic *vpic;
> + struct kvm_ioapic *vioapic;
> + unsigned int tss_addr;
> +};
> +
> +static struct kvm_x86 *to_kvm_x86(struct kvm *kvm)
> +{
> + return container_of(kvm, struct kvm_x86, kvm);
> +}
> +
> +static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
> +{
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + return kvm_x86->vpic;
> +}
> +
> +static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm)
> +{
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + return kvm_x86->vioapic;
> +}
> +
> +static inline int irqchip_in_kernel(struct kvm *kvm)
> +{
> + return pic_irqchip(kvm) != NULL;
> +}
>
> struct kvm_x86_ops {
> int (*cpu_has_kvm_support)(void); /* __init */
> @@ -313,7 +352,9 @@ int kvm_mmu_page_fault(struct kvm_vcpu *
>
> static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
> {
> - if (unlikely(vcpu->kvm->n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES))
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> +
> + if (unlikely(kvm_x86->n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES))
> __kvm_mmu_free_some_pages(vcpu);
> }
>
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Microsoft
> Defy all challenges. Microsoft(R) Visual Studio 2005.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> kvm-devel mailing list
> kvm-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/kvm-devel
>
>
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper
from Novell. From the desktop to the data center, Linux is going
mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
_______________________________________________
kvm-ppc-devel mailing list
kvm-ppc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-ppc-devel
WARNING: multiple messages have this Message-ID (diff)
From: Anthony Liguori <anthony-rdkfGonbjUSkNkDKm+mE6A@public.gmane.org>
To: Hollis Blanchard <hollisb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
kvm-ppc-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
carsteno-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org,
Xiantao <xiantao.zhang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
Subject: Re: [PATCH 1 of 3] Use kvm_x86 to hold x86 specific kvm fields
Date: Wed, 28 Nov 2007 15:20:23 -0600 [thread overview]
Message-ID: <474DDB97.6090400@codemonkey.ws> (raw)
In-Reply-To: <e74d8a8e127c7347427e.1195577833@basalt>
Hollis Blanchard wrote:
> Signed-off-by: Zhang xiantao <xiantao.zhang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Hollis Blanchard <hollisb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
> ---
> Changes from Xiantao's patch:
> - Fix whitespace
> - Reorder variables to avoid stack padding
> - Leave descriptor_table relocation for another patch
>
> 8 files changed, 132 insertions(+), 85 deletions(-)
> drivers/kvm/ioapic.c | 7 ++-
> drivers/kvm/irq.h | 1
> drivers/kvm/kvm.h | 26 --------------
> drivers/kvm/kvm_main.c | 9 ++---
> drivers/kvm/mmu.c | 85 ++++++++++++++++++++++++++++--------------------
> drivers/kvm/vmx.c | 9 +++--
> drivers/kvm/x86.c | 37 ++++++++++++--------
> drivers/kvm/x86.h | 43 +++++++++++++++++++++++-
>
>
> diff --git a/drivers/kvm/ioapic.c b/drivers/kvm/ioapic.c
> --- a/drivers/kvm/ioapic.c
> +++ b/drivers/kvm/ioapic.c
> @@ -276,7 +276,9 @@ static int get_eoi_gsi(struct kvm_ioapic
>
> void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
> {
> - struct kvm_ioapic *ioapic = kvm->vioapic;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + struct kvm_ioapic *ioapic = kvm_x86->vioapic;
> union ioapic_redir_entry *ent;
> int gsi;
>
> @@ -386,11 +388,12 @@ int kvm_ioapic_init(struct kvm *kvm)
> int kvm_ioapic_init(struct kvm *kvm)
> {
> struct kvm_ioapic *ioapic;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
>
> ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL);
> if (!ioapic)
> return -ENOMEM;
> - kvm->vioapic = ioapic;
> + kvm_x86->vioapic = ioapic;
> kvm_ioapic_reset(ioapic);
> ioapic->dev.read = ioapic_mmio_read;
> ioapic->dev.write = ioapic_mmio_write;
>
If the ioapic depends on x86_specific information, why is it taking a
generic kvm structure instead of the x86 one?
> diff --git a/drivers/kvm/irq.h b/drivers/kvm/irq.h
> --- a/drivers/kvm/irq.h
> +++ b/drivers/kvm/irq.h
> @@ -23,6 +23,7 @@
> #define __IRQ_H
>
> #include "kvm.h"
> +#include "x86.h"
>
> typedef void irq_request_func(void *opaque, int level);
>
> diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
> --- a/drivers/kvm/kvm.h
> +++ b/drivers/kvm/kvm.h
> @@ -309,41 +309,15 @@ struct kvm {
> int nmemslots;
> struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS +
> KVM_PRIVATE_MEM_SLOTS];
> - /*
> - * Hash table of struct kvm_mmu_page.
> - */
> - struct list_head active_mmu_pages;
> - unsigned int n_free_mmu_pages;
> - unsigned int n_requested_mmu_pages;
> - unsigned int n_alloc_mmu_pages;
> - struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
> struct kvm_vcpu *vcpus[KVM_MAX_VCPUS];
> struct list_head vm_list;
> struct file *filp;
> struct kvm_io_bus mmio_bus;
> struct kvm_io_bus pio_bus;
> - struct kvm_pic *vpic;
> - struct kvm_ioapic *vioapic;
> int round_robin_prev_vcpu;
> - unsigned int tss_addr;
> struct page *apic_access_page;
> struct kvm_vm_stat stat;
> };
> -
> -static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
> -{
> - return kvm->vpic;
> -}
> -
> -static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm)
> -{
> - return kvm->vioapic;
> -}
> -
> -static inline int irqchip_in_kernel(struct kvm *kvm)
> -{
> - return pic_irqchip(kvm) != NULL;
> -}
>
> struct descriptor_table {
> u16 limit;
> diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
> --- a/drivers/kvm/kvm_main.c
> +++ b/drivers/kvm/kvm_main.c
> @@ -232,6 +232,7 @@ int __kvm_set_memory_region(struct kvm *
> unsigned long i;
> struct kvm_memory_slot *memslot;
> struct kvm_memory_slot old, new;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
>
> r = -EINVAL;
> /* General sanity checks */
> @@ -332,18 +333,18 @@ int __kvm_set_memory_region(struct kvm *
> if (mem->slot >= kvm->nmemslots)
> kvm->nmemslots = mem->slot + 1;
>
> - if (!kvm->n_requested_mmu_pages) {
> + if (!kvm_x86->n_requested_mmu_pages) {
>
Why is anything in kvm_main.c accessing a memory of kvm_x86? Something
is broken in the abstraction if that's the case.
> unsigned int n_pages;
>
> if (npages) {
> n_pages = npages * KVM_PERMILLE_MMU_PAGES / 1000;
> - kvm_mmu_change_mmu_pages(kvm, kvm->n_alloc_mmu_pages +
> - n_pages);
> + kvm_mmu_change_mmu_pages(kvm,
> + kvm_x86->n_alloc_mmu_pages + n_pages);
> } else {
> unsigned int nr_mmu_pages;
>
> n_pages = old.npages * KVM_PERMILLE_MMU_PAGES / 1000;
> - nr_mmu_pages = kvm->n_alloc_mmu_pages - n_pages;
> + nr_mmu_pages = kvm_x86->n_alloc_mmu_pages - n_pages;
> nr_mmu_pages = max(nr_mmu_pages,
> (unsigned int) KVM_MIN_ALLOC_MMU_PAGES);
> kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages);
> diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
> --- a/drivers/kvm/mmu.c
> +++ b/drivers/kvm/mmu.c
> @@ -526,12 +526,14 @@ static void kvm_mmu_free_page(struct kvm
> static void kvm_mmu_free_page(struct kvm *kvm,
> struct kvm_mmu_page *page_head)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> ASSERT(is_empty_shadow_page(page_head->spt));
> list_del(&page_head->link);
> __free_page(virt_to_page(page_head->spt));
> __free_page(virt_to_page(page_head->gfns));
> kfree(page_head);
> - ++kvm->n_free_mmu_pages;
> + ++kvm_x86->n_free_mmu_pages;
> }
The mmu functions should probably take kvm_x86 since this won't be
shared with any other architecture.
Regards,
Anthony Liguori
>
> static unsigned kvm_page_table_hashfn(gfn_t gfn)
> @@ -543,8 +545,9 @@ static struct kvm_mmu_page *kvm_mmu_allo
> u64 *parent_pte)
> {
> struct kvm_mmu_page *page;
> -
> - if (!vcpu->kvm->n_free_mmu_pages)
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> +
> + if (!kvm_x86->n_free_mmu_pages)
> return NULL;
>
> page = mmu_memory_cache_alloc(&vcpu->mmu_page_header_cache,
> @@ -552,12 +555,12 @@ static struct kvm_mmu_page *kvm_mmu_allo
> page->spt = mmu_memory_cache_alloc(&vcpu->mmu_page_cache, PAGE_SIZE);
> page->gfns = mmu_memory_cache_alloc(&vcpu->mmu_page_cache, PAGE_SIZE);
> set_page_private(virt_to_page(page->spt), (unsigned long)page);
> - list_add(&page->link, &vcpu->kvm->active_mmu_pages);
> + list_add(&page->link, &kvm_x86->active_mmu_pages);
> ASSERT(is_empty_shadow_page(page->spt));
> page->slot_bitmap = 0;
> page->multimapped = 0;
> page->parent_pte = parent_pte;
> - --vcpu->kvm->n_free_mmu_pages;
> + --kvm_x86->n_free_mmu_pages;
> return page;
> }
>
> @@ -643,10 +646,11 @@ static struct kvm_mmu_page *kvm_mmu_look
> struct hlist_head *bucket;
> struct kvm_mmu_page *page;
> struct hlist_node *node;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
>
> pgprintk("%s: looking for gfn %lx\n", __FUNCTION__, gfn);
> index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
> - bucket = &kvm->mmu_page_hash[index];
> + bucket = &kvm_x86->mmu_page_hash[index];
> hlist_for_each_entry(page, node, bucket, hash_link)
> if (page->gfn == gfn && !page->role.metaphysical) {
> pgprintk("%s: found role %x\n",
> @@ -670,6 +674,7 @@ static struct kvm_mmu_page *kvm_mmu_get_
> struct hlist_head *bucket;
> struct kvm_mmu_page *page;
> struct hlist_node *node;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
>
> role.word = 0;
> role.glevels = vcpu->mmu.root_level;
> @@ -684,7 +689,7 @@ static struct kvm_mmu_page *kvm_mmu_get_
> pgprintk("%s: looking gfn %lx role %x\n", __FUNCTION__,
> gfn, role.word);
> index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
> - bucket = &vcpu->kvm->mmu_page_hash[index];
> + bucket = &kvm_x86->mmu_page_hash[index];
> hlist_for_each_entry(page, node, bucket, hash_link)
> if (page->gfn == gfn && page->role.word == role.word) {
> mmu_page_add_parent_pte(vcpu, page, parent_pte);
> @@ -754,6 +759,7 @@ static void kvm_mmu_zap_page(struct kvm
> struct kvm_mmu_page *page)
> {
> u64 *parent_pte;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
>
> ++kvm->stat.mmu_shadow_zapped;
> while (page->multimapped || page->parent_pte) {
> @@ -775,7 +781,7 @@ static void kvm_mmu_zap_page(struct kvm
> hlist_del(&page->hash_link);
> kvm_mmu_free_page(kvm, page);
> } else
> - list_move(&page->link, &kvm->active_mmu_pages);
> + list_move(&page->link, &kvm_x86->active_mmu_pages);
> kvm_mmu_reset_last_pte_updated(kvm);
> }
>
> @@ -785,36 +791,39 @@ static void kvm_mmu_zap_page(struct kvm
> */
> void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> /*
> * If we set the number of mmu pages to be smaller be than the
> * number of actived pages , we must to free some mmu pages before we
> * change the value
> */
>
> - if ((kvm->n_alloc_mmu_pages - kvm->n_free_mmu_pages) >
> + if ((kvm_x86->n_alloc_mmu_pages - kvm_x86->n_free_mmu_pages) >
> kvm_nr_mmu_pages) {
> - int n_used_mmu_pages = kvm->n_alloc_mmu_pages
> - - kvm->n_free_mmu_pages;
> + int n_used_mmu_pages = kvm_x86->n_alloc_mmu_pages
> + - kvm_x86->n_free_mmu_pages;
>
> while (n_used_mmu_pages > kvm_nr_mmu_pages) {
> struct kvm_mmu_page *page;
>
> - page = container_of(kvm->active_mmu_pages.prev,
> + page = container_of(kvm_x86->active_mmu_pages.prev,
> struct kvm_mmu_page, link);
> kvm_mmu_zap_page(kvm, page);
> n_used_mmu_pages--;
> }
> - kvm->n_free_mmu_pages = 0;
> + kvm_x86->n_free_mmu_pages = 0;
> }
> else
> - kvm->n_free_mmu_pages += kvm_nr_mmu_pages
> - - kvm->n_alloc_mmu_pages;
> -
> - kvm->n_alloc_mmu_pages = kvm_nr_mmu_pages;
> + kvm_x86->n_free_mmu_pages += kvm_nr_mmu_pages
> + - kvm_x86->n_alloc_mmu_pages;
> +
> + kvm_x86->n_alloc_mmu_pages = kvm_nr_mmu_pages;
> }
>
> static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> unsigned index;
> struct hlist_head *bucket;
> struct kvm_mmu_page *page;
> @@ -824,7 +833,7 @@ static int kvm_mmu_unprotect_page(struct
> pgprintk("%s: looking for gfn %lx\n", __FUNCTION__, gfn);
> r = 0;
> index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
> - bucket = &kvm->mmu_page_hash[index];
> + bucket = &kvm_x86->mmu_page_hash[index];
> hlist_for_each_entry_safe(page, node, n, bucket, hash_link)
> if (page->gfn == gfn && !page->role.metaphysical) {
> pgprintk("%s: gfn %lx role %x\n", __FUNCTION__, gfn,
> @@ -1251,6 +1260,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *
> void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
> const u8 *new, int bytes)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> gfn_t gfn = gpa >> PAGE_SHIFT;
> struct kvm_mmu_page *page;
> struct hlist_node *node, *n;
> @@ -1280,7 +1290,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *
> vcpu->last_pte_updated = NULL;
> }
> index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES;
> - bucket = &vcpu->kvm->mmu_page_hash[index];
> + bucket = &kvm_x86->mmu_page_hash[index];
> hlist_for_each_entry_safe(page, node, n, bucket, hash_link) {
> if (page->gfn != gfn || page->role.metaphysical)
> continue;
> @@ -1344,10 +1354,12 @@ int kvm_mmu_unprotect_page_virt(struct k
>
> void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
> {
> - while (vcpu->kvm->n_free_mmu_pages < KVM_REFILL_PAGES) {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> +
> + while (kvm_x86->n_free_mmu_pages < KVM_REFILL_PAGES) {
> struct kvm_mmu_page *page;
>
> - page = container_of(vcpu->kvm->active_mmu_pages.prev,
> + page = container_of(kvm_x86->active_mmu_pages.prev,
> struct kvm_mmu_page, link);
> kvm_mmu_zap_page(vcpu->kvm, page);
> ++vcpu->kvm->stat.mmu_recycled;
> @@ -1397,9 +1409,10 @@ static void free_mmu_pages(struct kvm_vc
> static void free_mmu_pages(struct kvm_vcpu *vcpu)
> {
> struct kvm_mmu_page *page;
> -
> - while (!list_empty(&vcpu->kvm->active_mmu_pages)) {
> - page = container_of(vcpu->kvm->active_mmu_pages.next,
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> +
> + while (!list_empty(&kvm_x86->active_mmu_pages)) {
> + page = container_of(kvm_x86->active_mmu_pages.next,
> struct kvm_mmu_page, link);
> kvm_mmu_zap_page(vcpu->kvm, page);
> }
> @@ -1408,15 +1421,16 @@ static void free_mmu_pages(struct kvm_vc
>
> static int alloc_mmu_pages(struct kvm_vcpu *vcpu)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> struct page *page;
> int i;
>
> ASSERT(vcpu);
>
> - if (vcpu->kvm->n_requested_mmu_pages)
> - vcpu->kvm->n_free_mmu_pages = vcpu->kvm->n_requested_mmu_pages;
> + if (kvm_x86->n_requested_mmu_pages)
> + kvm_x86->n_free_mmu_pages = kvm_x86->n_requested_mmu_pages;
> else
> - vcpu->kvm->n_free_mmu_pages = vcpu->kvm->n_alloc_mmu_pages;
> + kvm_x86->n_free_mmu_pages = kvm_x86->n_alloc_mmu_pages;
> /*
> * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64.
> * Therefore we need to allocate shadow page tables in the first
> @@ -1464,8 +1478,9 @@ void kvm_mmu_slot_remove_write_access(st
> void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
> {
> struct kvm_mmu_page *page;
> -
> - list_for_each_entry(page, &kvm->active_mmu_pages, link) {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + list_for_each_entry(page, &kvm_x86->active_mmu_pages, link) {
> int i;
> u64 *pt;
>
> @@ -1483,8 +1498,9 @@ void kvm_mmu_zap_all(struct kvm *kvm)
> void kvm_mmu_zap_all(struct kvm *kvm)
> {
> struct kvm_mmu_page *page, *node;
> -
> - list_for_each_entry_safe(page, node, &kvm->active_mmu_pages, link)
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + list_for_each_entry_safe(page, node, &kvm_x86->active_mmu_pages, link)
> kvm_mmu_zap_page(kvm, page);
>
> kvm_flush_remote_tlbs(kvm);
> @@ -1637,7 +1653,7 @@ static int count_writable_mappings(struc
> struct kvm_mmu_page *page;
> int i;
>
> - list_for_each_entry(page, &vcpu->kvm->active_mmu_pages, link) {
> + list_for_each_entry(page, &kvm_x86->active_mmu_pages, link) {
> u64 *pt = page->spt;
>
> if (page->role.level != PT_PAGE_TABLE_LEVEL)
> @@ -1672,8 +1688,9 @@ static void audit_write_protection(struc
> struct kvm_memory_slot *slot;
> unsigned long *rmapp;
> gfn_t gfn;
> -
> - list_for_each_entry(page, &vcpu->kvm->active_mmu_pages, link) {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + list_for_each_entry(page, &kvm_x86->active_mmu_pages, link) {
> if (page->role.metaphysical)
> continue;
>
> diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
> --- a/drivers/kvm/vmx.c
> +++ b/drivers/kvm/vmx.c
> @@ -1141,12 +1141,14 @@ static void enter_pmode(struct kvm_vcpu
>
> static gva_t rmode_tss_base(struct kvm *kvm)
> {
> - if (!kvm->tss_addr) {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + if (!kvm_x86->tss_addr) {
> gfn_t base_gfn = kvm->memslots[0].base_gfn +
> kvm->memslots[0].npages - 3;
> return base_gfn << PAGE_SHIFT;
> }
> - return kvm->tss_addr;
> + return kvm_x86->tss_addr;
> }
>
> static void fix_rmode_seg(int seg, struct kvm_save_segment *save)
> @@ -1768,6 +1770,7 @@ static void do_interrupt_requests(struct
>
> static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> int ret;
> struct kvm_userspace_memory_region tss_mem = {
> .slot = 8,
> @@ -1779,7 +1782,7 @@ static int vmx_set_tss_addr(struct kvm *
> ret = kvm_set_memory_region(kvm, &tss_mem, 0);
> if (ret)
> return ret;
> - kvm->tss_addr = addr;
> + kvm_x86->tss_addr = addr;
> return 0;
> }
>
> diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c
> --- a/drivers/kvm/x86.c
> +++ b/drivers/kvm/x86.c
> @@ -815,13 +815,15 @@ static int kvm_vm_ioctl_set_nr_mmu_pages
> static int kvm_vm_ioctl_set_nr_mmu_pages(struct kvm *kvm,
> u32 kvm_nr_mmu_pages)
> {
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> if (kvm_nr_mmu_pages < KVM_MIN_ALLOC_MMU_PAGES)
> return -EINVAL;
>
> mutex_lock(&kvm->lock);
>
> kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages);
> - kvm->n_requested_mmu_pages = kvm_nr_mmu_pages;
> + kvm_x86->n_requested_mmu_pages = kvm_nr_mmu_pages;
>
> mutex_unlock(&kvm->lock);
> return 0;
> @@ -829,7 +831,9 @@ static int kvm_vm_ioctl_set_nr_mmu_pages
>
> static int kvm_vm_ioctl_get_nr_mmu_pages(struct kvm *kvm)
> {
> - return kvm->n_alloc_mmu_pages;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + return kvm_x86->n_alloc_mmu_pages;
> }
>
> /*
> @@ -972,6 +976,7 @@ long kvm_arch_vm_ioctl(struct file *filp
> unsigned int ioctl, unsigned long arg)
> {
> struct kvm *kvm = filp->private_data;
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> void __user *argp = (void __user *)arg;
> int r = -EINVAL;
>
> @@ -1018,12 +1023,12 @@ long kvm_arch_vm_ioctl(struct file *filp
> }
> case KVM_CREATE_IRQCHIP:
> r = -ENOMEM;
> - kvm->vpic = kvm_create_pic(kvm);
> - if (kvm->vpic) {
> + kvm_x86->vpic = kvm_create_pic(kvm);
> + if (kvm_x86->vpic) {
> r = kvm_ioapic_init(kvm);
> if (r) {
> - kfree(kvm->vpic);
> - kvm->vpic = NULL;
> + kfree(kvm_x86->vpic);
> + kvm_x86->vpic = NULL;
> goto out;
> }
> } else
> @@ -1041,7 +1046,7 @@ long kvm_arch_vm_ioctl(struct file *filp
> kvm_pic_set_irq(pic_irqchip(kvm),
> irq_event.irq,
> irq_event.level);
> - kvm_ioapic_set_irq(kvm->vioapic,
> + kvm_ioapic_set_irq(kvm_x86->vioapic,
> irq_event.irq,
> irq_event.level);
> mutex_unlock(&kvm->lock);
> @@ -2603,14 +2608,14 @@ void kvm_arch_vcpu_uninit(struct kvm_vcp
>
> struct kvm *kvm_arch_create_vm(void)
> {
> - struct kvm *kvm = kzalloc(sizeof(struct kvm), GFP_KERNEL);
> -
> - if (!kvm)
> + struct kvm_x86 *kvm_x86 = kzalloc(sizeof(struct kvm_x86), GFP_KERNEL);
> +
> + if (!kvm_x86)
> return ERR_PTR(-ENOMEM);
>
> - INIT_LIST_HEAD(&kvm->active_mmu_pages);
> -
> - return kvm;
> + INIT_LIST_HEAD(&kvm_x86->active_mmu_pages);
> +
> + return &kvm_x86->kvm;
> }
>
> static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu)
> @@ -2641,8 +2646,10 @@ static void kvm_free_vcpus(struct kvm *k
>
> void kvm_arch_destroy_vm(struct kvm *kvm)
> {
> - kfree(kvm->vpic);
> - kfree(kvm->vioapic);
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + kfree(kvm_x86->vpic);
> + kfree(kvm_x86->vioapic);
> kvm_free_vcpus(kvm);
> kvm_free_physmem(kvm);
> kfree(kvm);
> diff --git a/drivers/kvm/x86.h b/drivers/kvm/x86.h
> --- a/drivers/kvm/x86.h
> +++ b/drivers/kvm/x86.h
> @@ -155,6 +155,45 @@ struct kvm_vcpu {
>
> struct x86_emulate_ctxt emulate_ctxt;
> };
> +
> +struct kvm_x86 {
> + struct kvm kvm;
> + /*
> + * Hash table of struct kvm_mmu_page.
> + */
> + struct list_head active_mmu_pages;
> + unsigned int n_free_mmu_pages;
> + unsigned int n_requested_mmu_pages;
> + unsigned int n_alloc_mmu_pages;
> + struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
> + struct kvm_pic *vpic;
> + struct kvm_ioapic *vioapic;
> + unsigned int tss_addr;
> +};
> +
> +static struct kvm_x86 *to_kvm_x86(struct kvm *kvm)
> +{
> + return container_of(kvm, struct kvm_x86, kvm);
> +}
> +
> +static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
> +{
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + return kvm_x86->vpic;
> +}
> +
> +static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm)
> +{
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(kvm);
> +
> + return kvm_x86->vioapic;
> +}
> +
> +static inline int irqchip_in_kernel(struct kvm *kvm)
> +{
> + return pic_irqchip(kvm) != NULL;
> +}
>
> struct kvm_x86_ops {
> int (*cpu_has_kvm_support)(void); /* __init */
> @@ -313,7 +352,9 @@ int kvm_mmu_page_fault(struct kvm_vcpu *
>
> static inline void kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
> {
> - if (unlikely(vcpu->kvm->n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES))
> + struct kvm_x86 *kvm_x86 = to_kvm_x86(vcpu->kvm);
> +
> + if (unlikely(kvm_x86->n_free_mmu_pages < KVM_MIN_FREE_MMU_PAGES))
> __kvm_mmu_free_some_pages(vcpu);
> }
>
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Microsoft
> Defy all challenges. Microsoft(R) Visual Studio 2005.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> kvm-devel mailing list
> kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> https://lists.sourceforge.net/lists/listinfo/kvm-devel
>
>
-------------------------------------------------------------------------
SF.Net email is sponsored by: The Future of Linux Business White Paper
from Novell. From the desktop to the data center, Linux is going
mainstream. Let it simplify your IT future.
http://altfarm.mediaplex.com/ad/ck/8857-50307-18918-4
next prev parent reply other threads:[~2007-11-28 21:20 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-20 16:57 [PATCH 0 of 3] create kvm_x86 Hollis Blanchard
2007-11-20 16:57 ` [PATCH 1 of 3] Use kvm_x86 to hold x86 specific kvm fields Hollis Blanchard
2007-11-28 21:20 ` Anthony Liguori [this message]
2007-11-28 21:20 ` Anthony Liguori
[not found] ` <474DDB97.6090400-rdkfGonbjUSkNkDKm+mE6A@public.gmane.org>
2007-11-28 21:43 ` [kvm-ppc-devel] [kvm-devel] [PATCH 1 of 3] Use kvm_x86 to hold Hollis Blanchard
2007-11-28 21:43 ` [PATCH 1 of 3] Use kvm_x86 to hold x86 specific kvm fields Hollis Blanchard
2007-11-20 16:57 ` [PATCH 2 of 3] Move vm_stat and apic_access_page to kvm_x86 Hollis Blanchard
2007-11-21 9:09 ` [PATCH 0 of 3] create kvm_x86 Carsten Otte
[not found] ` <4743F5AE.8090707-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org>
2007-11-21 9:18 ` Avi Kivity
[not found] ` <4743F7DF.4000107-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-11-21 9:32 ` Amit Shah
2007-11-21 9:44 ` [kvm-ppc-devel] [kvm-devel] " Amit Shah
2007-11-21 9:39 ` Carsten Otte
2007-11-21 9:42 ` Zhang, Xiantao
[not found] ` <42DFA526FC41B1429CE7279EF83C6BDC9E7193-wq7ZOvIWXbMAbVU2wMM1CrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-11-21 9:55 ` Avi Kivity
2007-11-28 21:15 ` [kvm-ppc-devel] [kvm-devel] " Hollis Blanchard
2007-11-28 21:15 ` Hollis Blanchard
2007-11-30 7:26 ` [kvm-ppc-devel] [kvm-devel] " Avi Kivity
2007-11-30 7:26 ` Avi Kivity
[not found] ` <474FBB17.6080800-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-11-30 8:36 ` [kvm-ppc-devel] [kvm-devel] " Zhang, Xiantao
2007-11-30 8:36 ` Zhang, Xiantao
[not found] ` <42DFA526FC41B1429CE7279EF83C6BDCA397C1-wq7ZOvIWXbMAbVU2wMM1CrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2007-11-30 9:04 ` [kvm-ppc-devel] [kvm-devel] " Avi Kivity
2007-11-30 9:04 ` Avi Kivity
[not found] ` <474FD234.5060203-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-11-30 11:42 ` [kvm-ppc-devel] [kvm-devel] " Zhang, Xiantao
2007-11-30 11:42 ` Zhang, Xiantao
2007-11-30 18:43 ` [kvm-ppc-devel] [kvm-devel] " Hollis Blanchard
2007-11-30 18:43 ` Hollis Blanchard
2007-11-30 20:31 ` [kvm-ppc-devel] [kvm-devel] " Avi Kivity
2007-11-30 20:31 ` Avi Kivity
[not found] ` <4750732B.7070502-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-11-30 21:09 ` [kvm-ppc-devel] [kvm-devel] " Hollis Blanchard
2007-11-30 21:09 ` Hollis Blanchard
2007-11-30 21:43 ` [kvm-ppc-devel] [kvm-devel] " Anthony Liguori
2007-11-30 21:43 ` Anthony Liguori
[not found] ` <47508408.8050202-rdkfGonbjUSkNkDKm+mE6A@public.gmane.org>
2007-11-30 22:08 ` [kvm-ppc-devel] [kvm-devel] " Hollis Blanchard
2007-11-30 22:08 ` Hollis Blanchard
2007-12-01 10:04 ` [kvm-ppc-devel] [kvm-devel] " Avi Kivity
2007-12-01 10:04 ` Avi Kivity
2007-12-01 10:02 ` [kvm-ppc-devel] [kvm-devel] " Avi Kivity
2007-12-01 10:02 ` 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=474DDB97.6090400@codemonkey.ws \
--to=anthony@codemonkey.ws \
--cc=avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org \
--cc=carsteno-tA70FqPdS9bQT0dZR+AlfA@public.gmane.org \
--cc=hollisb-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=kvm-ppc-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=xiantao.zhang-ral2JQCrhuEAvxtiuMwx3w@public.gmane.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 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.