From patchwork Wed Mar 24 21:24:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Tosatti X-Patchwork-Id: 88066 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o2OLTekH014216 for ; Wed, 24 Mar 2010 21:29:41 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753467Ab0CXV3Y (ORCPT ); Wed, 24 Mar 2010 17:29:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:64479 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753001Ab0CXV3X (ORCPT ); Wed, 24 Mar 2010 17:29:23 -0400 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o2OLTM6q024577 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 24 Mar 2010 17:29:23 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o2OLTMSA001790; Wed, 24 Mar 2010 17:29:22 -0400 Received: from amt.cnet (vpn-10-46.rdu.redhat.com [10.11.10.46]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o2OLTKK2008899; Wed, 24 Mar 2010 17:29:21 -0400 Received: from amt.cnet (amt.cnet [127.0.0.1]) by amt.cnet (Postfix) with ESMTP id B231E68AC6A; Wed, 24 Mar 2010 18:28:15 -0300 (BRT) Received: (from marcelo@localhost) by amt.cnet (8.14.3/8.14.3/Submit) id o2OLSExA022416; Wed, 24 Mar 2010 18:28:14 -0300 Message-Id: <20100324212726.503850241@amt.cnet> User-Agent: quilt/0.47-1 Date: Wed, 24 Mar 2010 18:24:14 -0300 From: Marcelo Tosatti To: kvm@vger.kernel.org Cc: Marcelo Tosatti Subject: [patch 6/8] test: parallel faults vs slot deletion References: <20100324212408.790319364@amt.cnet> Content-Disposition: inline; filename=test-slot-deletion X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 24 Mar 2010 21:29:41 +0000 (UTC) Index: qemu-kvm/kvm/user/config-x86-common.mak =================================================================== --- qemu-kvm.orig/kvm/user/config-x86-common.mak +++ qemu-kvm/kvm/user/config-x86-common.mak @@ -42,6 +42,9 @@ $(TEST_DIR)/sieve.flat: $(cstart.o) $(TE $(TEST_DIR)/print.o $(TEST_DIR)/vm.o $(TEST_DIR)/vmexit.flat: $(cstart.o) $(TEST_DIR)/vmexit.o + +$(TEST_DIR)/slot_deletion.flat: $(cstart.o) $(TEST_DIR)/slot_deletion.o \ + $(TEST_DIR)/print.o $(TEST_DIR)/vm.o $(TEST_DIR)/test32.flat: $(TEST_DIR)/test32.o Index: qemu-kvm/kvm/user/config-x86_64.mak =================================================================== --- qemu-kvm.orig/kvm/user/config-x86_64.mak +++ qemu-kvm/kvm/user/config-x86_64.mak @@ -7,6 +7,7 @@ CFLAGS += -D__x86_64__ tests = $(TEST_DIR)/access.flat $(TEST_DIR)/sieve.flat \ $(TEST_DIR)/simple.flat $(TEST_DIR)/stringio.flat \ $(TEST_DIR)/memtest1.flat $(TEST_DIR)/emulator.flat \ - $(TEST_DIR)/hypercall.flat $(TEST_DIR)/apic.flat + $(TEST_DIR)/hypercall.flat $(TEST_DIR)/apic.flat \ + $(TEST_DIR)/slot_deletion.flat include config-x86-common.mak Index: qemu-kvm/kvm/user/test/x86/slot_deletion.c =================================================================== --- /dev/null +++ qemu-kvm/kvm/user/test/x86/slot_deletion.c @@ -0,0 +1,130 @@ +/* test parallel faults vs slot deletion */ + +#include "libcflat.h" +#include "vm.h" +#include "smp.h" + +static unsigned int inl(unsigned short port) +{ + unsigned int val; + asm volatile ("inl %w1, %0":"=a" (val):"Nd" (port)); + return val; +} + +static void outl(unsigned int data, unsigned short port) +{ + asm volatile ("outl %0, %1"::"a" (data), "d" (port)); +} + +static int write_mem_slot (unsigned long start, unsigned long end) +{ + outl(start, 0x2018); + outl((unsigned long) start >> 32, 0x201c); + + outl(end, 0x2020); + outl((unsigned long) end >> 32, 0x2024); + return 0; +} + +#define CMD_CREATE_SLOT 0x0 +#define CMD_DELETE_SLOT 0x1 + +int create_mem_slot(unsigned long start, unsigned long end) +{ + write_mem_slot (start, end); + outl(CMD_CREATE_SLOT, 0x2028); + return 0; +} + +int delete_mem_slot(unsigned long start, unsigned long end) +{ + write_mem_slot (start, end); + outl(CMD_DELETE_SLOT, 0x2028); + return 0; +} + +void map_addr_with_pte_phys(void *virt_addr, unsigned long pte_phys, + void *target_page) +{ + /* 1:1 map the pagetable inside memslot */ + install_page(phys_to_virt(read_cr3()), pte_phys, (void *)pte_phys); + install_pte(phys_to_virt(read_cr3()), 1, virt_addr, + virt_to_phys(target_page) | PTE_PRESENT | PTE_WRITE, + (void *) pte_phys); +} + +#define define_barrier(x) int count_##x = 0; \ +static void barrier_##x(void) { \ + count_##x++; \ + while (count_##x < cpu_count()); \ +} + +define_barrier(cr3); +define_barrier(fault); +define_barrier(done); + +static void fault_vaddr(void *data) +{ + unsigned long *target_map = data; + + barrier_fault(); + *target_map = 0; + barrier_done(); +} + +void run_test(void) +{ + unsigned long start, end, pte_phys; + void *target_page, *virt_addr; + int i; + + start = inl(0xd1); + end = start + (PAGE_SIZE * 1000); + create_mem_slot(start, end); + target_page = alloc_page(); + + pte_phys = start; + virt_addr = (void *) 0xfffffa000; + for (i = 2; i <= cpu_count(); i++) { + map_addr_with_pte_phys(virt_addr, pte_phys, target_page); + pte_phys += PAGE_SIZE; + virt_addr += PAGE_SIZE * 512; + } + + count_fault = 0; + count_done = 0; + pte_phys = start; + virt_addr = (void *)0xfffffa000; + for (i = 2; i <= cpu_count(); i++) { + on_cpu_noipi(i-1, fault_vaddr, virt_addr); + pte_phys += PAGE_SIZE; + virt_addr += PAGE_SIZE * 512; + } + + barrier_fault(); + delete_mem_slot(start, end); + barrier_done(); +} + +static void setup_cr3 (void *cr3) +{ + load_cr3(virt_to_phys(cr3)); + barrier_cr3(); +} + +int main (void) +{ + int i; + + setup_vm(); + for (i = 2; i <= cpu_count(); i++) + on_cpu_noipi(i-1, setup_cr3, (void *)read_cr3()); + + barrier_cr3(); + + for (i = 0; i < 100; i++) + run_test(); + + printf("SUCCESS\n"); + return 0; +}