Re: QEMU, MCE, unpoison memory address across reboot

2010-12-28 Thread Avi Kivity

On 12/27/2010 11:27 PM, Marcelo Tosatti wrote:

On Sun, Dec 26, 2010 at 02:27:26PM +0200, Avi Kivity wrote:
 +static void kvm_unpoison_all(void *param)
 +{
 +HWPoisonPage *page, *next_page;
 +unsigned long address;
 +KVMState *s = param;
 +
 +QLIST_FOREACH_SAFE(page,hwpoison_page_list, list, next_page) {
 +address = (unsigned long)page-vaddr;
 +QLIST_REMOVE(page, list);
 +kvm_vm_ioctl(s, KVM_UNPOISON_ADDRESS, address);
 +qemu_free(page);
 +}
 +}
  
  Can't you free and reallocate all guest memory instead, on reboot, if
  there's a hwpoisoned page? Then you don't need this interface.
  

  Alternatively, MADV_DONTNEED?  We already use it for ballooning.

Does not work for hugetlbfs.



True.  We can munmap() the page (extending it to the huge page size in 
effect), and then mmap() it back in.  The kernel should merge the new 
vma with its neighbors.


--
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: QEMU, MCE, unpoison memory address across reboot

2010-12-28 Thread Gleb Natapov
On Mon, Dec 27, 2010 at 07:27:54PM -0200, Marcelo Tosatti wrote:
 On Sun, Dec 26, 2010 at 02:27:26PM +0200, Avi Kivity wrote:
+static void kvm_unpoison_all(void *param)
+{
+HWPoisonPage *page, *next_page;
+unsigned long address;
+KVMState *s = param;
+
+QLIST_FOREACH_SAFE(page,hwpoison_page_list, list, next_page) {
+address = (unsigned long)page-vaddr;
+QLIST_REMOVE(page, list);
+kvm_vm_ioctl(s, KVM_UNPOISON_ADDRESS, address);
+qemu_free(page);
+}
+}
  
  Can't you free and reallocate all guest memory instead, on reboot, if
  there's a hwpoisoned page? Then you don't need this interface.
  
  
  Alternatively, MADV_DONTNEED?  We already use it for ballooning.
 
 Does not work for hugetlbfs.
 
Don't we break huge page to 4k pages during poisoning?

--
Gleb.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: QEMU, MCE, unpoison memory address across reboot

2010-12-28 Thread Huang Ying
On Tue, 2010-12-28 at 16:27 +0800, Gleb Natapov wrote:
 On Mon, Dec 27, 2010 at 07:27:54PM -0200, Marcelo Tosatti wrote:
  On Sun, Dec 26, 2010 at 02:27:26PM +0200, Avi Kivity wrote:
 +static void kvm_unpoison_all(void *param)
 +{
 +HWPoisonPage *page, *next_page;
 +unsigned long address;
 +KVMState *s = param;
 +
 +QLIST_FOREACH_SAFE(page,hwpoison_page_list, list, next_page) {
 +address = (unsigned long)page-vaddr;
 +QLIST_REMOVE(page, list);
 +kvm_vm_ioctl(s, KVM_UNPOISON_ADDRESS, address);
 +qemu_free(page);
 +}
 +}
   
   Can't you free and reallocate all guest memory instead, on reboot, if
   there's a hwpoisoned page? Then you don't need this interface.
   
   
   Alternatively, MADV_DONTNEED?  We already use it for ballooning.
  
  Does not work for hugetlbfs.
  
 Don't we break huge page to 4k pages during poisoning?

Yes.  That has not been implemented yet.  So in fact, we can not deal
with hwpoison+hugetlb in kvm now.

Best Regards,
Huang Ying


--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: QEMU, MCE, unpoison memory address across reboot

2010-12-28 Thread Avi Kivity

On 12/28/2010 10:32 AM, Huang Ying wrote:

On Tue, 2010-12-28 at 16:11 +0800, Avi Kivity wrote:
  On 12/27/2010 11:27 PM, Marcelo Tosatti wrote:
On Sun, Dec 26, 2010 at 02:27:26PM +0200, Avi Kivity wrote:
   +static void kvm_unpoison_all(void *param)
   +{
   +HWPoisonPage *page, *next_page;
   +unsigned long address;
   +KVMState *s = param;
   +
   +QLIST_FOREACH_SAFE(page,hwpoison_page_list, list, 
next_page) {
   +address = (unsigned long)page-vaddr;
   +QLIST_REMOVE(page, list);
   +kvm_vm_ioctl(s, KVM_UNPOISON_ADDRESS, address);
   +qemu_free(page);
   +}
   +}
   
   Can't you free and reallocate all guest memory instead, on reboot, if
   there's a hwpoisoned page? Then you don't need this interface.
   

   Alternatively, MADV_DONTNEED?  We already use it for ballooning.
  
Does not work for hugetlbfs.
  

  True.  We can munmap() the page (extending it to the huge page size in
  effect), and then mmap() it back in.  The kernel should merge the new
  vma with its neighbors.

To merge the new vma with its neighbors, we need all information about
the original mmap (when doing allocating).  It appears that some
information is hided in glibc (posix_memalign).



It's likely just an anonymous mmap().

Even if it's not merged, it isn't the end of the world.  Poisoned pages 
should be very rare, and nothing bad happens from having two extra VMAs.


It is a little more complicated, we have to reissue MADV_MERGABLE etc, 
but it's better than adding new interfaces IMO.


--
error compiling committee.c: too many arguments to function

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: QEMU, MCE, unpoison memory address across reboot

2010-12-28 Thread Avi Kivity

On 12/28/2010 10:35 AM, Huang Ying wrote:

  
  Don't we break huge page to 4k pages during poisoning?

Yes.  That has not been implemented yet.  So in fact, we can not deal
with hwpoison+hugetlb in kvm now.


Should be a lot easier to deal with using transparent hugepages, since 
the break-apart function is already implemented.


--
error compiling committee.c: too many arguments to function

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[GIT PULL] kvm upstream updates

2010-12-28 Thread Avi Kivity

The following changes since commit 4cdc1cd137e0b98766916a7cdf2d5a9b3c6632fa:

  target-mips: fix host CPU consumption when guest is idle (2010-12-27 
00:58:06 +0100)


are available in the git repository at:
  git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master

Jan Kiszka (4):
  kvm: x86: Fix DPL write back of segment registers
  kvm: x86: Remove obsolete SS.RPL/DPL aligment
  kvm: x86: Prevent sign extension of DR7 in guest debugging mode
  kvm: x86: Fix a few coding style violations

Jin Dongming (6):
  Clean up cpu_inject_x86_mce()
  Add broadcast option for mce command
  Add function for checking mca broadcast of CPU
  kvm: introduce kvm_mce_in_progress
  kvm: kvm_mce_inj_* subroutines for templated error injections
  kvm: introduce kvm_inject_x86_mce_on

Lai Jiangshan (2):
  kvm: Enable user space NMI injection for kvm guest
  kvm: convert kvm_ioctl(KVM_CHECK_EXTENSION) to kvm_check_extension()

Marcelo Tosatti (1):
  Expose thread_id in info cpus

 configure |3 +
 cpu-all.h |3 +-
 cpu-defs.h|1 +
 cpus.c|5 +
 exec.c|1 +
 hmp-commands.hx   |6 +-
 kvm-all.c |2 +-
 monitor.c |   11 +-
 os-posix.c|   10 +
 os-win32.c|5 +
 osdep.h   |1 +
 target-i386/cpu.h |1 +
 target-i386/helper.c  |   76 ++-
 target-i386/kvm.c |  534 
-

 target-i386/kvm_x86.h |5 +-
 15 files changed, 416 insertions(+), 248 deletions(-)

--
error compiling committee.c: too many arguments to function

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Autotest] [KVM-AUTOTEST PATCH 03/28] KVM test: corrections to migration_with_reboot

2010-12-28 Thread Jason Wang
Michael Goldish writes:
  - Use wait_for() to try remote_login() multiple times before giving up.
  - Take VM parameters from vm.params, not params.
  

