From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757933AbbE3LCm (ORCPT ); Sat, 30 May 2015 07:02:42 -0400 Received: from mga03.intel.com ([134.134.136.65]:7660 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932602AbbE3LCU (ORCPT ); Sat, 30 May 2015 07:02:20 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,522,1427785200"; d="c'?scan'208";a="734141472" Message-ID: <556997D6.7020105@linux.intel.com> Date: Sat, 30 May 2015 18:58:30 +0800 From: Xiao Guangrong User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: pbonzini@redhat.com CC: gleb@kernel.org, mtosatti@redhat.com, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 00/15] KVM: x86: fully implement vMTRR References: <1432983566-15773-1-git-send-email-guangrong.xiao@linux.intel.com> In-Reply-To: <1432983566-15773-1-git-send-email-guangrong.xiao@linux.intel.com> Content-Type: multipart/mixed; boundary="------------020608050907020306000902" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This is a multi-part message in MIME format. --------------020608050907020306000902 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit On 05/30/2015 06:59 PM, Xiao Guangrong wrote: > Currently guest MTRR is completely prohibited if cache snoop is supported on > IOMMU (!noncoherent_dma) and host does the emulation based on the knowledge > from host side, however, host side is not the good point to know > what the purpose of guest is. A good example is that pass-throughed VGA > frame buffer is not always UC as host expected > > Besides that, there is a bugs in current code if noncoherent_dma is detected: > KVM still uses hugepage even if the 4K pages in that ranges span between > on different memory types and uses the cache type of first page to do memory > mapping > > This patchset enables full MTRR virtualization and currently only works on > Intel EPT architecture > > There is the code will be attached in this thread is used to check the effect > of this patchset: > [12834.843439] __INIT__. > [12835.909109] Running in preload MTRR_TYPE_UNCACHABLE 4753900 ns. > [12835.915232] Running in MTRR_TYPE_UNCACHABLE 5257522 ns. > [12838.083948] Running in preload MTRR_TYPE_WRBACK 13266 ns. > [12838.084998] Running in MTRR_TYPE_WRBACK 13099 ns. > Has been attached in this mail. --------------020608050907020306000902 Content-Type: text/x-csrc; name="main.c" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="main.c" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_MTRR #include #endif //#define DEBUG #ifdef DEBUG #define dprintk(fmt, args...) \ printk(fmt, ##args) #define debug_show_mtrr() show_mtrr() #else //#define pr_debug(format, ...) do {} while (0) #define dprintk(fmt, ...) do {} while (0) #define debug_show_mtrr() do {} while (0) #endif MODULE_LICENSE("GPL"); #define NR_PAGES_ORDER 1 static u64 __do_write(struct page *page, int page_nr) { void *addr = page_address(page); u64 total = 0; int i; for (i = 0; i < PAGE_SIZE * page_nr; i++) { ((char *)addr)[i] = (char)0x99; } return total; } static u64 __do_read(struct page *page, int page_nr) { void *addr = page_address(page); u64 total = 0; int i; for (i = 0; i < PAGE_SIZE * page_nr; i++) { total += ((char *)addr)[i]; if (((char *)addr)[i] != (char)0x99) { printk("read failed %x expected 0x99.\n", ((char *)addr)[i]); break; } } return total; } static void do_rw(struct page *page, int page_nr, const char *cachetype) { ktime_t start, end; u64 total; start = ktime_get(); __do_write(page, page_nr); total = __do_read(page, page_nr); end = ktime_get(); printk("Running in %s %lld ns.\n", cachetype, ktime_to_ns(ktime_sub(end, start))); } static int add_region_to_mtrr(struct page *page, int page_nr, int type, const char *cachetype) { unsigned long pfn; int ret; pfn = page_to_pfn(page); ret = mtrr_add(pfn << PAGE_SHIFT, PAGE_SIZE * page_nr, type, 1); if (ret < 0) printk("mtrr_add %s failed, return %d.\n", cachetype, ret); dprintk("%s add region %lx nrpage %d.\n", cachetype, pfn << PAGE_SHIFT, page_nr); return ret; } static int del_region_from_mtrr(int entry, struct page *page, int page_nr, const char *cachetype) { unsigned long pfn; int ret; pfn = page_to_pfn(page); ret = mtrr_del(entry, pfn << PAGE_SHIFT, PAGE_SIZE * page_nr); if (ret < 0) printk("mtrr_del %s failed, return %d.\n", cachetype, ret); dprintk("%s del region %lx nrpage %d.\n", cachetype, pfn << PAGE_SHIFT, page_nr); return ret; } static int memory_rw(void) { struct page *page; int page_order, page_nr, ret; page_order = NR_PAGES_ORDER; page_nr = 1 << page_order; page = alloc_pages(GFP_KERNEL, page_order); if (!page) return -ENOMEM; ret = add_region_to_mtrr(page, page_nr, MTRR_TYPE_UNCACHABLE, "MTRR_TYPE_UNCACHABLE"); if (ret < 0) goto exit; do_rw(page, page_nr, "preload MTRR_TYPE_UNCACHABLE"); do_rw(page, page_nr, "MTRR_TYPE_UNCACHABLE"); ret = del_region_from_mtrr(ret, page, page_nr, "MTRR_TYPE_UNCACHABLE"); if (ret < 0) goto exit; ret = add_region_to_mtrr(page, page_nr, MTRR_TYPE_WRBACK, "MTRR_TYPE_WRBACK"); if (ret < 0) goto exit; do_rw(page, page_nr, "preload MTRR_TYPE_WRBACK"); do_rw(page, page_nr, "MTRR_TYPE_WRBACK"); ret = del_region_from_mtrr(ret, page, page_nr, "MTRR_TYPE_WRBACK"); if (ret < 0) goto exit; ret = 0; exit: __free_pages(page, page_order); return ret; } static int __init my_init(void) { printk("__INIT__.\n"); dprintk("######### INIT MTRR...\n"); return memory_rw(); } static void __exit my_exit(void) { dprintk("###### EXIT MTRR...\n"); return; } module_init(my_init) module_exit(my_exit) --------------020608050907020306000902--