Is there any differnce between those in current context?
Other looks good, thanks.

  Signed-off-by: Michael Goldish mgold...@redhat.com
  ---
   client/tests/kvm/tests/migration_with_reboot.py |   26 
  +++---
   1 files changed, 13 insertions(+), 13 deletions(-)
  
  diff --git a/client/tests/kvm/tests/migration_with_reboot.py 
  b/client/tests/kvm/tests/migration_with_reboot.py
  index 5673b45..5070dbc 100644
  --- a/client/tests/kvm/tests/migration_with_reboot.py
  +++ b/client/tests/kvm/tests/migration_with_reboot.py
  @@ -24,7 +24,7 @@ def run_migration_with_reboot(test, params, env):
   password, prompt, linesep, log_filename, timeout):
   
   A version of reboot test which is safe to be called in the 
  background as
  -it only needs an vm object
  +it doesn't need a VM object.
   
   # Send a reboot command to the guest's shell
   session.sendline(reboot_command)
  @@ -37,12 +37,12 @@ def run_migration_with_reboot(test, params, env):
   session.close()
   
   # Try logging into the guest until timeout expires
  -logging.info(Guest is down. Waiting for it to go up again, timeout 
  %ds,
  - timeout)
  -session = kvm_utils.remote_login(client, address, port, username,
  - password, prompt, linesep,
  - log_filename, timeout)
  -
  +logging.info(Guest is down. Waiting for it to go up again, timeout 
  
  + %ds, timeout)
  +session = kvm_utils.wait_for(
  +lambda: kvm_utils.remote_login(client, address, port, username,
  +   password, prompt, linesep,
  +   log_filename), timeout, 0, 2)
   if not session:
   raise error.TestFail(Could not log into guest after reboot)
   logging.info(Guest is up again)
  @@ -53,16 +53,16 @@ def run_migration_with_reboot(test, params, env):
   session = kvm_test_utils.wait_for_login(vm, timeout=timeout)
   
   # params of reboot
  -username = params.get(username, )
  -password = params.get(password, )
  -prompt = params.get(shell_prompt, [\#\$])
  -linesep = eval('%s' % params.get(shell_linesep, r\n))
  -client = params.get(shell_client)
  +username = vm.params.get(username, )
  +password = vm.params.get(password, )
  +prompt = vm.params.get(shell_prompt, [\#\$])
  +linesep = eval('%s' % vm.params.get(shell_linesep, r\n))
  +client = vm.params.get(shell_client)
   address = vm.get_address(0)
   port = vm.get_port(int(params.get(shell_port)))
   log_filename = (migration-reboot-%s-%s.log %
   (vm.name, kvm_utils.generate_random_string(4)))
  -reboot_command = params.get(reboot_command)
  +reboot_command = vm.params.get(reboot_command)
   
   mig_timeout = float(params.get(mig_timeout, 3600))
   mig_protocol = params.get(migration_protocol, tcp)
  -- 
  1.7.3.3
  
  ___
  Autotest mailing list
  autot...@test.kernel.org
  http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Autotest] [KVM-AUTOTEST PATCH 04/28] KVM test: migration_with_reboot: use kvm_utils.Thread

2010-12-28 Thread Jason Wang
Michael Goldish writes:
  Signed-off-by: Michael Goldish mgold...@redhat.com

Looks good, thanks!

  ---
   client/tests/kvm/tests/migration_with_reboot.py |   19 +++
   1 files changed, 7 insertions(+), 12 deletions(-)
  
  diff --git a/client/tests/kvm/tests/migration_with_reboot.py 
  b/client/tests/kvm/tests/migration_with_reboot.py
  index 5070dbc..af5de64 100644
  --- a/client/tests/kvm/tests/migration_with_reboot.py
  +++ b/client/tests/kvm/tests/migration_with_reboot.py
  @@ -19,7 +19,6 @@ def run_migration_with_reboot(test, params, env):
   @param params: Dictionary with test parameters.
   @param env: Dictionary with the test environment.
   
  -
   def reboot_test(client, session, address, reboot_command, port, 
  username,
   password, prompt, linesep, log_filename, timeout):
   
  @@ -67,24 +66,20 @@ def run_migration_with_reboot(test, params, env):
   mig_timeout = float(params.get(mig_timeout, 3600))
   mig_protocol = params.get(migration_protocol, tcp)
   mig_cancel = bool(params.get(mig_cancel))
  -bg = None
   
   try:
  -# reboot the VM in background
  -bg = kvm_test_utils.BackgroundTest(reboot_test,
  -   (client, session, address,
  +# Reboot the VM in the background
  +bg = kvm_utils.Thread(reboot_test, (client, session, address,
   reboot_command, port, username,
   password, prompt, linesep,
   log_filename, timeout))
   bg.start()
   
  -while bg.is_alive():
  -# Migrate the VM
  -dest_vm = kvm_test_utils.migrate(vm, env, mig_timeout, 
  mig_protocol,
  - False)
  -vm = dest_vm
  +try:
  +while bg.is_alive():
  +vm = kvm_test_utils.migrate(vm, env, mig_timeout, 
  mig_protocol)
  +finally:
  +bg.join()
   
   finally:
  -if bg:
  -bg.join()
   session.close()
  -- 
  1.7.3.3
  
  ___
  Autotest mailing list
  autot...@test.kernel.org
  http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2][RFC] KVM: Emulate MSI-X table and PBA in kernel

2010-12-28 Thread Avi Kivity

On 12/22/2010 10:44 AM, Sheng Yang wrote:

Then we can support mask bit operation of assigned devices now.


@@ -3817,14 +3819,16 @@ static int emulator_write_emulated_onepage(unsigned 
long addr,

  mmio:
trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val);
+   r = vcpu_mmio_write(vcpu, gpa, bytes, val);
/*
 * Is this MMIO handled locally?
 */
-   if (!vcpu_mmio_write(vcpu, gpa, bytes, val))
+   if (!r)
return X86EMUL_CONTINUE;

vcpu-mmio_needed = 1;
-   vcpu-run-exit_reason = KVM_EXIT_MMIO;
+   vcpu-run-exit_reason = (r == -ENOTSYNC) ?
+   KVM_EXIT_MSIX_ROUTING_UPDATE : KVM_EXIT_MMIO;


This isn't very pretty, exit_reason should be written in 
vcpu_mmio_write().  I guess we can refactor it later.




+#define KVM_MSIX_MMIO_TYPE_ASSIGNED_DEV(1  0)
+
+#define KVM_MSIX_MMIO_TYPE_BASE_TABLE  (1  8)
+#define KVM_MSIX_MMIO_TYPE_BASE_PBA(1  9)
+
+#define KVM_MSIX_MMIO_TYPE_DEV_MASK0x00ff
+#define KVM_MSIX_MMIO_TYPE_BASE_MASK   0xff00


Any explanation of these?


+struct kvm_msix_mmio_user {
+   __u32 dev_id;
+   __u16 type;
+   __u16 max_entries_nr;
+   __u64 base_addr;
+   __u64 base_va;
+   __u64 flags;
+   __u64 reserved[4];
+};
+


+int kvm_assigned_device_update_msix_mask_bit(struct kvm *kvm,
+   int assigned_dev_id, int entry, u32 flag)
+{


Need a better name for 'flag' (and make it a bool).


+   int r = -EFAULT;
+   struct kvm_assigned_dev_kernel *adev;
+   int i;
+
+   if (!irqchip_in_kernel(kvm))
+   return r;
+
+   mutex_lock(kvm-lock);
+   adev = kvm_find_assigned_dev(kvm-arch.assigned_dev_head,
+ assigned_dev_id);
+   if (!adev)
+   goto out;
+
+   for (i = 0; i  adev-entries_nr; i++)
+   if (adev-host_msix_entries[i].entry == entry) {
+   if (flag)
+   disable_irq_nosync(
+   adev-host_msix_entries[i].vector);
+   else
+   enable_irq(adev-host_msix_entries[i].vector);
+   r = 0;
+   break;
+   }
+out:
+   mutex_unlock(kvm-lock);
+   return r;
+}

@@ -1988,6 +2008,12 @@ static int kvm_dev_ioctl_create_vm(void)
return r;
}
  #endif
+   r = kvm_register_msix_mmio_dev(kvm);
+   if (r  0) {
+   kvm_put_kvm(kvm);
+   return r;
+   }


Shouldn't this be part of individual KVM_REGISTER_MSIX_MMIO calls?


+static int msix_table_mmio_read(struct kvm_io_device *this, gpa_t addr, int 
len,
+   void *val)
+{
+   struct kvm_msix_mmio_dev *mmio_dev =
+   container_of(this, struct kvm_msix_mmio_dev, table_dev);
+   struct kvm_msix_mmio *mmio;
+   int idx, ret = 0, entry, offset, r;
+
+   mutex_lock(mmio_dev-lock);
+   idx = get_mmio_table_index(mmio_dev, addr, len);
+   if (idx  0) {
+   ret = -EOPNOTSUPP;
+   goto out;
+   }
+   if ((addr  0x3) || (len != 4  len != 8))
+   goto out;


What about (addr  4)  (len == 8)? Is it supported? It may cross entry 
boundaries.



+   mmio =mmio_dev-mmio[idx];
+
+   entry = (addr - mmio-table_base_addr) / PCI_MSIX_ENTRY_SIZE;
+   offset = addr  0xf;
+   r = copy_from_user(val, (void *)(mmio-table_base_va +
+   entry * PCI_MSIX_ENTRY_SIZE + offset), len);




+   if (r)
+   goto out;
+out:
+   mutex_unlock(mmio_dev-lock);
+   return ret;
+}
+
+static int msix_table_mmio_write(struct kvm_io_device *this, gpa_t addr,
+   int len, const void *val)
+{
+   struct kvm_msix_mmio_dev *mmio_dev =
+   container_of(this, struct kvm_msix_mmio_dev, table_dev);
+   struct kvm_msix_mmio *mmio;
+   int idx, entry, offset, ret = 0, r = 0;
+   gpa_t entry_base;
+   u32 old_ctrl, new_ctrl;
+
+   mutex_lock(mmio_dev-lock);
+   idx = get_mmio_table_index(mmio_dev, addr, len);
+   if (idx  0) {
+   ret = -EOPNOTSUPP;
+   goto out;
+   }
+   if ((addr  0x3) || (len != 4  len != 8))
+   goto out;
+   mmio =mmio_dev-mmio[idx];
+   entry = (addr - mmio-table_base_addr) / PCI_MSIX_ENTRY_SIZE;
+   entry_base = mmio-table_base_va + entry * PCI_MSIX_ENTRY_SIZE;
+   offset = addr  0xF;
+
+   if (copy_from_user(old_ctrl,
+   entry_base + PCI_MSIX_ENTRY_VECTOR_CTRL,
+   sizeof old_ctrl))
+   goto out;


get_user() is easier.


+
+   /* No allow writing to other fields when entry is unmasked */
+   if (!(old_ctrl  PCI_MSIX_ENTRY_CTRL_MASKBIT)
+   offset != PCI_MSIX_ENTRY_VECTOR_CTRL)
+   goto 

Re: FIXED: Re: [Qemu-devel] possible regression in qemu-kvm 0.13.0 (memtest)

2010-12-28 Thread Peter Lieven

 On 27.12.2010 04:51, Stefan Hajnoczi wrote:

On Sun, Dec 26, 2010 at 9:21 PM, Peter Lievenp...@dlh.net  wrote:

Am 25.12.2010 um 20:02 schrieb Peter Lieven:


Am 23.12.2010 um 03:42 schrieb Stefan Hajnoczi:


On Wed, Dec 22, 2010 at 10:02 AM, Peter Lievenp...@dlh.net  wrote:

If I start a VM with the following parameters
qemu-kvm-0.13.0 -m 2048 -smp 2 -monitor tcp:0:4014,server,nowait -vnc :14 -name 
'ubuntu.test'  -boot order=dc,menu=off  -cdrom ubuntu-10.04.1-desktop-amd64.iso 
-k de

and select memtest in the Ubuntu CD Boot Menu, the VM immediately resets. After 
this reset there happen several errors including graphic corruption or the 
qemu-kvm binary
aborting with error 134.

Exactly the same scenario on the same machine with qemu-kvm-0.12.5 works 
flawlessly.

Any ideas?

You could track down the commit which broke this using git-bisect(1).
The steps are:

$ git bisect start v0.13.0 v0.12.5

Then:

$ ./configure [...]  make
$ x86_64-softmmu/qemu-system-x86_64 -m 2048 -smp 2 -monitor
tcp:0:4014,server,nowait -vnc :14 -name 'ubuntu.test'  -boot
order=dc,menu=off  -cdrom ubuntu-10.04.1-desktop-amd64.iso -k de

If memtest runs as expected:
$ git bisect good
otherwise:
$ git bisect bad

Keep repeating this and you should end up at the commit that introduced the bug.

this was the outcome of my bisect session:

956a3e6bb7386de48b642d4fee11f7f86a2fcf9a is first bad commit
commit 956a3e6bb7386de48b642d4fee11f7f86a2fcf9a
Author: Blue Swirlblauwir...@gmail.com
Date:   Sat May 22 07:59:01 2010 +

Compile pckbd only once

Use a qemu_irq to indicate A20 line changes. Move I/O port 92
to pckbd.c.

Signed-off-by: Blue Swirlblauwir...@gmail.com

:100644 100644 acbaf227455f931f3ef6dbe0bb4494c6b41f2cd9 
1a33d4eb4a5624c55896871b5f4ecde78a49ff28 M  Makefile.objs
:100644 100644 a22484e1e98355a35deeb5038a45fb8fe8685a91 
ba5147fbc48e4faef072a5be6b0d69d3201c1e18 M  Makefile.target
:04 04 dd03f81a42b5162c93c40c517f45eb9f7bece93c 
309f472328632319a15128a59715aa63daf4d92c M  default-configs
:04 04 83201c4fcde2f592a771479246e0a33a8906515b 
b1192bce85f2a7129fb19cf2fe7462ef168165cb M  hw
bisect run success

I tracked down the regression to a bug in commit 
956a3e6bb7386de48b642d4fee11f7f86a2fcf9a

In the patch the outport of the keyboard controller and ioport 0x92 are made 
the same.

this cannot work:

a) both share bit 1 to enable a20_gate. 1=enable, 0=disable -  ok so far
b) both implement a fast reset option through bit 0, but with inverse logic!!!
the keyboard controller resets if bit 0 is lowered, the ioport 0x92 resets if 
bit 0 is raised.
c) all other bits have nothing in common at all.

see: http://www.brokenthorn.com/Resources/OSDev9.html

I have a proposed patch attached. Comments appreciated. The state of the A20 
Gate is still
shared between ioport 0x92 and outport of the keyboard controller, but all 
other bits are ignored.
They might be used in the future to emulate e.g. hdd led activity or other 
usage of ioport 0x92.

I have tested the attached patch. memtest works again as expected. I think it 
crashed because it uses
ioport 0x92 directly to enable the a20 gate.

Peter

---

--- qemu-0.13.0/hw/pckbd.c  2010-10-15 22:56:09.0 +0200
+++ qemu-0.13.0-fix/hw/pckbd.c  2010-12-26 19:38:35.835114033 +0100
@@ -212,13 +212,16 @@
static void ioport92_write(void *opaque, uint32_t addr, uint32_t val)
{
KBDState *s = opaque;
-
-DPRINTF(kbd: write outport=0x%02x\n, val);
-s-outport = val;
-if (s-a20_out) {
-qemu_set_irq(*s-a20_out, (val  1)  1);
+if (val  0x02) { // bit 1: enable/disable A20
+   if (s-a20_out) qemu_irq_raise(*s-a20_out);
+   s-outport |= KBD_OUT_A20;
+}
+else
+{
+   if (s-a20_out) qemu_irq_lower(*s-a20_out);
+   s-outport= ~KBD_OUT_A20;
}
-if (!(val  1)) {
+if ((val  1)) { // bit 0: raised -  fast reset
qemu_system_reset_request();
}
}
@@ -226,11 +229,8 @@
static uint32_t ioport92_read(void *opaque, uint32_t addr)
{
KBDState *s = opaque;
-uint32_t ret;
-
-ret = s-outport;
-DPRINTF(kbd: read outport=0x%02x\n, ret);
-return ret;
+return (s-outport  0x02); // only bit 1 (KBD_OUT_A20) of port 0x92 is 
identical to s-outport
+/* XXX: bit 0 is fast reset, bits 6-7 hdd activity */
}

static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val)
@@ -340,7 +340,9 @@
kbd_queue(s, val, 1);
break;
case KBD_CCMD_WRITE_OUTPORT:
-ioport92_write(s, 0, val);
+ioport92_write(s, 0, (ioport92_read(s,0)  0xfc) // copy bits 2-7 of 
0x92
+ | (val  0x02) // bit 1 (enable a20)
+ | (~val  0x01)); // bit 0 (fast reset) of port 
0x92 has inverse logic
break;
case KBD_CCMD_WRITE_MOUSE:
ps2_write_mouse(s-mouse, val);



I just replied to the original thread.  I think we should separate
0x92 and the keyboard controller port since they are quite 

[Autotest] [KVM-AUTOTEST PATCH v2] KVM test: migration_with_file_transfer: verify transfer correctness

2010-12-28 Thread Jason Wang
Michael Goldish writes:
  After the transfer, copy the file back from the guest to the host and make 
  sure
  the returned file is identical to the one sent to the guest.
  
  Changes from v1:
  - hash_file() is in autotest_lib.client.bin.utils, so import that as
client_utils.
  - Pass host_path_returned (not host_path) to copy_files_from().
  

Looks good to me.

  Signed-off-by: Michael Goldish mgold...@redhat.com
  ---
   .../kvm/tests/migration_with_file_transfer.py  |   37 
  +---
   1 files changed, 32 insertions(+), 5 deletions(-)
  
  diff --git a/client/tests/kvm/tests/migration_with_file_transfer.py 
  b/client/tests/kvm/tests/migration_with_file_transfer.py
  index 73e70b9..d311350 100644
  --- a/client/tests/kvm/tests/migration_with_file_transfer.py
  +++ b/client/tests/kvm/tests/migration_with_file_transfer.py
  @@ -1,5 +1,6 @@
   import logging, time, os
   from autotest_lib.client.common_lib import utils, error
  +from autotest_lib.client.bin import utils as client_utils
   import kvm_subprocess, kvm_test_utils, kvm_utils
   
   
  @@ -35,15 +36,16 @@ def run_migration_with_file_transfer(test, params, env):
   (vm.name, address,
kvm_utils.generate_random_string(4)))
   host_path = /tmp/file-%s % kvm_utils.generate_random_string(6)
  +host_path_returned = %s-returned % host_path
   guest_path = params.get(guest_path, /tmp/file)
  -file_size = params.get(file_size, 1000)
  +file_size = params.get(file_size, 500)
   transfer_timeout = int(params.get(transfer_timeout, 240))
   
   try:
  -utils.run(dd if=/dev/zero of=%s bs=1M count=%s % (host_path,
  -file_size))
  +utils.run(dd if=/dev/urandom of=%s bs=1M count=%s % (host_path,
  +   file_size))
   
  -# Transfer file from host to guest in the backgroud
  +logging.info(Transferring file from host to guest)
   bg = kvm_utils.Thread(kvm_utils.copy_files_to,
 (address, client, username, password, port,
  host_path, guest_path, log_filename,
  @@ -57,9 +59,34 @@ def run_migration_with_file_transfer(test, params, env):
   finally:
   # bg.join() returns the value returned by copy_files_to()
   if not bg.join():
  -raise error.TestFail(File transfer failed)
  +raise error.TestFail(File transfer from host to guest 
  failed)
  +
  +logging.info(Transferring file back from guest to host)
  +bg = kvm_utils.Thread(kvm_utils.copy_files_from,
  +  (address, client, username, password, port,
  +   host_path_returned, guest_path, log_filename,
  +   transfer_timeout))
  +bg.start()
  +try:
  +while bg.is_alive():
  +logging.info(File transfer not ended, starting a round of 
  + migration...)
  +vm = kvm_test_utils.migrate(vm, env, mig_timeout, 
  mig_protocol)
  +finally:
  +if not bg.join():
  +raise error.TestFail(File transfer from guest to host 
  failed)
  +
  +# Make sure the returned file is indentical to the original one
  +orig_hash = client_utils.hash_file(host_path)
  +returned_hash = client_utils.hash_file(host_path_returned)
  +if orig_hash != returned_hash:
  +raise error.TestFail(Returned file hash (%s) differs from 
  + original one (%s) % (returned_hash,
  +orig_hash))
   
   finally:
   session.close()
   if os.path.isfile(host_path):
   os.remove(host_path)
  +if os.path.isfile(host_path_returned):
  +os.remove(host_path_returned)
  -- 
  1.7.3.4
  
  ___
  Autotest mailing list
  autot...@test.kernel.org
  http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest] [KVM-AUTOTEST PATCH 03/28] KVM test: corrections to migration_with_reboot

2010-12-28 Thread Michael Goldish
On 12/28/2010 02:25 PM, Jason Wang wrote:
 Michael Goldish writes:
   - Use wait_for() to try remote_login() multiple times before giving up.
   - Take VM parameters from vm.params, not params.
   
 
 Is there any differnce between those in current context?
 Other looks good, thanks.

In the current context no, but there can be a difference in odd cases
such as:

vms = vm1 vm2
main_vm = vm2
password = 1234
password_vm2 = 5678

In that case params['password'] is 1234 but vm.params['password'] is
5678 (because main_vm = vm2).

   Signed-off-by: Michael Goldish mgold...@redhat.com
   ---
client/tests/kvm/tests/migration_with_reboot.py |   26 
 +++---
1 files changed, 13 insertions(+), 13 deletions(-)
   
   diff --git a/client/tests/kvm/tests/migration_with_reboot.py 
 b/client/tests/kvm/tests/migration_with_reboot.py
   index 5673b45..5070dbc 100644
   --- a/client/tests/kvm/tests/migration_with_reboot.py
   +++ b/client/tests/kvm/tests/migration_with_reboot.py
   @@ -24,7 +24,7 @@ def run_migration_with_reboot(test, params, env):
password, prompt, linesep, log_filename, timeout):

A version of reboot test which is safe to be called in the 
 background as
   -it only needs an vm object
   +it doesn't need a VM object.

# Send a reboot command to the guest's shell
session.sendline(reboot_command)
   @@ -37,12 +37,12 @@ def run_migration_with_reboot(test, params, env):
session.close()

# Try logging into the guest until timeout expires
   -logging.info(Guest is down. Waiting for it to go up again, 
 timeout %ds,
   - timeout)
   -session = kvm_utils.remote_login(client, address, port, username,
   - password, prompt, linesep,
   - log_filename, timeout)
   -
   +logging.info(Guest is down. Waiting for it to go up again, 
 timeout 
   + %ds, timeout)
   +session = kvm_utils.wait_for(
   +lambda: kvm_utils.remote_login(client, address, port, 
 username,
   +   password, prompt, linesep,
   +   log_filename), timeout, 0, 2)
if not session:
raise error.TestFail(Could not log into guest after reboot)
logging.info(Guest is up again)
   @@ -53,16 +53,16 @@ def run_migration_with_reboot(test, params, env):
session = kvm_test_utils.wait_for_login(vm, timeout=timeout)

# params of reboot
   -username = params.get(username, )
   -password = params.get(password, )
   -prompt = params.get(shell_prompt, [\#\$])
   -linesep = eval('%s' % params.get(shell_linesep, r\n))
   -client = params.get(shell_client)
   +username = vm.params.get(username, )
   +password = vm.params.get(password, )
   +prompt = vm.params.get(shell_prompt, [\#\$])
   +linesep = eval('%s' % vm.params.get(shell_linesep, r\n))
   +client = vm.params.get(shell_client)
address = vm.get_address(0)
port = vm.get_port(int(params.get(shell_port)))
log_filename = (migration-reboot-%s-%s.log %
(vm.name, kvm_utils.generate_random_string(4)))
   -reboot_command = params.get(reboot_command)
   +reboot_command = vm.params.get(reboot_command)

mig_timeout = float(params.get(mig_timeout, 3600))
mig_protocol = params.get(migration_protocol, tcp)
   -- 
   1.7.3.3
   
   ___
   Autotest mailing list
   autot...@test.kernel.org
   http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest] [KVM-AUTOTEST PATCH v2] KVM test: migration_with_file_transfer: verify transfer correctness

2010-12-28 Thread Michael Goldish
On 12/28/2010 02:38 PM, Jason Wang wrote:
 Michael Goldish writes:
   After the transfer, copy the file back from the guest to the host and make 
 sure
   the returned file is identical to the one sent to the guest.
   
   Changes from v1:
   - hash_file() is in autotest_lib.client.bin.utils, so import that as
 client_utils.
   - Pass host_path_returned (not host_path) to copy_files_from().
   
 
 Looks good to me.

BTW, not sure if you've ever noticed, but this test fails consistently
on a very recent qemu-kvm: the returned file's MD5 hash always differs
from the original one.  Either I'm doing something wrong or there's a
bug in qemu-kvm.

   Signed-off-by: Michael Goldish mgold...@redhat.com
   ---
.../kvm/tests/migration_with_file_transfer.py  |   37 
 +---
1 files changed, 32 insertions(+), 5 deletions(-)
   
   diff --git a/client/tests/kvm/tests/migration_with_file_transfer.py 
 b/client/tests/kvm/tests/migration_with_file_transfer.py
   index 73e70b9..d311350 100644
   --- a/client/tests/kvm/tests/migration_with_file_transfer.py
   +++ b/client/tests/kvm/tests/migration_with_file_transfer.py
   @@ -1,5 +1,6 @@
import logging, time, os
from autotest_lib.client.common_lib import utils, error
   +from autotest_lib.client.bin import utils as client_utils
import kvm_subprocess, kvm_test_utils, kvm_utils


   @@ -35,15 +36,16 @@ def run_migration_with_file_transfer(test, params, 
 env):
(vm.name, address,
 kvm_utils.generate_random_string(4)))
host_path = /tmp/file-%s % kvm_utils.generate_random_string(6)
   +host_path_returned = %s-returned % host_path
guest_path = params.get(guest_path, /tmp/file)
   -file_size = params.get(file_size, 1000)
   +file_size = params.get(file_size, 500)
transfer_timeout = int(params.get(transfer_timeout, 240))

try:
   -utils.run(dd if=/dev/zero of=%s bs=1M count=%s % (host_path,
   -file_size))
   +utils.run(dd if=/dev/urandom of=%s bs=1M count=%s % (host_path,
   +   file_size))

   -# Transfer file from host to guest in the backgroud
   +logging.info(Transferring file from host to guest)
bg = kvm_utils.Thread(kvm_utils.copy_files_to,
  (address, client, username, password, port,
   host_path, guest_path, log_filename,
   @@ -57,9 +59,34 @@ def run_migration_with_file_transfer(test, params, env):
finally:
# bg.join() returns the value returned by copy_files_to()
if not bg.join():
   -raise error.TestFail(File transfer failed)
   +raise error.TestFail(File transfer from host to guest 
 failed)
   +
   +logging.info(Transferring file back from guest to host)
   +bg = kvm_utils.Thread(kvm_utils.copy_files_from,
   +  (address, client, username, password, port,
   +   host_path_returned, guest_path, 
 log_filename,
   +   transfer_timeout))
   +bg.start()
   +try:
   +while bg.is_alive():
   +logging.info(File transfer not ended, starting a round 
 of 
   + migration...)
   +vm = kvm_test_utils.migrate(vm, env, mig_timeout, 
 mig_protocol)
   +finally:
   +if not bg.join():
   +raise error.TestFail(File transfer from guest to host 
 failed)
   +
   +# Make sure the returned file is indentical to the original one
   +orig_hash = client_utils.hash_file(host_path)
   +returned_hash = client_utils.hash_file(host_path_returned)
   +if orig_hash != returned_hash:
   +raise error.TestFail(Returned file hash (%s) differs from 
   + original one (%s) % (returned_hash,
   +orig_hash))

finally:
session.close()
if os.path.isfile(host_path):
os.remove(host_path)
   +if os.path.isfile(host_path_returned):
   +os.remove(host_path_returned)
   -- 
   1.7.3.4
   
   ___
   Autotest mailing list
   autot...@test.kernel.org
   http://test.kernel.org/cgi-bin/mailman/listinfo/autotest

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Autotest] [KVM-AUTOTEST PATCH 11/28] KVM test: make_qemu_command(): catch IndexError when accessing self.netdev_id

2010-12-28 Thread Jason Wang
Michael Goldish writes:
  make_qemu_command() is sometimes called to see if a VM needs to be restarted
  using a different qemu command line.  When it's called with more NICs than 
  the
  VM currently has, accessing self.netdev_id can raise an IndexError.
  
  Signed-off-by: Michael Goldish mgold...@redhat.com
  ---
   client/tests/kvm/kvm_vm.py |   12 +++-
   1 files changed, 7 insertions(+), 5 deletions(-)
  
  diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
  index 6aa8eb4..aeb7448 100755
  --- a/client/tests/kvm/kvm_vm.py
  +++ b/client/tests/kvm/kvm_vm.py
  @@ -402,11 +402,14 @@ class VM:
   vlan = 0
   for nic_name in kvm_utils.get_sub_dict_names(params, nics):
   nic_params = kvm_utils.get_sub_dict(params, nic_name)
  +try:
  +netdev_id = self.netdev_id[vlan]
  +except IndexError:
  +netdev_id = None
   # Handle the '-net nic' part
   mac = self.get_mac_address(vlan)
   qemu_cmd += add_nic(help, vlan, nic_params.get(nic_model), 
  mac,
  -self.netdev_id[vlan],
  -nic_params.get(nic_extra_params))
  +netdev_id, 
  nic_params.get(nic_extra_params))
   # Handle the '-net tap' or '-net user' part
   script = nic_params.get(nic_script)
   downscript = nic_params.get(nic_downscript)
  @@ -420,9 +423,8 @@ class VM:
   qemu_cmd += add_net(help, vlan, nic_params.get(nic_mode, 
  user),
   self.get_ifname(vlan),
   script, downscript, tftp,
  -nic_params.get(bootp), redirs,
  -self.netdev_id[vlan],
  -nic_params.get(netdev_extra_params))
  +nic_params.get(bootp), redirs, netdev_id,
  +nic_params.get(vhost) == yes)

Why drop netdev_extra_params here, we've used it to enable vhost. And it seems
the bootp is useless here as we've already used -kernel and -initrd to do
the unattended installation.

   # Proceed to next NIC
   vlan += 1
   
  -- 
  1.7.3.3
  
  ___
  Autotest mailing list
  autot...@test.kernel.org
  http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Autotest] [KVM-AUTOTEST PATCH v2] KVM test: migration_with_file_transfer: verify transfer correctness

2010-12-28 Thread Jason Wang
Michael Goldish writes:
  On 12/28/2010 02:38 PM, Jason Wang wrote:
   Michael Goldish writes:
 After the transfer, copy the file back from the guest to the host and 
   make sure
 the returned file is identical to the one sent to the guest.
 
 Changes from v1:
 - hash_file() is in autotest_lib.client.bin.utils, so import that as
   client_utils.
 - Pass host_path_returned (not host_path) to copy_files_from().
 
   
   Looks good to me.
  
  BTW, not sure if you've ever noticed, but this test fails consistently
  on a very recent qemu-kvm: the returned file's MD5 hash always differs
  from the original one.  Either I'm doing something wrong or there's a
  bug in qemu-kvm.
  

Not notice yet and I would have a look at this, which kind of model did you use?

 Signed-off-by: Michael Goldish mgold...@redhat.com
 ---
  .../kvm/tests/migration_with_file_transfer.py  |   37 
   +---
  1 files changed, 32 insertions(+), 5 deletions(-)
 
 diff --git a/client/tests/kvm/tests/migration_with_file_transfer.py 
   b/client/tests/kvm/tests/migration_with_file_transfer.py
 index 73e70b9..d311350 100644
 --- a/client/tests/kvm/tests/migration_with_file_transfer.py
 +++ b/client/tests/kvm/tests/migration_with_file_transfer.py
 @@ -1,5 +1,6 @@
  import logging, time, os
  from autotest_lib.client.common_lib import utils, error
 +from autotest_lib.client.bin import utils as client_utils
  import kvm_subprocess, kvm_test_utils, kvm_utils
  
  
 @@ -35,15 +36,16 @@ def run_migration_with_file_transfer(test, params, 
   env):
  (vm.name, address,
   kvm_utils.generate_random_string(4)))
  host_path = /tmp/file-%s % kvm_utils.generate_random_string(6)
 +host_path_returned = %s-returned % host_path
  guest_path = params.get(guest_path, /tmp/file)
 -file_size = params.get(file_size, 1000)
 +file_size = params.get(file_size, 500)
  transfer_timeout = int(params.get(transfer_timeout, 240))
  
  try:
 -utils.run(dd if=/dev/zero of=%s bs=1M count=%s % (host_path,
 -file_size))
 +utils.run(dd if=/dev/urandom of=%s bs=1M count=%s % 
   (host_path,
 +   
   file_size))
  
 -# Transfer file from host to guest in the backgroud
 +logging.info(Transferring file from host to guest)
  bg = kvm_utils.Thread(kvm_utils.copy_files_to,
(address, client, username, password, 
   port,
 host_path, guest_path, log_filename,
 @@ -57,9 +59,34 @@ def run_migration_with_file_transfer(test, params, 
   env):
  finally:
  # bg.join() returns the value returned by copy_files_to()
  if not bg.join():
 -raise error.TestFail(File transfer failed)
 +raise error.TestFail(File transfer from host to guest 
   failed)
 +
 +logging.info(Transferring file back from guest to host)
 +bg = kvm_utils.Thread(kvm_utils.copy_files_from,
 +  (address, client, username, password, 
   port,
 +   host_path_returned, guest_path, 
   log_filename,
 +   transfer_timeout))
 +bg.start()
 +try:
 +while bg.is_alive():
 +logging.info(File transfer not ended, starting a 
   round of 
 + migration...)
 +vm = kvm_test_utils.migrate(vm, env, mig_timeout, 
   mig_protocol)
 +finally:
 +if not bg.join():
 +raise error.TestFail(File transfer from guest to host 
   failed)
 +
 +# Make sure the returned file is indentical to the original one
 +orig_hash = client_utils.hash_file(host_path)
 +returned_hash = client_utils.hash_file(host_path_returned)
 +if orig_hash != returned_hash:
 +raise error.TestFail(Returned file hash (%s) differs from 
   
 + original one (%s) % (returned_hash,
 +orig_hash))
  
  finally:
  session.close()
  if os.path.isfile(host_path):
  os.remove(host_path)
 +if os.path.isfile(host_path_returned):
 +os.remove(host_path_returned)
 -- 
 1.7.3.4
 
 ___
 Autotest mailing list
 autot...@test.kernel.org
 http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
  
--
To unsubscribe from this list: send the line 

Re: [Autotest] [KVM-AUTOTEST PATCH v2] KVM test: migration_with_file_transfer: verify transfer correctness

2010-12-28 Thread Michael Goldish
On 12/28/2010 03:31 PM, Jason Wang wrote:
 Michael Goldish writes:
   On 12/28/2010 02:38 PM, Jason Wang wrote:
Michael Goldish writes:
  After the transfer, copy the file back from the guest to the host and 
 make sure
  the returned file is identical to the one sent to the guest.
  
  Changes from v1:
  - hash_file() is in autotest_lib.client.bin.utils, so import that as
client_utils.
  - Pass host_path_returned (not host_path) to copy_files_from().
  

Looks good to me.
   
   BTW, not sure if you've ever noticed, but this test fails consistently
   on a very recent qemu-kvm: the returned file's MD5 hash always differs
   from the original one.  Either I'm doing something wrong or there's a
   bug in qemu-kvm.
   
 
 Not notice yet and I would have a look at this, which kind of model did you 
 use?

rtl8139 on Fedora 12 64.  I haven't tried virtio or Windows yet.

  Signed-off-by: Michael Goldish mgold...@redhat.com
  ---
   .../kvm/tests/migration_with_file_transfer.py  |   37 
 +---
   1 files changed, 32 insertions(+), 5 deletions(-)
  
  diff --git a/client/tests/kvm/tests/migration_with_file_transfer.py 
 b/client/tests/kvm/tests/migration_with_file_transfer.py
  index 73e70b9..d311350 100644
  --- a/client/tests/kvm/tests/migration_with_file_transfer.py
  +++ b/client/tests/kvm/tests/migration_with_file_transfer.py
  @@ -1,5 +1,6 @@
   import logging, time, os
   from autotest_lib.client.common_lib import utils, error
  +from autotest_lib.client.bin import utils as client_utils
   import kvm_subprocess, kvm_test_utils, kvm_utils
   
   
  @@ -35,15 +36,16 @@ def run_migration_with_file_transfer(test, 
 params, env):
   (vm.name, address,
kvm_utils.generate_random_string(4)))
   host_path = /tmp/file-%s % kvm_utils.generate_random_string(6)
  +host_path_returned = %s-returned % host_path
   guest_path = params.get(guest_path, /tmp/file)
  -file_size = params.get(file_size, 1000)
  +file_size = params.get(file_size, 500)
   transfer_timeout = int(params.get(transfer_timeout, 240))
   
   try:
  -utils.run(dd if=/dev/zero of=%s bs=1M count=%s % 
 (host_path,
  -
 file_size))
  +utils.run(dd if=/dev/urandom of=%s bs=1M count=%s % 
 (host_path,
  +   
 file_size))
   
  -# Transfer file from host to guest in the backgroud
  +logging.info(Transferring file from host to guest)
   bg = kvm_utils.Thread(kvm_utils.copy_files_to,
 (address, client, username, password, 
 port,
  host_path, guest_path, log_filename,
  @@ -57,9 +59,34 @@ def run_migration_with_file_transfer(test, params, 
 env):
   finally:
   # bg.join() returns the value returned by copy_files_to()
   if not bg.join():
  -raise error.TestFail(File transfer failed)
  +raise error.TestFail(File transfer from host to 
 guest failed)
  +
  +logging.info(Transferring file back from guest to host)
  +bg = kvm_utils.Thread(kvm_utils.copy_files_from,
  +  (address, client, username, password, 
 port,
  +   host_path_returned, guest_path, 
 log_filename,
  +   transfer_timeout))
  +bg.start()
  +try:
  +while bg.is_alive():
  +logging.info(File transfer not ended, starting a 
 round of 
  + migration...)
  +vm = kvm_test_utils.migrate(vm, env, mig_timeout, 
 mig_protocol)
  +finally:
  +if not bg.join():
  +raise error.TestFail(File transfer from guest to 
 host failed)
  +
  +# Make sure the returned file is indentical to the original 
 one
  +orig_hash = client_utils.hash_file(host_path)
  +returned_hash = client_utils.hash_file(host_path_returned)
  +if orig_hash != returned_hash:
  +raise error.TestFail(Returned file hash (%s) differs 
 from 
  + original one (%s) % 
 (returned_hash,
  +orig_hash))
   
   finally:
   session.close()
   if os.path.isfile(host_path):
   os.remove(host_path)
  +if os.path.isfile(host_path_returned):
  +os.remove(host_path_returned)
  -- 
  1.7.3.4
  
  

Re: [Autotest] [KVM-AUTOTEST PATCH 12/28] KVM test: use VM.clone() in make_qemu_command()

2010-12-28 Thread Michael Goldish
On 12/28/2010 03:13 PM, Jason Wang wrote:
 Michael Goldish writes:
   When make_qemu_command() is called in order to see if a VM should be 
 restarted
   using a different qemu command line, construction of the qemu command 
 should be
   based only on the parameters provided to make_qemu_command() (name, params,
   root_dir).  However, some VM methods are called which use the internal 
 state of
   the VM (self.params).  For example, when calling make_qemu_command() with
   params that define 3 NICs, for a VM that currently has only 1 NIC,
   make_qemu_command() will call VM.get_ifname() for 2 NICs that don't exist 
 in
   self.params.
   To solve this, allow VM.clone() to copy the state of the VM to the clone, 
 and
   use such a clone with altered params in make_qemu_command(), instead of 
 using
   'self'.  That way, all methods that use self.params will use the correct
   (altered) params in make_qemu_command().
   
 
 If we use VM.clone() we also need to destroy it as it may left entries in mac
 address pool. Other looks good.

I don't think so because the clone doesn't do anything except allow
proper access to VM data.  The clone shares the same instance string
with the original VM, so they share the same address pool entries.  If
we destroy() the clone, the original VM will be destroyed too.

The above is only true because we pass copy_state=True to clone().  If
we didn't do that, the clone would be independent with its own instance
string and would have to be create()d separately.

   Signed-off-by: Michael Goldish mgold...@redhat.com
   ---
client/tests/kvm/kvm_vm.py |   72 
 ++-
1 files changed, 43 insertions(+), 29 deletions(-)
   
   diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
   index aeb7448..b80d2c2 100755
   --- a/client/tests/kvm/kvm_vm.py
   +++ b/client/tests/kvm/kvm_vm.py
   @@ -97,7 +97,7 @@ class VM:
This class handles all basic VM operations.


   -def __init__(self, name, params, root_dir, address_cache):
   +def __init__(self, name, params, root_dir, address_cache, state=None):

Initialize the object and set a few attributes.

   @@ -106,30 +106,35 @@ class VM:
(see method make_qemu_command for a full description)
@param root_dir: Base directory for relative filenames
@param address_cache: A dict that maps MAC addresses to IP 
 addresses
   +@param state: If provided, use this as self.__dict__

   -self.process = None
   -self.serial_console = None
   -self.redirs = {}
   -self.vnc_port = 5900
   -self.monitors = []
   -self.pci_assignable = None
   -self.netdev_id = []
   -self.uuid = None
   +if state:
   +self.__dict__ = state
   +else:
   +self.process = None
   +self.serial_console = None
   +self.redirs = {}
   +self.vnc_port = 5900
   +self.monitors = []
   +self.pci_assignable = None
   +self.netdev_id = []
   +self.uuid = None
   +
   +# Find a unique identifier for this VM
   +while True:
   +self.instance = (time.strftime(%Y%m%d-%H%M%S-) +
   + kvm_utils.generate_random_string(4))
   +if not glob.glob(/tmp/*%s % self.instance):
   +break

self.name = name
self.params = params
self.root_dir = root_dir
self.address_cache = address_cache

   -# Find a unique identifier for this VM
   -while True:
   -self.instance = (time.strftime(%Y%m%d-%H%M%S-) +
   - kvm_utils.generate_random_string(4))
   -if not glob.glob(/tmp/*%s % self.instance):
   -break
   -

   -def clone(self, name=None, params=None, root_dir=None, 
 address_cache=None):
   +def clone(self, name=None, params=None, root_dir=None, 
 address_cache=None,
   +  copy_state=False):

Return a clone of the VM object with optionally modified 
 parameters.
The clone is initially not alive and needs to be started using 
 create().
   @@ -140,6 +145,8 @@ class VM:
@param params: Optional new VM creation parameters
@param root_dir: Optional new base directory for relative 
 filenames
@param address_cache: A dict that maps MAC addresses to IP 
 addresses
   +@param copy_state: If True, copy the original VM's state to the 
 clone.
   +Mainly useful for make_qemu_command().

if name is None:
name = self.name
   @@ -149,7 +156,11 @@ class VM:
root_dir = self.root_dir
if address_cache is None:
address_cache = 

Re: [Autotest] [KVM-AUTOTEST PATCH 11/28] KVM test: make_qemu_command(): catch IndexError when accessing self.netdev_id

2010-12-28 Thread Michael Goldish
On 12/28/2010 03:23 PM, Jason Wang wrote:
 Michael Goldish writes:
   make_qemu_command() is sometimes called to see if a VM needs to be 
 restarted
   using a different qemu command line.  When it's called with more NICs than 
 the
   VM currently has, accessing self.netdev_id can raise an IndexError.
   
   Signed-off-by: Michael Goldish mgold...@redhat.com
   ---
client/tests/kvm/kvm_vm.py |   12 +++-
1 files changed, 7 insertions(+), 5 deletions(-)
   
   diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
   index 6aa8eb4..aeb7448 100755
   --- a/client/tests/kvm/kvm_vm.py
   +++ b/client/tests/kvm/kvm_vm.py
   @@ -402,11 +402,14 @@ class VM:
vlan = 0
for nic_name in kvm_utils.get_sub_dict_names(params, nics):
nic_params = kvm_utils.get_sub_dict(params, nic_name)
   +try:
   +netdev_id = self.netdev_id[vlan]
   +except IndexError:
   +netdev_id = None
# Handle the '-net nic' part
mac = self.get_mac_address(vlan)
qemu_cmd += add_nic(help, vlan, nic_params.get(nic_model), 
 mac,
   -self.netdev_id[vlan],
   -nic_params.get(nic_extra_params))
   +netdev_id, 
 nic_params.get(nic_extra_params))
# Handle the '-net tap' or '-net user' part
script = nic_params.get(nic_script)
downscript = nic_params.get(nic_downscript)
   @@ -420,9 +423,8 @@ class VM:
qemu_cmd += add_net(help, vlan, nic_params.get(nic_mode, 
 user),
self.get_ifname(vlan),
script, downscript, tftp,
   -nic_params.get(bootp), redirs,
   -self.netdev_id[vlan],
   -nic_params.get(netdev_extra_params))
   +nic_params.get(bootp), redirs, 
 netdev_id,
   +nic_params.get(vhost) == yes)
 
 Why drop netdev_extra_params here, we've used it to enable vhost. And it seems

This is a rebase mistake.  I'll fix it and re-post the patch.  Thanks.

 the bootp is useless here as we've already used -kernel and -initrd to do
 the unattended installation.

If we decide to remove bootp we should do it in a different patch.

# Proceed to next NIC
vlan += 1

   -- 
   1.7.3.3
   
   ___
   Autotest mailing list
   autot...@test.kernel.org
   http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
 --
 To unsubscribe from this list: send the line unsubscribe kvm in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH v2] KVM test: make_qemu_command(): catch IndexError when accessing self.netdev_id

2010-12-28 Thread Michael Goldish
make_qemu_command() is sometimes called to see if a VM needs to be restarted
using a different qemu command line.  When it's called with more NICs than the
VM currently has, accessing self.netdev_id can raise an IndexError.

Changes from v1:
- Fix rebase error (omitted netdev_extra_params).

Signed-off-by: Michael Goldish mgold...@redhat.com
---
 client/tests/kvm/kvm_vm.py |   10 ++
 1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py
index 6aa8eb4..ebab981 100755
--- a/client/tests/kvm/kvm_vm.py
+++ b/client/tests/kvm/kvm_vm.py
@@ -402,11 +402,14 @@ class VM:
 vlan = 0
 for nic_name in kvm_utils.get_sub_dict_names(params, nics):
 nic_params = kvm_utils.get_sub_dict(params, nic_name)
+try:
+netdev_id = self.netdev_id[vlan]
+except IndexError:
+netdev_id = None
 # Handle the '-net nic' part
 mac = self.get_mac_address(vlan)
 qemu_cmd += add_nic(help, vlan, nic_params.get(nic_model), mac,
-self.netdev_id[vlan],
-nic_params.get(nic_extra_params))
+netdev_id, nic_params.get(nic_extra_params))
 # Handle the '-net tap' or '-net user' part
 script = nic_params.get(nic_script)
 downscript = nic_params.get(nic_downscript)
@@ -420,8 +423,7 @@ class VM:
 qemu_cmd += add_net(help, vlan, nic_params.get(nic_mode, user),
 self.get_ifname(vlan),
 script, downscript, tftp,
-nic_params.get(bootp), redirs,
-self.netdev_id[vlan],
+nic_params.get(bootp), redirs, netdev_id,
 nic_params.get(netdev_extra_params))
 # Proceed to next NIC
 vlan += 1
-- 
1.7.3.4

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 1/4] KVM test: introduce the Env class

2010-12-28 Thread Michael Goldish
It's a wrapper to the 'env' object used by KVM tests.  It behaves like a
dictionary, but may implement additional common operations used by KVM tests.

Signed-off-by: Eduardo Habkost ehabk...@raisama.net
---
 client/tests/kvm/kvm_utils.py |   85 +
 1 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py
index 2e4ba92..2423dd9 100644
--- a/client/tests/kvm/kvm_utils.py
+++ b/client/tests/kvm/kvm_utils.py
@@ -62,6 +62,91 @@ def load_env(filename, version):
 return default
 
 
+class Env(UserDict.IterableUserDict):
+
+A dict-like object containing global objects used by tests.
+
+def __init__(self, filename=None, version=0):
+
+Create an empty Env object or load an existing one from a file.
+
+If the version recorded in the file is lower than version, or if some
+error occurs during unpickling, or if filename is not supplied,
+create an empty Env object.
+
+@param filename: Path to an env file.
+@param version: Required env version (int).
+
+UserDict.IterableUserDict.__init__(self)
+empty = {version: version}
+if filename:
+self._filename = filename
+try:
+f = open(filename, r)
+env = cPickle.load(f)
+f.close()
+if env.get(version, 0) = version:
+self.data = env
+else:
+logging.warn(Incompatible env file found. Not using it.)
+self.data = empty
+# Almost any exception can be raised during unpickling, so let's
+# catch them all
+except Exception, e:
+logging.warn(e)
+self.data = empty
+else:
+self.data = empty
+
+
+def save(self, filename=None):
+
+Pickle the contents of the Env object into a file.
+
+@param filename: Filename to pickle the dict into.  If not supplied,
+use the filename from which the dict was loaded.
+
+filename = filename or self._filename
+f = open(filename, w)
+cPickle.dump(self.data, f)
+f.close()
+
+
+def get_all_vms(self):
+
+Return a list of all VM objects in this Env object.
+
+return [o for o in self.values() if is_vm(o)]
+
+
+def get_vm(self, name):
+
+Return a VM object by its name.
+
+@param name: VM name.
+
+return self.get(vm__%s % name)
+
+
+def register_vm(self, name, vm):
+
+Register a VM in this Env object.
+
+@param name: VM name.
+@param vm: VM object.
+
+self[vm__%s % name] = vm
+
+
+def unregister_vm(self, name):
+
+Remove a given VM.
+
+@param name: VM name.
+
+del self[vm__%s % name]
+
+
 class Params(UserDict.IterableUserDict):
 
 A dict-like object passed to every test.
-- 
1.7.3.4

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 2/4] KVM test: use kvm_utils.Env wherever appropriate

2010-12-28 Thread Michael Goldish
The new Env object is backward compatible with the regular env dict, so
all the kvm_utils.env_*() functions should work as usual.

Signed-off-by: Eduardo Habkost ehabk...@raisama.net
---
 client/tests/kvm/kvm.py   |   10 +-
 client/tests/kvm/kvm_scheduler.py |4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/client/tests/kvm/kvm.py b/client/tests/kvm/kvm.py
index ceee88f..9d942d3 100644
--- a/client/tests/kvm/kvm.py
+++ b/client/tests/kvm/kvm.py
@@ -43,7 +43,7 @@ class kvm(test.test):
 logging.info(Unpickling env. You may see some harmless error 
  messages.)
 env_filename = os.path.join(self.bindir, params.get(env, env))
-env = kvm_utils.load_env(env_filename, self.env_version)
+env = kvm_utils.Env(env_filename, self.env_version)
 
 test_passed = False
 
@@ -68,13 +68,13 @@ class kvm(test.test):
 try:
 kvm_preprocessing.preprocess(self, params, env)
 finally:
-kvm_utils.dump_env(env, env_filename)
+env.save()
 # Run the test function
 run_func = getattr(test_module, run_%s % t_type)
 try:
 run_func(self, params, env)
 finally:
-kvm_utils.dump_env(env, env_filename)
+env.save()
 test_passed = True
 
 except Exception, e:
@@ -85,7 +85,7 @@ class kvm(test.test):
 kvm_preprocessing.postprocess_on_error(
 self, params, env)
 finally:
-kvm_utils.dump_env(env, env_filename)
+env.save()
 raise
 
 finally:
@@ -99,7 +99,7 @@ class kvm(test.test):
 logging.error(Exception raised during 
   postprocessing: %s, e)
 finally:
-kvm_utils.dump_env(env, env_filename)
+env.save()
 
 except Exception, e:
 if params.get(abort_on_error) != yes:
diff --git a/client/tests/kvm/kvm_scheduler.py 
b/client/tests/kvm/kvm_scheduler.py
index aa581ad..95282e4 100644
--- a/client/tests/kvm/kvm_scheduler.py
+++ b/client/tests/kvm/kvm_scheduler.py
@@ -74,13 +74,13 @@ class scheduler:
 # The scheduler wants this worker to free its used resources
 elif cmd[0] == cleanup:
 env_filename = os.path.join(self.bindir, self_dict[env])
-env = kvm_utils.load_env(env_filename, {})
+env = kvm_utils.Env(env_filename)
 for obj in env.values():
 if isinstance(obj, kvm_vm.VM):
 obj.destroy()
 elif isinstance(obj, kvm_subprocess.Spawn):
 obj.close()
-kvm_utils.dump_env(env, env_filename)
+env.save()
 w.write(cleanup_done\n)
 w.write(ready\n)
 
-- 
1.7.3.4

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM-AUTOTEST PATCH 3/4] KVM test: use the new Env methods instead of the old env_* functions

2010-12-28 Thread Michael Goldish
Signed-off-by: Eduardo Habkost ehabk...@raisama.net
---
 client/tests/kvm/kvm.py  |2 +-
 client/tests/kvm/kvm_preprocessing.py|   12 ++--
 client/tests/kvm/kvm_test_utils.py   |4 ++--
 client/tests/kvm/tests/ksm_overcommit.py |4 ++--
 client/tests/kvm/tests/qemu_img.py   |6 +++---
 client/tests/kvm/tests/stepmaker.py  |2 +-
 client/tests/kvm/tests/steps.py  |2 +-
 client/tests/kvm/tests/stress_boot.py|2 +-
 client/tests/kvm/tests/unittest.py   |2 +-
 client/tests/kvm/tests/virtio_console.py |2 +-
 10 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/client/tests/kvm/kvm.py b/client/tests/kvm/kvm.py
index 9d942d3..7d7bf55 100644
--- a/client/tests/kvm/kvm.py
+++ b/client/tests/kvm/kvm.py
@@ -106,7 +106,7 @@ class kvm(test.test):
 raise
 # Abort on error
 logging.info(Aborting job (%s), e)
-for vm in kvm_utils.env_get_all_vms(env):
+for vm in env.get_all_vms():
 if vm.is_dead():
 continue
 logging.info(VM '%s' is alive., vm.name)
diff --git a/client/tests/kvm/kvm_preprocessing.py 
b/client/tests/kvm/kvm_preprocessing.py
index 25c4e5f..4daafec 100644
--- a/client/tests/kvm/kvm_preprocessing.py
+++ b/client/tests/kvm/kvm_preprocessing.py
@@ -50,13 +50,13 @@ def preprocess_vm(test, params, env, name):
 @param name: The name of the VM object.
 
 logging.debug(Preprocessing VM '%s'... % name)
-vm = kvm_utils.env_get_vm(env, name)
+vm = env.get_vm(name)
 if vm:
 logging.debug(VM object found in environment)
 else:
 logging.debug(VM object does not exist; creating it)
 vm = kvm_vm.VM(name, params, test.bindir, env.get(address_cache))
-kvm_utils.env_register_vm(env, name, vm)
+env.register_vm(name, vm)
 
 start_vm = False
 
@@ -122,7 +122,7 @@ def postprocess_vm(test, params, env, name):
 @param name: The name of the VM object.
 
 logging.debug(Postprocessing VM '%s'... % name)
-vm = kvm_utils.env_get_vm(env, name)
+vm = env.get_vm(name)
 if vm:
 logging.debug(VM object found in environment)
 else:
@@ -338,7 +338,7 @@ def postprocess(test, params, env):
 if params.get(kill_unresponsive_vms) == yes:
 logging.debug('kill_unresponsive_vms' specified; killing all VMs 
   that fail to respond to a remote login request...)
-for vm in kvm_utils.env_get_all_vms(env):
+for vm in env.get_all_vms():
 if vm.is_alive():
 session = vm.remote_login()
 if session:
@@ -350,7 +350,7 @@ def postprocess(test, params, env):
 kvm_subprocess.kill_tail_threads()
 
 # Terminate tcpdump if no VMs are alive
-living_vms = [vm for vm in kvm_utils.env_get_all_vms(env) if vm.is_alive()]
+living_vms = [vm for vm in env.get_all_vms() if vm.is_alive()]
 if not living_vms and tcpdump in env:
 env[tcpdump].close()
 del env[tcpdump]
@@ -408,7 +408,7 @@ def _take_screendumps(test, params, env):
 cache = {}
 
 while True:
-for vm in kvm_utils.env_get_all_vms(env):
+for vm in env.get_all_vms():
 if not vm.is_alive():
 continue
 try:
diff --git a/client/tests/kvm/kvm_test_utils.py 
b/client/tests/kvm/kvm_test_utils.py
index 6569d3b..7ed3330 100644
--- a/client/tests/kvm/kvm_test_utils.py
+++ b/client/tests/kvm/kvm_test_utils.py
@@ -35,7 +35,7 @@ def get_living_vm(env, vm_name):
 @param vm_name: Name of the desired VM object.
 @return: A VM object.
 
-vm = kvm_utils.env_get_vm(env, vm_name)
+vm = env.get_vm(vm_name)
 if not vm:
 raise error.TestError(VM '%s' not found in environment % vm_name)
 if not vm.is_alive():
@@ -275,7 +275,7 @@ def migrate(vm, env=None, mig_timeout=3600, 
mig_protocol=tcp,
 
 # Replace the source VM with the new cloned VM
 if (dest_host == 'localhost') and (env is not None):
-kvm_utils.env_register_vm(env, vm.name, dest_vm)
+env.register_vm(vm.name, dest_vm)
 
 # Return the new cloned VM
 if dest_host == 'localhost':
diff --git a/client/tests/kvm/tests/ksm_overcommit.py 
b/client/tests/kvm/tests/ksm_overcommit.py
index deadda1..c6368d3 100644
--- a/client/tests/kvm/tests/ksm_overcommit.py
+++ b/client/tests/kvm/tests/ksm_overcommit.py
@@ -544,7 +544,7 @@ def run_ksm_overcommit(test, params, env):
 
 # Creating the first guest
 kvm_preprocessing.preprocess_vm(test, params, env, vm_name)
-lvms.append(kvm_utils.env_get_vm(env, vm_name))
+lvms.append(env.get_vm(vm_name))
 if not lvms[0]:
 raise error.TestError(VM object not found in environment)
 if not lvms[0].is_alive():
@@ -575,7 +575,7 @@ def run_ksm_overcommit(test, params, env):
 
 # Last VM is later used to run more allocators simultaneously
 

Re: [Autotest] [KVM-AUTOTEST PATCH 0/4] KVM test: replace 'env' dict with an Env object

2010-12-28 Thread Lucas Meneghel Rodrigues
On Tue, 2010-12-28 at 17:43 +0200, Michael Goldish wrote:
 This is a respin of Eduardo's patchset with small modifications.
 
 Differences from Eduardo's patches:
 - These patches don't change the module structure of the KVM test (no kvm
   package is created).  We can still do that in the future if we choose to.
 - The class is named Env instead of KvmEnv.
 - It's defined in kvm_utils.py instead of a module of its own.
 - No unittests for Env.  I personally don't think they're necessary, nor do I
   think anyone will bother to use them, but let me know if you disagree.
 - The __init__() method takes care of the loading if a filename is provided.
 - save() can do what _dump() did, so _dump() is unnecessary.
 - The series is a lot shorter and will hopefully be easier to review.

Hi Michael, thanks! The only thing I do not agree is with the unittest,
it's useful, specially for me when I am applying and checking the
patches, so I ask you to send the unittest Eduardo created on a future
patch. Other than that, great work!

 Michael Goldish (4):
   KVM test: introduce the Env class
   KVM test: use kvm_utils.Env wherever appropriate
   KVM test: use the new Env methods instead of the old env_* functions
   KVM test: get rid of the kvm_utils.env_* functions
 
  client/tests/kvm/kvm.py  |   12 +-
  client/tests/kvm/kvm_preprocessing.py|   12 +-
  client/tests/kvm/kvm_scheduler.py|4 +-
  client/tests/kvm/kvm_test_utils.py   |4 +-
  client/tests/kvm/kvm_utils.py|  165 +++--
  client/tests/kvm/tests/ksm_overcommit.py |4 +-
  client/tests/kvm/tests/qemu_img.py   |6 +-
  client/tests/kvm/tests/stepmaker.py  |2 +-
  client/tests/kvm/tests/steps.py  |2 +-
  client/tests/kvm/tests/stress_boot.py|2 +-
  client/tests/kvm/tests/unittest.py   |2 +-
  client/tests/kvm/tests/virtio_console.py |2 +-
  12 files changed, 111 insertions(+), 106 deletions(-)
 


--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [Qemu-devel] possible regression in qemu-kvm 0.13.0 (memtest)

2010-12-28 Thread Blue Swirl
On Mon, Dec 27, 2010 at 3:47 AM, Stefan Hajnoczi stefa...@gmail.com wrote:
 On Sat, Dec 25, 2010 at 7:02 PM, Peter Lieven p...@dlh.net wrote:
 this was the outcome of my bisect session:

 956a3e6bb7386de48b642d4fee11f7f86a2fcf9a is first bad commit
 commit 956a3e6bb7386de48b642d4fee11f7f86a2fcf9a
 Author: Blue Swirl blauwir...@gmail.com
 Date:   Sat May 22 07:59:01 2010 +

    Compile pckbd only once

    Use a qemu_irq to indicate A20 line changes. Move I/O port 92
    to pckbd.c.

    Signed-off-by: Blue Swirl blauwir...@gmail.com

 :100644 100644 acbaf227455f931f3ef6dbe0bb4494c6b41f2cd9 
 1a33d4eb4a5624c55896871b5f4ecde78a49ff28 M      Makefile.objs
 :100644 100644 a22484e1e98355a35deeb5038a45fb8fe8685a91 
 ba5147fbc48e4faef072a5be6b0d69d3201c1e18 M      Makefile.target
 :04 04 dd03f81a42b5162c93c40c517f45eb9f7bece93c 
 309f472328632319a15128a59715aa63daf4d92c M      default-configs
 :04 04 83201c4fcde2f592a771479246e0a33a8906515b 
 b1192bce85f2a7129fb19cf2fe7462ef168165cb M      hw
 bisect run success

 Nice job bisecting this!  I can reproduce the Memtest86+ V4.10 system
 reset with qemu-kvm.git and qemu.git.

 The following code path is hit when val=0x2:
 if (!(val  1)) {
    qemu_system_reset_request();
 }

 I think unifying ioport 0x92 and KBD_CCMD_WRITE_OUTPORT was incorrect.
  ioport 0x92 is the System Control Port A and resets the system if bit
 0 is 1.  The keyboard outport seems to reset if bit 0 is 0.

 Here are the links I've found describing the i8042 keyboard controller
 and System Control Port A:
 http://www.computer-engineering.org/ps2keyboard/
 http://www.win.tue.nl/~aeb/linux/kbd/A20.html

 Blue Swirl: Any thoughts on this?

SMSC LPC47S45x data sheet (p. 112) also confirms this. The proper fix
is to split the ports.

But then A20 logic becomes more complex, disabling either of keyboard
or port 92 A20 lines should disable system A20 gate.

I think we should move port 92 back to pc.c and add the missing A20
logic there as well.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC -v2 PATCH 2/3] sched: add yield_to function

2010-12-28 Thread Rik van Riel

On 12/28/2010 12:54 AM, Mike Galbraith wrote:

On Mon, 2010-12-20 at 17:04 +0100, Mike Galbraith wrote:

On Mon, 2010-12-20 at 10:40 -0500, Rik van Riel wrote:

On 12/17/2010 02:15 AM, Mike Galbraith wrote:


BTW, with this vruntime donation thingy, what prevents a task from
forking off accomplices who do nothing but wait for a wakeup and
yield_to(exploit)?

Even swapping vruntimes in the same cfs_rq is dangerous as hell, because
one party is going backward.


I just realized the answer to this question.

We only give cpu time to tasks that are runnable, but not
currently running.  That ensures one task cannot block others
from running by having time yielded to it constantly.


Hm.  Don't think that will 100% sure prevent clock stoppage, because the
running task doesn't necessarily advance min_vruntime.

What about something like the below instead?  It compiles, but may eat
your first born child.


(either it's christmas, or nobody cares to try it.  ho ho hum:)


It's christmas.

I've replaced my original patch with your patch in my
series, just haven't gotten around to running Avi's
latest test on it yet :)

--
All rights reversed
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


KVM clock synchronization

2010-12-28 Thread Zachary Amsden
A further set of improvements to KVM clock.  Now it actually can
stay synchronized on SMP systems with a stable TSC, does not get
destabilized by host suspend, and is resistant to migration.

I did look a bit into the second to last remaining migration issue;
that is, we read the TSCs for all VCPUs at different times, then
write them back at different times as well.  We have compensation
for this already (see patch 1), but there is a possibility that
ordering issues create a backwards condition:

  read VTSC-0
  stop VCPU-0
  read VTSC-1
  stop VCPU-1

In that case, what the compensation code does is reset VTSC-1
back to VTSC-0.  With the above ordering, this is broken.

However, in QEMU, the migration order is:

  stop VCPU-0
  stop VCPU-1
  read VTSC-0
  read VTSC-1

So even if a higher TSC value is read for VTSC-1, no backwards
condition can be generated, as VCPU-1 was not running at the time
and thus could not have observed the higher TSC.

This brings us close to having a perfect KVM clock.

Next steps will be testing to see if this in practice allows us
to drop the atomic backwards protection for KVM clock, and if so,
to implement vread so we have fast system calls for time.

Zach

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM Clock Synchronization 1/4] Make cyc_to_nsec conversions more reliable

2010-12-28 Thread Zachary Amsden
Rather than use the host CPU TSC rate, which can change, compute
cycle to nanosecond conversion in the guest TSC rate, which is
fixed.  This allows the math for write compensation detection
to be made more reliable.

Signed-off-by: Zachary Amsden zams...@redhat.com
---
 arch/x86/kvm/x86.c |   58 +--
 1 files changed, 24 insertions(+), 34 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index bfcf8fd..b9118f4 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -964,26 +964,10 @@ static inline u64 get_kernel_ns(void)
 static DEFINE_PER_CPU(unsigned long, cpu_tsc_khz);
 unsigned long max_tsc_khz;
 
-static inline int kvm_tsc_changes_freq(void)
+static inline u64 nsec_to_cycles(struct kvm *kvm, u64 nsec)
 {
-   int cpu = get_cpu();
-   int ret = !boot_cpu_has(X86_FEATURE_CONSTANT_TSC) 
- cpufreq_quick_get(cpu) != 0;
-   put_cpu();
-   return ret;
-}
-
-static inline u64 nsec_to_cycles(u64 nsec)
-{
-   u64 ret;
-
-   WARN_ON(preemptible());
-   if (kvm_tsc_changes_freq())
-   printk_once(KERN_WARNING
-kvm: unreliable cycle conversion on adjustable rate TSC\n);
-   ret = nsec * __get_cpu_var(cpu_tsc_khz);
-   do_div(ret, USEC_PER_SEC);
-   return ret;
+   return pvclock_scale_delta(nsec, kvm-arch.virtual_tsc_mult,
+  kvm-arch.virtual_tsc_shift);
 }
 
 static void kvm_arch_set_tsc_khz(struct kvm *kvm, u32 this_tsc_khz)
@@ -1010,6 +994,7 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data)
u64 offset, ns, elapsed;
unsigned long flags;
s64 sdiff;
+   u64 delta;
 
spin_lock_irqsave(kvm-arch.tsc_write_lock, flags);
offset = data - native_read_tsc();
@@ -1020,29 +1005,34 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data)
sdiff = -sdiff;
 
/*
-* Special case: close write to TSC within 5 seconds of
-* another CPU is interpreted as an attempt to synchronize
-* The 5 seconds is to accomodate host load / swapping as
-* well as any reset of TSC during the boot process.
+* Special case: TSC write with a small delta (1 second) of virtual
+* cycle time against real time is interpreted as an attempt
+* to synchronize the CPU.
 *
-* In that case, for a reliable TSC, we can match TSC offsets,
-* or make a best guest using elapsed value.
+* For a reliable TSC, we can match TSC offsets, and for an
+* unstable TSC, we will write the update, but ignore elapsed time
+* in this computation. The reason for this is that unstable TSC
+* will be compensated by the catchup code, and guest loops which
+* continually write the TSC could end up overshooting the TSC if
+* the elapsed time is factored in.
 */
-   if (sdiff  nsec_to_cycles(5ULL * NSEC_PER_SEC) 
-   elapsed  5ULL * NSEC_PER_SEC) {
+   delta = nsec_to_cycles(kvm, elapsed);
+   sdiff -= delta;
+   if (sdiff  0)
+   sdiff = -sdiff;
+   if (sdiff  nsec_to_cycles(kvm, NSEC_PER_SEC) ) {
if (!check_tsc_unstable()) {
offset = kvm-arch.last_tsc_offset;
pr_debug(kvm: matched tsc offset for %llu\n, data);
} else {
-   u64 delta = nsec_to_cycles(elapsed);
-   offset += delta;
-   pr_debug(kvm: adjusted tsc offset by %llu\n, delta);
+   /* Unstable write; don't add elapsed time */
+   pr_debug(kvm: matched write on unstable tsc\n);
}
-   ns = kvm-arch.last_tsc_nsec;
+   } else {
+   kvm-arch.last_tsc_nsec = ns;
+   kvm-arch.last_tsc_write = data;
+   kvm-arch.last_tsc_offset = offset;
}
-   kvm-arch.last_tsc_nsec = ns;
-   kvm-arch.last_tsc_write = data;
-   kvm-arch.last_tsc_offset = offset;
kvm_x86_ops-write_tsc_offset(vcpu, offset);
spin_unlock_irqrestore(kvm-arch.tsc_write_lock, flags);
 
-- 
1.7.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[KVM Clock Synchronization 2/4] Keep TSC synchronized across host suspend

2010-12-28 Thread Zachary Amsden
During a host suspend, TSC may go backwards, which KVM interprets
as an unstable TSC.  Technically, KVM should not be marking the
TSC unstable, which causes the TSC clocksource to go bad, but
should be adjusting the TSC offsets in such a case.

Signed-off-by: Zachary Amsden zams...@redhat.com
---
 arch/x86/include/asm/kvm_host.h |1 +
 arch/x86/kvm/x86.c  |   66 +++---
 2 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 9e6fe39..63a82b0 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -386,6 +386,7 @@ struct kvm_vcpu_arch {
u64 last_kernel_ns;
u64 last_tsc_nsec;
u64 last_tsc_write;
+   u64 tsc_offset_adjustment;
bool tsc_catchup;
 
bool nmi_pending;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b9118f4..b509c01 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2042,12 +2042,20 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
}
 
kvm_x86_ops-vcpu_load(vcpu, cpu);
+
+   /* Apply any externally detected TSC adjustments (due to suspend) */
+   if (unlikely(vcpu-arch.tsc_offset_adjustment)) {
+   kvm_x86_ops-adjust_tsc_offset(vcpu,
+   vcpu-arch.tsc_offset_adjustment);
+   vcpu-arch.tsc_offset_adjustment = 0;
+   kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
+   }
if (unlikely(vcpu-cpu != cpu) || check_tsc_unstable()) {
/* Make sure TSC doesn't go backwards */
s64 tsc_delta = !vcpu-arch.last_host_tsc ? 0 :
native_read_tsc() - vcpu-arch.last_host_tsc;
if (tsc_delta  0)
-   mark_tsc_unstable(KVM discovered backwards TSC);
+   WARN_ON(!check_tsc_unstable());
if (check_tsc_unstable()) {
kvm_x86_ops-adjust_tsc_offset(vcpu, -tsc_delta);
vcpu-arch.tsc_catchup = 1;
@@ -5778,14 +5786,60 @@ int kvm_arch_hardware_enable(void *garbage)
 {
struct kvm *kvm;
struct kvm_vcpu *vcpu;
-   int i;
+   int i, ret;
+   u64 local_tsc;
+   u64 max_tsc = 0;
+   bool stable, backwards_tsc = false;
 
kvm_shared_msr_cpu_online();
-   list_for_each_entry(kvm, vm_list, vm_list)
-   kvm_for_each_vcpu(i, vcpu, kvm)
-   if (vcpu-cpu == smp_processor_id())
+   local_tsc = native_read_tsc();
+   stable = !check_tsc_unstable();
+   ret = kvm_x86_ops-hardware_enable(garbage);
+   if (ret)
+   return ret;
+
+   list_for_each_entry(kvm, vm_list, vm_list) {
+   kvm_for_each_vcpu(i, vcpu, kvm) {
+   if (!stable  vcpu-cpu == smp_processor_id())
kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
-   return kvm_x86_ops-hardware_enable(garbage);
+   if (stable  vcpu-arch.last_host_tsc  local_tsc) {
+   backwards_tsc = true;
+   if (vcpu-arch.last_host_tsc  max_tsc)
+   max_tsc = vcpu-arch.last_host_tsc;
+   }
+   }
+   }
+
+   /*
+* Sometimes, reliable TSCs go backwards.  This happens
+* on platforms that reset TSC during suspend or hibernate
+* actions, but maintain synchronization.  We must compensate.
+* Unfortunately, we can't bring the TSCs fully up to date
+* with real time.  The reason is that we aren't yet far
+* enough into CPU bringup that we know how much real time
+* has actually elapsed; our helper function, get_kernel_ns()
+* will be using boot variables that haven't been updated yet.
+* We simply find the maximum observed TSC above, then record
+* the adjustment to TSC in each VCPU.  When the VCPU later
+* gets loaded, the adjustment will be applied.  Note that we
+* accumulate adjustments, in case multiple suspend cycles
+* happen before the VCPU gets a chance to run again.
+*
+* Note that unreliable TSCs will be compensated already by
+* the logic in vcpu_load, which sets the TSC to catchup mode.
+* This will catchup all VCPUs to real time, but cannot
+* guarantee synchronization.
+*/
+   if (backwards_tsc) {
+   u64 delta_cyc = max_tsc - local_tsc;
+   list_for_each_entry(kvm, vm_list, vm_list)
+   kvm_for_each_vcpu(i, vcpu, kvm) {
+   vcpu-arch.tsc_offset_adjustment += delta_cyc;
+   vcpu-arch.last_host_tsc = 0;
+   }
+   }
+
+   return 0;
 }
 
 void kvm_arch_hardware_disable(void *garbage)
-- 
1.7.1

--
To unsubscribe from 

[KVM Clock Synchronization 4/4] Add master clock for KVM clock

2010-12-28 Thread Zachary Amsden
On systems with synchronized TSCs, we still have VCPU individual
KVM clocks, each with their own computed offset.  As this all happens
at different times, the computed KVM clock offset can vary, causing a
globally visible backwards clock.  Currently this is protected against
by using an atomic compare to ensure it does not happen.

This change should remove that requirement.

Signed-off-by: Zachary Amsden zams...@redhat.com
---
 arch/x86/include/asm/kvm_host.h |1 +
 arch/x86/kvm/x86.c  |   42 ++-
 2 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 8d829b8..ff651b7 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -445,6 +445,7 @@ struct kvm_arch {
unsigned long irq_sources_bitmap;
s64 kvmclock_offset;
spinlock_t clock_lock;
+   struct pvclock_vcpu_time_info master_clock;
u64 last_tsc_nsec;
u64 last_tsc_offset;
u64 last_tsc_write;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 59d5999..a339e50 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1116,6 +1116,38 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
return 0;
 
/*
+* If there is a stable TSC, we use a master reference clock for
+* the KVM clock; otherwise, individual computations for each VCPU
+* would exhibit slight drift relative to each other, which could
+* cause global time to go backwards.
+*
+* If the master clock has no TSC timestamp, that means we must
+* recompute the clock as either some real time has elapsed during
+* a suspend cycle, or we are measuring the clock for the first time
+* during VM creation (or following a migration).  Since master clock
+* changes should happen only at rare occasions, so we can ignore
+* the precautions below.
+*/
+   if (!check_tsc_unstable()) {
+   struct pvclock_vcpu_time_info *master =
+   v-kvm-arch.master_clock;
+   if (vcpu-hv_clock.version != master-version) {
+   spin_lock(v-kvm-arch.clock_lock);
+   WARN_ON(master-version  vcpu-hv_clock.version);
+   if (!master-tsc_timestamp) {
+   pr_debug(KVM: computing new master clock\n);
+   update_pvclock(v, master, tsc_timestamp,
+   kernel_ns, tsc_khz);
+   }
+   memcpy(vcpu-hv_clock, master, sizeof(*master));
+   spin_unlock(v-kvm-arch.clock_lock);
+   update_user_kvmclock(v, vcpu-hv_clock);
+   } else
+   pr_debug(ignoring spurious KVM clock update);
+   return 0;
+   }
+
+   /*
 * Time as measured by the TSC may go backwards when resetting the base
 * tsc_timestamp.  The reason for this is that the TSC resolution is
 * higher than the resolution of the other clock scales.  Thus, many
@@ -3482,7 +3514,11 @@ long kvm_arch_vm_ioctl(struct file *filp,
r = 0;
now_ns = get_kernel_ns();
delta = user_ns.clock - now_ns;
+   spin_lock(kvm-arch.clock_lock);
+   kvm-arch.master_clock.version += 2;
+   kvm-arch.master_clock.tsc_timestamp = 0;
kvm-arch.kvmclock_offset = delta;
+   spin_unlock(kvm-arch.clock_lock);
break;
}
case KVM_GET_CLOCK: {
@@ -5845,11 +5881,14 @@ int kvm_arch_hardware_enable(void *garbage)
 */
if (backwards_tsc) {
u64 delta_cyc = max_tsc - local_tsc;
-   list_for_each_entry(kvm, vm_list, vm_list)
+   list_for_each_entry(kvm, vm_list, vm_list) {
kvm_for_each_vcpu(i, vcpu, kvm) {
vcpu-arch.tsc_offset_adjustment += delta_cyc;
vcpu-arch.last_host_tsc = 0;
}
+   kvm-arch.master_clock.tsc_timestamp = 0;
+   kvm-arch.master_clock.version += 2;
+   }
}
 
return 0;
@@ -5965,6 +6004,7 @@ struct  kvm *kvm_arch_create_vm(void)
set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, kvm-arch.irq_sources_bitmap);
 
spin_lock_init(kvm-arch.clock_lock);
+   kvm-arch.master_clock.version = 1000;
 
return kvm;
 }
-- 
1.7.1

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2][RFC] KVM: Emulate MSI-X table and PBA in kernel

2010-12-28 Thread Sheng Yang
On Tuesday 28 December 2010 20:26:13 Avi Kivity wrote:
 On 12/22/2010 10:44 AM, Sheng Yang wrote:
  Then we can support mask bit operation of assigned devices now.
  
  
  @@ -3817,14 +3819,16 @@ static int
  emulator_write_emulated_onepage(unsigned long addr,
  
mmio:
  trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, bytes, gpa, *(u64 *)val);
  
  +   r = vcpu_mmio_write(vcpu, gpa, bytes, val);
  
  /*
  
   * Is this MMIO handled locally?
   */
  
  -   if (!vcpu_mmio_write(vcpu, gpa, bytes, val))
  +   if (!r)
  
  return X86EMUL_CONTINUE;
  
  vcpu-mmio_needed = 1;
  
  -   vcpu-run-exit_reason = KVM_EXIT_MMIO;
  +   vcpu-run-exit_reason = (r == -ENOTSYNC) ?
  +   KVM_EXIT_MSIX_ROUTING_UPDATE : KVM_EXIT_MMIO;
 
 This isn't very pretty, exit_reason should be written in
 vcpu_mmio_write().  I guess we can refactor it later.

Sure.
 
  +#define KVM_MSIX_MMIO_TYPE_ASSIGNED_DEV(1  0)
  +
  +#define KVM_MSIX_MMIO_TYPE_BASE_TABLE  (1  8)
  +#define KVM_MSIX_MMIO_TYPE_BASE_PBA(1  9)
  +
  +#define KVM_MSIX_MMIO_TYPE_DEV_MASK0x00ff
  +#define KVM_MSIX_MMIO_TYPE_BASE_MASK   0xff00
 
 Any explanation of these?

I chose to use assigned device id instead of one specific table id, because 
every 
device should got at most one MSI MMIO(the same should applied to vfio device 
as 
well), and if we use specific table ID, we need way to associate with the 
device 
anyway, to perform mask/unmask or other operation. So I think it's better to 
use 
device ID here directly. 

And for the table and pba address, it's due to the mapping in userspace may 
know 
the guest MSI-X table address and PBA address at different time(due to 
different 
BAR, refer to the code in assigned_dev_iomem_map() of qemu). So I purposed this 
API to allow each of them can be passed to kernel space individually.
 
  +struct kvm_msix_mmio_user {
  +   __u32 dev_id;
  +   __u16 type;
  +   __u16 max_entries_nr;
  +   __u64 base_addr;
  +   __u64 base_va;
  +   __u64 flags;
  +   __u64 reserved[4];
  +};
  +
  
  
  +int kvm_assigned_device_update_msix_mask_bit(struct kvm *kvm,
  +   int assigned_dev_id, int entry, u32 flag)
  +{
 
 Need a better name for 'flag' (and make it a bool).
 
  +   int r = -EFAULT;
  +   struct kvm_assigned_dev_kernel *adev;
  +   int i;
  +
  +   if (!irqchip_in_kernel(kvm))
  +   return r;
  +
  +   mutex_lock(kvm-lock);
  +   adev = kvm_find_assigned_dev(kvm-arch.assigned_dev_head,
  + assigned_dev_id);
  +   if (!adev)
  +   goto out;
  +
  +   for (i = 0; i  adev-entries_nr; i++)
  +   if (adev-host_msix_entries[i].entry == entry) {
  +   if (flag)
  +   disable_irq_nosync(
  +   adev-host_msix_entries[i].vector);
  +   else
  +   enable_irq(adev-host_msix_entries[i].vector);
  +   r = 0;
  +   break;
  +   }
  +out:
  +   mutex_unlock(kvm-lock);
  +   return r;
  +}
  
  @@ -1988,6 +2008,12 @@ static int kvm_dev_ioctl_create_vm(void)
  
  return r;
  
  }

#endif
  
  +   r = kvm_register_msix_mmio_dev(kvm);
  +   if (r  0) {
  +   kvm_put_kvm(kvm);
  +   return r;
  +   }
 
 Shouldn't this be part of individual KVM_REGISTER_MSIX_MMIO calls?

In fact this MMIO device is more like global one for the VM, not for every 
devices. It should handle all MMIO from all MSI-X enabled devices, so I put it 
in 
the VM init/destroy process.

  +static int msix_table_mmio_read(struct kvm_io_device *this, gpa_t addr,
  int len, +  void *val)
  +{
  +   struct kvm_msix_mmio_dev *mmio_dev =
  +   container_of(this, struct kvm_msix_mmio_dev, table_dev);
  +   struct kvm_msix_mmio *mmio;
  +   int idx, ret = 0, entry, offset, r;
  +
  +   mutex_lock(mmio_dev-lock);
  +   idx = get_mmio_table_index(mmio_dev, addr, len);
  +   if (idx  0) {
  +   ret = -EOPNOTSUPP;
  +   goto out;
  +   }
  +   if ((addr  0x3) || (len != 4  len != 8))
  +   goto out;
 
 What about (addr  4)  (len == 8)? Is it supported? It may cross entry
 boundaries.

Should not supported. But I haven't found words on the PCI spec for it. So I 
didn't add this check.
 
  +   mmio =mmio_dev-mmio[idx];
  +
  +   entry = (addr - mmio-table_base_addr) / PCI_MSIX_ENTRY_SIZE;
  +   offset = addr  0xf;
  +   r = copy_from_user(val, (void *)(mmio-table_base_va +
  +   entry * PCI_MSIX_ENTRY_SIZE + offset), len);
  
  
  +   if (r)
  +   goto out;
  +out:
  +   mutex_unlock(mmio_dev-lock);
  +   return ret;
  +}
  +
  +static int msix_table_mmio_write(struct kvm_io_device *this, gpa_t addr,
  +   int len, const void *val)
  +{
  +   struct kvm_msix_mmio_dev *mmio_dev =
  +   container_of(this, struct