Re: [Qemu-devel] [PATCH] PPC: Fix linker scripts on ppc hosts

2011-12-12 Thread Alexander Graf

On 13.12.2011, at 07:19, Paul Brook  wrote:

>>> When compiling qemu statically with multilib on PPC, we hit the
>>> same issue that commit 845f2c2812d9ed24b36c02a3d06ee83aeafe8b49
>>> is fixing. Do the same here.
>> 
>> How many of these ld files can we get rid of if we use -Ttext-segment
>> instead? Generally all we're really caring about is moving the program
>> base around so that it doesn't conflict with the address space we want to
>> use for the client.
> 
> Now that we have the automatic GUEST_BASE stuff you shouldn't need to do 
> either.

If it was working, yes :)

Alex




Re: [Qemu-devel] buildbot failure in qemu on default_mingw32

2011-12-12 Thread Paolo Bonzini

On 12/13/2011 02:02 AM, q...@buildbot.b1-systems.de wrote:

The Buildbot has detected a new failure on builder default_mingw32 while 
building qemu.
Full details are available at:
  http://buildbot.b1-systems.de/qemu/builders/default_mingw32/builds/114

Buildbot URL: http://buildbot.b1-systems.de/qemu/

Buildslave for this Build: kraxel_rhel61

Build Reason: The Nightly scheduler named 'nightly_default' triggered this build
Build Source Stamp: [branch master] HEAD
Blamelist:

BUILD FAILED: failed compile


This is a merge conflict with my thread_join series, will fix.

Paolo





Re: [Qemu-devel] [PATCH] PPC: Fix linker scripts on ppc hosts

2011-12-12 Thread Paul Brook
> > When compiling qemu statically with multilib on PPC, we hit the
> > same issue that commit 845f2c2812d9ed24b36c02a3d06ee83aeafe8b49
> > is fixing. Do the same here.
> 
> How many of these ld files can we get rid of if we use -Ttext-segment
> instead? Generally all we're really caring about is moving the program
> base around so that it doesn't conflict with the address space we want to
> use for the client.

Now that we have the automatic GUEST_BASE stuff you shouldn't need to do 
either.

Paul



Re: [Qemu-devel] [RFC][PATCT 0/5 v2] dump memory when host pci device is used by guest

2011-12-12 Thread HATAYAMA Daisuke
From: Wen Congyang 
Subject: Re: [Qemu-devel] [RFC][PATCT 0/5 v2] dump memory when host pci device 
is used by guest
Date: Tue, 13 Dec 2011 11:35:53 +0800

> Hi, hatayama-san
> 
> At 12/13/2011 11:12 AM, HATAYAMA Daisuke Write:
>> Hello Wen,
>> 
>> From: Wen Congyang 
>> Subject: [Qemu-devel] [RFC][PATCT 0/5 v2] dump memory when host pci device 
>> is used by guest
>> Date: Fri, 09 Dec 2011 15:57:26 +0800
>> 
>>> Hi, all
>>>
>>> 'virsh dump' can not work when host pci device is used by guest. We have
>>> discussed this issue here:
>>> http://lists.nongnu.org/archive/html/qemu-devel/2011-10/msg00736.html
>>>
>>> We have determined to introduce a new command dump to dump memory. The core
>>> file's format can be elf.
>>>
>>> Note:
>>> 1. The guest should be x86 or x86_64. The other arch is not supported.
>>> 2. If you use old gdb, gdb may crash. I use gdb-7.3.1, and it does not 
>>> crash.
>>> 3. If the OS is in the second kernel, gdb may not work well, and crash can
>>>work by specifying '--machdep phys_addr=xxx' in the command line. The
>>>reason is that the second kernel will update the page table, and we can
>>>not get the page table for the first kernel.
>> 
>> I guess still the current implementation breaks vmalloc'ed area that
>> needs page tables originally located in the first 640kB, right? If you
>> want to do so in a correct way, you need to identify a position of
>> backup region and get data of 1st kernel's page tables.
> 
> I do not know anything about vmalloc'ed area. Can you explain it more
> detailed?
> 

It's memory area not straight-mapped. To read the area, it's necessary
to look up guest machine's page tables. If I understand correctly,
your current implementation translates the vmalloc'ed area so that the
generated vmcore is linearly mapped w.r.t. virtual-address for gdb to
work.

kdump saves the first 640kB physical memory into the backup region. I
guess, for some vmcores created by the current implementation, gdb and
crash cannot see the vmalloc'ed memory area that needs page tables
placed at the 640kB region, correctly. For example, try to use mod
sub-command. Kernel modules are allocated on vmalloc'ed area.

I have developped a very similar logic for sadump. Look at sadump.c in
crash. Logic itself is very simple, but debugging information is
necessary. Documentation/kdump/kdump.txt and the following paper
explains backup region mechanism very well, and the implementaion
around there remains same now.

  http://lse.sourceforge.net/kdump/documentation/ols2oo5-kdump-paper.pdf

On the other hand, have you written patch for crash to read this
vmcore? I expect it's possible by a little fix to kcore code.

> 
> Do you mean dump guest's memory while it is running(do not stop the guest)?
> If so, this command can not be used for creating live dump.
> 

I mean dump that keeps machine running as you say.
Do you have plan for live dump?

Thanks.
HATAYAMA, Daisuke




Re: [Qemu-devel] [PATCH V13 0/7] Qemu Trusted Platform Module (TPM) integration

2011-12-12 Thread Stefan Weil

Am 12.12.2011 20:12, schrieb Stefan Berger:

The following series of patches adds TPM (Trusted Platform Module) support
to Qemu. An emulator for the TIS (TPM Interface Spec) interface is
added that provides the basis for accessing a 'backend' implementing the actual
TPM functionality. The TIS emulator serves as a 'frontend' enabling for
example Linux's TPM TIS (tpm_tis) driver.

In this series I am posting a backend implementation that makes use of the
host's TPM through a passthrough driver, which on Linux is accessed
using /dev/tpm0.



Hi Stefan,

please use "GPL V2 or later" (not GPL V2 only) for new files.
"Qemu" should be replaced by "QEMU".

Regards,
Stefan Weil




[Qemu-devel] [PATCH 7/8] pseries: Populate "/chosen/linux, stdout-path" in the FDT

2011-12-12 Thread David Gibson
There is a device tree property "/chosen/linux,stdout-path" which indicates
which device should be used as stdout - ie. "the console".

Currently we don't specify anything, which means both firmware and Linux
choose something arbitrarily. Use the routine we added in the last patch
to pick a default vty and specify it as stdout.

Currently SLOF doesn't use the property, but we are hoping to update it
to do so.

Signed-off-by: Michael Ellerman 
Signed-off-by: David Gibson 
---
 hw/spapr.c |2 ++
 hw/spapr_vio.c |   34 ++
 hw/spapr_vio.h |3 +++
 hw/spapr_vty.c |2 +-
 4 files changed, 40 insertions(+), 1 deletions(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index 1883270..6a543de 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -441,6 +441,8 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
 }
 }
 
+spapr_populate_chosen_stdout(fdt, spapr->vio_bus);
+
 _FDT((fdt_pack(fdt)));
 
 cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 339c1c3..b188a71 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -791,4 +791,38 @@ out:
 
 return ret;
 }
+
+int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus)
+{
+VIOsPAPRDevice *dev;
+char *name, *path;
+int ret, offset;
+
+dev = spapr_vty_get_default(bus);
+if (!dev)
+return 0;
+
+offset = fdt_path_offset(fdt, "/chosen");
+if (offset < 0) {
+return offset;
+}
+
+name = vio_format_dev_name(dev);
+if (!name) {
+return -ENOMEM;
+}
+
+if (asprintf(&path, "/vdevice/%s", name) < 0) {
+path = NULL;
+ret = -ENOMEM;
+goto out;
+}
+
+ret = fdt_setprop_string(fdt, offset, "linux,stdout-path", path);
+out:
+free(name);
+free(path);
+
+return ret;
+}
 #endif /* CONFIG_FDT */
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index 2430d45..0984d55 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -82,6 +82,7 @@ extern VIOsPAPRBus *spapr_vio_bus_init(void);
 extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
 extern void spapr_vio_bus_register_withprop(VIOsPAPRDeviceInfo *info);
 extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt);
+extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus);
 
 extern int spapr_vio_signal(VIOsPAPRDevice *dev, target_ulong mode);
 
@@ -107,6 +108,8 @@ void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, 
CharDriverState *chardev);
 void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd);
 void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg);
 
+VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus);
+
 int spapr_tce_set_bypass(uint32_t unit, uint32_t enable);
 void spapr_vio_quiesce(void);
 
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index fc8d91a..0a8016f 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -149,7 +149,7 @@ static VIOsPAPRDeviceInfo spapr_vty = {
 },
 };
 
-static VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
+VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
 {
 VIOsPAPRDevice *sdev, *selected;
 DeviceState *iter;
-- 
1.7.7.3




[Qemu-devel] [PATCH 3/8] pseries: FDT NUMA extensions to support multi-node guests

2011-12-12 Thread David Gibson
From: Bharata B Rao 

Add NUMA specific properties to guest's device tree to boot a multi-node
guests. This patch adds the following properties:

ibm,associativity
ibm,architecture-vec-5
ibm,associativity-reference-points

With this, it becomes possible to use -numa option on pseries targets.

Signed-off-by: Bharata B Rao 
Signed-off-by: David Gibson 
---
 hw/spapr.c |  112 ++--
 hw/spapr.h |1 +
 2 files changed, 102 insertions(+), 11 deletions(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index 2b901f1..1883270 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -97,6 +97,44 @@ qemu_irq spapr_allocate_irq(uint32_t hint, uint32_t *irq_num)
 return qirq;
 }
 
+static int spapr_set_associativity(void *fdt, sPAPREnvironment *spapr)
+{
+int ret = 0, offset;
+CPUState *env;
+char cpu_model[32];
+int smt = kvmppc_smt_threads();
+
+assert(spapr->cpu_model);
+
+for (env = first_cpu; env != NULL; env = env->next_cpu) {
+uint32_t associativity[] = {cpu_to_be32(0x5),
+cpu_to_be32(0x0),
+cpu_to_be32(0x0),
+cpu_to_be32(0x0),
+cpu_to_be32(env->numa_node),
+cpu_to_be32(env->cpu_index)};
+
+if ((env->cpu_index % smt) != 0) {
+continue;
+}
+
+snprintf(cpu_model, 32, "/cpus/%s@%x", spapr->cpu_model,
+ env->cpu_index);
+
+offset = fdt_path_offset(fdt, cpu_model);
+if (offset < 0) {
+return offset;
+}
+
+ret = fdt_setprop(fdt, offset, "ibm,associativity", associativity,
+  sizeof(associativity));
+if (ret < 0) {
+return ret;
+}
+}
+return ret;
+}
+
 static void *spapr_create_fdt_skel(const char *cpu_model,
target_phys_addr_t rma_size,
target_phys_addr_t initrd_base,
@@ -107,9 +145,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
 {
 void *fdt;
 CPUState *env;
-uint64_t mem_reg_property_rma[] = { 0, cpu_to_be64(rma_size) };
-uint64_t mem_reg_property_nonrma[] = { cpu_to_be64(rma_size),
-   cpu_to_be64(ram_size - rma_size) };
+uint64_t mem_reg_property[2];
 uint32_t start_prop = cpu_to_be32(initrd_base);
 uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
 uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
@@ -119,6 +155,13 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
 int i;
 char *modelname;
 int smt = kvmppc_smt_threads();
+unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
+uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
+uint32_t associativity[] = {cpu_to_be32(0x4), cpu_to_be32(0x0),
+cpu_to_be32(0x0), cpu_to_be32(0x0),
+cpu_to_be32(0x0)};
+char mem_name[32];
+target_phys_addr_t node0_size, mem_start;
 
 #define _FDT(exp) \
 do { \
@@ -146,6 +189,9 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
 /* /chosen */
 _FDT((fdt_begin_node(fdt, "chosen")));
 
+/* Set Form1_affinity */
+_FDT((fdt_property(fdt, "ibm,architecture-vec-5", vec5, sizeof(vec5;
+
 _FDT((fdt_property_string(fdt, "bootargs", kernel_cmdline)));
 _FDT((fdt_property(fdt, "linux,initrd-start",
&start_prop, sizeof(start_prop;
@@ -164,24 +210,54 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
 _FDT((fdt_end_node(fdt)));
 
 /* memory node(s) */
-_FDT((fdt_begin_node(fdt, "memory@0")));
+node0_size = (nb_numa_nodes > 1) ? node_mem[0] : ram_size;
+if (rma_size > node0_size) {
+rma_size = node0_size;
+}
 
+/* RMA */
+mem_reg_property[0] = 0;
+mem_reg_property[1] = cpu_to_be64(rma_size);
+_FDT((fdt_begin_node(fdt, "memory@0")));
 _FDT((fdt_property_string(fdt, "device_type", "memory")));
-_FDT((fdt_property(fdt, "reg", mem_reg_property_rma,
-   sizeof(mem_reg_property_rma;
+_FDT((fdt_property(fdt, "reg", mem_reg_property,
+sizeof(mem_reg_property;
+_FDT((fdt_property(fdt, "ibm,associativity", associativity,
+sizeof(associativity;
 _FDT((fdt_end_node(fdt)));
 
-if (ram_size > rma_size) {
-char mem_name[32];
+/* RAM: Node 0 */
+if (node0_size > rma_size) {
+mem_reg_property[0] = cpu_to_be64(rma_size);
+mem_reg_property[1] = cpu_to_be64(node0_size - rma_size);
 
-sprintf(mem_name, "memory@%" PRIx64, (uint64_t)rma_size);
+sprintf(mem_name, "memory@" TARGET_FMT_lx, rma_size);
 _FDT((fdt_begin_node(fdt, mem_name)));
 _FDT((fdt_property_string(fdt, "device_type", "memory")));
-_FDT((fdt_propert

[Qemu-devel] [PATCH 6/8] pseries: Add a routine to find a stable "default" vty and use it

2011-12-12 Thread David Gibson
In vty_lookup() we have a special case for supporting early debug in
the kernel. This accepts reg == 0 as a special case to mean "any vty".

We implement this by searching the vtys on the bus and returning the
first we find. This means that the vty we chose depends on the order
the vtys are specified on the QEMU command line - because that determines
the order of the vtys on the bus.

We'd rather the command line order was irrelevant, so instead return
the vty with the lowest reg value. This is still a guess as to what the
user really means, but it is at least stable WRT command line ordering.

Signed-off-by: Michael Ellerman 
Signed-off-by: David Gibson 
---
 hw/spapr_vty.c |   46 +-
 1 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index e217314..fc8d91a 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -149,24 +149,52 @@ static VIOsPAPRDeviceInfo spapr_vty = {
 },
 };
 
+static VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
+{
+VIOsPAPRDevice *sdev, *selected;
+DeviceState *iter;
+
+/*
+ * To avoid the console bouncing around we want one VTY to be
+ * the "default". We haven't really got anything to go on, so
+ * arbitrarily choose the one with the lowest reg value.
+ */
+
+selected = NULL;
+QTAILQ_FOREACH(iter, &bus->bus.children, sibling) {
+/* Only look at VTY devices */
+if (iter->info != &spapr_vty.qdev) {
+continue;
+}
+
+sdev = DO_UPCAST(VIOsPAPRDevice, qdev, iter);
+
+/* First VTY we've found, so it is selected for now */
+if (!selected) {
+selected = sdev;
+continue;
+}
+
+/* Choose VTY with lowest reg value */
+if (sdev->reg < selected->reg)
+selected = sdev;
+}
+
+return selected;
+}
+
 static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
 {
 VIOsPAPRDevice *sdev;
 
 sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
 if (!sdev && reg == 0) {
-DeviceState *qdev;
-
 /* Hack for kernel early debug, which always specifies reg==0.
- * We search all VIO devices, and grab the first available vty
- * device.  This attempts to mimic existing PowerVM behaviour
+ * We search all VIO devices, and grab the vty with the lowest
+ * reg.  This attempts to mimic existing PowerVM behaviour
  * (early debug does work there, despite having no vty with
  * reg==0. */
-QTAILQ_FOREACH(qdev, &spapr->vio_bus->bus.children, sibling) {
-if (qdev->info == &spapr_vty.qdev) {
-return DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
-}
-}
+return spapr_vty_get_default(spapr->vio_bus);
 }
 
 return sdev;
-- 
1.7.7.3




[Qemu-devel] [PATCH 8/8] pseries: Check for duplicate addresses on the spapr-vio bus

2011-12-12 Thread David Gibson
From: Michael Ellerman 

Check that devices on the spapr vio bus aren't given duplicate
addresses. Currently we will not run with duplicate devices, the
fdt code will spot it, but the error reporting is not great. With
this patch we can report the error nicely in terms of the device
names given by the user.

Signed-off-by: Michael Ellerman 
Signed-off-by: David Gibson 
---
 hw/spapr_vio.c |   32 
 1 files changed, 32 insertions(+), 0 deletions(-)

diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index b188a71..0e5581c 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -621,11 +621,43 @@ static void rtas_quiesce(sPAPREnvironment *spapr, 
uint32_t token,
 rtas_st(rets, 0, 0);
 }
 
+static int spapr_vio_check_reg(VIOsPAPRDevice *sdev, VIOsPAPRDeviceInfo *info)
+{
+VIOsPAPRDevice *other_sdev;
+DeviceState *qdev;
+VIOsPAPRBus *sbus;
+
+sbus = DO_UPCAST(VIOsPAPRBus, bus, sdev->qdev.parent_bus);
+
+/*
+ * Check two device aren't given clashing addresses by the user (or some
+ * other mechanism). We have to open code this because we have to check
+ * for matches with devices other than us.
+ */
+QTAILQ_FOREACH(qdev, &sbus->bus.children, sibling) {
+other_sdev = DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
+
+if (other_sdev != sdev && other_sdev->reg == sdev->reg) {
+fprintf(stderr, "vio: %s and %s devices conflict at address %#x\n",
+info->qdev.name, other_sdev->qdev.info->name, sdev->reg);
+return -EEXIST;
+}
+}
+
+return 0;
+}
+
 static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo)
 {
 VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
 VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
 char *id;
+int ret;
+
+ret = spapr_vio_check_reg(dev, info);
+if (ret) {
+return ret;
+}
 
 /* Don't overwrite ids assigned on the command line */
 if (!dev->qdev.id) {
-- 
1.7.7.3




Re: [Qemu-devel] [PATCH V13 6/7] Introduce --enable-tpm-passthrough configure option

2011-12-12 Thread Paul Brook
> >> +tpm_passthrough="no"
> > 
> > Same as before, please probe for existence.
> 
> We would be probing for /dev/tpm0. Is that really what we want that this
> driver only gets compiled if /dev/tpm0 is (currently) available?

If what you say is true then this code should always be enabled.

Paul



Re: [Qemu-devel] [RFC] Plan for moving forward with QOM

2011-12-12 Thread Paul Brook
> The full set of devices names and properties used in this example are
> below:
> 
>   Type: I440FX
>   Is-a: Device
>   Implements: PciBus
>   Name: i440fx
>   Properties:
>piix3: Composition
>slot[1.0]: Backlink
> 
>   Type: PIIX3
>   Isa-a: PciDevice
>   Implements: IsaBus
>   Name: i440fx::piix3
>   Properties:
>i8042: Composition
>bus: Backlink (inherited from PciDevice)
>
>   Type: I8042
>   Isa-a: Device
>   Implements: Ps2Controller
>   Name: i440fx::piix3::i8042
>   Properties:
>aux: Backlink

I haven't looks at the patches in detail, but your description looks fairly 
dubious in its current form.

Is the type of piix3::bus a typo? I think this should be Backlink.

What is the difference between "Is-a" and "Implements"? It sounds like some 
form of multiple inheritance, but it's unclear to me which should be the 
primary type.  For PCI host bridges like the i440fx we currently have to split 
them into two, one fot the host bus and the other for the PCI bus.  It feels 
like if we design the model properly this should no longer be necessary.

I'm not so sure we should have Is-a at all.  Isn't the point of replacing the 
bus/device hierachy with a set of links that devices don't follow a simple 
tree structure?  It's fairly common for the tree branches to merge back 
together when a single device communicates via multiple busses.

It's somewhat unlear what the purpose of composition is.  Using composition 
for piix4::piiix and piix3::i8042 seems wrong.  In fact piix3 shouldn't have 
any knowledge of i8042 at all, it's just annother random ISA device.

Speaking of which, presumably i8042 should be an IsaDevice, which inherits 
(amongst other things) a bus: Backlink property.

What happens when my device has multiple parts that need to be referred to by 
other devices?  An interrupt controller is the most obvious example, but 
similar issues occur for any device that has multiple connections of the same 
type.  Am I expected to create a whole bunch of dummy devices and a private 
interface to bounce everything back to the main device, somethig like:

Type: MagicInterruptController
  Is-a: SystemBusDevice
  Implements: MagicInterruptInterface
  Properties:
in_pin0: Composition
in_pin1: Composition
out_pin: link

Type: MagicInterruptPin
  Implements: IRQ
  Properties:
pin_number: int
controller: BackLink

It seems like rather than having a device implement a set of interfaces, it 
might be better to have these be properties.  Call them a Target<>.  The above 
then becomes something like:

Type: MagicInterruptController
  Is-a: SystemBusDevice
  Properties:
in_pin0: Target
in_pin1: Target
out_pin: Link


Where the Target<> properties are objects/methods provided by the device, and 
the Link<> properties are pointed to them as the machine is constructed.

Paul



[Qemu-devel] [PATCH 1/8] pseries: Remove hcalls callback

2011-12-12 Thread David Gibson
For forgotten historical reasons, PAPR hypercalls for specific virtual IO
devices (oh which there are quite a number) are registered via a callback
in the VIOsPAPRDeviceInfo structure.

This is kind of ugly, so this patch instead registers hypercalls from
device_init() functions for each device type.  This works just as well,
and is cleaner.

Signed-off-by: David Gibson 
---
 hw/spapr_llan.c |   17 ++---
 hw/spapr_vio.c  |   13 -
 hw/spapr_vio.h  |1 -
 hw/spapr_vty.c  |9 ++---
 4 files changed, 8 insertions(+), 32 deletions(-)

diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index abe1297..45674c4 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -474,16 +474,6 @@ static target_ulong h_multicast_ctrl(CPUState *env, 
sPAPREnvironment *spapr,
 return H_SUCCESS;
 }
 
-static void vlan_hcalls(VIOsPAPRBus *bus)
-{
-spapr_register_hypercall(H_REGISTER_LOGICAL_LAN, h_register_logical_lan);
-spapr_register_hypercall(H_FREE_LOGICAL_LAN, h_free_logical_lan);
-spapr_register_hypercall(H_SEND_LOGICAL_LAN, h_send_logical_lan);
-spapr_register_hypercall(H_ADD_LOGICAL_LAN_BUFFER,
- h_add_logical_lan_buffer);
-spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
-}
-
 static VIOsPAPRDeviceInfo spapr_vlan = {
 .init = spapr_vlan_init,
 .devnode = spapr_vlan_devnode,
@@ -491,7 +481,6 @@ static VIOsPAPRDeviceInfo spapr_vlan = {
 .dt_type = "network",
 .dt_compatible = "IBM,l-lan",
 .signal_mask = 0x1,
-.hcalls = vlan_hcalls,
 .qdev.name = "spapr-vlan",
 .qdev.size = sizeof(VIOsPAPRVLANDevice),
 .qdev.props = (Property[]) {
@@ -504,5 +493,11 @@ static VIOsPAPRDeviceInfo spapr_vlan = {
 static void spapr_vlan_register(void)
 {
 spapr_vio_bus_register_withprop(&spapr_vlan);
+spapr_register_hypercall(H_REGISTER_LOGICAL_LAN, h_register_logical_lan);
+spapr_register_hypercall(H_FREE_LOGICAL_LAN, h_free_logical_lan);
+spapr_register_hypercall(H_SEND_LOGICAL_LAN, h_send_logical_lan);
+spapr_register_hypercall(H_ADD_LOGICAL_LAN_BUFFER,
+ h_add_logical_lan_buffer);
+spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
 }
 device_init(spapr_vlan_register);
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 2dcc036..5a35541 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -684,7 +684,6 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
 VIOsPAPRBus *bus;
 BusState *qbus;
 DeviceState *dev;
-DeviceInfo *qinfo;
 
 /* Create bridge device */
 dev = qdev_create(NULL, "spapr-vio-bridge");
@@ -711,18 +710,6 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
 spapr_rtas_register("ibm,set-tce-bypass", rtas_set_tce_bypass);
 spapr_rtas_register("quiesce", rtas_quiesce);
 
-for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
-VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
-
-if (qinfo->bus_info != &spapr_vio_bus_info) {
-continue;
-}
-
-if (info->hcalls) {
-info->hcalls(bus);
-}
-}
-
 return bus;
 }
 
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index a325a5f..2430d45 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -75,7 +75,6 @@ typedef struct {
 const char *dt_name, *dt_type, *dt_compatible;
 target_ulong signal_mask;
 int (*init)(VIOsPAPRDevice *dev);
-void (*hcalls)(VIOsPAPRBus *bus);
 int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
 } VIOsPAPRDeviceInfo;
 
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index f23cc36..e217314 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -135,18 +135,11 @@ void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, 
CharDriverState *chardev)
 qdev_init_nofail(dev);
 }
 
-static void vty_hcalls(VIOsPAPRBus *bus)
-{
-spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char);
-spapr_register_hypercall(H_GET_TERM_CHAR, h_get_term_char);
-}
-
 static VIOsPAPRDeviceInfo spapr_vty = {
 .init = spapr_vty_init,
 .dt_name = "vty",
 .dt_type = "serial",
 .dt_compatible = "hvterm1",
-.hcalls = vty_hcalls,
 .qdev.name = "spapr-vty",
 .qdev.size = sizeof(VIOsPAPRVTYDevice),
 .qdev.props = (Property[]) {
@@ -182,5 +175,7 @@ static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, 
target_ulong reg)
 static void spapr_vty_register(void)
 {
 spapr_vio_bus_register_withprop(&spapr_vty);
+spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char);
+spapr_register_hypercall(H_GET_TERM_CHAR, h_get_term_char);
 }
 device_init(spapr_vty_register);
-- 
1.7.7.3




[Qemu-devel] [PATCH 5/8] pseries: Emit device tree nodes in reg order

2011-12-12 Thread David Gibson
Although in theory the device tree has no inherent ordering, in practice
the order of nodes in the device tree does effect the order that devices
are detected by software.

Currently the ordering is determined by the order the devices appear on
the QEMU command line. Although that does give the user control over the
ordering, it is fragile, especially when the user does not generate the
command line manually - eg. when using libvirt etc.

So order the device tree based on the reg value, ie. the address of on
the VIO bus of the devices. This gives us a sane and stable ordering.

Signed-off-by: Michael Ellerman 
Signed-off-by: David Gibson 
---
 hw/spapr_vio.c |   48 +++-
 1 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 5a35541..339c1c3 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -736,21 +736,59 @@ static void spapr_vio_register_devices(void)
 device_init(spapr_vio_register_devices)
 
 #ifdef CONFIG_FDT
+static int compare_reg(const void *p1, const void *p2)
+{
+VIOsPAPRDevice const *dev1, *dev2;
+
+dev1 = (VIOsPAPRDevice *)*(DeviceState **)p1;
+dev2 = (VIOsPAPRDevice *)*(DeviceState **)p2;
+
+if (dev1->reg < dev2->reg)
+return -1;
+if (dev1->reg == dev2->reg)
+return 0;
+
+/* dev1->reg > dev2->reg */
+return 1;
+}
+
 int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt)
 {
-DeviceState *qdev;
-int ret = 0;
+DeviceState *qdev, **qdevs;
+int i, num, ret = 0;
 
+/* Count qdevs on the bus list */
+num = 0;
 QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
-VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
+num++;
+}
+
+/* Copy out into an array of pointers */
+qdevs = g_malloc(sizeof(qdev) * num);
+num = 0;
+QTAILQ_FOREACH(qdev, &bus->bus.children, sibling) {
+qdevs[num++] = qdev;
+}
+
+/* Sort the array */
+qsort(qdevs, num, sizeof(qdev), compare_reg);
+
+/* Hack alert. Give the devices to libfdt in reverse order, we happen
+ * to know that will mean they are in forward order in the tree. */
+for (i = num - 1; i >= 0; i--) {
+VIOsPAPRDevice *dev = (VIOsPAPRDevice *)(qdevs[i]);
 
 ret = vio_make_devnode(dev, fdt);
 
 if (ret < 0) {
-return ret;
+goto out;
 }
 }
 
-return 0;
+ret = 0;
+out:
+free(qdevs);
+
+return ret;
 }
 #endif /* CONFIG_FDT */
-- 
1.7.7.3




[Qemu-devel] [PATCH 2/8] monitor: add ability to dump SLB entries

2011-12-12 Thread David Gibson
From: Nishanth Aravamudan 

When run with a PPC Book3S (server) CPU Currently 'info tlb' in the
qemu monitor reports "dump_mmu: unimplemented".  However, during
bringup work, it can be quite handy to have the SLB entries, which are
available in the CPUPPCState.  This patch adds an implementation of
info tlb for book3s, which dumps the SLB.

Signed-off-by: Nishanth Aravamudan 
Signed-off-by: David Gibson 
---
 target-ppc/helper.c |   32 +++-
 1 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 137a494..29c7050 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1545,14 +1545,36 @@ static void mmubooke206_dump_mmu(FILE *f, 
fprintf_function cpu_fprintf,
 }
 }
 
+static void mmubooks_dump_mmu(FILE *f, fprintf_function cpu_fprintf,
+  CPUState *env)
+{
+int i;
+uint64_t slbe, slbv;
+
+cpu_synchronize_state(env);
+
+cpu_fprintf(f, "SLB\tESID\t\t\tVSID\n");
+for (i = 0; i < env->slb_nr; i++) {
+slbe = env->slb[i].esid;
+slbv = env->slb[i].vsid;
+if (slbe == 0 && slbv == 0) {
+continue;
+}
+cpu_fprintf(f, "%d\t0x%016" PRIx64 "\t0x%016" PRIx64 "\n",
+i, slbe, slbv);
+}
+}
+
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
 {
-switch (env->mmu_model) {
-case POWERPC_MMU_BOOKE206:
+if (env->mmu_model == POWERPC_MMU_BOOKE206) {
 mmubooke206_dump_mmu(f, cpu_fprintf, env);
-break;
-default:
-cpu_fprintf(f, "%s: unimplemented\n", __func__);
+} else {
+if ((env->mmu_model & POWERPC_MMU_64B) != 0) {
+mmubooks_dump_mmu(f, cpu_fprintf, env);
+} else {
+cpu_fprintf(f, "%s: unimplemented\n", __func__);
+}
 }
 }
 
-- 
1.7.7.3




[Qemu-devel] [0/8] Assorted pseries updates

2011-12-12 Thread David Gibson
Now that qemu 1.0 is out there, here are a number of cleanups and
minor bugfixes for the pseries machine to queue up for post 1.0.  Many
of these fix problems with non-default device configurations exposed
by the w.i.p. port of libvirt for powerkvm.




Re: [Qemu-devel] [BUG] [Seabios] PCI 64bit BARs on Win2008 - unable to start the device. (ACPI lacks the _DSM method)

2011-12-12 Thread Alexey Korolev


Hi Gerd,



I'd strongly suggest to move forward to qemu 1.0.  Memory region
handling has seen a major rewrite in 1.0 (memory api patches by avi).
Chances are good that the 64bit bar bugs in qemu have been fixed meanwhile.

Thanks, will try it. Hope it will be better.

I have experimental patches which add a 64bit bar to the qxl device and
seabios handles it just fine (although memory-backed not mmio), except
that there is no support yet to map 64bit bars above 4G.

It shouldn't be that hard to add the latter though.  seabios needs two
more pci_region_type (PCI_REGION_TYPE_MEM_64 and
PCI_REGION_TYPE_PREFMEM_64) to track and map 64bit bars separately.  And
a address space window where it can map 64bit bars to.
Right. This is a thing I'm thinking about now. I seems that the 
specifying 0x0 address in 64bit BARS is a bad idea. At least older 
versions of Linux just hang as soon as requested range does not fit in 
first 4GB.
So the only option would be specifying the particular address range. It 
seems this works for everything - yet.

Sorry that I haven't specified all this initially. I just want to make
64bit PCI bar working properly. Linux guests works correctly (except
early versions - not investigated this yet). At the moment I have some
issues with windows which relies on ACPI _CRS.

... and a _CRS entry for the 64bit bar address space window of course.

Yes.

Cheers,
Alexey





[Qemu-devel] [PATCH] migration.h: remove incoming_expected declarations

2011-12-12 Thread Isaku Yamahata
The variable is deleted by 1bcef683bf840a928d633755031ac572d5fdb851
So remove its declaration.

Cc: Luiz Capitulino 
Signed-off-by: Isaku Yamahata 
---
 migration.h |2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/migration.h b/migration.h
index 999d60f..372b066 100644
--- a/migration.h
+++ b/migration.h
@@ -81,8 +81,6 @@ uint64_t ram_bytes_total(void);
 int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque);
 int ram_load(QEMUFile *f, void *opaque, int version_id);
 
-extern int incoming_expected;
-
 /**
  * @migrate_add_blocker - prevent migration from proceeding
  *
-- 
1.7.1.1




Re: [Qemu-devel] [RFC][PATCT 0/5 v2] dump memory when host pci device is used by guest

2011-12-12 Thread Wen Congyang
Hi, hatayama-san

At 12/13/2011 11:12 AM, HATAYAMA Daisuke Write:
> Hello Wen,
> 
> From: Wen Congyang 
> Subject: [Qemu-devel] [RFC][PATCT 0/5 v2] dump memory when host pci device is 
> used by guest
> Date: Fri, 09 Dec 2011 15:57:26 +0800
> 
>> Hi, all
>>
>> 'virsh dump' can not work when host pci device is used by guest. We have
>> discussed this issue here:
>> http://lists.nongnu.org/archive/html/qemu-devel/2011-10/msg00736.html
>>
>> We have determined to introduce a new command dump to dump memory. The core
>> file's format can be elf.
>>
>> Note:
>> 1. The guest should be x86 or x86_64. The other arch is not supported.
>> 2. If you use old gdb, gdb may crash. I use gdb-7.3.1, and it does not crash.
>> 3. If the OS is in the second kernel, gdb may not work well, and crash can
>>work by specifying '--machdep phys_addr=xxx' in the command line. The
>>reason is that the second kernel will update the page table, and we can
>>not get the page table for the first kernel.
> 
> I guess still the current implementation breaks vmalloc'ed area that
> needs page tables originally located in the first 640kB, right? If you
> want to do so in a correct way, you need to identify a position of
> backup region and get data of 1st kernel's page tables.

I do not know anything about vmalloc'ed area. Can you explain it more
detailed?

> 
> But it needs debugging information of guest kernel, and I don't think
> it good idea that qemu uses too guest-specific information.
> 
> On the other hand, I have a basic question. Can this command used for
> creating live dump? or crash dump only?

Do you mean dump guest's memory while it is running(do not stop the guest)?
If so, this command can not be used for creating live dump.

Thanks
Wen Congyang

> 
> Thanks.
> HATAYAMA, Daisuke
> 
> 




Re: [Qemu-devel] [PATCH v3 064/197] killall VIOsPAPRDeviceInfo

2011-12-12 Thread David Gibson
On Mon, Dec 12, 2011 at 08:25:51PM -0600, Anthony Liguori wrote:
> On 12/12/2011 08:22 PM, Michael Ellerman wrote:
> >On Mon, 2011-12-12 at 20:10 -0600, Anthony Liguori wrote:
> >>On 12/12/2011 08:04 PM, Michael Ellerman wrote:
> >>>On Mon, 2011-12-12 at 14:19 -0600, Anthony Liguori wrote:
> This was doing something evil building a dt tree so we broke the device.
> >>>
> @@ -711,8 +711,12 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
>    spapr_rtas_register("ibm,set-tce-bypass", rtas_set_tce_bypass);
>    spapr_rtas_register("quiesce", rtas_quiesce);
> 
> +#if 0
> +/* Evil and broken */
> >>>
> >>>By which you mean: works fine, broken by your patch?

Um, yeah.  It may have been evil, but it wasn't broken, whereas it
certainly is broken by this patch.

> >>These patches were never supposed to go out.  Ignore this series entirely.

Phew.

> >But I just read all 197 of them ! ;)
> >
>    for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
>    VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
> +VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
> 
>    if (qinfo->bus_info !=&spapr_vio_bus_info) {
>    continue;
> @@ -722,6 +726,7 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
>    info->hcalls(bus);
>    }
>    }
> +#endif
> >>>
> >>>It's registering hcalls for each class of device we find on the spapr
> >>>vio bus. I don't understand why that is evil, but what do you suggest we
> >>>do instead?
> >>
> >>I talked to David about this, the hcalls can just be registered as part the
> >>device_init entry points.
> >
> >OK I'll talk to him about it. I don't think device_init() works, because
> >we only want to register the hcalls if an instance of the device is
> >instantiated. But I guess we'll come up with something.

Hm, no, actually.  The reason we're stepping through the device infos
rather than vio devices is so that hcalls are registered per device
type rather than per device instance.

> Since the hcalls are well known and CPUState doesn't get touched at
> all, why not register all of the possible hcalls in the VIO bus and
> then use a higher level interface to dispatch to devices?  I think
> that conceptionally makes more sense than the devices directly
> registering hcalls themselves.

No, not really.  It means spapr_vio.c has to contain knowledge of
every possible VIO device.

> I know you're dealing with an existing virtual I/O model, but it's
> strange to have an hcall dispatched directly to a device without
> going through any type of controller/bus hierarchy.  It doesn't fit
> how hardware works very well.

But VIO devices don't work much like real hardware.  Other than the
CRQ and a few other hcalls, which are already handled at the bus
level, there is *no* common processing we can do for the device
specific hcalls.  Routing them through spapr_vio.c would just be
pointless redirection.


Anyway, I'll make a [atch to move the hypercall registrations to
device_init functions.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson




Re: [Qemu-devel] [RFC][PATCT 0/5 v2] dump memory when host pci device is used by guest

2011-12-12 Thread HATAYAMA Daisuke
Hello Wen,

From: Wen Congyang 
Subject: [Qemu-devel] [RFC][PATCT 0/5 v2] dump memory when host pci device is 
used by guest
Date: Fri, 09 Dec 2011 15:57:26 +0800

> Hi, all
> 
> 'virsh dump' can not work when host pci device is used by guest. We have
> discussed this issue here:
> http://lists.nongnu.org/archive/html/qemu-devel/2011-10/msg00736.html
> 
> We have determined to introduce a new command dump to dump memory. The core
> file's format can be elf.
> 
> Note:
> 1. The guest should be x86 or x86_64. The other arch is not supported.
> 2. If you use old gdb, gdb may crash. I use gdb-7.3.1, and it does not crash.
> 3. If the OS is in the second kernel, gdb may not work well, and crash can
>work by specifying '--machdep phys_addr=xxx' in the command line. The
>reason is that the second kernel will update the page table, and we can
>not get the page table for the first kernel.

I guess still the current implementation breaks vmalloc'ed area that
needs page tables originally located in the first 640kB, right? If you
want to do so in a correct way, you need to identify a position of
backup region and get data of 1st kernel's page tables.

But it needs debugging information of guest kernel, and I don't think
it good idea that qemu uses too guest-specific information.

On the other hand, I have a basic question. Can this command used for
creating live dump? or crash dump only?

Thanks.
HATAYAMA, Daisuke




[Qemu-devel] (no subject)

2011-12-12 Thread Erik Lotspeich
Hi,

I posted this on qemu-discuss and didn't receive any replies; sorry
for posting it twice.

I have OpenSUSE 12.1 and I have a 64-bit Windows 7 VM that recognizes
the emulated ICH6 sound (HDA audio device).  Although Windows
recognizes this sound device just fine, there is no sound from the
Windows 7 VM.  Sound works fine in KDE and from all other applications
on the Linux side.  I would appreciate any ideas or help?

Thanks!

Regards,

Erik



[Qemu-devel] [PATCH v3 1/3] memory: add a memory API about ioeventfd for PIO long

2011-12-12 Thread zanghongyong
From: Hongyong Zang 

The new memory API, named kvm_set_ioeventfd_pio_long, is about ioeventfd for 
PIO long.

Signed-off-by: Hongyong Zang 
---
 kvm-all.c  |   23 +++
 kvm-stub.c |5 +
 kvm.h  |1 +
 memory.c   |   20 
 4 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 4c466d6..4614c5d 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1365,6 +1365,29 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, 
uint32_t val, bool assign
 return 0;
 }
 
+int kvm_set_ioeventfd_pio_long(int fd, uint32_t addr, uint32_t val, bool 
assign)
+{
+struct kvm_ioeventfd kick = {
+.datamatch = val,
+.addr = addr,
+.len = 4,
+.flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO,
+.fd = fd,
+};
+int r;
+if (!kvm_enabled()) {
+return -ENOSYS;
+}
+if (!assign) {
+kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN;
+}
+r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick);
+if (r < 0) {
+return r;
+}
+return 0;
+}
+
 int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool 
assign)
 {
 struct kvm_ioeventfd kick = {
diff --git a/kvm-stub.c b/kvm-stub.c
index 06064b9..64cdd7c 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -115,6 +115,11 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, 
uint16_t val, bool assign)
 return -ENOSYS;
 }
 
+int kvm_set_ioeventfd_pio_long(int fd, uint32_t adr, uint32_t val, bool assign)
+{
+return -ENOSYS;
+}
+
 int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool 
assign)
 {
 return -ENOSYS;
diff --git a/kvm.h b/kvm.h
index 243b063..64b1737 100644
--- a/kvm.h
+++ b/kvm.h
@@ -195,5 +195,6 @@ int kvm_physical_memory_addr_from_ram(KVMState *s, 
ram_addr_t ram_addr,
 #endif
 int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool 
assign);
 
+int kvm_set_ioeventfd_pio_long(int fd, uint32_t adr, uint32_t val, bool 
assign);
 int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool 
assign);
 #endif
diff --git a/memory.c b/memory.c
index adfdf14..544c955 100644
--- a/memory.c
+++ b/memory.c
@@ -480,10 +480,16 @@ static void as_io_ioeventfd_add(AddressSpace *as, 
MemoryRegionIoeventfd *fd)
 {
 int r;
 
-assert(fd->match_data && int128_get64(fd->addr.size) == 2);
-
-r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start),
+assert(fd->match_data && (int128_get64(fd->addr.size) == 2 ||
+  int128_get64(fd->addr.size) == 4));
+if(int128_get64(fd->addr.size) == 2) {
+r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start),
+   fd->data, true);
+}
+else {
+r = kvm_set_ioeventfd_pio_long(fd->fd, int128_get64(fd->addr.start),
fd->data, true);
+}
 if (r < 0) {
 abort();
 }
@@ -493,8 +499,14 @@ static void as_io_ioeventfd_del(AddressSpace *as, 
MemoryRegionIoeventfd *fd)
 {
 int r;
 
-r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start),
+if(int128_get64(fd->addr.size) == 2) {
+r = kvm_set_ioeventfd_pio_word(fd->fd, int128_get64(fd->addr.start),
fd->data, false);
+}
+else {
+r = kvm_set_ioeventfd_pio_long(fd->fd, int128_get64(fd->addr.start),
+   fd->data, false);
+}
 if (r < 0) {
 abort();
 }
-- 
1.7.1




[Qemu-devel] [PATCH v3 3/3] ivshmem: update the spec

2011-12-12 Thread zanghongyong
From: Hongyong Zang 


Signed-off-by: Hongyong Zang 
---
 docs/specs/ivshmem_device_spec.txt |8 ++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/docs/specs/ivshmem_device_spec.txt 
b/docs/specs/ivshmem_device_spec.txt
index 23dd2ba..d36c737 100644
--- a/docs/specs/ivshmem_device_spec.txt
+++ b/docs/specs/ivshmem_device_spec.txt
@@ -13,10 +13,14 @@ The Inter-VM PCI device
 
 *BARs*
 
-The device supports three BARs.  BAR0 is a 1 Kbyte MMIO region to support
+The device supports four BARs.  BAR0 is a 1 Kbyte MMIO region to support
 registers.  BAR1 is used for MSI-X when it is enabled in the device.  BAR2 is
 used to map the shared memory object from the host.  The size of BAR2 is
 specified when the guest is started and must be a power of 2 in size.
+BAR4 is a 16 bytes PIO region to support registers. BAR4 plays the same role
+as BAR0, while it reduces notifying time 30% in comparison with BAR0. For
+compatibility, BAR4 will be not visible on guests created with -M pc-1.0 or
+below.
 
 *Registers*
 
@@ -89,7 +93,7 @@ Usage in the Guest
 --
 
 The shared memory device is intended to be used with the provided UIO driver.
-Very little configuration is needed.  The guest should map BAR0 to access the
+Very little configuration is needed.  The guest should map BAR0 or BAR4 to 
access the
 registers (an array of 32-bit ints allows simple writing) and map BAR2 to
 access the shared memory region itself.  The size of the shared memory region
 is specified when the guest (or shared memory server) is started.  A guest may
-- 
1.7.1




[Qemu-devel] [PATCH v3 2/3] ivshmem: add a new PIO BAR4(Doorbell) to reduce notification time

2011-12-12 Thread zanghongyong
From: Hongyong Zang 

This patch adds a PIO BAR4 for guest notifying qemu to reduce notification time.
And the new notification way of PIO BAR4 reduces 30% time in comparison with the
original MMIO BAR0 way.

Also, this patch introduces a new feature named IVSHMEM_PIO_NOTIFY to make PIO
BAR4 disappeared for compatible with machine type pc-1.0 or blow.

Signed-off-by: Hongyong Zang 
---
 hw/ivshmem.c |   34 --
 hw/pc_piix.c |   28 
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 80b5db0..6845ade 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -26,11 +26,13 @@
 
 #define IVSHMEM_IOEVENTFD   0
 #define IVSHMEM_MSI 1
+#define IVSHMEM_PIO_NOTIFY 2
 
 #define IVSHMEM_PEER0
 #define IVSHMEM_MASTER  1
 
 #define IVSHMEM_REG_BAR_SIZE 0x100
+#define IVSHIO_REG_BAR_SIZE 0x10
 
 //#define DEBUG_IVSHMEM
 #ifdef DEBUG_IVSHMEM
@@ -59,6 +61,7 @@ typedef struct IVShmemState {
 CharDriverState **eventfd_chr;
 CharDriverState *server_chr;
 MemoryRegion ivshmem_mmio;
+MemoryRegion ivshmem_pio;
 
 /* We might need to register the BAR before we actually have the memory.
  * So prepare a container MemoryRegion for the BAR immediately and
@@ -237,7 +240,7 @@ static uint64_t ivshmem_io_read(void *opaque, 
target_phys_addr_t addr,
 return ret;
 }
 
-static const MemoryRegionOps ivshmem_mmio_ops = {
+static const MemoryRegionOps ivshmem_io_ops = {
 .read = ivshmem_io_read,
 .write = ivshmem_io_write,
 .endianness = DEVICE_NATIVE_ENDIAN,
@@ -356,6 +359,14 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
  true,
  (posn << 16) | i,
  s->peers[posn].eventfds[i]);
+if(ivshmem_has_feature(s, IVSHMEM_PIO_NOTIFY)) {
+memory_region_del_eventfd(&s->ivshmem_pio,
+ DOORBELL,
+ 4,
+ true,
+ (posn << 16) | i,
+ s->peers[posn].eventfds[i]);
+}
 }
 close(s->peers[posn].eventfds[i]);
 }
@@ -490,6 +501,14 @@ static void ivshmem_read(void *opaque, const uint8_t * 
buf, int flags)
   true,
   (incoming_posn << 16) | guest_max_eventfd,
   incoming_fd);
+if(ivshmem_has_feature(s, IVSHMEM_PIO_NOTIFY)) {
+memory_region_add_eventfd(&s->ivshmem_pio,
+  DOORBELL,
+  4,
+  true,
+  (incoming_posn << 16) | 
guest_max_eventfd,
+  incoming_fd);
+}
 }
 
 return;
@@ -652,13 +671,20 @@ static int pci_ivshmem_init(PCIDevice *dev)
 
 s->shm_fd = 0;
 
-memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s,
+memory_region_init_io(&s->ivshmem_mmio, &ivshmem_io_ops, s,
   "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE);
 
 /* region for registers*/
 pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
  &s->ivshmem_mmio);
 
+if(ivshmem_has_feature(s, IVSHMEM_PIO_NOTIFY)) {
+memory_region_init_io(&s->ivshmem_pio, &ivshmem_io_ops, s,
+  "ivshmem-pio", IVSHIO_REG_BAR_SIZE);
+pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO,
+ &s->ivshmem_pio);
+}
+
 memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size);
 
 if ((s->server_chr != NULL) &&
@@ -738,6 +764,9 @@ static int pci_ivshmem_uninit(PCIDevice *dev)
 error_free(s->migration_blocker);
 }
 
+if(ivshmem_has_feature(s, IVSHMEM_PIO_NOTIFY)) {
+memory_region_destroy(&s->ivshmem_pio);
+}
 memory_region_destroy(&s->ivshmem_mmio);
 memory_region_del_subregion(&s->bar, &s->ivshmem);
 memory_region_destroy(&s->ivshmem);
@@ -762,6 +791,7 @@ static PCIDeviceInfo ivshmem_info = {
 DEFINE_PROP_UINT32("vectors", IVShmemState, vectors, 1),
 DEFINE_PROP_BIT("ioeventfd", IVShmemState, features, 
IVSHMEM_IOEVENTFD, false),
 DEFINE_PROP_BIT("msi", IVShmemState, features, IVSHMEM_MSI, true),
+DEFINE_PROP_BIT("pio_notify", IVShmemState, features, 
IVSHMEM_PIO_NOTIFY, true),
 DEFINE_PROP_STRING("shm", IVShmemState, shmobj),
 DEFINE_PROP_STRING("role", IVShmemState, role),
 DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 970f43c..fe64874 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -304,6 +304,14 @@ static QEMUMachine pc_machine_v1_0 = {
 .init = pc_init_pci,
 .max_cpus = 255,
 .is_default = 1,
+.compat_prop

[Qemu-devel] [PATCH v3 0/3] ivshmem: add a new PIO BAR4(Doorbell) besides MMIO BAR0 to reduce notification time

2011-12-12 Thread zanghongyong
From: Hongyong Zang 

This patch series, adds a PIO BAR4 for guest notifying qemu. And the new
notification way of PIO BAR4 reduces 30% time in comparison with the original
MMIO BAR0 way.
Meantime, this patch adds a memory API named kvm_set_ioeventfd_pio_long which
is about ioeventfd for PIO long. Also, this patch introduces a new feature
named IVSHMEM_PIO_NOTIFY to make PIO BAR4 disappeared for compatible with
machine type pc-1.0 or blow.

Notes: the patch series are based on the former patch "[PATCH] ivshmem: fix
guest unable to start with ioeventfd".

In v3, some changes come from Avi and Cam's comments:
  -split the v2 patch to an infrastructure patch(memory API) and an ivshmem 
patch
  -change BAR3 to BAR4 so that the shared memory region could be made a 64-bit
BAR(take BAR2 and BAR3)
  -make BAR4 disappeared for compatible with machine type pc-1.0 or blow
  -update the ivshmem spec


Hongyong Zang (3):
  memory: add a memory API about ioeventfd for PIO long
  ivshmem: add a new PIO BAR4(Doorbell) to reduce notification time
  ivshmem: update the spec

 docs/specs/ivshmem_device_spec.txt |8 ++--
 hw/ivshmem.c   |   34 --
 hw/pc_piix.c   |   28 
 kvm-all.c  |   23 +++
 kvm-stub.c |5 +
 kvm.h  |1 +
 memory.c   |   20 
 7 files changed, 111 insertions(+), 8 deletions(-)




Re: [Qemu-devel] [PATCH v3 064/197] killall VIOsPAPRDeviceInfo

2011-12-12 Thread Anthony Liguori

On 12/12/2011 08:22 PM, Michael Ellerman wrote:

On Mon, 2011-12-12 at 20:10 -0600, Anthony Liguori wrote:

On 12/12/2011 08:04 PM, Michael Ellerman wrote:

On Mon, 2011-12-12 at 14:19 -0600, Anthony Liguori wrote:

This was doing something evil building a dt tree so we broke the device.



@@ -711,8 +711,12 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
   spapr_rtas_register("ibm,set-tce-bypass", rtas_set_tce_bypass);
   spapr_rtas_register("quiesce", rtas_quiesce);

+#if 0
+/* Evil and broken */


By which you mean: works fine, broken by your patch?


These patches were never supposed to go out.  Ignore this series entirely.


But I just read all 197 of them ! ;)


   for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
   VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
+VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);

   if (qinfo->bus_info !=&spapr_vio_bus_info) {
   continue;
@@ -722,6 +726,7 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
   info->hcalls(bus);
   }
   }
+#endif


It's registering hcalls for each class of device we find on the spapr
vio bus. I don't understand why that is evil, but what do you suggest we
do instead?


I talked to David about this, the hcalls can just be registered as part the
device_init entry points.


OK I'll talk to him about it. I don't think device_init() works, because
we only want to register the hcalls if an instance of the device is
instantiated. But I guess we'll come up with something.


Since the hcalls are well known and CPUState doesn't get touched at all, why not 
register all of the possible hcalls in the VIO bus and then use a higher level 
interface to dispatch to devices?  I think that conceptionally makes more sense 
than the devices directly registering hcalls themselves.


I know you're dealing with an existing virtual I/O model, but it's strange to 
have an hcall dispatched directly to a device without going through any type of 
controller/bus hierarchy.  It doesn't fit how hardware works very well.


Regards,

Anthony Liguori



cheers






Re: [Qemu-devel] [PATCH v3 064/197] killall VIOsPAPRDeviceInfo

2011-12-12 Thread Michael Ellerman
On Mon, 2011-12-12 at 20:10 -0600, Anthony Liguori wrote:
> On 12/12/2011 08:04 PM, Michael Ellerman wrote:
> > On Mon, 2011-12-12 at 14:19 -0600, Anthony Liguori wrote:
> >> This was doing something evil building a dt tree so we broke the device.
> >
> >> @@ -711,8 +711,12 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
> >>   spapr_rtas_register("ibm,set-tce-bypass", rtas_set_tce_bypass);
> >>   spapr_rtas_register("quiesce", rtas_quiesce);
> >>
> >> +#if 0
> >> +/* Evil and broken */
> >
> > By which you mean: works fine, broken by your patch?
> 
> These patches were never supposed to go out.  Ignore this series entirely.

But I just read all 197 of them ! ;)

> >>   for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
> >>   VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
> >> +VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
> >>
> >>   if (qinfo->bus_info !=&spapr_vio_bus_info) {
> >>   continue;
> >> @@ -722,6 +726,7 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
> >>   info->hcalls(bus);
> >>   }
> >>   }
> >> +#endif
> >
> > It's registering hcalls for each class of device we find on the spapr
> > vio bus. I don't understand why that is evil, but what do you suggest we
> > do instead?
> 
> I talked to David about this, the hcalls can just be registered as part the 
> device_init entry points.

OK I'll talk to him about it. I don't think device_init() works, because
we only want to register the hcalls if an instance of the device is
instantiated. But I guess we'll come up with something.

cheers



signature.asc
Description: This is a digitally signed message part


Re: [Qemu-devel] [PATCH V13 1/7] Support for TPM command line options

2011-12-12 Thread Stefan Berger

On 12/12/2011 06:16 PM, Anthony Liguori wrote:

On 12/12/2011 01:12 PM, Stefan Berger wrote:

@@ -2735,6 +2736,15 @@ static mon_cmd_t info_cmds[] = {
  .help   = "show available trace-events&  their state",
  .mhandler.info = do_trace_print_events,
  },
+#if defined(CONFIG_TPM)
+{
+.name   = "tpm",
+.args_type  = "",
+.params = "",
+.help   = "show the TPM device",
+.mhandler.info = do_info_tpm,
+},
+#endif


Please don't make monitor commands conditional.  Make it fail in a 
predictable fashion if tpm isn't configured.




This will then require tpm.c to always be compiled. You'll find the 
CONFIG_TPM there then.

@@ -563,6 +582,7 @@ static QemuOptsList *vm_config_groups[32] = {

&qemu_option_rom_opts,
&qemu_machine_opts,
&qemu_boot_opts,
+&qemu_tpmdev_opts,


I assume this is my mailer or is the whitespace munged here?



Must be your mailer.@@ -0,0 +1,167 @@

+/*
+ * TPM configuration
+ *
+ * Copyright (C) 2011 IBM Corporation
+ *
+ * Authors:
+ *  Stefan Berger
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  
See

+ * the COPYING file in the top-level directory.



v2 or later please.


ok.


+
+void tpm_display_backend_drivers(void)
+{
+int i;
+
+fprintf(stderr, "Supported TPM types (choose only one):\n");


Having fprintfs to stderr is a sign something is wrong.

In this case, we should have a programatic way to query the backends 
(like via qmp_query_tpm) and then in the option handling code, we 
should use that function and print to the screen from there.




Will try to convert but keep this function ?


+
+void do_info_tpm(Monitor *mon)
+{
+TPMBackend *drv;
+unsigned int c = 0;
+
+monitor_printf(mon, "TPM device:\n");
+
+QLIST_FOREACH(drv,&tpm_backends, list) {
+monitor_printf(mon, " tpm%d: model=%s\n",
+   c, drv->fe_model);
+monitor_printf(mon, "  \\ %s: type=%s%s%s\n",
+   drv->id, drv->ops->id,
+   drv->parameters ? "," : "",
+   drv->parameters ? drv->parameters : "");
+c++;
+}
+}


We should do this through sure QAPI now that it's in the the tree with 
a proper schema entry and an implementation in hmp.c.


True...


+void tpm_config_parse(QemuOptsList *opts_list, const char *optarg)
+{
+QemuOpts *opts;
+
+if (strcmp("none", optarg) != 0) {
+if (*optarg == '?') {
+tpm_display_backend_drivers();
+exit(0);


Don't exit from something other than vl.c.  Return an error code and 
let vl.c exit.


I implemented this following along the lines of

qemu-system-x86_64 -soundhw ?

which then also shows and error code 0. What error code should it return 
to the shell ?






+}
+opts = qemu_opts_parse(opts_list, optarg, 1);
+if (!opts) {
+exit(1);
+}
+}
+}
diff --git a/tpm.h b/tpm.h
new file mode 100644
index 000..85c2a35
--- /dev/null
+++ b/tpm.h
@@ -0,0 +1,90 @@


Needs a copyright.


Ok.


+static inline void tpm_dump_buffer(FILE *stream,
+   unsigned char *buffer, unsigned 
int len)

+{
+int i;
+
+for (i = 0; i<  len; i++) {
+if (i&&  !(i % 16)) {
+fprintf(stream, "\n");
+}
+fprintf(stream, "%.2X ", buffer[i]);
+}
+fprintf(stream, "\n");
+}


This definitely shouldn't be static inline and it's questionable 
whether it should exist in the first place.


Do you have an alternative for this function? Assuming it's useful for 
debugging, should I just move it into tpm.c ?






+#define TPM_DEFAULT_DEVICE_MODEL "tpm-tis"
+
+void tpm_config_parse(QemuOptsList *opts_list, const char *optarg);
+int tpm_init(void);
+void tpm_cleanup(void);
+TPMBackend *qemu_find_tpm(const char *id);
+void do_info_tpm(Monitor *mon);
+void tpm_display_backend_drivers(void);
+const TPMDriverOps *tpm_get_backend_driver(const char *id);


Please document these functions.


Will document them in tpm.c where their implementation is.


@@ -2550,6 +2551,11 @@ int main(int argc, char **argv, char **envp)

  ram_size = value;
  break;
  }
+#ifdef CONFIG_TPM
+case QEMU_OPTION_tpmdev:
+tpm_config_parse(qemu_find_opts("tpmdev"), optarg);
+break;
+#endif


Don't make options conditional.


Can I have an #ifdef-#else-#endif construct there along the lines of 
CONFIG_SDL with an exit(1) in the #else branch?



   Stefan




Re: [Qemu-devel] [PATCH v3 064/197] killall VIOsPAPRDeviceInfo

2011-12-12 Thread Anthony Liguori

On 12/12/2011 08:04 PM, Michael Ellerman wrote:

On Mon, 2011-12-12 at 14:19 -0600, Anthony Liguori wrote:

This was doing something evil building a dt tree so we broke the device.



@@ -711,8 +711,12 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
  spapr_rtas_register("ibm,set-tce-bypass", rtas_set_tce_bypass);
  spapr_rtas_register("quiesce", rtas_quiesce);

+#if 0
+/* Evil and broken */


By which you mean: works fine, broken by your patch?


These patches were never supposed to go out.  Ignore this series entirely.




+
  for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
  VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
+VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);

  if (qinfo->bus_info !=&spapr_vio_bus_info) {
  continue;
@@ -722,6 +726,7 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
  info->hcalls(bus);
  }
  }
+#endif


It's registering hcalls for each class of device we find on the spapr
vio bus. I don't understand why that is evil, but what do you suggest we
do instead?


I talked to David about this, the hcalls can just be registered as part the 
device_init entry points.


If you must initialize them via a per-device callback, then you should walk it 
from the bus's children, not by walking the entire device model.  That was the 
bit that I was referring to as evil.   It's a layering violation.


Regards,

Anthony Liguori



cheers







Re: [Qemu-devel] [PATCH v3 064/197] killall VIOsPAPRDeviceInfo

2011-12-12 Thread Michael Ellerman
On Mon, 2011-12-12 at 14:19 -0600, Anthony Liguori wrote:
> This was doing something evil building a dt tree so we broke the device.

> @@ -711,8 +711,12 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
>  spapr_rtas_register("ibm,set-tce-bypass", rtas_set_tce_bypass);
>  spapr_rtas_register("quiesce", rtas_quiesce);
>  
> +#if 0
> +/* Evil and broken */

By which you mean: works fine, broken by your patch?

> +
>  for (qinfo = device_info_list; qinfo; qinfo = qinfo->next) {
>  VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo;
> +VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
>  
>  if (qinfo->bus_info != &spapr_vio_bus_info) {
>  continue;
> @@ -722,6 +726,7 @@ VIOsPAPRBus *spapr_vio_bus_init(void)
>  info->hcalls(bus);
>  }
>  }
> +#endif

It's registering hcalls for each class of device we find on the spapr
vio bus. I don't understand why that is evil, but what do you suggest we
do instead?

cheers




signature.asc
Description: This is a digitally signed message part


[Qemu-devel] [PATCH 1/2] error: Add an accessor for progname

2011-12-12 Thread mich...@ellerman.id.au
We'd like to get the progname for help output, so add an accessor.

Signed-off-by: Michael Ellerman 
---
 qemu-error.c |5 +
 qemu-error.h |1 +
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/qemu-error.c b/qemu-error.c
index 4b20d28..7cd5ffe 100644
--- a/qemu-error.c
+++ b/qemu-error.c
@@ -157,6 +157,11 @@ void error_set_progname(const char *argv0)
 progname = p ? p + 1 : argv0;
 }
 
+const char *error_get_progname(void)
+{
+return progname;
+}
+
 /*
  * Print current location to current monitor if we have one, else to stderr.
  */
diff --git a/qemu-error.h b/qemu-error.h
index 4d5c537..93d74b4 100644
--- a/qemu-error.h
+++ b/qemu-error.h
@@ -36,5 +36,6 @@ void error_printf_unless_qmp(const char *fmt, ...) 
GCC_FMT_ATTR(1, 2);
 void error_print_loc(void);
 void error_set_progname(const char *argv0);
 void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
+const char *error_get_progname(void);
 
 #endif
-- 
1.7.7.3




[Qemu-devel] [PATCH 2/2] vl.c: Print the actual program name in help output

2011-12-12 Thread mich...@ellerman.id.au
In help() we do what boils down to:

  printf("%s", "qemu");

This seems to be an artifact of be995c27640a82c7056b6f53d02ec823570114e5
("removed unused code"), which removed some ifdef'ery that used to print
a different name depending on CONFIG_SOFTMMU.

Instead print the actual program name, originally from argv[0].

Signed-off-by: Michael Ellerman 
---
 vl.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/vl.c b/vl.c
index a50842b..6e5742a 100644
--- a/vl.c
+++ b/vl.c
@@ -1513,7 +1513,7 @@ static void help(int exitcode)
"ctrl-alttoggle mouse and keyboard grab\n"
"\n"
"When using -nographic, press 'ctrl-a h' to get some help.\n",
-   "qemu",
+   error_get_progname(),
options_help);
 exit(exitcode);
 }
-- 
1.7.7.3




[Qemu-devel] [PATCH V2] Fix parse of usb device description with multiple configurations

2011-12-12 Thread mars
From: Cao,Bing Bu 


Changed From V1:
Use DPRINTF instead of fprintf,because it is not an error.

When testing ipod on QEMU by He Jie Xu,qemu made a 
assertion.
We found that the ipod with 2 configurations,and the usb-linux did not parse 
the descriptor correctly.
The descr_len returned is the total length of the all configurations,not one 
configuration.
The older version will through the other configurations instead of 
skip,continue parsing the descriptor of interfaces/endpoints in other 
configurations,then went wrong.

This patch will put the configuration descriptor parse in loop outside and 
dispel the other configurations not requested.



Signed-off-by: Cao,Bing Bu 
---
 usb-linux.c |   19 +++
 1 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/usb-linux.c b/usb-linux.c
index ab4c693..ed14bb1 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -1141,15 +1141,18 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
 length = s->descr_len - 18;
 i = 0;
 
-if (descriptors[i + 1] != USB_DT_CONFIG ||
-descriptors[i + 5] != s->configuration) {
-fprintf(stderr, "invalid descriptor data - configuration %d\n",
-s->configuration);
-return 1;
-}
-i += descriptors[i];
-
 while (i < length) {
+if (descriptors[i + 1] != USB_DT_CONFIG) {
+fprintf(stderr, "invalid descriptor data\n");
+return 1;
+} else if (descriptors[i + 5] != s->configuration) {
+DPRINTF("not requested configuration %d\n", s->configuration);
+i += (descriptors[i + 3] << 8) + descriptors[i + 2];
+continue;
+}
+
+i += descriptors[i];
+
 if (descriptors[i + 1] != USB_DT_INTERFACE ||
 (descriptors[i + 1] == USB_DT_INTERFACE &&
  descriptors[i + 4] == 0)) {
-- 
1.7.1




Re: [Qemu-devel] [PATCH] PPC: Fix linker scripts on ppc hosts

2011-12-12 Thread Alexander Graf

On 13.12.2011, at 01:55, Richard Henderson wrote:

> On 12/12/2011 01:36 PM, Alexander Graf wrote:
>> When compiling qemu statically with multilib on PPC, we hit the
>> same issue that commit 845f2c2812d9ed24b36c02a3d06ee83aeafe8b49
>> is fixing. Do the same here.
> 
> How many of these ld files can we get rid of if we use -Ttext-segment instead?
> Generally all we're really caring about is moving the program base around so
> that it doesn't conflict with the address space we want to use for the client.

I tried to play with that as well but couldn't get it to work. If you do, I'd 
be more than happy to get rid of them :)


Alex




Re: [Qemu-devel] [PATCH] PPC: Fix linker scripts on ppc hosts

2011-12-12 Thread Richard Henderson
On 12/12/2011 01:36 PM, Alexander Graf wrote:
> When compiling qemu statically with multilib on PPC, we hit the
> same issue that commit 845f2c2812d9ed24b36c02a3d06ee83aeafe8b49
> is fixing. Do the same here.

How many of these ld files can we get rid of if we use -Ttext-segment instead?
Generally all we're really caring about is moving the program base around so
that it doesn't conflict with the address space we want to use for the client.


r~



[Qemu-devel] buildbot failure in qemu on default_mingw32

2011-12-12 Thread qemu
The Buildbot has detected a new failure on builder default_mingw32 while 
building qemu.
Full details are available at:
 http://buildbot.b1-systems.de/qemu/builders/default_mingw32/builds/114

Buildbot URL: http://buildbot.b1-systems.de/qemu/

Buildslave for this Build: kraxel_rhel61

Build Reason: The Nightly scheduler named 'nightly_default' triggered this build
Build Source Stamp: [branch master] HEAD
Blamelist: 

BUILD FAILED: failed compile

sincerely,
 -The Buildbot



Re: [Qemu-devel] [PATCH V13 7/7] Add fd parameter for TPM passthrough driver

2011-12-12 Thread Stefan Berger

On 12/12/2011 06:30 PM, Anthony Liguori wrote:

On 12/12/2011 01:12 PM, Stefan Berger wrote:
Enable the passing of a file descriptor via fd=<..>  to access the 
host's

TPM device using the TPM passthrough driver.

Signed-off-by: Stefan Berger


[...]

-tb->s.tpm_pt->tpm_fd = open(tb->s.tpm_pt->tpm_dev, O_RDWR);
-if (tb->s.tpm_pt->tpm_fd<  0) {
-error_report("Cannot access TPM device using '%s'.\n",
- tb->s.tpm_pt->tpm_dev);
-goto err_exit;
+if (fstat(tb->s.tpm_pt->tpm_fd,&statbuf) != 0) {
+error_report("Cannot determine file descriptor type for TPM "
+ "device: %s", strerror(errno));
+goto err_close_tpmdev;
+}
+
+/* only allow character devices for now */
+if (!S_ISCHR(statbuf.st_mode)) {
+error_report("TPM file descriptor is not a character device");
+goto err_close_tpmdev;
  }


I think you're being overzealous here.  The backend only uses 
read/write to interact with the passthrough device.  You could use 
this as a mechanism to tie in an emulated VTPM by using a socket.  I'm 
not suggesting we do that for libvtpm, but I think we don't gain 
anything from being overly restrictive here.


We prevent files, pipes, sockets and block devices using this check. 
Sockets may make sense in the future, but would like to enable that 
separately.




I don't think a user passing the wrong type of fd is the common case 
to optimize for wrt usability.


I don't think it makes sense to have the TPM passthrough driver write() 
into a block device or file, so therefore I prevented that. The above 
check is just a single line...


   Stefan




Re: [Qemu-devel] [PATCH V13 6/7] Introduce --enable-tpm-passthrough configure option

2011-12-12 Thread Stefan Berger

On 12/12/2011 06:27 PM, Anthony Liguori wrote:

On 12/12/2011 01:12 PM, Stefan Berger wrote:

Introduce --enable-tpm-passthrough configure option.

Signed-off-by: Stefan Berger
---
  configure |   16 +++-
  1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/configure b/configure
index 25995bc..ffb599e 100755
--- a/configure
+++ b/configure
@@ -186,6 +186,7 @@ zlib="yes"
  guest_agent="yes"
  libiscsi=""
  tpm="no"
+tpm_passthrough="no"


Same as before, please probe for existence.



We would be probing for /dev/tpm0. Is that really what we want that this 
driver only gets compiled if /dev/tpm0 is (currently) available?


 Regards,
 Stefan




Re: [Qemu-devel] [PATCH V13 5/7] Add a TPM Passthrough backend driver implementation

2011-12-12 Thread Stefan Berger

On 12/12/2011 06:27 PM, Anthony Liguori wrote:

On 12/12/2011 01:12 PM, Stefan Berger wrote:
 From Andreas Niederl's original posting with adaptations where 
necessary:


This patch is based of off version 9 of Stefan Berger's patch series
   "Qemu Trusted Platform Module (TPM) integration"
and adds a new backend driver for it.

This patch adds a passthrough backend driver for passing commands 
sent to the

emulated TPM device directly to a TPM device opened on the host machine.

Thus it is possible to use a hardware TPM device in a system running 
on QEMU,
providing the ability to access a TPM in a special state (e.g. after 
a Trusted

Boot).

This functionality is being used in the acTvSM Trusted Virtualization 
Platform

which is available on [1].

[...]


+static void *tpm_passthrough_main_loop(void *d)
+{
+TPMPassthruThreadParams *thr_parms = d;
+TPMPassthruState *tpm_pt = thr_parms->tb->s.tpm_pt;
+uint32_t in_len, out_len;
+uint8_t *in, *out;
+uint8_t locty;
+TPMLocality *cmd_locty;
+int ret;


This is rather scary.  I'd rather see us make use of a GThreadPool in 
order to submit read/write requests asynchronously to the /dev/tpm 
device.   I don't think the code should be structured expecting 
synchronous command execution.


This part here is running as a thread, create via qemu_thread_create(). 
Relative to the main thread this is of course running asynchronously. 
The same design will re-appear when the libtpms based TPM backend 
appears. Here we will need a thread for concurrent execution of more 
time consuming crypto functions.


Regards,
   Stefan




Re: [Qemu-devel] [PATCH V13 4/7] Build the TPM frontend code

2011-12-12 Thread Stefan Berger

On 12/12/2011 06:24 PM, Anthony Liguori wrote:

On 12/12/2011 01:12 PM, Stefan Berger wrote:

Build the TPM frontend code that has been added so far.

Signed-off-by: Stefan Berger
---
  Makefile.target |1 +
  configure   |   11 +++
  2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 39b2e5a..37d5d10 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -205,6 +205,7 @@ obj-$(CONFIG_REALLY_VIRTFS) += 
9pfs/virtio-9p-device.o

  obj-$(CONFIG_KVM) += kvm.o kvm-all.o
  obj-$(CONFIG_NO_KVM) += kvm-stub.o
  obj-y += memory.o
+obj-$(CONFIG_TPM) += tpm.o tpm_tis.o
  LIBS+=-lz

  QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
diff --git a/configure b/configure
index cc5ae87..385feb4 100755
--- a/configure
+++ b/configure
@@ -185,6 +185,7 @@ opengl=""
  zlib="yes"
  guest_agent="yes"
  libiscsi=""
+tpm="no"


Please probe instead of requiring it to be explicitly enabled.


At this point there is not much to probe. We're only building the 
front-end with no backend, i.e., passthrough, being built in.


   Stefan



Regards,

Anthony Liguori



  # parse CC options first
  for opt do
@@ -784,6 +785,8 @@ for opt do
;;
--disable-guest-agent) guest_agent="no"
;;
+  --enable-tpm) tpm="yes"
+  ;;
*) echo "ERROR: unknown option $opt"; show_help="yes"
;;
esac
@@ -1070,6 +1073,7 @@ echo "  --disable-usb-redir  disable usb 
network redirection support"
  echo "  --enable-usb-redir   enable usb network redirection 
support"
  echo "  --disable-guest-agentdisable building of the QEMU Guest 
Agent"
  echo "  --enable-guest-agent enable building of the QEMU Guest 
Agent"

+echo "  --enable-tpm enable TPM support"
  echo ""
  echo "NOTE: The object files are built at the place where configure 
is launched"

  exit 1
@@ -2845,6 +2849,7 @@ echo "usb net redir $usb_redir"
  echo "OpenGL support$opengl"
  echo "libiscsi support  $libiscsi"
  echo "build guest agent $guest_agent"
+echo "TPM support   $tpm"

  if test "$sdl_too_old" = "yes"; then
  echo "->  Your SDL version is too old - please upgrade to have SDL 
support"

@@ -3714,6 +3719,12 @@ if test "$gprof" = "yes" ; then
fi
  fi

+if test "$tpm" = "yes"; then
+  if test "$target_softmmu" = "yes" ; then
+echo "CONFIG_TPM=y">>  $config_host_mak
+  fi
+fi
+
  if test "$ARCH" = "tci"; then
linker_script=""
  else







Re: [Qemu-devel] [PATCH V13 2/7] Add TPM (frontend) hardware interface (TPM TIS) to Qemu

2011-12-12 Thread Stefan Berger

On 12/12/2011 06:23 PM, Anthony Liguori wrote:

On 12/12/2011 01:12 PM, Stefan Berger wrote:

This patch adds the main code of the TPM frontend driver, the TPM TIS
interface, to Qemu. The code is largely based on the previous 
implementation

for Xen but has been significantly extended to meet the standard's
requirements, such as the support for changing of localities and all the
functionality of the available flags.

Communication with the backend (i.e., for Xen or the libtpms-based one)
is cleanly separated through an interface which the backend driver needs
to implement.

The TPM TIS driver's backend was previously chosen in the code added
to arch_init. The frontend holds a pointer to the chosen backend 
(interface).


Communication with the backend is largely based on signals and 
conditions.

Whenever the frontend has collected a complete packet, it will signal
the backend, which then starts processing the command. Once the result
has been returned, the backend invokes a callback function
(tis_tpm_receive_cb()).

The one tricky part is support for VM suspend while the TPM is 
processing

a command. In this case the frontend driver is waiting for the backend
to return the result of the last command before shutting down. It waits
on a condition for a signal from the backend, which is delivered in
tis_tpm_receive_cb().

Testing the proper functioning of the different flags and localities
cannot be done from user space when running in Linux for example, since
access to the address space of the TPM TIS interface is not possible. 
Also

the Linux driver itself does not exercise all functionality. So, for
testing there is a fairly extensive test suite as part of the SeaBIOS 
patches
since from within the BIOS one can have full access to all the TPM's 
registers.



Signed-off-by: Stefan Berger

[...]


+
+/*
+ * Send a TPM request.
+ * Call this with the state_lock held so we can sync with the receive
+ * callback.
+ */
+static void tpm_tis_tpm_send(TPMState *s, uint8_t locty)
+{
+TPMTISState *tis =&s->s.tis;
+#ifdef DEBUG_TIS
+tpm_tis_show_buffer(&tis->loc[locty].w_buffer, "tpm_tis: To TPM");
+#endif
+s->command_locty = locty;
+s->cmd_locty =&tis->loc[locty];
+
+/* w_offset serves as length indicator for length of data;
+   it's reset when the response comes back */
+tis->loc[locty].state = TPM_TIS_STATE_EXECUTION;
+tis->loc[locty].sts&= ~TPM_TIS_STS_EXPECT;
+
+s->to_tpm_execute = true;
+qemu_cond_signal(&s->to_tpm_cond);


The locking seems to presume that the device model is re-entrant which 
it's not today.  Am I missing something here?




The TPM TIS frontend communicates with the TPM backend via a condition 
notifying it when a complete buffer with a TPM request has been 
received. The TPM backend is running as a thread, created via 
qemu_thread_create(). This is the design that was driven by the 
libtpms-based implementation.


   Stefan




Re: [Qemu-devel] [PATCH v3 03/14] ARM: exynos4210: UART support

2011-12-12 Thread Peter Maydell
On 12 December 2011 06:43, Evgeny Voevodin  wrote:
> From: Maksim Kozlov 
>
> Add basic support of exynos4210 UART
>
> Conflicts:
>
>        Makefile.target

Don't leave git's conflicts notes in the commit logs :-)

>
> Signed-off-by: Evgeny Voevodin 
> ---
>  Makefile.target      |    2 +-
>  hw/exynos4210.c      |   51 
>  hw/exynos4210.h      |    9 +
>  hw/exynos4210_uart.c |  674 
> ++
>  4 files changed, 735 insertions(+), 1 deletions(-)
>  create mode 100644 hw/exynos4210_uart.c
>
> diff --git a/Makefile.target b/Makefile.target
> index ce4f1f8..4c706b1 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -344,7 +344,7 @@ obj-arm-y = integratorcp.o versatilepb.o arm_pic.o 
> arm_timer.o
>  obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o 
> pl190.o
>  obj-arm-y += versatile_pci.o
>  obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
> -obj-arm-y += exynos4210.o exynos4210_cmu.o
> +obj-arm-y += exynos4210.o exynos4210_cmu.o exynos4210_uart.o
>  obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
>  obj-arm-y += pl061.o
>  obj-arm-y += arm-semi.o
> diff --git a/hw/exynos4210.c b/hw/exynos4210.c
> index 1a6e353..d5a1fe0 100644
> --- a/hw/exynos4210.c
> +++ b/hw/exynos4210.c
> @@ -63,6 +63,18 @@
>  /* SFR Base Address for CMUs */
>  #define EXYNOS4210_CMU_BASE_ADDR            0x1003
>
> +/* UART's definitions */
> +#define EXYNOS4210_UART_BASE_ADDR           0x1380
> +#define EXYNOS4210_UART_SHIFT               0x0001
> +
> +#define EXYNOS4210_UARTS_NUMBER             4
> +
> +#define EXYNOS4210_UART_CHANNEL(addr)       ((addr >> 16) & 0x7)
> +#define EXYNOS4210_UART0_FIFO_SIZE          256
> +#define EXYNOS4210_UART1_FIFO_SIZE          64
> +#define EXYNOS4210_UART2_FIFO_SIZE          16
> +#define EXYNOS4210_UART3_FIFO_SIZE          16
> +
>
>  static struct arm_boot_info exynos4210_binfo = {
>         .loader_start     = EXYNOS4210_BASE_BOOT_ADDR,
> @@ -179,6 +191,45 @@ static void exynos4210_init(ram_addr_t ram_size,
>     /* CMU */
>     sysbus_create_simple("exynos4210.cmu", EXYNOS4210_CMU_BASE_ADDR, NULL);
>
> +    /*** UARTs ***/
> +    for (n = 0; n < EXYNOS4210_UARTS_NUMBER; n++) {
> +
> +        uint32_t addr = EXYNOS4210_UART_BASE_ADDR + EXYNOS4210_UART_SHIFT * 
> n;
> +        int channel = EXYNOS4210_UART_CHANNEL(addr);

Is there any case where channel is not the same as n ?

> +        qemu_irq uart_irq;
> +        int fifo_size = 0;
> +
> +        switch (channel) {
> +        case 0:
> +            fifo_size = EXYNOS4210_UART0_FIFO_SIZE;
> +            break;
> +        case 1:
> +            fifo_size = EXYNOS4210_UART1_FIFO_SIZE;
> +            break;
> +        case 2:
> +            fifo_size = EXYNOS4210_UART2_FIFO_SIZE;
> +            break;
> +        case 3:
> +            fifo_size = EXYNOS4210_UART3_FIFO_SIZE;
> +            break;
> +        default:
> +            fifo_size = 0;
> +            PRINT_DEBUG("Wrong channel number: %d\n", channel);
> +            break;
> +        }
> +
> +        if (fifo_size == 0) {
> +            PRINT_DEBUG("Can't create UART%d with fifo size %d\n",
> +                        channel, fifo_size);
> +            continue;
> +        }
> +
> +        uart_irq = NULL;
> +
> +        exynos4210_uart_create(addr, fifo_size, channel, NULL, uart_irq);
> +    }
> +
> +
>     /*** Load kernel ***/
>
>     exynos4210_binfo.ram_size = ram_size;
> diff --git a/hw/exynos4210.h b/hw/exynos4210.h
> index 683a4a6..3df7322 100644
> --- a/hw/exynos4210.h
> +++ b/hw/exynos4210.h
> @@ -53,4 +53,13 @@ typedef enum {
>
>  uint64_t exynos4210_cmu_get_rate(Exynos4210CmuClock clock);
>
> +/*
> + * exynos4210 UART
> + */
> +DeviceState *exynos4210_uart_create(target_phys_addr_t addr,
> +                                    int fifo_size,
> +                                    int channel,
> +                                    CharDriverState *chr,
> +                                    qemu_irq irq);
> +
>  #endif /* EXYNOS4210_H_ */
> diff --git a/hw/exynos4210_uart.c b/hw/exynos4210_uart.c
> new file mode 100644
> index 000..22c24b7
> --- /dev/null
> +++ b/hw/exynos4210_uart.c
> @@ -0,0 +1,674 @@
> +/*
> + *  exynos4210 UART Emulation
> + *
> + *  Copyright (C) 2011 Samsung Electronics Co Ltd.
> + *    Maksim Kozlov, 
> + *
> + *  Created on: 07.2011
> + *
> + *
> + *  This program is free software; you can redistribute it and/or modify it
> + *  under the terms of the GNU General Public License as published by the
> + *  Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful, but 
> WITHOUT
> + *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> + *  for more details.
> + *
> + *  You should have rec

Re: [Qemu-devel] [PATCH] build: Cleanup qga make output

2011-12-12 Thread Michael Roth

On 12/12/2011 05:03 PM, Anthony Liguori wrote:

On 12/07/2011 10:33 AM, Adam Litke wrote:

Currently the make variable qapi-dir refers to the qapi-generated
directory in
absolute terms. This causes the harmless but ugly make output below. By
changing this variable to the relative path the output conforms to the
norm and
the build works fine.

Before patch:
CC /home/aglitke/src/qemu/qapi-generated/qga-qapi-types.o
CC /home/aglitke/src/qemu/qapi-generated/qga-qapi-visit.o
CC /home/aglitke/src/qemu/qapi-generated/qga-qmp-marshal.o
After patch:
CC qapi-generated/qga-qapi-types.o
CC qapi-generated/qga-qapi-visit.o
CC qapi-generated/qga-qmp-marshal.o


This was supposedly to fix a build issue that I was never able to
reproduce. I think Luiz could reproduce it though. Luiz, could you try
out Adam's patch and confirm it breaks for you?


I think that was Stefano:

http://lists.gnu.org/archive/html/qemu-devel/2011-11/msg02752.html

Stefano had a patch that fixed a build breakage he saw with dirty 
directories by setting:


qapi-dir := $(SRC_DIR)/qapi-generated

That patch ended up breaking the build for others, however, and was 
reverted.


This patch was an improvement on the original, but we'd all agreed that 
it wasn't necessary since we don't support working around issues related 
to dirty directories.


So if it's ugly, we can safely drop it.



Regards,

Anthony Liguori



Signed-off-by: Adam Litke
---
Makefile | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index 301c75e..7c93739 100644
--- a/Makefile
+++ b/Makefile
@@ -168,7 +168,7 @@ check-qjson: check-qjson.o $(qobject-obj-y)
$(tools-obj-y)
test-coroutine: test-coroutine.o qemu-timer-common.o async.o
$(coroutine-obj-y) $(tools-obj-y)

$(qapi-obj-y): $(GENERATED_HEADERS)
-qapi-dir := $(BUILD_DIR)/qapi-generated
+qapi-dir := qapi-generated
test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I
$(qapi-dir)
qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)









[Qemu-devel] buildbot failure in qemu on default_x86_64_rhel5

2011-12-12 Thread qemu
The Buildbot has detected a new failure on builder default_x86_64_rhel5 while 
building qemu.
Full details are available at:
 http://buildbot.b1-systems.de/qemu/builders/default_x86_64_rhel5/builds/98

Buildbot URL: http://buildbot.b1-systems.de/qemu/

Buildslave for this Build: kraxel_rhel5

Build Reason: The Nightly scheduler named 'nightly_default' triggered this build
Build Source Stamp: [branch master] HEAD
Blamelist: 

BUILD FAILED: failed compile

sincerely,
 -The Buildbot



Re: [Qemu-devel] [PATCH v2 0/4] add qemu_thread_join, use it to fix bug in ccid

2011-12-12 Thread Anthony Liguori

On 12/12/2011 10:21 AM, Paolo Bonzini wrote:

Patches introducing qemu_thread_join have floated around multiple times.
Now I found a bug that requires it to be fixed, so perhaps this time
it will be more successful.

For the actual bug, see patch 4.

v1->v2: remove spurious submodule change, fix blank lines


Applied all.  Thanks.

Regards,

Anthony Liguori



Jan Kiszka (2):
   qemu-thread: add API for joinable threads
   qemu-thread: implement joinable threads for POSIX

Paolo Bonzini (2):
   qemu-thread: implement joinable threads for Win32
   ccid: make threads joinable

  cpus.c  |6 ++-
  hw/ccid-card-emulated.c |   25 +--
  qemu-thread-posix.c |   35 ++--
  qemu-thread-win32.c |  107 ++
  qemu-thread-win32.h |5 +-
  qemu-thread.h   |8 +++-
  ui/vnc-jobs-async.c |2 +-
  8 files changed, 127 insertions(+), 63 deletions(-)






Re: [Qemu-devel] [PATCH 1/2] guest agent: add RPC blacklist command-line option

2011-12-12 Thread Anthony Liguori

On 12/06/2011 10:03 PM, Michael Roth wrote:

This adds a command-line option, -b/--blacklist, that accepts a
comma-seperated list of RPCs to disable, or prints a list of
available RPCs if passed "?".

In consequence this also adds general blacklisting and RPC listing
facilities to the new QMP dispatch/registry facilities, should the
QMP monitor ever have a need for such a thing.

Ideally, to avoid support/compatability issues in the future,
blacklisting guest agent functionality will be the exceptional
case, but we add the functionality here to handle guest administrators
with specific requirements.

Signed-off-by: Michael Roth


Applied.  Thanks.

Regards,

Anthony Liguori


---
  qapi/qmp-core.h |3 +++
  qapi/qmp-dispatch.c |4 
  qapi/qmp-registry.c |   43 ++-
  qemu-ga.c   |   37 ++---
  qerror.c|4 
  qerror.h|3 +++
  6 files changed, 86 insertions(+), 8 deletions(-)

diff --git a/qapi/qmp-core.h b/qapi/qmp-core.h
index f1c26e4..3cf1781 100644
--- a/qapi/qmp-core.h
+++ b/qapi/qmp-core.h
@@ -31,11 +31,14 @@ typedef struct QmpCommand
  QmpCommandType type;
  QmpCommandFunc *fn;
  QTAILQ_ENTRY(QmpCommand) node;
+bool enabled;
  } QmpCommand;

  void qmp_register_command(const char *name, QmpCommandFunc *fn);
  QmpCommand *qmp_find_command(const char *name);
  QObject *qmp_dispatch(QObject *request);
+void qmp_disable_command(const char *name);
+char **qmp_get_command_list(void);

  #endif

diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 5584693..43f640a 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -79,6 +79,10 @@ static QObject *do_qmp_dispatch(QObject *request, Error 
**errp)
  error_set(errp, QERR_COMMAND_NOT_FOUND, command);
  return NULL;
  }
+if (!cmd->enabled) {
+error_set(errp, QERR_COMMAND_DISABLED, command);
+return NULL;
+}

  if (!qdict_haskey(dict, "arguments")) {
  args = qdict_new();
diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
index 5ff99cf..abafa34 100644
--- a/qapi/qmp-registry.c
+++ b/qapi/qmp-registry.c
@@ -14,7 +14,7 @@

  #include "qapi/qmp-core.h"

-static QTAILQ_HEAD(, QmpCommand) qmp_commands =
+static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands =
  QTAILQ_HEAD_INITIALIZER(qmp_commands);

  void qmp_register_command(const char *name, QmpCommandFunc *fn)
@@ -24,17 +24,50 @@ void qmp_register_command(const char *name, QmpCommandFunc 
*fn)
  cmd->name = name;
  cmd->type = QCT_NORMAL;
  cmd->fn = fn;
+cmd->enabled = true;
  QTAILQ_INSERT_TAIL(&qmp_commands, cmd, node);
  }

  QmpCommand *qmp_find_command(const char *name)
  {
-QmpCommand *i;
+QmpCommand *cmd;

-QTAILQ_FOREACH(i,&qmp_commands, node) {
-if (strcmp(i->name, name) == 0) {
-return i;
+QTAILQ_FOREACH(cmd,&qmp_commands, node) {
+if (strcmp(cmd->name, name) == 0) {
+return cmd;
  }
  }
  return NULL;
  }
+
+void qmp_disable_command(const char *name)
+{
+QmpCommand *cmd;
+
+QTAILQ_FOREACH(cmd,&qmp_commands, node) {
+if (strcmp(cmd->name, name) == 0) {
+cmd->enabled = false;
+return;
+}
+}
+}
+
+char **qmp_get_command_list(void)
+{
+QmpCommand *cmd;
+int count = 1;
+char **list_head, **list;
+
+QTAILQ_FOREACH(cmd,&qmp_commands, node) {
+count++;
+}
+
+list_head = list = g_malloc0(count * sizeof(char *));
+
+QTAILQ_FOREACH(cmd,&qmp_commands, node) {
+*list = strdup(cmd->name);
+list++;
+}
+
+return list_head;
+}
diff --git a/qemu-ga.c b/qemu-ga.c
index 4932013..200bb15 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -27,6 +27,7 @@
  #include "signal.h"
  #include "qerror.h"
  #include "error_int.h"
+#include "qapi/qmp-core.h"

  #define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent.0"
  #define QGA_PIDFILE_DEFAULT "/var/run/qemu-ga.pid"
@@ -91,6 +92,8 @@ static void usage(const char *cmd)
  "  -v, --verbose log extra debugging information\n"
  "  -V, --version print version information and exit\n"
  "  -d, --daemonize   become a daemon\n"
+"  -b, --blacklist   comma-seperated list of RPCs to disable (no spaces, \"?\""
+"to list available RPCs)\n"
  "  -h, --helpdisplay this help and exit\n"
  "\n"
  "Report bugs to\n"
@@ -548,7 +551,7 @@ static void init_guest_agent(GAState *s)

  int main(int argc, char **argv)
  {
-const char *sopt = "hVvdm:p:l:f:";
+const char *sopt = "hVvdm:p:l:f:b:";
  const char *method = NULL, *path = NULL, *pidfile = QGA_PIDFILE_DEFAULT;
  const struct option lopt[] = {
  { "help", 0, NULL, 'h' },
@@ -559,13 +562,16 @@ int main(int argc, char **argv)
  { "method", 0, NULL, 'm' },
  { "path", 0, NULL, 'p' },
  { "daemonize", 0, NULL, 'd' },
+{ "blackl

Re: [Qemu-devel] [PATCH] Add a .mailmap to map pre-git-conversion authors to friendly names

2011-12-12 Thread Anthony Liguori

On 12/12/2011 04:58 AM, Peter Maydell wrote:

Add a .mailmap file so 'git shortlog' can map the unfriendly
pre-git-conversion author entries to real names.

Signed-off-by: Peter Maydell


Applied.  Thanks.

Regards,

Anthony Liguori


---
v1->v2:
  fixed Andrzej's email to match MAINTAINERS file
  added entries for Fabrice Bellard, Jocelyn Mayer
  cc'd active maintainers with an entry in the mailmap
v2->v3:
  sorted into alpha order by first column

  .mailmap |   16 
  1 files changed, 16 insertions(+), 0 deletions(-)
  create mode 100644 .mailmap

diff --git a/.mailmap b/.mailmap
new file mode 100644
index 000..9797802
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,16 @@
+# This mailmap just translates the weird addresses from the original import 
into git
+# into proper addresses so that they are counted properly in git shortlog 
output.
+#
+Andrzej Zaborowski  
balrog
+Anthony Liguori  
aliguori
+Aurelien Jarno  
aurel32
+Blue Swirl  
blueswir1
+Edgar E. Iglesias  
edgar_igl
+Fabrice Bellard  
bellard
+Jocelyn Mayer  
j_mayer
+Paul Brook  
pbrook
+Thiemo Seufer  ths
+malc  malc
+# There is also a:
+#(no author)<(no author)@c046a42c-6fe2-441c-8c8c-71466251a162>
+# for the cvs2svn initialization commit e63c3dc74bf.





[Qemu-devel] [PATCH V13 3/7] Add a debug register

2011-12-12 Thread Stefan Berger
This patch uses the possibility to add a vendor-specific register and
adds a debug register useful for dumping the TIS's internal state. This
register is only active in a debug build (#define DEBUG_TIS).

Signed-off-by: Stefan Berger 

---

v9:
 - prefixing all function with tpm_tis_ and all constants with TPM_TIS_

v3:
 - all output goes to stderr
---
 hw/tpm_tis.c |   73 ++
 1 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/hw/tpm_tis.c b/hw/tpm_tis.c
index 34d0043..1fd105e 100644
--- a/hw/tpm_tis.c
+++ b/hw/tpm_tis.c
@@ -47,6 +47,9 @@
 #define TPM_TIS_REG_DID_VID   0xf00
 #define TPM_TIS_REG_RID   0xf04
 
+/* vendor-specific registers */
+#define TPM_TIS_REG_DEBUG 0xf90
+
 #define TPM_TIS_STS_VALID (1 << 7)
 #define TPM_TIS_STS_COMMAND_READY (1 << 6)
 #define TPM_TIS_STS_TPM_GO(1 << 5)
@@ -92,6 +95,11 @@
 
 #define TPM_TIS_NO_DATA_BYTE  0xff
 
+/* local prototypes */
+static uint64_t tpm_tis_mmio_read(void *opaque, target_phys_addr_t addr,
+  unsigned size);
+
+
 #ifdef DEBUG_TIS
 static void tpm_tis_show_buffer(const TPMSizedBuffer *sb, const char *string)
 {
@@ -319,6 +327,66 @@ static uint32_t tpm_tis_data_read(TPMState *s, uint8_t 
locty)
 return ret;
 }
 
+#ifdef DEBUG_TIS
+static void tpm_tis_dump_state(void *opaque, target_phys_addr_t addr)
+{
+static const unsigned regs[] = {
+TPM_TIS_REG_ACCESS,
+TPM_TIS_REG_INT_ENABLE,
+TPM_TIS_REG_INT_VECTOR,
+TPM_TIS_REG_INT_STATUS,
+TPM_TIS_REG_INTF_CAPABILITY,
+TPM_TIS_REG_STS,
+TPM_TIS_REG_DID_VID,
+TPM_TIS_REG_RID,
+0xfff};
+int idx;
+uint8_t locty = tpm_tis_locality_from_addr(addr);
+target_phys_addr_t base = addr & ~0xfff;
+TPMState *s = opaque;
+TPMTISState *tis = &s->s.tis;
+
+fprintf(stderr,
+"tpm_tis: active locality  : %d\n"
+"tpm_tis: state of locality %d : %d\n"
+"tpm_tis: register dump:\n",
+tis->active_locty,
+locty, tis->loc[locty].state);
+
+for (idx = 0; regs[idx] != 0xfff; idx++) {
+fprintf(stderr, "tpm_tis: 0x%04x : 0x%08x\n", regs[idx],
+(uint32_t)tpm_tis_mmio_read(opaque, base + regs[idx], 4));
+}
+
+fprintf(stderr,
+"tpm_tis: read offset   : %d\n"
+"tpm_tis: result buffer : ",
+tis->loc[locty].r_offset);
+for (idx = 0;
+ idx < tpm_tis_get_size_from_buffer(&tis->loc[locty].r_buffer);
+ idx++) {
+fprintf(stderr, "%c%02x%s",
+tis->loc[locty].r_offset == idx ? '>' : ' ',
+tis->loc[locty].r_buffer.buffer[idx],
+((idx & 0xf) == 0xf) ? "\ntpm_tis: " : "");
+}
+fprintf(stderr,
+"\n"
+"tpm_tis: write offset  : %d\n"
+"tpm_tis: request buffer: ",
+tis->loc[locty].w_offset);
+for (idx = 0;
+ idx < tpm_tis_get_size_from_buffer(&tis->loc[locty].w_buffer);
+ idx++) {
+fprintf(stderr, "%c%02x%s",
+tis->loc[locty].w_offset == idx ? '>' : ' ',
+tis->loc[locty].w_buffer.buffer[idx],
+((idx & 0xf) == 0xf) ? "\ntpm_tis: " : "");
+}
+fprintf(stderr, "\n");
+}
+#endif
+
 /*
  * Read a register of the TIS interface
  * See specs pages 33-63 for description of the registers
@@ -391,6 +459,11 @@ static uint64_t tpm_tis_mmio_read(void *opaque, 
target_phys_addr_t addr,
 case TPM_TIS_REG_RID:
 val = TPM_TIS_TPM_RID;
 break;
+#ifdef DEBUG_TIS
+case TPM_TIS_REG_DEBUG:
+tpm_tis_dump_state(opaque, addr);
+break;
+#endif
 }
 
 qemu_mutex_unlock(&s->state_lock);
-- 
1.7.6.4




Re: [Qemu-devel] [PATCH 0/2] net: clean up net/socket.c

2011-12-12 Thread Anthony Liguori

On 12/07/2011 09:01 AM, Stefan Hajnoczi wrote:

There is no consistent policy on closing the socket file descriptor when
net/socket.c initialization fails.  This has been on my TODO list for a while
and I had a few minutes to fix it now.


Applied all.  Thanks.

Regards,

Anthony Liguori



Stefan Hajnoczi (2):
   net: expand tabs in net/socket.c
   net: take ownership of fd in socket init functions

  net/socket.c |   88 ++---
  1 files changed, 46 insertions(+), 42 deletions(-)






[Qemu-devel] [PATCH V13 2/7] Add TPM (frontend) hardware interface (TPM TIS) to Qemu

2011-12-12 Thread Stefan Berger
This patch adds the main code of the TPM frontend driver, the TPM TIS
interface, to Qemu. The code is largely based on the previous implementation
for Xen but has been significantly extended to meet the standard's
requirements, such as the support for changing of localities and all the
functionality of the available flags.

Communication with the backend (i.e., for Xen or the libtpms-based one)
is cleanly separated through an interface which the backend driver needs
to implement.

The TPM TIS driver's backend was previously chosen in the code added
to arch_init. The frontend holds a pointer to the chosen backend (interface).

Communication with the backend is largely based on signals and conditions.
Whenever the frontend has collected a complete packet, it will signal
the backend, which then starts processing the command. Once the result
has been returned, the backend invokes a callback function
(tis_tpm_receive_cb()).

The one tricky part is support for VM suspend while the TPM is processing
a command. In this case the frontend driver is waiting for the backend
to return the result of the last command before shutting down. It waits
on a condition for a signal from the backend, which is delivered in
tis_tpm_receive_cb().

Testing the proper functioning of the different flags and localities
cannot be done from user space when running in Linux for example, since
access to the address space of the TPM TIS interface is not possible. Also
the Linux driver itself does not exercise all functionality. So, for
testing there is a fairly extensive test suite as part of the SeaBIOS patches
since from within the BIOS one can have full access to all the TPM's registers.


Signed-off-by: Stefan Berger 

---

v13:
  - don't call destroy callback in error path in tpm_tis_init

v11:
  - initialize val with 0x as default value to return from MMIO
read to an undefined location
  - display size of read or write operations in debugging output

v10:
  - Use error_report where necessary
  - Convert to use memory_region_init_io; use DEVICE_NATIVE_ENDIAN which
works for an x86 VM on x86 or ppc host
  - Implement cleanup in tpm_tis_init
  - put frontend model name into TPMBackend driver structure for later display
with the monitor

v9:
  - prefixing all function with tpm_tis_ and all constants with TPM_TIS_
  - adding minimum VMStateDescription and marking device as non-migratable

v5:
  - adding comment to tis_data_read
  - refactoring following support for split command line options
-tpmdev and -device
  - code handling the configuration of the TPM device was moved to tpm.c
  - removed empty line at end of file

v3:
  - prefixing functions with tis_
  - added a function to the backend interface 'early_startup_tpm' that
allows to detect the presence of the block storage and gracefully fails
Qemu if it's not available. This works with migration using shared
storage but doesn't support migration with block storage migration.
For encyrypted QCoW2 and in case of a snapshot resue the late_startup_tpm
interface function is called
---
 hw/tpm_tis.c |  818 ++
 1 files changed, 818 insertions(+), 0 deletions(-)
 create mode 100644 hw/tpm_tis.c

diff --git a/hw/tpm_tis.c b/hw/tpm_tis.c
new file mode 100644
index 000..34d0043
--- /dev/null
+++ b/hw/tpm_tis.c
@@ -0,0 +1,818 @@
+/*
+ * tpm_tis.c - QEMU's TPM TIS interface emulator
+ *
+ * Copyright (C) 2006,2010,2011 IBM Corporation
+ *
+ * Authors:
+ *  Stefan Berger 
+ *  David Safford 
+ *
+ * Xen 4 support: Andrease Niederl 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ *
+ * Implementation of the TIS interface according to specs found at
+ * http://www.trustedcomputiggroup.org.
+ * In the developers menu choose the PC Client section then find the TIS
+ * specification.
+ */
+
+#include "tpm.h"
+#include "block.h"
+#include "exec-memory.h"
+#include "hw/hw.h"
+#include "hw/pc.h"
+#include "hw/tpm_tis.h"
+#include "qemu-error.h"
+
+#include 
+
+/*#define DEBUG_TIS */
+
+/* whether the STS interrupt is supported */
+/*#define RAISE_STS_IRQ */
+
+/* tis registers */
+#define TPM_TIS_REG_ACCESS0x00
+#define TPM_TIS_REG_INT_ENABLE0x08
+#define TPM_TIS_REG_INT_VECTOR0x0c
+#define TPM_TIS_REG_INT_STATUS0x10
+#define TPM_TIS_REG_INTF_CAPABILITY   0x14
+#define TPM_TIS_REG_STS   0x18
+#define TPM_TIS_REG_DATA_FIFO 0x24
+#define TPM_TIS_REG_DID_VID   0xf00
+#define TPM_TIS_REG_RID   0xf04
+
+#define TPM_TIS_STS_VALID (1 << 7)
+#define TPM_TIS_STS_COMMAND_READY (1 << 6)
+#define TPM_TIS_STS_TPM_GO(1 << 5)
+#define TPM_TIS_STS_DATA_AVAILABLE(1 << 4)
+#define TPM_TIS_STS_EX

Re: [Qemu-devel] KVM call agenda for Tuesday 13

2011-12-12 Thread Anthony Liguori

On 12/12/2011 05:16 PM, Juan Quintela wrote:


Hi

Please send in any agenda items you are interested in covering.


- QOM merge plan

I'd also like to do a code walk through of QOM at the first call of the new 
year.

Regards,

Anthony Liguori



Thanks, Juan.






Re: [Qemu-devel] [PATCH V13 7/7] Add fd parameter for TPM passthrough driver

2011-12-12 Thread Anthony Liguori

On 12/12/2011 01:12 PM, Stefan Berger wrote:

Enable the passing of a file descriptor via fd=<..>  to access the host's
TPM device using the TPM passthrough driver.

Signed-off-by: Stefan Berger

---

v13:
  - Only accepting a character device's file descriptor

v12:
  - added documentation part
---
  hw/tpm_passthrough.c |   73 +-
  qemu-config.c|5 +++
  qemu-options.hx  |6 +++-
  3 files changed, 64 insertions(+), 20 deletions(-)

diff --git a/hw/tpm_passthrough.c b/hw/tpm_passthrough.c
index f9cfe3d..57bb77a 100644
--- a/hw/tpm_passthrough.c
+++ b/hw/tpm_passthrough.c
@@ -361,33 +361,68 @@ static int tpm_passthrough_handle_device_opts(QemuOpts 
*opts, TPMBackend *tb)
  const char *value;
  char buf[64];
  int n;
+struct stat statbuf;

-value = qemu_opt_get(opts, "path");
-if (!value) {
-value = TPM_PASSTHROUGH_DEFAULT_DEVICE;
-}
+value = qemu_opt_get(opts, "fd");
+if (value) {
+if (qemu_opt_get(opts, "path")) {
+error_report("fd= is invalid with path=");
+return -1;
+}
+
+tb->s.tpm_pt->tpm_fd = qemu_parse_fd(value);
+if (tb->s.tpm_pt->tpm_fd<  0) {
+error_report("Illegal file descriptor for TPM device.\n");
+return -1;
+}

-n = snprintf(tb->s.tpm_pt->tpm_dev, sizeof(tb->s.tpm_pt->tpm_dev),
- "%s", value);
+snprintf(buf, sizeof(buf), "fd=%d", tb->s.tpm_pt->tpm_fd);

-if (n>= sizeof(tb->s.tpm_pt->tpm_dev)) {
-error_report("TPM device path is too long.\n");
-goto err_exit;
-}
+tb->parameters = g_strdup(buf);

-snprintf(buf, sizeof(buf), "path=%s", tb->s.tpm_pt->tpm_dev);
+if (tb->parameters == NULL) {
+goto err_close_tpmdev;
+}
+} else {
+value = qemu_opt_get(opts, "path");
+if (!value) {
+value = TPM_PASSTHROUGH_DEFAULT_DEVICE;
+}
+
+n = snprintf(tb->s.tpm_pt->tpm_dev, sizeof(tb->s.tpm_pt->tpm_dev),
+ "%s", value);
+
+if (n>= sizeof(tb->s.tpm_pt->tpm_dev)) {
+error_report("TPM device path is too long.\n");
+goto err_exit;
+}

-tb->parameters = g_strdup(buf);
+snprintf(buf, sizeof(buf), "path=%s", tb->s.tpm_pt->tpm_dev);

-if (tb->parameters == NULL) {
-return 1;
+tb->parameters = g_strdup(buf);
+
+if (tb->parameters == NULL) {
+return 1;
+}
+
+tb->s.tpm_pt->tpm_fd = open(tb->s.tpm_pt->tpm_dev, O_RDWR);
+if (tb->s.tpm_pt->tpm_fd<  0) {
+error_report("Cannot access TPM device using '%s'.\n",
+ tb->s.tpm_pt->tpm_dev);
+goto err_exit;
+}
  }

-tb->s.tpm_pt->tpm_fd = open(tb->s.tpm_pt->tpm_dev, O_RDWR);
-if (tb->s.tpm_pt->tpm_fd<  0) {
-error_report("Cannot access TPM device using '%s'.\n",
- tb->s.tpm_pt->tpm_dev);
-goto err_exit;
+if (fstat(tb->s.tpm_pt->tpm_fd,&statbuf) != 0) {
+error_report("Cannot determine file descriptor type for TPM "
+ "device: %s", strerror(errno));
+goto err_close_tpmdev;
+}
+
+/* only allow character devices for now */
+if (!S_ISCHR(statbuf.st_mode)) {
+error_report("TPM file descriptor is not a character device");
+goto err_close_tpmdev;
  }


I think you're being overzealous here.  The backend only uses read/write to 
interact with the passthrough device.  You could use this as a mechanism to tie 
in an emulated VTPM by using a socket.  I'm not suggesting we do that for 
libvtpm, but I think we don't gain anything from being overly restrictive here.


I don't think a user passing the wrong type of fd is the common case to optimize 
for wrt usability.


Regards,

Anthony Liguori



Re: [Qemu-devel] [PATCH V13 6/7] Introduce --enable-tpm-passthrough configure option

2011-12-12 Thread Anthony Liguori

On 12/12/2011 01:12 PM, Stefan Berger wrote:

Introduce --enable-tpm-passthrough configure option.

Signed-off-by: Stefan Berger
---
  configure |   16 +++-
  1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/configure b/configure
index 25995bc..ffb599e 100755
--- a/configure
+++ b/configure
@@ -186,6 +186,7 @@ zlib="yes"
  guest_agent="yes"
  libiscsi=""
  tpm="no"
+tpm_passthrough="no"


Same as before, please probe for existence.

Regards,

Anthony Liguori



  # parse CC options first
  for opt do
@@ -787,11 +788,20 @@ for opt do
;;
--enable-tpm) tpm="yes"
;;
+  --enable-tpm-passthrough) tpm_passthrough="yes"
+  ;;
*) echo "ERROR: unknown option $opt"; show_help="yes"
;;
esac
  done

+if test "$tpm" = "no" ; then
+if test "$tpm_passthrough" = "yes"; then
+echo "ERROR: --enable-tpm-passthrough requires --enable-tpm"
+exit 1
+fi
+fi
+
  #
  # If cpu ~= sparc and  sparc_cpu hasn't been defined, plug in the right
  # QEMU_CFLAGS/LDFLAGS (assume sparc_v8plus for 32-bit and sparc_v9 for 64-bit)
@@ -1074,6 +1084,7 @@ echo "  --enable-usb-redir   enable usb network 
redirection support"
  echo "  --disable-guest-agentdisable building of the QEMU Guest Agent"
  echo "  --enable-guest-agent enable building of the QEMU Guest Agent"
  echo "  --enable-tpm enable TPM support"
+echo "  --enable-tpm-passthrough enable TPM passthrough driver"
  echo ""
  echo "NOTE: The object files are built at the place where configure is 
launched"
  exit 1
@@ -2850,6 +2861,7 @@ echo "OpenGL support$opengl"
  echo "libiscsi support  $libiscsi"
  echo "build guest agent $guest_agent"
  echo "TPM support   $tpm"
+echo "TPM passthrough   $tpm_passthrough"

  if test "$sdl_too_old" = "yes"; then
  echo "->  Your SDL version is too old - please upgrade to have SDL support"
@@ -3722,7 +3734,9 @@ fi
  if test "$tpm" = "yes"; then
if test "$target_softmmu" = "yes" ; then
  if test "$linux" = "yes" ; then
-  echo "CONFIG_TPM_PASSTHROUGH=y">>  $config_target_mak
+  if test "$tpm_passthrough" = "yes" ; then
+echo "CONFIG_TPM_PASSTHROUGH=y">>  $config_target_mak
+  fi
  fi
  echo "CONFIG_TPM=y">>  $config_host_mak
fi





Re: [Qemu-devel] [PATCH V13 5/7] Add a TPM Passthrough backend driver implementation

2011-12-12 Thread Anthony Liguori

On 12/12/2011 01:12 PM, Stefan Berger wrote:

 From Andreas Niederl's original posting with adaptations where necessary:

This patch is based of off version 9 of Stefan Berger's patch series
   "Qemu Trusted Platform Module (TPM) integration"
and adds a new backend driver for it.

This patch adds a passthrough backend driver for passing commands sent to the
emulated TPM device directly to a TPM device opened on the host machine.

Thus it is possible to use a hardware TPM device in a system running on QEMU,
providing the ability to access a TPM in a special state (e.g. after a Trusted
Boot).

This functionality is being used in the acTvSM Trusted Virtualization Platform
which is available on [1].

Usage example:
   qemu-system-x86_64 -tpmdev passthrough,id=tpm0,path=/dev/tpm0 \
  -device tpm-tis,tpmdev=tpm0 \
  -cdrom test.iso -boot d

Some notes about the host TPM:
The TPM needs to be enabled and activated. If that's not the case one
has to go through the BIOS/UEFI and enable and activate that TPM for TPM
commands to work as expected.
It may be necessary to boot the kernel using tpm_tis.force=1 in the boot
command line or 'modprobe tpm_tis force=1' in case of using it as a module.

Regards,
Andreas Niederl, Stefan Berger

[1] http://trustedjava.sourceforge.net/

Signed-off-by: Andreas Niederl
Signed-off-by: Stefan Berger

---

Changes for v12:
  - check size indicator in response from TPM to match that of the received
packet

Changes for v10:
  - clarified documentation
  - using /dev/tpm0 as default device if path option is not given
  - refactored code handling 'device' option into its own function
  - fixed name of structure to TPMPassthruThreadParams
  - only add tpm_passthrough_driver to collection of backends if
it is compiled on the host

Changes for v9:
  - prefixing of all functions and variables with tpm_passthrough_
  - cleanup of all variables into a structure that is now accessed
using TPMBackend (tb->s.tpm_pt)
  - build it on Linux machines
  - added function to test whether given device is a TPM and refuse
startup if it is not
---
  Makefile.target  |1 +
  configure|3 +
  hw/tpm_passthrough.c |  477 ++
  qemu-options.hx  |   33 
  tpm.c|   23 +++
  tpm.h|   34 
  6 files changed, 571 insertions(+), 0 deletions(-)
  create mode 100644 hw/tpm_passthrough.c

diff --git a/Makefile.target b/Makefile.target
index 37d5d10..4fc96e6 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -206,6 +206,7 @@ obj-$(CONFIG_KVM) += kvm.o kvm-all.o
  obj-$(CONFIG_NO_KVM) += kvm-stub.o
  obj-y += memory.o
  obj-$(CONFIG_TPM) += tpm.o tpm_tis.o
+obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
  LIBS+=-lz

  QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
diff --git a/configure b/configure
index 385feb4..25995bc 100755
--- a/configure
+++ b/configure
@@ -3721,6 +3721,9 @@ fi

  if test "$tpm" = "yes"; then
if test "$target_softmmu" = "yes" ; then
+if test "$linux" = "yes" ; then
+  echo "CONFIG_TPM_PASSTHROUGH=y">>  $config_target_mak
+fi
  echo "CONFIG_TPM=y">>  $config_host_mak
fi
  fi
diff --git a/hw/tpm_passthrough.c b/hw/tpm_passthrough.c
new file mode 100644
index 000..f9cfe3d
--- /dev/null
+++ b/hw/tpm_passthrough.c
@@ -0,0 +1,477 @@
+/*
+ *  passthrough TPM driver
+ *
+ *  Copyright (c) 2010, 2011 IBM Corporation
+ *  Authors:
+ *Stefan Berger
+ *
+ *  Copyright (C) 2011 IAIK, Graz University of Technology
+ *Author: Andreas Niederl
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ */
+
+#include "qemu-common.h"
+#include "qemu-error.h"
+#include "tpm.h"
+#include "hw/hw.h"
+#include "hw/tpm_tis.h"
+#include "hw/pc.h"
+
+/* #define DEBUG_TPM */
+
+/* data structures */
+
+typedef struct TPMPassthruThreadParams {
+TPMState *tpm_state;
+
+TPMRecvDataCB *recv_data_callback;
+TPMBackend *tb;
+} TPMPassthruThreadParams;
+
+struct TPMPassthruState {
+QemuThread thread;
+bool thread_terminate;
+bool thread_running;
+
+TPMPassthruThreadParams tpm_thread_params;
+
+char tpm_dev[64];
+int tpm_fd;
+bool had_startup_error;
+};
+
+#define TPM_PASSTHROUGH_DEFAULT_DEVICE "/dev/tpm0"
+
+/* borrowed from qemu-char.c */
+static int tpm_passthrough_unix_write(int fd, cons

Re: [Qemu-devel] [PATCH V13 4/7] Build the TPM frontend code

2011-12-12 Thread Anthony Liguori

On 12/12/2011 01:12 PM, Stefan Berger wrote:

Build the TPM frontend code that has been added so far.

Signed-off-by: Stefan Berger
---
  Makefile.target |1 +
  configure   |   11 +++
  2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 39b2e5a..37d5d10 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -205,6 +205,7 @@ obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
  obj-$(CONFIG_KVM) += kvm.o kvm-all.o
  obj-$(CONFIG_NO_KVM) += kvm-stub.o
  obj-y += memory.o
+obj-$(CONFIG_TPM) += tpm.o tpm_tis.o
  LIBS+=-lz

  QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
diff --git a/configure b/configure
index cc5ae87..385feb4 100755
--- a/configure
+++ b/configure
@@ -185,6 +185,7 @@ opengl=""
  zlib="yes"
  guest_agent="yes"
  libiscsi=""
+tpm="no"


Please probe instead of requiring it to be explicitly enabled.

Regards,

Anthony Liguori



  # parse CC options first
  for opt do
@@ -784,6 +785,8 @@ for opt do
;;
--disable-guest-agent) guest_agent="no"
;;
+  --enable-tpm) tpm="yes"
+  ;;
*) echo "ERROR: unknown option $opt"; show_help="yes"
;;
esac
@@ -1070,6 +1073,7 @@ echo "  --disable-usb-redir  disable usb network 
redirection support"
  echo "  --enable-usb-redir   enable usb network redirection support"
  echo "  --disable-guest-agentdisable building of the QEMU Guest Agent"
  echo "  --enable-guest-agent enable building of the QEMU Guest Agent"
+echo "  --enable-tpm enable TPM support"
  echo ""
  echo "NOTE: The object files are built at the place where configure is 
launched"
  exit 1
@@ -2845,6 +2849,7 @@ echo "usb net redir $usb_redir"
  echo "OpenGL support$opengl"
  echo "libiscsi support  $libiscsi"
  echo "build guest agent $guest_agent"
+echo "TPM support   $tpm"

  if test "$sdl_too_old" = "yes"; then
  echo "->  Your SDL version is too old - please upgrade to have SDL support"
@@ -3714,6 +3719,12 @@ if test "$gprof" = "yes" ; then
fi
  fi

+if test "$tpm" = "yes"; then
+  if test "$target_softmmu" = "yes" ; then
+echo "CONFIG_TPM=y">>  $config_host_mak
+  fi
+fi
+
  if test "$ARCH" = "tci"; then
linker_script=""
  else





Re: [Qemu-devel] [PATCH V13 2/7] Add TPM (frontend) hardware interface (TPM TIS) to Qemu

2011-12-12 Thread Anthony Liguori

On 12/12/2011 01:12 PM, Stefan Berger wrote:

This patch adds the main code of the TPM frontend driver, the TPM TIS
interface, to Qemu. The code is largely based on the previous implementation
for Xen but has been significantly extended to meet the standard's
requirements, such as the support for changing of localities and all the
functionality of the available flags.

Communication with the backend (i.e., for Xen or the libtpms-based one)
is cleanly separated through an interface which the backend driver needs
to implement.

The TPM TIS driver's backend was previously chosen in the code added
to arch_init. The frontend holds a pointer to the chosen backend (interface).

Communication with the backend is largely based on signals and conditions.
Whenever the frontend has collected a complete packet, it will signal
the backend, which then starts processing the command. Once the result
has been returned, the backend invokes a callback function
(tis_tpm_receive_cb()).

The one tricky part is support for VM suspend while the TPM is processing
a command. In this case the frontend driver is waiting for the backend
to return the result of the last command before shutting down. It waits
on a condition for a signal from the backend, which is delivered in
tis_tpm_receive_cb().

Testing the proper functioning of the different flags and localities
cannot be done from user space when running in Linux for example, since
access to the address space of the TPM TIS interface is not possible. Also
the Linux driver itself does not exercise all functionality. So, for
testing there is a fairly extensive test suite as part of the SeaBIOS patches
since from within the BIOS one can have full access to all the TPM's registers.


Signed-off-by: Stefan Berger

---

v13:
   - don't call destroy callback in error path in tpm_tis_init

v11:
   - initialize val with 0x as default value to return from MMIO
 read to an undefined location
   - display size of read or write operations in debugging output

v10:
   - Use error_report where necessary
   - Convert to use memory_region_init_io; use DEVICE_NATIVE_ENDIAN which
 works for an x86 VM on x86 or ppc host
   - Implement cleanup in tpm_tis_init
   - put frontend model name into TPMBackend driver structure for later display
 with the monitor

v9:
   - prefixing all function with tpm_tis_ and all constants with TPM_TIS_
   - adding minimum VMStateDescription and marking device as non-migratable

v5:
   - adding comment to tis_data_read
   - refactoring following support for split command line options
 -tpmdev and -device
   - code handling the configuration of the TPM device was moved to tpm.c
   - removed empty line at end of file

v3:
   - prefixing functions with tis_
   - added a function to the backend interface 'early_startup_tpm' that
 allows to detect the presence of the block storage and gracefully fails
 Qemu if it's not available. This works with migration using shared
 storage but doesn't support migration with block storage migration.
 For encyrypted QCoW2 and in case of a snapshot resue the late_startup_tpm
 interface function is called
---
  hw/tpm_tis.c |  818 ++
  1 files changed, 818 insertions(+), 0 deletions(-)
  create mode 100644 hw/tpm_tis.c

diff --git a/hw/tpm_tis.c b/hw/tpm_tis.c
new file mode 100644
index 000..34d0043
--- /dev/null
+++ b/hw/tpm_tis.c
@@ -0,0 +1,818 @@
+/*
+ * tpm_tis.c - QEMU's TPM TIS interface emulator
+ *
+ * Copyright (C) 2006,2010,2011 IBM Corporation
+ *
+ * Authors:
+ *  Stefan Berger
+ *  David Safford
+ *
+ * Xen 4 support: Andrease Niederl
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ *
+ * Implementation of the TIS interface according to specs found at
+ * http://www.trustedcomputiggroup.org.
+ * In the developers menu choose the PC Client section then find the TIS
+ * specification.
+ */
+
+#include "tpm.h"
+#include "block.h"
+#include "exec-memory.h"
+#include "hw/hw.h"
+#include "hw/pc.h"
+#include "hw/tpm_tis.h"
+#include "qemu-error.h"
+
+#include



#include "qemu-common.h"


+
+/*#define DEBUG_TIS */
+
+/* whether the STS interrupt is supported */
+/*#define RAISE_STS_IRQ */
+
+/* tis registers */
+#define TPM_TIS_REG_ACCESS0x00
+#define TPM_TIS_REG_INT_ENABLE0x08
+#define TPM_TIS_REG_INT_VECTOR0x0c
+#define TPM_TIS_REG_INT_STATUS0x10
+#define TPM_TIS_REG_INTF_CAPABILITY   0x14
+#define TPM_TIS_REG_STS   0x18
+#define TPM_TIS_REG_DATA_FIFO 0x24
+#define TPM_TIS_REG_DID_VID   0xf00
+#define TPM_TIS_REG_RID   0xf04
+
+#define TPM_TIS_STS_VALID (1<<  7)
+#define TPM_TIS_STS_COMMAND_READY (1<<  6)
+#define TPM_TIS_STS_TPM_GO 

[Qemu-devel] [PATCH V13 0/7] Qemu Trusted Platform Module (TPM) integration

2011-12-12 Thread Stefan Berger
The following series of patches adds TPM (Trusted Platform Module) support
to Qemu. An emulator for the TIS (TPM Interface Spec) interface is
added that provides the basis for accessing a 'backend' implementing the actual
TPM functionality. The TIS emulator serves as a 'frontend' enabling for
example Linux's TPM TIS (tpm_tis) driver.

In this series I am posting a backend implementation that makes use of the
host's TPM through a passthrough driver, which on Linux is accessed
using /dev/tpm0.

v13:
 - applies to checkout of 61a5872 (Dec 12)
 - only allowing character devices as fd parameter
 - fixing error path in tpm_tis_init

v12:
 - applies to checkout of ebffe2a (Oct 11)
 - added documentation for fd parameter
 - nits

v11:
 - applies to checkout of 46f3069 (Sep 28)
 - some filing on the documentation
 - small nits fixed

v10:
 - applies to checkout of 1ce9ce6 (Sep 27)
 - addressed Michael Tsirkin's comments on v9

v9:
 - addressed Michael Tsirkin's and other reviewers' comments
 - only posting Andreas Niederl's passthrough driver as the backend driver

v8:
 - applies to checkout of f0fb8b7 (Aug 30)
 - fixing compilation error pointed out by Andreas Niederl
 - adding patch that allows to feed an initial state into the libtpms TPM
 - following memory API changes (glib) where necessary

v7:
 - applies to checkout of b9c6cbf (Aug 9)
 - measuring the modules if multiboot is used
 - coding style fixes

v6:
 - applies to checkout of 75ef849 (July 2nd)
 - some fixes and improvements to existing patches; see individual patches
 - added a patch with a null driver responding to all TPM requests with
   a response indicating failure; this backend has no dependencies and
   can alwayy be built;
 - added a patch to support the hashing of kernel, ramfs and command line
   if those were passed to Qemu using -kernel, -initrd and -append
   respectively. Measurements are taken, logged, and passed to SeaBIOS using
   the firmware interface.
 - libtpms revision 7 now requires 83kb of block storage due to having more
   NVRAM space

v5:
 - applies to checkout of 1fddfba1
 - adding support for split command line using the -tpmdev ... -device ...
   options while keeping the -tpm option
 - support for querying the device models using -tpm model=?
 - support for monitor 'info tpm'
 - adding documentation of command line options for man page and web page
 - increasing room for ACPI tables that qemu reserves to 128kb (from 64kb)
 - adding (experimental) support for block migration
 - adding (experimental) support for taking measurements when kernel,
   initrd and kernel command line are directly passed to Qemu

v4:
 - applies to checkout of d2d979c6
 - more coding style fixes
 - adding patch for supporting blob encryption (in addition to the existing
   QCoW2-level encryption)
   - this allows for graceful termination of a migration if the target
 is detected to have a wrong key
   - tested with big and little endian hosts
 - main thread releases mutex while checking for work to do on behalf of
   backend
 - introducing file locking (fcntl) on the block layer for serializing access
   to shared (QCoW2) files (used during migration)

v3:
 - Building a null driver at patch 5/8 that responds to all requests
   with an error response; subsequently this driver is transformed to the
   libtpms-based driver for real TPM functionality
 - Reworked the threading; dropped the patch for qemu_thread_join; the
   main thread synchronizing with the TPM thread termination may need
   to write data to the block storage while waiting for the thread to 
   terminate; did not previously show a problem but is safer
 - A lot of testing based on recent git checkout 4b4a72e5 (4/10):
   - migration of i686 VM from x86_64 host to i686 host to ppc64 host while
 running tests inside the VM
   - tests with S3 suspend/resume
   - tests with snapshots
   - multiple-hour tests with VM suspend/resume (using virsh save/restore)
 while running a TPM test suite inside the VM
   All tests passed; [not all of them were done on the ppc64 host]

v2:
 - splitting some of the patches into smaller ones for easier review
 - fixes in individual patches

Regards,
Stefan


Stefan Berger (7):
  Support for TPM command line options
  Add TPM (frontend) hardware interface (TPM TIS) to Qemu
  Add a debug register
  Build the TPM frontend code
  Add a TPM Passthrough backend driver implementation
  Introduce --enable-tpm-passthrough configure option
  Add fd parameter for TPM passthrough driver

 Makefile.target  |2 +
 configure|   28 ++
 hmp-commands.hx  |2 +
 hw/tpm_passthrough.c |  512 +
 hw/tpm_tis.c |  891 ++
 hw/tpm_tis.h |   91 +
 monitor.c|   10 +
 qemu-config.c|   25 ++
 qemu-options.hx  |   71 
 tpm.c|  190 +++
 tpm.h|  124 +++
 vl.c |   15 +
 1

[Qemu-devel] KVM call agenda for Tuesday 13

2011-12-12 Thread Juan Quintela

Hi

Please send in any agenda items you are interested in covering.

Thanks, Juan.



Re: [Qemu-devel] [PATCH V13 1/7] Support for TPM command line options

2011-12-12 Thread Anthony Liguori

On 12/12/2011 01:12 PM, Stefan Berger wrote:

This patch adds support for TPM command line options.
The command line options supported here are

./qemu-... -tpmdev passthrough,path=,id=
-device tpm-tis,tpmdev=

and

./qemu-... -tpmdev ?

where the latter works similar to -soundhw ? and shows a list of
available TPM backends (for example 'passthrough').

Using the type parameter, the backend is chosen, i.e., 'passthrough' for the
passthrough driver. The interpretation of the other parameters along
with determining whether enough parameters were provided is pushed into
the backend driver, which needs to implement the interface function
'create' and return a TPMDriver structure if the VM can be started or 'NULL'
if not enough or bad parameters were provided.

Monitor support for 'info tpm' has been added. It for example prints the
following:

(qemu) info tpm
TPM devices:
  tpm0: model=tpm-tis
   \ tpm0: type=passthrough,path=/dev/tpm0

Signed-off-by: Stefan Berger

---

v12:
  - use all 4 bytes of the message length indicator

v10:
  - tpm_display_backend_drivers always prints to stderr

v9:
  - prefixing all functions with tpm_tis_ and all constants with TPM_TIS_
  - splitting off of -tpm command line support into its own patch
  - only support TPM passthrough for now

v8:
  - adjusting formatting of backend drivers output to accomodate better
formatting of 'passthrough' backend output

v6:
  - use #idef CONFIG_TPM to surround TPM calls
  - use QLIST_FOREACH_SAFE rather than QLIST_FOREACH in tpm_cleanup
  - commented backend ops in tpm.h
  - moving to IRQ 5 (11 collided with network cards)

v5:
  - fixing typo reported by Serge Hallyn
  - Adapting code to split command line parameters supporting
-tpmdev ... -device tpm-tis,tpmdev=...
  - moved code out of arch_init.c|h into tpm.c|h
  - increasing reserved memory for ACPI tables to 128kb (from 64kb)
  - the backend interface has a create() function for interpreting the command
line parameters and returning a TPMDevice structure; previoulsy
this function was called handle_options()
  - the backend interface has a destroy() function for cleaning up after
the create() function was called
  - added support for 'info tpm' in monitor

v4:
  - coding style fixes

v3:
  - added hw/tpm_tis.h to this patch so Qemu compiles at this stage
---
  hmp-commands.hx |2 +
  hw/tpm_tis.h|   91 ++
  monitor.c   |   10 +++
  qemu-config.c   |   20 +++
  qemu-options.hx |   34 +++
  tpm.c   |  167 +++
  tpm.h   |   90 +
  vl.c|   15 +
  8 files changed, 429 insertions(+), 0 deletions(-)
  create mode 100644 hw/tpm_tis.h
  create mode 100644 tpm.c
  create mode 100644 tpm.h

diff --git a/hmp-commands.hx b/hmp-commands.hx
index fdbed15..4506f56 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1352,6 +1352,8 @@ show device tree
  show qdev device model list
  @item info roms
  show roms
+@item info tpm
+show the TPM device
  @end table
  ETEXI

diff --git a/hw/tpm_tis.h b/hw/tpm_tis.h
new file mode 100644
index 000..e6a9a4b
--- /dev/null
+++ b/hw/tpm_tis.h
@@ -0,0 +1,91 @@
+/*
+ * tpm_tis.c - QEMU's TPM TIS interface emulator
+ *
+ * Copyright (C) 2006,2010,2011 IBM Corporation
+ *
+ * Authors:
+ *  Stefan Berger
+ *  David Safford
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ *
+ * Implementation of the TIS interface according to specs found at
+ * http://www.trustedcomputiggroup.org
+ *
+ */
+#ifndef _HW_TPM_TIS_H
+#define _HW_TPM_TIS_H


Macros shouldn't start with '_' as that namespace is reserved in C.


+#include "isa.h"
+#include "qemu-thread.h"
+
+#include


Just include "qemu-common.h"


+#define TPM_TIS_ADDR_BASE   0xFED4
+
+#define TPM_TIS_NUM_LOCALITIES  5 /* per spec */
+#define TPM_TIS_NO_LOCALITY 0xff
+
+#define TPM_TIS_IS_VALID_LOCTY(x)   ((x)<  TPM_TIS_NUM_LOCALITIES)
+
+#define TPM_TIS_IRQ 5
+
+#define TPM_TIS_BUFFER_MAX  4096
+
+
+typedef struct TPMSizedBuffer {
+uint32_t size;
+uint8_t  *buffer;
+} TPMSizedBuffer;
+
+enum tpm_tis_state {
+TPM_TIS_STATE_IDLE = 0,
+TPM_TIS_STATE_READY,
+TPM_TIS_STATE_COMPLETION,
+TPM_TIS_STATE_EXECUTION,
+TPM_TIS_STATE_RECEPTION,
+};


Typed enums still need to be CamelCase and typedefed.


+/* locality data  -- all fields are persisted */
+typedef struct TPMLocality {
+enum tpm_tis_state state;
+uint8_t access;
+uint8_t sts;
+uint32_t inte;
+uint32_t ints;
+
+uint16_t w_offset;
+uint16_t r_offset;
+TPMSizedBuffer w_buffer;
+TPMSizedBuffer r_buffer;
+} TPMLocality;
+
+typedef struct TPMTISState {
+uint32_t offset;
+uint8_t buf[TPM_TIS_BUF

[Qemu-devel] [PATCH V13 5/7] Add a TPM Passthrough backend driver implementation

2011-12-12 Thread Stefan Berger
>From Andreas Niederl's original posting with adaptations where necessary:

This patch is based of off version 9 of Stefan Berger's patch series
  "Qemu Trusted Platform Module (TPM) integration"
and adds a new backend driver for it.

This patch adds a passthrough backend driver for passing commands sent to the
emulated TPM device directly to a TPM device opened on the host machine.

Thus it is possible to use a hardware TPM device in a system running on QEMU,
providing the ability to access a TPM in a special state (e.g. after a Trusted
Boot).

This functionality is being used in the acTvSM Trusted Virtualization Platform
which is available on [1].

Usage example:
  qemu-system-x86_64 -tpmdev passthrough,id=tpm0,path=/dev/tpm0 \
 -device tpm-tis,tpmdev=tpm0 \
 -cdrom test.iso -boot d

Some notes about the host TPM:
The TPM needs to be enabled and activated. If that's not the case one
has to go through the BIOS/UEFI and enable and activate that TPM for TPM
commands to work as expected.
It may be necessary to boot the kernel using tpm_tis.force=1 in the boot
command line or 'modprobe tpm_tis force=1' in case of using it as a module.

Regards,
Andreas Niederl, Stefan Berger

[1] http://trustedjava.sourceforge.net/

Signed-off-by: Andreas Niederl 
Signed-off-by: Stefan Berger 

---

Changes for v12:
 - check size indicator in response from TPM to match that of the received
   packet

Changes for v10:
 - clarified documentation
 - using /dev/tpm0 as default device if path option is not given
 - refactored code handling 'device' option into its own function
 - fixed name of structure to TPMPassthruThreadParams
 - only add tpm_passthrough_driver to collection of backends if
   it is compiled on the host

Changes for v9:
 - prefixing of all functions and variables with tpm_passthrough_
 - cleanup of all variables into a structure that is now accessed
   using TPMBackend (tb->s.tpm_pt)
 - build it on Linux machines
 - added function to test whether given device is a TPM and refuse
   startup if it is not
---
 Makefile.target  |1 +
 configure|3 +
 hw/tpm_passthrough.c |  477 ++
 qemu-options.hx  |   33 
 tpm.c|   23 +++
 tpm.h|   34 
 6 files changed, 571 insertions(+), 0 deletions(-)
 create mode 100644 hw/tpm_passthrough.c

diff --git a/Makefile.target b/Makefile.target
index 37d5d10..4fc96e6 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -206,6 +206,7 @@ obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
 obj-y += memory.o
 obj-$(CONFIG_TPM) += tpm.o tpm_tis.o
+obj-$(CONFIG_TPM_PASSTHROUGH) += tpm_passthrough.o
 LIBS+=-lz
 
 QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
diff --git a/configure b/configure
index 385feb4..25995bc 100755
--- a/configure
+++ b/configure
@@ -3721,6 +3721,9 @@ fi
 
 if test "$tpm" = "yes"; then
   if test "$target_softmmu" = "yes" ; then
+if test "$linux" = "yes" ; then
+  echo "CONFIG_TPM_PASSTHROUGH=y" >> $config_target_mak
+fi
 echo "CONFIG_TPM=y" >> $config_host_mak
   fi
 fi
diff --git a/hw/tpm_passthrough.c b/hw/tpm_passthrough.c
new file mode 100644
index 000..f9cfe3d
--- /dev/null
+++ b/hw/tpm_passthrough.c
@@ -0,0 +1,477 @@
+/*
+ *  passthrough TPM driver
+ *
+ *  Copyright (c) 2010, 2011 IBM Corporation
+ *  Authors:
+ *Stefan Berger 
+ *
+ *  Copyright (C) 2011 IAIK, Graz University of Technology
+ *Author: Andreas Niederl
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see 
+ */
+
+#include "qemu-common.h"
+#include "qemu-error.h"
+#include "tpm.h"
+#include "hw/hw.h"
+#include "hw/tpm_tis.h"
+#include "hw/pc.h"
+
+/* #define DEBUG_TPM */
+
+/* data structures */
+
+typedef struct TPMPassthruThreadParams {
+TPMState *tpm_state;
+
+TPMRecvDataCB *recv_data_callback;
+TPMBackend *tb;
+} TPMPassthruThreadParams;
+
+struct TPMPassthruState {
+QemuThread thread;
+bool thread_terminate;
+bool thread_running;
+
+TPMPassthruThreadParams tpm_thread_params;
+
+char tpm_dev[64];
+int tpm_fd;
+bool had_startup_error;
+};
+
+#define TPM_PASSTHROUGH_DEFAULT_DEVICE "/dev/tpm0"
+
+/* borrowed from qemu-char.c */
+static int tpm_passthrough_unix_write(int fd, const uint8_t *buf, uint32_t len)
+{
+int ret, len1;
+
+len1 = len;
+

Re: [Qemu-devel] [PATCH 0/2] split hw/hw.h

2011-12-12 Thread Anthony Liguori

On 12/06/2011 11:34 AM, Paolo Bonzini wrote:

Extract qemu-file.h and vmstate.h from it.  Last for this week, promised.


This conflicts badly for me.  Can you rebase?

Regards,

Anthony Liguori



Paolo Bonzini (2):
   ptimer: move declarations to ptimer.h
   vmstate: extract declarations out of hw/hw.h

  hw/arm_timer.c|1 +
  hw/etraxfs_timer.c|1 +
  hw/grlib_apbuart.c|1 +
  hw/grlib_gptimer.c|1 +
  hw/hid.h  |   23 ++
  hw/hw.h   |  882 +
  hw/i2c.h  |   10 +
  hw/lan9118.c  |1 +
  hw/leon3.c|1 +
  hw/lm32_timer.c   |1 +
  hw/mcf5206.c  |1 +
  hw/mcf5208.c  |1 +
  hw/milkymist-sysctl.c |1 +
  hw/musicpal.c |1 +
  hw/pcie.h |   11 +
  hw/ptimer.c   |1 +
  hw/ptimer.h   |   39 +++
  hw/sh_timer.c |1 +
  hw/slavio_timer.c |1 +
  hw/syborg_timer.c |1 +
  hw/usb.h  |   12 +
  hw/xilinx_axidma.c|1 +
  hw/xilinx_timer.c |1 +
  net.h |   13 +
  qemu-file.h   |  232 +
  qemu-timer.h  |   13 -
  vmstate.h |  613 ++
  27 files changed, 972 insertions(+), 893 deletions(-)
  create mode 100644 hw/ptimer.h
  create mode 100644 qemu-file.h
  create mode 100644 vmstate.h






Re: [Qemu-devel] [PATCH] build: Cleanup qga make output

2011-12-12 Thread Anthony Liguori

On 12/07/2011 10:33 AM, Adam Litke wrote:

Currently the make variable qapi-dir refers to the qapi-generated directory in
absolute terms.  This causes the harmless but ugly make output below.  By
changing this variable to the relative path the output conforms to the norm and
the build works fine.

Before patch:
   CC/home/aglitke/src/qemu/qapi-generated/qga-qapi-types.o
   CC/home/aglitke/src/qemu/qapi-generated/qga-qapi-visit.o
   CC/home/aglitke/src/qemu/qapi-generated/qga-qmp-marshal.o
After patch:
   CCqapi-generated/qga-qapi-types.o
   CCqapi-generated/qga-qapi-visit.o
   CCqapi-generated/qga-qmp-marshal.o


This was supposedly to fix a build issue that I was never able to reproduce.  I 
think Luiz could reproduce it though.  Luiz, could you try out Adam's patch and 
confirm it breaks for you?


Regards,

Anthony Liguori



Signed-off-by: Adam Litke
---
  Makefile |2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/Makefile b/Makefile
index 301c75e..7c93739 100644
--- a/Makefile
+++ b/Makefile
@@ -168,7 +168,7 @@ check-qjson: check-qjson.o $(qobject-obj-y) $(tools-obj-y)
  test-coroutine: test-coroutine.o qemu-timer-common.o async.o 
$(coroutine-obj-y) $(tools-obj-y)

  $(qapi-obj-y): $(GENERATED_HEADERS)
-qapi-dir := $(BUILD_DIR)/qapi-generated
+qapi-dir := qapi-generated
  test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I 
$(qapi-dir)
  qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)






[Qemu-devel] [PATCH V13 1/7] Support for TPM command line options

2011-12-12 Thread Stefan Berger
This patch adds support for TPM command line options.
The command line options supported here are

./qemu-... -tpmdev passthrough,path=,id=
   -device tpm-tis,tpmdev=

and

./qemu-... -tpmdev ?

where the latter works similar to -soundhw ? and shows a list of
available TPM backends (for example 'passthrough').

Using the type parameter, the backend is chosen, i.e., 'passthrough' for the
passthrough driver. The interpretation of the other parameters along
with determining whether enough parameters were provided is pushed into
the backend driver, which needs to implement the interface function
'create' and return a TPMDriver structure if the VM can be started or 'NULL'
if not enough or bad parameters were provided.

Monitor support for 'info tpm' has been added. It for example prints the
following:

(qemu) info tpm
TPM devices:
 tpm0: model=tpm-tis
  \ tpm0: type=passthrough,path=/dev/tpm0

Signed-off-by: Stefan Berger 

---

v12:
 - use all 4 bytes of the message length indicator

v10:
 - tpm_display_backend_drivers always prints to stderr

v9:
 - prefixing all functions with tpm_tis_ and all constants with TPM_TIS_
 - splitting off of -tpm command line support into its own patch
 - only support TPM passthrough for now

v8:
 - adjusting formatting of backend drivers output to accomodate better
   formatting of 'passthrough' backend output

v6:
 - use #idef CONFIG_TPM to surround TPM calls
 - use QLIST_FOREACH_SAFE rather than QLIST_FOREACH in tpm_cleanup
 - commented backend ops in tpm.h
 - moving to IRQ 5 (11 collided with network cards)

v5:
 - fixing typo reported by Serge Hallyn
 - Adapting code to split command line parameters supporting
   -tpmdev ... -device tpm-tis,tpmdev=...
 - moved code out of arch_init.c|h into tpm.c|h
 - increasing reserved memory for ACPI tables to 128kb (from 64kb)
 - the backend interface has a create() function for interpreting the command
   line parameters and returning a TPMDevice structure; previoulsy
   this function was called handle_options()
 - the backend interface has a destroy() function for cleaning up after
   the create() function was called
 - added support for 'info tpm' in monitor

v4:
 - coding style fixes

v3:
 - added hw/tpm_tis.h to this patch so Qemu compiles at this stage
---
 hmp-commands.hx |2 +
 hw/tpm_tis.h|   91 ++
 monitor.c   |   10 +++
 qemu-config.c   |   20 +++
 qemu-options.hx |   34 +++
 tpm.c   |  167 +++
 tpm.h   |   90 +
 vl.c|   15 +
 8 files changed, 429 insertions(+), 0 deletions(-)
 create mode 100644 hw/tpm_tis.h
 create mode 100644 tpm.c
 create mode 100644 tpm.h

diff --git a/hmp-commands.hx b/hmp-commands.hx
index fdbed15..4506f56 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1352,6 +1352,8 @@ show device tree
 show qdev device model list
 @item info roms
 show roms
+@item info tpm
+show the TPM device
 @end table
 ETEXI
 
diff --git a/hw/tpm_tis.h b/hw/tpm_tis.h
new file mode 100644
index 000..e6a9a4b
--- /dev/null
+++ b/hw/tpm_tis.h
@@ -0,0 +1,91 @@
+/*
+ * tpm_tis.c - QEMU's TPM TIS interface emulator
+ *
+ * Copyright (C) 2006,2010,2011 IBM Corporation
+ *
+ * Authors:
+ *  Stefan Berger 
+ *  David Safford 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ *
+ * Implementation of the TIS interface according to specs found at
+ * http://www.trustedcomputiggroup.org
+ *
+ */
+#ifndef _HW_TPM_TIS_H
+#define _HW_TPM_TIS_H
+
+#include "isa.h"
+#include "qemu-thread.h"
+
+#include 
+
+#define TPM_TIS_ADDR_BASE   0xFED4
+
+#define TPM_TIS_NUM_LOCALITIES  5 /* per spec */
+#define TPM_TIS_NO_LOCALITY 0xff
+
+#define TPM_TIS_IS_VALID_LOCTY(x)   ((x) < TPM_TIS_NUM_LOCALITIES)
+
+#define TPM_TIS_IRQ 5
+
+#define TPM_TIS_BUFFER_MAX  4096
+
+
+typedef struct TPMSizedBuffer {
+uint32_t size;
+uint8_t  *buffer;
+} TPMSizedBuffer;
+
+enum tpm_tis_state {
+TPM_TIS_STATE_IDLE = 0,
+TPM_TIS_STATE_READY,
+TPM_TIS_STATE_COMPLETION,
+TPM_TIS_STATE_EXECUTION,
+TPM_TIS_STATE_RECEPTION,
+};
+
+/* locality data  -- all fields are persisted */
+typedef struct TPMLocality {
+enum tpm_tis_state state;
+uint8_t access;
+uint8_t sts;
+uint32_t inte;
+uint32_t ints;
+
+uint16_t w_offset;
+uint16_t r_offset;
+TPMSizedBuffer w_buffer;
+TPMSizedBuffer r_buffer;
+} TPMLocality;
+
+typedef struct TPMTISState {
+uint32_t offset;
+uint8_t buf[TPM_TIS_BUFFER_MAX];
+
+uint8_t active_locty;
+uint8_t aborting_locty;
+uint8_t next_locty;
+
+TPMLocality loc[TPM_TIS_NUM_LOCALITIES];
+
+qemu_irq irq;
+uint32_t irq_num;
+} TPMTISState;
+
+/* utility functions */
+
+static inlin

[Qemu-devel] [PATCH V13 6/7] Introduce --enable-tpm-passthrough configure option

2011-12-12 Thread Stefan Berger
Introduce --enable-tpm-passthrough configure option.

Signed-off-by: Stefan Berger 
---
 configure |   16 +++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/configure b/configure
index 25995bc..ffb599e 100755
--- a/configure
+++ b/configure
@@ -186,6 +186,7 @@ zlib="yes"
 guest_agent="yes"
 libiscsi=""
 tpm="no"
+tpm_passthrough="no"
 
 # parse CC options first
 for opt do
@@ -787,11 +788,20 @@ for opt do
   ;;
   --enable-tpm) tpm="yes"
   ;;
+  --enable-tpm-passthrough) tpm_passthrough="yes"
+  ;;
   *) echo "ERROR: unknown option $opt"; show_help="yes"
   ;;
   esac
 done
 
+if test "$tpm" = "no" ; then
+if test "$tpm_passthrough" = "yes"; then
+echo "ERROR: --enable-tpm-passthrough requires --enable-tpm"
+exit 1
+fi
+fi
+
 #
 # If cpu ~= sparc and  sparc_cpu hasn't been defined, plug in the right
 # QEMU_CFLAGS/LDFLAGS (assume sparc_v8plus for 32-bit and sparc_v9 for 64-bit)
@@ -1074,6 +1084,7 @@ echo "  --enable-usb-redir   enable usb network 
redirection support"
 echo "  --disable-guest-agentdisable building of the QEMU Guest Agent"
 echo "  --enable-guest-agent enable building of the QEMU Guest Agent"
 echo "  --enable-tpm enable TPM support"
+echo "  --enable-tpm-passthrough enable TPM passthrough driver"
 echo ""
 echo "NOTE: The object files are built at the place where configure is 
launched"
 exit 1
@@ -2850,6 +2861,7 @@ echo "OpenGL support$opengl"
 echo "libiscsi support  $libiscsi"
 echo "build guest agent $guest_agent"
 echo "TPM support   $tpm"
+echo "TPM passthrough   $tpm_passthrough"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -3722,7 +3734,9 @@ fi
 if test "$tpm" = "yes"; then
   if test "$target_softmmu" = "yes" ; then
 if test "$linux" = "yes" ; then
-  echo "CONFIG_TPM_PASSTHROUGH=y" >> $config_target_mak
+  if test "$tpm_passthrough" = "yes" ; then
+echo "CONFIG_TPM_PASSTHROUGH=y" >> $config_target_mak
+  fi
 fi
 echo "CONFIG_TPM=y" >> $config_host_mak
   fi
-- 
1.7.6.4




[Qemu-devel] [PATCH V13 4/7] Build the TPM frontend code

2011-12-12 Thread Stefan Berger
Build the TPM frontend code that has been added so far.

Signed-off-by: Stefan Berger 
---
 Makefile.target |1 +
 configure   |   11 +++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 39b2e5a..37d5d10 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -205,6 +205,7 @@ obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
 obj-y += memory.o
+obj-$(CONFIG_TPM) += tpm.o tpm_tis.o
 LIBS+=-lz
 
 QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
diff --git a/configure b/configure
index cc5ae87..385feb4 100755
--- a/configure
+++ b/configure
@@ -185,6 +185,7 @@ opengl=""
 zlib="yes"
 guest_agent="yes"
 libiscsi=""
+tpm="no"
 
 # parse CC options first
 for opt do
@@ -784,6 +785,8 @@ for opt do
   ;;
   --disable-guest-agent) guest_agent="no"
   ;;
+  --enable-tpm) tpm="yes"
+  ;;
   *) echo "ERROR: unknown option $opt"; show_help="yes"
   ;;
   esac
@@ -1070,6 +1073,7 @@ echo "  --disable-usb-redir  disable usb network 
redirection support"
 echo "  --enable-usb-redir   enable usb network redirection support"
 echo "  --disable-guest-agentdisable building of the QEMU Guest Agent"
 echo "  --enable-guest-agent enable building of the QEMU Guest Agent"
+echo "  --enable-tpm enable TPM support"
 echo ""
 echo "NOTE: The object files are built at the place where configure is 
launched"
 exit 1
@@ -2845,6 +2849,7 @@ echo "usb net redir $usb_redir"
 echo "OpenGL support$opengl"
 echo "libiscsi support  $libiscsi"
 echo "build guest agent $guest_agent"
+echo "TPM support   $tpm"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -3714,6 +3719,12 @@ if test "$gprof" = "yes" ; then
   fi
 fi
 
+if test "$tpm" = "yes"; then
+  if test "$target_softmmu" = "yes" ; then
+echo "CONFIG_TPM=y" >> $config_host_mak
+  fi
+fi
+
 if test "$ARCH" = "tci"; then
   linker_script=""
 else
-- 
1.7.6.4




[Qemu-devel] [PATCH V13 7/7] Add fd parameter for TPM passthrough driver

2011-12-12 Thread Stefan Berger
Enable the passing of a file descriptor via fd=<..> to access the host's
TPM device using the TPM passthrough driver.

Signed-off-by: Stefan Berger 

---

v13:
 - Only accepting a character device's file descriptor

v12:
 - added documentation part
---
 hw/tpm_passthrough.c |   73 +-
 qemu-config.c|5 +++
 qemu-options.hx  |6 +++-
 3 files changed, 64 insertions(+), 20 deletions(-)

diff --git a/hw/tpm_passthrough.c b/hw/tpm_passthrough.c
index f9cfe3d..57bb77a 100644
--- a/hw/tpm_passthrough.c
+++ b/hw/tpm_passthrough.c
@@ -361,33 +361,68 @@ static int tpm_passthrough_handle_device_opts(QemuOpts 
*opts, TPMBackend *tb)
 const char *value;
 char buf[64];
 int n;
+struct stat statbuf;
 
-value = qemu_opt_get(opts, "path");
-if (!value) {
-value = TPM_PASSTHROUGH_DEFAULT_DEVICE;
-}
+value = qemu_opt_get(opts, "fd");
+if (value) {
+if (qemu_opt_get(opts, "path")) {
+error_report("fd= is invalid with path=");
+return -1;
+}
+
+tb->s.tpm_pt->tpm_fd = qemu_parse_fd(value);
+if (tb->s.tpm_pt->tpm_fd < 0) {
+error_report("Illegal file descriptor for TPM device.\n");
+return -1;
+}
 
-n = snprintf(tb->s.tpm_pt->tpm_dev, sizeof(tb->s.tpm_pt->tpm_dev),
- "%s", value);
+snprintf(buf, sizeof(buf), "fd=%d", tb->s.tpm_pt->tpm_fd);
 
-if (n >= sizeof(tb->s.tpm_pt->tpm_dev)) {
-error_report("TPM device path is too long.\n");
-goto err_exit;
-}
+tb->parameters = g_strdup(buf);
 
-snprintf(buf, sizeof(buf), "path=%s", tb->s.tpm_pt->tpm_dev);
+if (tb->parameters == NULL) {
+goto err_close_tpmdev;
+}
+} else {
+value = qemu_opt_get(opts, "path");
+if (!value) {
+value = TPM_PASSTHROUGH_DEFAULT_DEVICE;
+}
+
+n = snprintf(tb->s.tpm_pt->tpm_dev, sizeof(tb->s.tpm_pt->tpm_dev),
+ "%s", value);
+
+if (n >= sizeof(tb->s.tpm_pt->tpm_dev)) {
+error_report("TPM device path is too long.\n");
+goto err_exit;
+}
 
-tb->parameters = g_strdup(buf);
+snprintf(buf, sizeof(buf), "path=%s", tb->s.tpm_pt->tpm_dev);
 
-if (tb->parameters == NULL) {
-return 1;
+tb->parameters = g_strdup(buf);
+
+if (tb->parameters == NULL) {
+return 1;
+}
+
+tb->s.tpm_pt->tpm_fd = open(tb->s.tpm_pt->tpm_dev, O_RDWR);
+if (tb->s.tpm_pt->tpm_fd < 0) {
+error_report("Cannot access TPM device using '%s'.\n",
+ tb->s.tpm_pt->tpm_dev);
+goto err_exit;
+}
 }
 
-tb->s.tpm_pt->tpm_fd = open(tb->s.tpm_pt->tpm_dev, O_RDWR);
-if (tb->s.tpm_pt->tpm_fd < 0) {
-error_report("Cannot access TPM device using '%s'.\n",
- tb->s.tpm_pt->tpm_dev);
-goto err_exit;
+if (fstat(tb->s.tpm_pt->tpm_fd, &statbuf) != 0) {
+error_report("Cannot determine file descriptor type for TPM "
+ "device: %s", strerror(errno));
+goto err_close_tpmdev;
+}
+
+/* only allow character devices for now */
+if (!S_ISCHR(statbuf.st_mode)) {
+error_report("TPM file descriptor is not a character device");
+goto err_close_tpmdev;
 }
 
 if (tpm_passthrough_test_tpmdev(tb->s.tpm_pt->tpm_fd)) {
diff --git a/qemu-config.c b/qemu-config.c
index cc4c31d..e49f4d8 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -564,6 +564,11 @@ static QemuOptsList qemu_tpmdev_opts = {
 .type = QEMU_OPT_STRING,
 .help = "Persistent storage for TPM state",
 },
+{
+.name = "fd",
+.type = QEMU_OPT_STRING,
+.help = "Filedescriptor for accessing the TPM",
+},
 { /* end of list */ }
 },
 };
diff --git a/qemu-options.hx b/qemu-options.hx
index 4916baf..7eca701 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1932,7 +1932,7 @@ Use ? to print all available TPM backend types.
 qemu -tpmdev ?
 @end example
 
-@item -tpmdev passthrough, id=@var{id}, path=@var{path}
+@item -tpmdev passthrough, id=@var{id}, path=@var{path}, fd=@var{h}
 
 (Linux-host only) Enable access to the host's TPM using the passthrough
 driver.
@@ -1941,6 +1941,10 @@ driver.
 a Linux host this would be @code{/dev/tpm0}.
 @option{path} is optional and by default @code{/dev/tpm0} is used.
 
+@option{fd} specifies the file descriptor of the host's TPM device.
+@option{fd} and @option{path} are mutually exclusive.
+@option{fd} is optional.
+
 Some notes about using the host's TPM with the passthrough driver:
 
 The TPM device accessed by the passthrough driver must not be
-- 
1.7.6.4




[Qemu-devel] [PATCH] PPC: Fix linker scripts on ppc hosts

2011-12-12 Thread Alexander Graf
When compiling qemu statically with multilib on PPC, we hit the
same issue that commit 845f2c2812d9ed24b36c02a3d06ee83aeafe8b49
is fixing. Do the same here.

Signed-off-by: Alexander Graf 
---
 ppc.ld   |   16 ++--
 ppc64.ld |   16 ++--
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/ppc.ld b/ppc.ld
index 69aa3f2..2a0dcad 100644
--- a/ppc.ld
+++ b/ppc.ld
@@ -49,8 +49,20 @@ SECTIONS
   .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
   .rel.bss: { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
   .rela.bss   : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
-  .rel.plt: { *(.rel.plt) }
-  .rela.plt   : { *(.rela.plt) }
+  .rel.plt  :
+  {
+*(.rel.plt)
+PROVIDE (__rel_iplt_start = .);
+*(.rel.iplt)
+PROVIDE (__rel_iplt_end = .);
+  }
+  .rela.plt   :
+  {
+*(.rela.plt)
+PROVIDE (__rela_iplt_start = .);
+*(.rela.iplt)
+PROVIDE (__rela_iplt_end = .);
+  }
   .init   :
   {
 KEEP (*(.init))
diff --git a/ppc64.ld b/ppc64.ld
index 0a7c0dd..e2dafa0 100644
--- a/ppc64.ld
+++ b/ppc64.ld
@@ -54,8 +54,20 @@ SECTIONS
   *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
   *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
 }
-  .rel.plt: { *(.rel.plt) }
-  .rela.plt   : { *(.rela.plt) }
+  .rel.plt  :
+  {
+*(.rel.plt)
+PROVIDE (__rel_iplt_start = .);
+*(.rel.iplt)
+PROVIDE (__rel_iplt_end = .);
+  }
+  .rela.plt   :
+  {
+*(.rela.plt)
+PROVIDE (__rela_iplt_start = .);
+*(.rela.iplt)
+PROVIDE (__rela_iplt_end = .);
+  }
   .rela.tocbss   : { *(.rela.tocbss) }
   .init   :
   {
-- 
1.6.0.2




[Qemu-devel] [PATCH v3 068/197] Patch monkey PCIDeviceInfo conversion

2011-12-12 Thread Anthony Liguori
---
 hw/ac97.c   |   39 +--
 hw/acpi_piix4.c |   43 ++---
 hw/apb_pci.c|   54 +
 hw/bonito.c |   30 +++-
 hw/cirrus_vga.c |   29 +++
 hw/dec_pci.c|   56 ++
 hw/e1000.c  |   43 ++---
 hw/es1370.c |   31 +++-
 hw/grackle_pci.c|   23 ++---
 hw/gt64xxx.c|   23 ++---
 hw/intel-hda.c  |   45 +++---
 hw/ioh3420.c|   57 --
 hw/ivshmem.c|   47 +++---
 hw/lsi53c895a.c |   31 +++-
 hw/ne2000.c |   35 +-
 hw/pcnet-pci.c  |   39 +--
 hw/ppce500_pci.c|   21 ++---
 hw/qxl.c|   62 +++-
 hw/rtl8139.c|   41 ++--
 hw/sh_pci.c |   19 +--
 hw/spapr_pci.c  |   15 --
 hw/sun4u.c  |   23 ++---
 hw/unin_pci.c   |   92 +++
 hw/usb-ohci.c   |   37 +--
 hw/versatile_pci.c  |   22 ++---
 hw/vga-pci.c|   27 ++
 hw/vmware_vga.c |   34 --
 hw/vt82c686.c   |  120 +--
 hw/wdt_i6300esb.c   |   31 +++-
 hw/xen_platform.c   |   34 --
 hw/xio3130_downstream.c |   57 --
 hw/xio3130_upstream.c   |   51 +++-
 32 files changed, 806 insertions(+), 505 deletions(-)

diff --git a/hw/ac97.c b/hw/ac97.c
index 0dbba3b..3f8075a 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1341,21 +1341,30 @@ int ac97_init (PCIBus *bus)
 return 0;
 }
 
-static PCIDeviceInfo ac97_info = {
-.qdev.name= "AC97",
-.qdev.desc= "Intel 82801AA AC97 Audio",
-.qdev.size= sizeof (AC97LinkState),
-.qdev.vmsd= &vmstate_ac97,
-.init = ac97_initfn,
-.exit = ac97_exitfn,
-.vendor_id= PCI_VENDOR_ID_INTEL,
-.device_id= PCI_DEVICE_ID_INTEL_82801AA_5,
-.revision = 0x01,
-.class_id = PCI_CLASS_MULTIMEDIA_AUDIO,
-.qdev.props   = (Property[]) {
-DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
-DEFINE_PROP_END_OF_LIST(),
-}
+static Property ac97_properties[] = {
+DEFINE_PROP_UINT32("use_broken_id", AC97LinkState, use_broken_id, 0),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ac97_class_init(ObjectClass *klass, void *data)
+{
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+k->init = ac97_initfn;
+k->exit = ac97_exitfn;
+k->vendor_id = PCI_VENDOR_ID_INTEL;
+k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
+k->revision = 0x01;
+k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+}
+
+static DeviceInfo ac97_info = {
+.name = "AC97",
+.desc = "Intel 82801AA AC97 Audio",
+.size = sizeof (AC97LinkState),
+.vmsd = &vmstate_ac97,
+.props = ac97_properties,
+.class_init = ac97_class_init,
 };
 
 static void ac97_register (void)
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index ce7135b..c62f03a 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -394,23 +394,32 @@ i2c_bus *piix4_pm_init(PCIBus *bus, DeviceState **pdev, 
int devfn,
 return s->smb.smbus;
 }
 
-static PCIDeviceInfo piix4_pm_info = {
-.qdev.name  = "PIIX4_PM",
-.qdev.desc  = "PM",
-.qdev.size  = sizeof(PIIX4PMState),
-.qdev.vmsd  = &vmstate_acpi,
-.qdev.no_user   = 1,
-.no_hotplug = 1,
-.init   = piix4_pm_initfn,
-.config_write   = pm_write_config,
-.vendor_id  = PCI_VENDOR_ID_INTEL,
-.device_id  = PCI_DEVICE_ID_INTEL_82371AB_3,
-.revision   = 0x03,
-.class_id   = PCI_CLASS_BRIDGE_OTHER,
-.qdev.props = (Property[]) {
-DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
-DEFINE_PROP_END_OF_LIST(),
-}
+static Property piix4_pm_properties[] = {
+DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
+DEFINE_PROP_END_OF_LIST(),
+};
+
+static void piix4_pm_class_init(ObjectClass *klass, void *data)
+{
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+k->no_hotplug = 1;
+k->init = piix4_pm_initfn;
+k->config_write = pm_write_config;
+k->vendor_id = PCI_VENDOR_ID_INTEL;
+k->device_id = PCI_DEVICE_ID_INTEL_82371AB_3;
+k->revision = 0x03;
+k->class_id = PCI_CLASS_BRIDGE_OTHER;
+}
+
+static DeviceInfo piix4_pm_info = {
+.name = "PIIX4_PM",
+.desc = "PM",
+.size = sizeof(PIIX4PMState),
+.vmsd = &vmstate_acpi,
+.no_user = 1,
+.props = piix4_pm_properties,
+.class_init = piix4_pm_class_init,
 };
 
 static void piix4_pm_register(void)
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index c232946..7442e26 100644
--- a/hw/apb_pci.c
+++ b

[Qemu-devel] [PATCH v3 009/197] qapi: allow a 'gen' key to suppress code generation

2011-12-12 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 scripts/qapi-commands.py |1 +
 scripts/qapi-types.py|1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index f7def16..54d1f5d 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -405,6 +405,7 @@ except os.error, e:
 
 exprs = parse_schema(sys.stdin)
 commands = filter(lambda expr: expr.has_key('command'), exprs)
+commands = filter(lambda expr: not expr.has_key('gen'), commands)
 
 if dispatch_type == "sync":
 fdecl = open(h_file, 'w')
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index f64d84c..267cb49 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -238,6 +238,7 @@ fdecl.write(mcgen('''
   guard=guardname(h_file)))
 
 exprs = parse_schema(sys.stdin)
+exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
 
 for expr in exprs:
 ret = "\n"
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 010/197] qmp: add qom-list command

2011-12-12 Thread Anthony Liguori
This can be used to list properties in the device model.

Signed-off-by: Anthony Liguori 
---
 qapi-schema.json |   48 
 qmp-commands.hx  |6 ++
 qmp.c|   28 
 3 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index cb1ba77..276b7c3 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -887,3 +887,51 @@
 # Notes: Do not use this command.
 ##
 { 'command': 'cpu', 'data': {'index': 'int'} }
+
+##
+# @DevicePropertyInfo:
+#
+# @name: the name of the property
+#
+# @type: the type of the property.  This will typically come in one of four
+#forms:
+#
+#1) A primitive type such as 'u8', 'u16', 'bool', 'str', or 'double'.
+#   These types are mapped to the appropriate JSON type.
+#
+#2) A legacy type in the form 'legacy' where subtype is the
+#   legacy qdev typename.  These types are always treated as strings.
+#
+#3) A child type in the form 'child' where subtype is a qdev
+#   device type name.  Child properties create the composition tree.
+#
+#4) A link type in the form 'link' where subtype is a qdev
+#   device type name.  Link properties form the device model graph.
+#
+# Since: 1.1
+#
+# Notes: This type is experimental.  Its syntax may change in future releases.
+##
+{ 'type': 'DevicePropertyInfo',
+  'data': { 'name': 'str', 'type': 'str' } }
+
+##
+# @qom-list:
+#
+# This command will list any properties of a device given a path in the device
+# model.
+#
+# @path: the path within the device model.  See @qom-get for a description of
+#this parameter.
+#
+# Returns: a list of @DevicePropertyInfo that describe the properties of the
+#  device.
+#
+# Since: 1.1
+#
+# Notes: This command is experimental.  It's syntax may change in future
+#releases.
+##
+{ 'command': 'qom-list',
+  'data': { 'path': 'str' },
+  'returns': [ 'DevicePropertyInfo' ] }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 97975a5..d6ff466 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2001,3 +2001,9 @@ EQMP
 .args_type  = "",
 .mhandler.cmd_new = qmp_marshal_input_query_balloon,
 },
+
+{
+.name   = "qom-list",
+.args_type  = "path:s",
+.mhandler.cmd_new = qmp_marshal_input_qom_list,
+},
diff --git a/qmp.c b/qmp.c
index 511dd62..06ae569 100644
--- a/qmp.c
+++ b/qmp.c
@@ -16,6 +16,7 @@
 #include "qmp-commands.h"
 #include "kvm.h"
 #include "arch_init.h"
+#include "hw/qdev.h"
 
 NameInfo *qmp_query_name(Error **errp)
 {
@@ -117,3 +118,30 @@ SpiceInfo *qmp_query_spice(Error **errp)
 return NULL;
 };
 #endif
+
+DevicePropertyInfoList *qmp_qom_list(const char *path, Error **errp)
+{
+DeviceState *dev;
+bool ambiguous = false;
+DevicePropertyInfoList *props = NULL;
+DeviceProperty *prop;
+
+dev = qdev_resolve_path(path, &ambiguous);
+if (dev == NULL) {
+error_set(errp, QERR_DEVICE_NOT_FOUND, path);
+return NULL;
+}
+
+QTAILQ_FOREACH(prop, &dev->properties, node) {
+DevicePropertyInfoList *entry = g_malloc0(sizeof(*entry));
+
+entry->value = g_malloc0(sizeof(DevicePropertyInfo));
+entry->next = props;
+props = entry;
+
+entry->value->name = g_strdup(prop->name);
+entry->value->type = g_strdup(prop->type);
+}
+
+return props;
+}
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 004/197] qom: introduce root device

2011-12-12 Thread Anthony Liguori
This is based on Jan's suggestion for how to do unique naming.  The root device
is the root of composition.  All devices are reachable via child<> links from
this device.

Signed-off-by: Anthony Liguori 
---
 Makefile.objs  |2 +-
 hw/container.c |   20 
 hw/qdev.c  |   12 
 hw/qdev.h  |8 
 4 files changed, 41 insertions(+), 1 deletions(-)
 create mode 100644 hw/container.c

diff --git a/Makefile.objs b/Makefile.objs
index d7a6539..10e794c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -279,7 +279,7 @@ hw-obj-$(CONFIG_LSI_SCSI_PCI) += lsi53c895a.o
 hw-obj-$(CONFIG_ESP) += esp.o
 
 hw-obj-y += dma-helpers.o sysbus.o isa-bus.o
-hw-obj-y += qdev-addr.o
+hw-obj-y += qdev-addr.o container.o
 
 # VGA
 hw-obj-$(CONFIG_VGA_PCI) += vga-pci.o
diff --git a/hw/container.c b/hw/container.c
new file mode 100644
index 000..9cbf399
--- /dev/null
+++ b/hw/container.c
@@ -0,0 +1,20 @@
+#include "sysbus.h"
+
+static int container_initfn(SysBusDevice *dev)
+{
+return 0;
+}
+
+static SysBusDeviceInfo container_info = {
+.init = container_initfn,
+.qdev.name = "container",
+.qdev.size = sizeof(SysBusDevice),
+.qdev.no_user = 1,
+};
+
+static void container_init(void)
+{
+sysbus_register_withprop(&container_info);
+}
+
+device_init(container_init);
diff --git a/hw/qdev.c b/hw/qdev.c
index 6f77af9..bb0b9f7 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1161,3 +1161,15 @@ void qdev_property_add_legacy(DeviceState *dev, Property 
*prop,
 
 g_free(type);
 }
+
+DeviceState *qdev_get_root(void)
+{
+static DeviceState *qdev_root;
+
+if (!qdev_root) {
+qdev_root = qdev_create(NULL, "container");
+qdev_init_nofail(qdev_root);
+}
+
+return qdev_root;
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 3b629d4..52aadd2 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -482,4 +482,12 @@ const char *qdev_property_get_type(DeviceState *dev, const 
char *name,
  */
 void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp);
 
+/**
+ * @qdev_get_root - returns the root device of the composition tree
+ *
+ * Returns:
+ *   The root of the composition tree.
+ */
+DeviceState *qdev_get_root(void);
+
 #endif
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 040/197] get rid of more DO_UPCAST

2011-12-12 Thread Anthony Liguori
---
 hw/scsi-bus.c |   14 +++---
 hw/scsi-generic.c |2 +-
 hw/usb-bus.c  |   12 ++--
 hw/usb-ccid.c |4 ++--
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index e8eb521..731c1f3 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -81,7 +81,7 @@ static void scsi_dma_restart_cb(void *opaque, int running, 
RunState state)
 
 static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
-SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+SCSIDevice *dev = SCSI_DEVICE(qdev);
 SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base);
 SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
 SCSIDevice *d;
@@ -140,7 +140,7 @@ err:
 
 static int scsi_qdev_exit(DeviceState *qdev)
 {
-SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+SCSIDevice *dev = SCSI_DEVICE(qdev);
 
 if (dev->vmsentry) {
 qemu_del_vm_change_state_handler(dev->vmsentry);
@@ -182,7 +182,7 @@ SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, 
BlockDriverState *bdrv,
 }
 if (qdev_init(dev) < 0)
 return NULL;
-return DO_UPCAST(SCSIDevice, qdev, dev);
+return SCSI_DEVICE(dev);
 }
 
 int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
@@ -278,7 +278,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq 
*r)
 found_lun0 = false;
 n = 0;
 QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
-SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+SCSIDevice *dev = SCSI_DEVICE(qdev);
 
 if (dev->channel == channel && dev->id == id) {
 if (dev->lun == 0) {
@@ -300,7 +300,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq 
*r)
 stl_be_p(&r->buf, n);
 i = found_lun0 ? 8 : 16;
 QTAILQ_FOREACH(qdev, &r->req.bus->qbus.children, sibling) {
-SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+SCSIDevice *dev = SCSI_DEVICE(qdev);
 
 if (dev->channel == channel && dev->id == id) {
 store_lun(&r->buf[i], dev->lun);
@@ -1367,7 +1367,7 @@ void scsi_device_purge_requests(SCSIDevice *sdev, 
SCSISense sense)
 
 static char *scsibus_get_fw_dev_path(DeviceState *dev)
 {
-SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
+SCSIDevice *d = SCSI_DEVICE(dev);
 char path[100];
 
 snprintf(path, sizeof(path), "channel@%x/%s@%x,%x", d->channel,
@@ -1382,7 +1382,7 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, 
int id, int lun)
 SCSIDevice *target_dev = NULL;
 
 QTAILQ_FOREACH_REVERSE(qdev, &bus->qbus.children, ChildrenHead, sibling) {
-SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+SCSIDevice *dev = SCSI_DEVICE(qdev);
 
 if (dev->channel == channel && dev->id == id) {
 if (dev->lun == lun) {
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index e62044f..ef76e4b 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -361,7 +361,7 @@ static int get_stream_blocksize(BlockDriverState *bdrv)
 
 static void scsi_generic_reset(DeviceState *dev)
 {
-SCSIDevice *s = DO_UPCAST(SCSIDevice, qdev, dev);
+SCSIDevice *s = SCSI_DEVICE(dev);
 
 scsi_device_purge_requests(s, SENSE_CODE(RESET));
 }
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 80cf560..8924ac3 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -67,7 +67,7 @@ USBBus *usb_bus_find(int busnr)
 
 static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
-USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+USBDevice *dev = USB_DEVICE(qdev);
 USBDeviceInfo *info = DO_UPCAST(USBDeviceInfo, qdev, base);
 int rc;
 
@@ -98,7 +98,7 @@ err:
 
 static int usb_qdev_exit(DeviceState *qdev)
 {
-USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+USBDevice *dev = USB_DEVICE(qdev);
 
 if (dev->attached) {
 usb_device_detach(dev);
@@ -145,7 +145,7 @@ USBDevice *usb_create(USBBus *bus, const char *name)
 #endif
 
 dev = qdev_create(&bus->qbus, name);
-return DO_UPCAST(USBDevice, qdev, dev);
+return USB_DEVICE(dev);
 }
 
 USBDevice *usb_create_simple(USBBus *bus, const char *name)
@@ -366,7 +366,7 @@ static const char *usb_speed(unsigned int speed)
 
 static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
 {
-USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+USBDevice *dev = USB_DEVICE(qdev);
 USBBus *bus = usb_bus_from_device(dev);
 
 monitor_printf(mon, "%*saddr %d.%d, port %s, speed %s, name %s%s\n",
@@ -378,13 +378,13 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState 
*qdev, int indent)
 
 static char *usb_get_dev_path(DeviceState *qdev)
 {
-USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+USBDevice *dev = USB_DEVICE(qdev);
 return g_strdup(dev->port->path);
 }
 
 static char *usb_get_fw_dev_path(DeviceState *qdev)
 {
-USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
+USBDevice *dev = USB_DEVICE(qdev);
 char *fw_path, *in;
 ssize_t pos

[Qemu-devel] [PATCH v3 044/197] usb: don't access dev->info directly

2011-12-12 Thread Anthony Liguori
---
 hw/usb-bus.c  |   81 +---
 hw/usb-desc.c |   18 ++--
 hw/usb.c  |   24 +++--
 hw/usb.h  |   22 +++
 4 files changed, 117 insertions(+), 28 deletions(-)

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 8924ac3..24a805d 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -65,13 +65,22 @@ USBBus *usb_bus_find(int busnr)
 return NULL;
 }
 
+static int usb_device_init(USBDevice *dev)
+{
+if (dev->info->init) {
+return dev->info->init(dev);
+}
+return 0;
+}
+
 static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
 {
 USBDevice *dev = USB_DEVICE(qdev);
 USBDeviceInfo *info = DO_UPCAST(USBDeviceInfo, qdev, base);
 int rc;
 
-pstrcpy(dev->product_desc, sizeof(dev->product_desc), info->product_desc);
+pstrcpy(dev->product_desc, sizeof(dev->product_desc),
+usb_device_get_product_desc(dev));
 dev->info = info;
 dev->auto_attach = 1;
 QLIST_INIT(&dev->strings);
@@ -79,7 +88,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
 if (rc != 0) {
 goto err;
 }
-rc = dev->info->init(dev);
+rc = usb_device_init(dev);
 if (rc != 0) {
 goto err;
 }
@@ -96,6 +105,13 @@ err:
 return rc;
 }
 
+static void usb_device_handle_destroy(USBDevice *dev)
+{
+if (dev->info->handle_destroy) {
+dev->info->handle_destroy(dev);
+}
+}
+
 static int usb_qdev_exit(DeviceState *qdev)
 {
 USBDevice *dev = USB_DEVICE(qdev);
@@ -103,9 +119,7 @@ static int usb_qdev_exit(DeviceState *qdev)
 if (dev->attached) {
 usb_device_detach(dev);
 }
-if (dev->info->handle_destroy) {
-dev->info->handle_destroy(dev);
-}
+usb_device_handle_destroy(dev);
 if (dev->port) {
 usb_release_port(dev);
 }
@@ -481,6 +495,63 @@ USBDevice *usbdevice_create(const char *cmdline)
 return usb->usbdevice_init(params);
 }
 
+int usb_device_handle_packet(USBDevice *dev, USBPacket *p)
+{
+if (dev->info->handle_packet) {
+return dev->info->handle_packet(dev, p);
+}
+return -ENOSYS;
+}
+
+void usb_device_cancel_packet(USBDevice *dev, USBPacket *p)
+{
+if (dev->info->cancel_packet) {
+dev->info->cancel_packet(dev, p);
+}
+}
+
+void usb_device_handle_attach(USBDevice *dev)
+{
+if (dev->info->handle_attach) {
+dev->info->handle_attach(dev);
+}
+}
+
+void usb_device_handle_reset(USBDevice *dev)
+{
+if (dev->info->handle_reset) {
+dev->info->handle_reset(dev);
+}
+}
+
+int usb_device_handle_control(USBDevice *dev, USBPacket *p, int request,
+  int value, int index, int length, uint8_t *data)
+{
+if (dev->info->handle_control) {
+return dev->info->handle_control(dev, p, request, value, index, length,
+ data);
+}
+return -ENOSYS;
+}
+
+int usb_device_handle_data(USBDevice *dev, USBPacket *p)
+{
+if (dev->info->handle_data) {
+return dev->info->handle_data(dev, p);
+}
+return -ENOSYS;
+}
+
+const char *usb_device_get_product_desc(USBDevice *dev)
+{
+return dev->info->product_desc;
+}
+
+const USBDesc *usb_device_get_usb_desc(USBDevice *dev)
+{
+return dev->info->usb_desc;
+}
+
 static TypeInfo usb_device_type_info = {
 .name = TYPE_USB_DEVICE,
 .parent = TYPE_DEVICE,
diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index ae2d384..1f5fc7a 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -225,7 +225,7 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, 
size_t len)
 
 static void usb_desc_setdefaults(USBDevice *dev)
 {
-const USBDesc *desc = dev->info->usb_desc;
+const USBDesc *desc = usb_device_get_usb_desc(dev);
 
 assert(desc != NULL);
 switch (dev->speed) {
@@ -242,7 +242,7 @@ static void usb_desc_setdefaults(USBDevice *dev)
 
 void usb_desc_init(USBDevice *dev)
 {
-const USBDesc *desc = dev->info->usb_desc;
+const USBDesc *desc = usb_device_get_usb_desc(dev);
 
 assert(desc != NULL);
 dev->speed = USB_SPEED_FULL;
@@ -258,7 +258,7 @@ void usb_desc_init(USBDevice *dev)
 
 void usb_desc_attach(USBDevice *dev)
 {
-const USBDesc *desc = dev->info->usb_desc;
+const USBDesc *desc = usb_device_get_usb_desc(dev);
 
 assert(desc != NULL);
 if (desc->high && (dev->port->speedmask & USB_SPEED_MASK_HIGH)) {
@@ -267,7 +267,7 @@ void usb_desc_attach(USBDevice *dev)
 dev->speed = USB_SPEED_FULL;
 } else {
 fprintf(stderr, "usb: port/device speed mismatch for \"%s\"\n",
-dev->info->product_desc);
+usb_device_get_product_desc(dev));
 return;
 }
 usb_desc_setdefaults(dev);
@@ -323,7 +323,7 @@ int usb_desc_string(USBDevice *dev, int index, uint8_t 
*dest, size_t len)
 
 str = usb_desc_get_string(dev, index);
 if (str == NULL) {
-str = dev->info->usb_desc->str[index];
+str = usb_devic

[Qemu-devel] [PATCH v3 026/197] qom: add qobject

2011-12-12 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 Makefile.objs |2 +
 hw/qobject.c  |  463 
 hw/qobject.h  |  471 +
 3 files changed, 936 insertions(+), 0 deletions(-)
 create mode 100644 hw/qobject.c
 create mode 100644 hw/qobject.h

diff --git a/Makefile.objs b/Makefile.objs
index 67e1ae5..8e629f1 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -123,6 +123,8 @@ common-obj-$(CONFIG_WIN32) += version.o
 
 common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o 
ui/spice-display.o spice-qemu-char.o
 
+common-obj-y += qobject.o
+
 audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
 audio-obj-$(CONFIG_SDL) += sdlaudio.o
 audio-obj-$(CONFIG_OSS) += ossaudio.o
diff --git a/hw/qobject.c b/hw/qobject.c
new file mode 100644
index 000..54398ab
--- /dev/null
+++ b/hw/qobject.c
@@ -0,0 +1,463 @@
+/*
+ * QEMU Object Model
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Anthony Liguori   
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qobject.h"
+
+#define MAX_INTERFACES 32
+
+typedef struct QInterfaceImpl
+{
+const char *parent;
+void (*interface_initfn)(QObjectClass *class);
+QType type;
+} QInterfaceImpl;
+
+typedef struct QTypeImpl
+{
+const char *name;
+QType type;
+
+size_t class_size;
+
+size_t instance_size;
+
+void (*base_init)(QObjectClass *klass);
+void (*base_finalize)(QObjectClass *klass);
+
+void (*class_init)(QObjectClass *klass);
+void (*class_finalize)(QObjectClass *klass);
+
+void (*instance_init)(QObject *obj);
+void (*instance_finalize)(QObject *obj);
+
+bool abstract;
+
+const char *parent;
+
+QObjectClass *class;
+
+int num_interfaces;
+QInterfaceImpl interfaces[MAX_INTERFACES];
+} QTypeImpl;
+
+static int num_types = 1;
+static QTypeImpl type_table[1024];
+
+QType qtype_register_static(const QTypeInfo *info)
+{
+QType type = num_types++;
+QTypeImpl *ti;
+
+ti = &type_table[type];
+
+assert(info->name != NULL);
+
+ti->name = info->name;
+ti->parent = info->parent;
+ti->type = type;
+
+ti->class_size = info->class_size;
+ti->instance_size = info->instance_size;
+
+ti->base_init = info->base_init;
+ti->base_finalize = info->base_finalize;
+
+ti->class_init = info->class_init;
+ti->class_finalize = info->class_finalize;
+
+ti->instance_init = info->instance_init;
+ti->instance_finalize = info->instance_finalize;
+
+ti->abstract = info->abstract;
+
+if (info->interfaces) {
+int i;
+
+for (i = 0; info->interfaces[i].type; i++) {
+ti->interfaces[i].parent = info->interfaces[i].type;
+ti->interfaces[i].interface_initfn = 
info->interfaces[i].interface_initfn;
+ti->num_interfaces++;
+}
+}
+
+return type;
+}
+
+static QType qtype_register_anonymous(const QTypeInfo *info)
+{
+QType type = num_types++;
+QTypeImpl *ti;
+char buffer[32];
+static int count;
+
+ti = &type_table[type];
+
+snprintf(buffer, sizeof(buffer), "", count++);
+ti->name = g_strdup(buffer);
+ti->parent = g_strdup(info->parent);
+ti->type = type;
+
+ti->class_size = info->class_size;
+ti->instance_size = info->instance_size;
+
+ti->base_init = info->base_init;
+ti->base_finalize = info->base_finalize;
+
+ti->class_init = info->class_init;
+ti->class_finalize = info->class_finalize;
+
+ti->instance_init = info->instance_init;
+ti->instance_finalize = info->instance_finalize;
+
+if (info->interfaces) {
+int i;
+
+for (i = 0; info->interfaces[i].type; i++) {
+ti->interfaces[i].parent = info->interfaces[i].type;
+ti->interfaces[i].interface_initfn = 
info->interfaces[i].interface_initfn;
+ti->num_interfaces++;
+}
+}
+
+return type;
+}
+
+static QTypeImpl *qtype_get_instance(QType type)
+{
+assert(type != 0);
+assert(type < num_types);
+
+return &type_table[type];
+}
+
+QType qtype_get_by_name(const char *name)
+{
+int i;
+
+if (name == NULL) {
+return 0;
+}
+
+for (i = 1; i < num_types; i++) {
+if (strcmp(name, type_table[i].name) == 0) {
+return i;
+}
+}
+
+return 0;
+}
+
+static void qtype_class_base_init(QTypeImpl *base_ti, const char *typename)
+{
+QTypeImpl *ti;
+
+if (!typename) {
+return;
+}
+
+ti = qtype_get_instance(qtype_get_by_name(typename));
+
+qtype_class_base_init(base_ti, ti->parent);
+
+if (ti->base_init) {
+ti->base_init(base_ti->class);
+}
+}
+
+static size_t qtype_class_get_size(QTypeImpl *ti)
+{
+if (ti->class_size) {
+return ti->class_size;
+}
+
+if (ti->parent) {
+return 
qtype_class_get_size(qtype_get_instance(q

[Qemu-devel] [PATCH v3 059/197] kill off SMBusDeviceInfo

2011-12-12 Thread Anthony Liguori
---
 hw/smbus.c|   55 +++--
 hw/smbus.h|   35 +++--
 hw/smbus_eeprom.c |   27 -
 3 files changed, 61 insertions(+), 56 deletions(-)

diff --git a/hw/smbus.c b/hw/smbus.c
index 2711229..3f2d1f4 100644
--- a/hw/smbus.c
+++ b/hw/smbus.c
@@ -37,37 +37,38 @@ enum {
 
 static void smbus_do_quick_cmd(SMBusDevice *dev, int recv)
 {
-SMBusDeviceInfo *t = container_of(dev->i2c.info, SMBusDeviceInfo, i2c);
+SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
 
 DPRINTF("Quick Command %d\n", recv);
-if (t->quick_cmd)
-t->quick_cmd(dev, recv);
+if (sc->quick_cmd) {
+sc->quick_cmd(dev, recv);
+}
 }
 
 static void smbus_do_write(SMBusDevice *dev)
 {
-SMBusDeviceInfo *t = container_of(dev->i2c.info, SMBusDeviceInfo, i2c);
+SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
 
 if (dev->data_len == 0) {
 smbus_do_quick_cmd(dev, 0);
 } else if (dev->data_len == 1) {
 DPRINTF("Send Byte\n");
-if (t->send_byte) {
-t->send_byte(dev, dev->data_buf[0]);
+if (sc->send_byte) {
+sc->send_byte(dev, dev->data_buf[0]);
 }
 } else {
 dev->command = dev->data_buf[0];
 DPRINTF("Command %d len %d\n", dev->command, dev->data_len - 1);
-if (t->write_data) {
-t->write_data(dev, dev->command, dev->data_buf + 1,
-  dev->data_len - 1);
+if (sc->write_data) {
+sc->write_data(dev, dev->command, dev->data_buf + 1,
+   dev->data_len - 1);
 }
 }
 }
 
 static void smbus_i2c_event(I2CSlave *s, enum i2c_event event)
 {
-SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
+SMBusDevice *dev = SMBUS_DEVICE(s);
 
 switch (event) {
 case I2C_START_SEND:
@@ -150,14 +151,14 @@ static void smbus_i2c_event(I2CSlave *s, enum i2c_event 
event)
 
 static int smbus_i2c_recv(I2CSlave *s)
 {
-SMBusDeviceInfo *t = container_of(s->info, SMBusDeviceInfo, i2c);
-SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
+SMBusDevice *dev = SMBUS_DEVICE(s);
+SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
 int ret;
 
 switch (dev->mode) {
 case SMBUS_RECV_BYTE:
-if (t->receive_byte) {
-ret = t->receive_byte(dev);
+if (sc->receive_byte) {
+ret = sc->receive_byte(dev);
 } else {
 ret = 0;
 }
@@ -165,8 +166,8 @@ static int smbus_i2c_recv(I2CSlave *s)
 dev->mode = SMBUS_DONE;
 break;
 case SMBUS_READ_DATA:
-if (t->read_data) {
-ret = t->read_data(dev, dev->command, dev->data_len);
+if (sc->read_data) {
+ret = sc->read_data(dev, dev->command, dev->data_len);
 dev->data_len++;
 } else {
 ret = 0;
@@ -184,7 +185,7 @@ static int smbus_i2c_recv(I2CSlave *s)
 
 static int smbus_i2c_send(I2CSlave *s, uint8_t data)
 {
-SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, s);
+SMBusDevice *dev = SMBUS_DEVICE(s);
 
 switch (dev->mode) {
 case SMBUS_WRITE_DATA:
@@ -200,20 +201,20 @@ static int smbus_i2c_send(I2CSlave *s, uint8_t data)
 
 static int smbus_device_init(I2CSlave *i2c)
 {
-SMBusDeviceInfo *t = container_of(i2c->info, SMBusDeviceInfo, i2c);
-SMBusDevice *dev = FROM_I2C_SLAVE(SMBusDevice, i2c);
+SMBusDevice *dev = SMBUS_DEVICE(i2c);
+SMBusDeviceClass *sc = SMBUS_DEVICE_GET_CLASS(dev);
 
-return t->init(dev);
+return sc->init(dev);
 }
 
-void smbus_register_device(SMBusDeviceInfo *info)
+void smbus_register_device(I2CSlaveInfo *info)
 {
-assert(info->i2c.qdev.size >= sizeof(SMBusDevice));
-info->i2c.init = smbus_device_init;
-info->i2c.event = smbus_i2c_event;
-info->i2c.recv = smbus_i2c_recv;
-info->i2c.send = smbus_i2c_send;
-i2c_register_slave_subclass(&info->i2c, TYPE_SMBUS_DEVICE);
+assert(info->qdev.size >= sizeof(SMBusDevice));
+info->init = smbus_device_init;
+info->event = smbus_i2c_event;
+info->recv = smbus_i2c_recv;
+info->send = smbus_i2c_send;
+i2c_register_slave_subclass(info, TYPE_SMBUS_DEVICE);
 }
 
 /* Master device commands.  */
diff --git a/hw/smbus.h b/hw/smbus.h
index 9dd055c..fa9088a 100644
--- a/hw/smbus.h
+++ b/hw/smbus.h
@@ -26,30 +26,16 @@
 
 #define TYPE_SMBUS_DEVICE "smbus-device"
 #define SMBUS_DEVICE(obj) \
- OBJECT_CHECK(SMBUSDevice, (obj), TYPE_SMBUS_DEVICE)
+ OBJECT_CHECK(SMBusDevice, (obj), TYPE_SMBUS_DEVICE)
 #define SMBUS_DEVICE_CLASS(klass) \
- OBJECT_CLASS_CHECK(SMBUSDeviceClass, (klass), TYPE_SMBUS_DEVICE)
+ OBJECT_CLASS_CHECK(SMBusDeviceClass, (klass), TYPE_SMBUS_DEVICE)
 #define SMBUS_DEVICE_GET_CLASS(obj) \
- OBJECT_GET_CLASS(SMBUSDeviceClass, (obj), TYPE_SMBUS_DEVICE)
+ OBJECT_GET_CLASS(SMBusDeviceClass, (obj), TYPE_SMBUS_DEVICE)
 
 typedef struct SMBusDeviceClass
 {
 I2CSlaveClass 

Re: [Qemu-devel] [PATCH v3 01/14] ARM: Samsung exynos4210-based boards emulation

2011-12-12 Thread Peter Maydell
On 12 December 2011 06:43, Evgeny Voevodin  wrote:
> From: Maksim Kozlov 
>
> Add initial code for support of NURI and SMDKC210 boards

This patch doesn't compile:

/home/pm215/src/qemu/qemu/hw/exynos4210.c: In function ‘exynos4210_init’:
/home/pm215/src/qemu/qemu/hw/exynos4210.c:98:14: error: variable
‘cpu_irq’ set but not used [-Werror=unused-but-set-variable]
cc1: all warnings being treated as errors


> ---
>  Makefile.target |    1 +
>  hw/exynos4210.c |  224 
> +++
>  hw/exynos4210.h |   34 
>  3 files changed, 259 insertions(+), 0 deletions(-)
>  create mode 100644 hw/exynos4210.c
>  create mode 100644 hw/exynos4210.h
>
> diff --git a/Makefile.target b/Makefile.target
> index a111521..624a142 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -344,6 +344,7 @@ obj-arm-y = integratorcp.o versatilepb.o arm_pic.o 
> arm_timer.o
>  obj-arm-y += arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o 
> pl190.o
>  obj-arm-y += versatile_pci.o
>  obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
> +obj-arm-y += exynos4210.o
>  obj-arm-y += armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
>  obj-arm-y += pl061.o
>  obj-arm-y += arm-semi.o
> diff --git a/hw/exynos4210.c b/hw/exynos4210.c
> new file mode 100644
> index 000..1550016
> --- /dev/null
> +++ b/hw/exynos4210.c
> @@ -0,0 +1,224 @@
> +/*
> + *  Samsung exynos4210-based boards emulation
> + *
> + *  Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
> + *    Maksim Kozlov 
> + *    Evgeny Voevodin 
> + *    Igor Mitsyanko  
> + *
> + *  This program is free software; you can redistribute it and/or modify it
> + *  under the terms of the GNU General Public License as published by the
> + *  Free Software Foundation; either version 2 of the License, or
> + *  (at your option) any later version.
> + *
> + *  This program is distributed in the hope that it will be useful, but 
> WITHOUT
> + *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + *  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> + *  for more details.
> + *
> + *  You should have received a copy of the GNU General Public License along
> + *  with this program; if not, write to the Free Software Foundation, Inc., 
> 51
> + *  Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + *
> + */
> +
> +#include "boards.h"
> +#include "sysemu.h"
> +#include "sysbus.h"
> +#include "arm-misc.h"
> +#include "exec-memory.h"
> +#include "exynos4210.h"
> +
> +#undef DEBUG
> +
> +//#define DEBUG
> +
> +#ifdef DEBUG
> +    #undef PRINT_DEBUG
> +    #define  PRINT_DEBUG(fmt, args...) \
> +        do { \
> +            fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
> +        } while (0)
> +#else
> +    #define  PRINT_DEBUG(fmt, args...) \
> +        do {} while (0)
> +#endif
> +
> +#define EXYNOS4210_DRAM0_BASE_ADDR          0x4000
> +#define EXYNOS4210_DRAM1_BASE_ADDR          0xa000
> +#define EXYNOS4210_DRAM_MAX_SIZE            0x6000  /* 1.5 GB */
> +
> +#define EXYNOS4210_IROM_BASE_ADDR           0x
> +#define EXYNOS4210_IROM_SIZE                0x0001  /* 64 KB */
> +#define EXYNOS4210_IROM_MIRROR_BASE_ADDR    0x0200
> +#define EXYNOS4210_IROM_MIRROR_SIZE         0x0001  /* 64 KB */
> +
> +#define EXYNOS4210_IRAM_BASE_ADDR           0x0202
> +#define EXYNOS4210_IRAM_SIZE                0x0002  /* 128 KB */
> +
> +#define EXYNOS4210_SFR_BASE_ADDR            0x1000
> +
> +#define EXYNOS4210_BASE_BOOT_ADDR           EXYNOS4210_DRAM0_BASE_ADDR
> +
> +static struct arm_boot_info exynos4210_binfo = {
> +        .loader_start     = EXYNOS4210_BASE_BOOT_ADDR,
> +};
> +
> +static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
> +                                    0x09, 0x00, 0x00, 0x00 };
> +
> +enum exynos4210_board_type {
> +    BOARD_EXYNOS4210_NURI,
> +    BOARD_EXYNOS4210_SMDKC210,
> +};
> +
> +enum exynos4210_mach_id {
> +    MACH_NURI_ID     = 0xD33,
> +    MACH_SMDKC210_ID = 0xB16,
> +};
> +
> +
> +static void exynos4210_init(ram_addr_t ram_size,
> +        const char *boot_device,
> +        const char *kernel_filename,
> +        const char *kernel_cmdline,
> +        const char *initrd_filename,
> +        const char *cpu_model,
> +        enum exynos4210_board_type board_type)
> +{
> +    CPUState *env;
> +    MemoryRegion *system_mem = get_system_memory();
> +    MemoryRegion *chipid_mem = g_new(MemoryRegion, 1);
> +    MemoryRegion *iram_mem = g_new(MemoryRegion, 1);
> +    MemoryRegion *irom_mem = g_new(MemoryRegion, 1);
> +    MemoryRegion *irom_alias_mem = g_new(MemoryRegion, 1);
> +    MemoryRegion *dram0_mem = g_new(MemoryRegion, 1);
> +    MemoryRegion *dram1_mem = NULL;
> +    qemu_irq *irqp;
> +    qemu_irq cpu_irq[4];
> +    ram_addr_t mem_size;
> +    int n;
> +
> +    switch (board_type) {
> +    case BOARD_EXYNOS4210_NURI:
> +        ex

[Qemu-devel] [PATCH v3 06/20] qdev: provide a path resolution (v2)

2011-12-12 Thread Anthony Liguori
There are two types of supported paths--absolute paths and partial paths.

Absolute paths are derived from the root device and can follow child<> or
link<> properties.  Since they can follow link<> properties, they can be
arbitrarily long.  Absolute paths look like absolute filenames and are prefixed
with a leading slash.

Partial paths are look like relative filenames.  They do not begin with a
prefix.  The matching rules for partial paths are subtle but designed to make
specifying devices easy.  At each level of the composition tree, the partial
path is matched as an absolute path.  The first match is not returned.  At
least two matches are searched for.  A successful result is only returned if
only one match is founded.  If more than one match is found, a flag is returned
to indicate that the match was ambiguous.

At the end of the day, partial path support means that if you create a device
called 'ide0', you can just say 'ide0' as the path name and it will Just Work.
If we internally create a device called 'i440fx', you can just say 'i440fx' and
it will Just Work and long as you don't do anything silly.

A management tool should probably always use absolute paths since then they
don't have to deal with the possibility of ambiguity.

Signed-off-by: Anthony Liguori 
---
v1 -> v2
 - fix comments (Stefan)
 - always initialize ambiguous to false (Stefan)
 - change from gslist to qemu-queue (Kevin/Gerd)
---
 hw/qdev.c |  103 +
 hw/qdev.h |   28 
 2 files changed, 131 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 79849c9..2519f00 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1221,3 +1221,106 @@ gchar *qdev_get_canonical_path(DeviceState *dev)
 
 return newpath;
 }
+
+static DeviceState *qdev_resolve_abs_path(DeviceState *parent,
+  gchar **parts,
+  int index)
+{
+DeviceProperty *prop;
+DeviceState *child;
+
+if (parts[index] == NULL) {
+return parent;
+}
+
+if (strcmp(parts[index], "") == 0) {
+return qdev_resolve_abs_path(parent, parts, index + 1);
+}
+
+prop = qdev_property_find(parent, parts[index]);
+if (prop == NULL) {
+return NULL;
+}
+
+child = NULL;
+if (strstart(prop->type, "link<", NULL)) {
+DeviceState **pchild = prop->opaque;
+if (*pchild) {
+child = *pchild;
+}
+} else if (strstart(prop->type, "child<", NULL)) {
+child = prop->opaque;
+}
+
+if (!child) {
+return NULL;
+}
+
+return qdev_resolve_abs_path(child, parts, index + 1);
+}
+
+static DeviceState *qdev_resolve_partial_path(DeviceState *parent,
+  gchar **parts,
+  bool *ambiguous)
+{
+DeviceState *dev;
+DeviceProperty *prop;
+
+dev = qdev_resolve_abs_path(parent, parts, 0);
+
+QTAILQ_FOREACH(prop, &parent->properties, node) {
+DeviceState *found;
+
+if (!strstart(prop->type, "child<", NULL)) {
+continue;
+}
+
+found = qdev_resolve_partial_path(prop->opaque, parts, ambiguous);
+if (found) {
+if (dev) {
+if (ambiguous) {
+*ambiguous = true;
+}
+return NULL;
+}
+dev = found;
+}
+
+if (ambiguous && *ambiguous) {
+return NULL;
+}
+}
+
+return dev;
+}
+
+DeviceState *qdev_resolve_path(const char *path, bool *ambiguous)
+{
+bool partial_path = true;
+DeviceState *dev;
+gchar **parts;
+
+parts = g_strsplit(path, "/", 0);
+if (parts == NULL || parts[0] == NULL) {
+g_strfreev(parts);
+return qdev_get_root();
+}
+
+if (strcmp(parts[0], "") == 0) {
+partial_path = false;
+}
+
+if (partial_path) {
+if (ambiguous) {
+*ambiguous = false;
+}
+dev = qdev_resolve_partial_path(qdev_get_root(), parts, ambiguous);
+} else {
+dev = qdev_resolve_abs_path(qdev_get_root(), parts, 1);
+}
+
+g_strfreev(parts);
+
+return dev;
+}
+
diff --git a/hw/qdev.h b/hw/qdev.h
index 0f00497..641d134 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -499,4 +499,32 @@ DeviceState *qdev_get_root(void);
  */
 gchar *qdev_get_canonical_path(DeviceState *dev);
 
+/**
+ * @qdev_resolve_path - resolves a path returning a device
+ *
+ * There are two types of supported paths--absolute paths and partial paths.
+ * 
+ * Absolute paths are derived from the root device and can follow child<> or
+ * link<> properties.  Since they can follow link<> properties, they can be
+ * arbitrarily long.  Absolute paths look like absolute filenames and are
+ * prefixed with a leading slash.
+ * 
+ * Partial paths look like relative filenames.  They do not begin with a
+ * prefix.

[Qemu-devel] [PATCH v3 000/197] qom: dynamic properties and composition tree (v2)

2011-12-12 Thread Anthony Liguori
This is a follow up to my previous series to get us started in the QOM
direction.  A few things are different this time around.  Most notably:

 1) Devices no longer have names.  Instead, path names are always used to
identify devices.

 2) In order to support (1), dynamic properties are now supported.

 3) The concept of a "root device" has been introduced.  The root device is
roughly modelling the motherboard of a machine.  This type is a container
type and it's best to think of it as something like a PCB board I guess.

To try it out, here's an example session:

Launch:

anthony@titi:~/build/qemu$ x86_64-softmmu/qemu-system-x86_64 -hda 
~/images/linux.img -snapshot -device virtio-balloon-pci,id=foo -qmp 
unix:/tmp/server.sock,server,nowait

Explore the object model:

anthony@titi:~/git/qemu/QMP$ ./qom-list /
peripheral/
i440fx/
anthony@titi:~/git/qemu/QMP$ ./qom-list /i440fx/
piix3/
anthony@titi:~/git/qemu/QMP$ ./qom-list /i440fx/piix3
rtc/
anthony@titi:~/git/qemu/QMP$ ./qom-list /i440fx/piix3/rtc
date
base_year
anthony@titi:~/git/qemu/QMP$ ./qom-get /i440fx/piix3/rtc.date
tm_sec: 33
tm_hour: 21
tm_mday: 30
tm_year: 111
tm_mon: 10
tm_min: 2
anthony@titi:~/git/qemu/QMP$ ./qom-get rtc.date
tm_sec: 38
tm_hour: 21
tm_mday: 30
tm_year: 111
tm_mon: 10
tm_min: 2
anthony@titi:~/git/qemu/QMP$ ./qom-list /peripheral
foo/
anthony@titi:~/git/qemu/QMP$ ./qom-list /peripheral/foo
event_idx
indirect_desc

Anthony Liguori (197):
  qom: add a reference count to qdev objects
  qom: add new dynamic property infrastructure based on Visitors (v2)
  qom: register legacy properties as new style properties (v2)
  qom: introduce root device
  qdev: provide an interface to return canonical path from root (v2)
  qdev: provide a path resolution (v2)
  qom: add child properties (composition) (v2)
  qom: add link properties (v2)
  qapi: allow a 'gen' key to suppress code generation
  qmp: add qom-list command
  qom: qom_{get,set} monitor commands (v2)
  qdev: add explicitly named devices to the root complex
  dev: add an anonymous peripheral container
  rtc: make piix3 set the rtc as a child (v2)
  rtc: add a dynamic property for retrieving the date
  qom: optimize qdev_get_canonical_path using a parent link
  qmp: make qmp.py easier to use
  qom: add test tools (v2)
  bug fix spotted by paolo
  qom: add vga node to the pc composition tree
  qom: add string property type
  qdev: add a qdev_get_type() function and expose as a 'type' property
  pc: fill out most of the composition tree
  i440fx: split out piix3 device
  i440fx: rename piix_pci -> i440fx
  qom: add qobject
  rename qobject -> object
  more renames
  Start integration of qom w/qdev.
  qdev: move qdev->info to class
  qdev: don't access name through info
  qdev: user a wrapper to access reset and promote reset to a class
method
  a little better approach to this
  qdev: add isa-device as a subclass of device
  isa: more isa stuff
  qom: make pcidevice part of the hierarchy
  get rid of DO_UPCAST
  ccid card and usb
  virtio-serial-port
  get rid of more DO_UPCAST
  add class_init to deviceinfo
  isa: move methods from isadeviceinfo to isadeviceclass
  kill off ISADeviceInfo
  usb: don't access dev->info directly
  usb: get rid of info pointer
  usb: promote all of the methods for USBDevice to class methods
  usb: use a factory instead of doing silly things for legacy
  usb: kill USBDeviceInfo
  usb-hid: simply class initialization a bit
  accessors for scsideviceinfo
  drop info link in SCSIDeviceInfo
  move methods out of SCSIDeviceInfo into SCSIDeviceClass
  kill off SCSIDeviceInfo
  get rid of CCIDCardInfo
  rename i2c_slave -> I2CSlave
  add I2CSlave to the type hierarchy
  add SMBusDevice to the type hiearchy
  fixup type registration
  kill off SMBusDeviceInfo
  add guards
  killall I2CSlaveInfo
  killall HDACodecDeviceInfo
  make spapr a bit more patch monkey friendly
  killall VIOsPAPRDeviceInfo
  qxl: be more patch monkey friendly
  make es1370 more script monkey friendly
  remove arrays of PCIDeviceInfo
  Patch monkey PCIDeviceInfo conversion
  patch monkey, that funky monkey
  fixup for patch monkey
  Mr. Patch Monkey at it again
  Get rid of PCIDeviceInfo
  More cleanups from PCIDeviceInfo removal
  Make sysbus a QOM type
  Remove SysBusDeviceInfo
  fixup some pci issues
  fixup some ehci issues
  fixup rtl8139
  fixups for patch monkey
  Here comes the monkey...
  little fix
  pm fix
  patch monkey
  pm fixups
  patch monkey
  little fix
  little fix
  prep virtio-9p for the monkey
  stoopid monkey
  Get rid of VirtIOSerialPortInfo
  patch monkey
  virtio-console is doing something bad
  small fix to virtioserialportinfo removal
  killall SSIDeviceInfo
  patch monkey
  fixup unin_pci.c
  fixup some network devices
  fixup patch monkey problem with I2CSlave
  fixup killall ssislaveinfo
  bump version to enable Werror
  prep_pci is busted
  macio is busted
  fix mips malta after piix4 pm refactoring
  networking fix
  hack to fix marvell audio

[Qemu-devel] [PATCH v3 063/197] make spapr a bit more patch monkey friendly

2011-12-12 Thread Anthony Liguori
---
 hw/spapr_llan.c  |4 ++--
 hw/spapr_vscsi.c |4 ++--
 hw/spapr_vty.c   |4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index abe1297..958702c 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -484,7 +484,7 @@ static void vlan_hcalls(VIOsPAPRBus *bus)
 spapr_register_hypercall(H_MULTICAST_CTRL, h_multicast_ctrl);
 }
 
-static VIOsPAPRDeviceInfo spapr_vlan = {
+static VIOsPAPRDeviceInfo spapr_vlan_info = {
 .init = spapr_vlan_init,
 .devnode = spapr_vlan_devnode,
 .dt_name = "l-lan",
@@ -503,6 +503,6 @@ static VIOsPAPRDeviceInfo spapr_vlan = {
 
 static void spapr_vlan_register(void)
 {
-spapr_vio_bus_register_withprop(&spapr_vlan);
+spapr_vio_bus_register_withprop(&spapr_vlan_info);
 }
 device_init(spapr_vlan_register);
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 00e2d2d..21d946e 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -947,7 +947,7 @@ static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void 
*fdt, int node_off)
 return 0;
 }
 
-static VIOsPAPRDeviceInfo spapr_vscsi = {
+static VIOsPAPRDeviceInfo spapr_vscsi_info = {
 .init = spapr_vscsi_init,
 .devnode = spapr_vscsi_devnode,
 .dt_name = "v-scsi",
@@ -964,6 +964,6 @@ static VIOsPAPRDeviceInfo spapr_vscsi = {
 
 static void spapr_vscsi_register(void)
 {
-spapr_vio_bus_register_withprop(&spapr_vscsi);
+spapr_vio_bus_register_withprop(&spapr_vscsi_info);
 }
 device_init(spapr_vscsi_register);
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index f23cc36..fddecd8 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -141,7 +141,7 @@ static void vty_hcalls(VIOsPAPRBus *bus)
 spapr_register_hypercall(H_GET_TERM_CHAR, h_get_term_char);
 }
 
-static VIOsPAPRDeviceInfo spapr_vty = {
+static VIOsPAPRDeviceInfo spapr_vty_info = {
 .init = spapr_vty_init,
 .dt_name = "vty",
 .dt_type = "serial",
@@ -181,6 +181,6 @@ static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, 
target_ulong reg)
 
 static void spapr_vty_register(void)
 {
-spapr_vio_bus_register_withprop(&spapr_vty);
+spapr_vio_bus_register_withprop(&spapr_vty_info);
 }
 device_init(spapr_vty_register);
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 003/197] qom: register legacy properties as new style properties (v2)

2011-12-12 Thread Anthony Liguori
Expose all legacy properties through the new QOM property mechanism.  The qdev
property types are exposed through the 'legacy<>' namespace.  They are always
visited as strings since they do their own string parsing.

Signed-off-by: Anthony Liguori 
---
v1 -> v2
 - add bus properties (Gerd)
---
 hw/qdev.c |   86 +
 hw/qdev.h |7 +
 2 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 94f14c1..6f77af9 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -83,6 +83,7 @@ static DeviceInfo *qdev_find_info(BusInfo *bus_info, const 
char *name)
 static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
 {
 DeviceState *dev;
+Property *prop;
 
 assert(bus->info == info->bus_info);
 dev = g_malloc0(info->size);
@@ -100,6 +101,15 @@ static DeviceState *qdev_create_from_info(BusState *bus, 
DeviceInfo *info)
 dev->instance_id_alias = -1;
 QTAILQ_INIT(&dev->properties);
 dev->state = DEV_STATE_CREATED;
+
+for (prop = dev->info->props; prop && prop->name; prop++) {
+qdev_property_add_legacy(dev, prop, NULL);
+}
+
+for (prop = dev->info->bus_info->props; prop && prop->name; prop++) {
+qdev_property_add_legacy(dev, prop, NULL);
+}
+
 return dev;
 }
 
@@ -1075,3 +1085,79 @@ const char *qdev_property_get_type(DeviceState *dev, 
const char *name, Error **e
 
 return prop->type;
 }
+
+/**
+ * Legacy property handling
+ */
+
+static void qdev_get_legacy_property(DeviceState *dev, Visitor *v, void 
*opaque,
+ const char *name, Error **errp)
+{
+Property *prop = opaque;
+
+if (prop->info->print) {
+char buffer[1024];
+char *ptr = buffer;
+
+prop->info->print(dev, prop, buffer, sizeof(buffer));
+visit_type_str(v, &ptr, name, errp);
+} else {
+error_set(errp, QERR_PERMISSION_DENIED);
+}
+}
+
+static void qdev_set_legacy_property(DeviceState *dev, Visitor *v, void 
*opaque,
+ const char *name, Error **errp)
+{
+Property *prop = opaque;
+
+if (dev->state != DEV_STATE_CREATED) {
+error_set(errp, QERR_PERMISSION_DENIED);
+return;
+}
+
+if (prop->info->parse) {
+Error *local_err = NULL;
+char *ptr = NULL;
+
+visit_type_str(v, &ptr, name, &local_err);
+if (!local_err) {
+int ret;
+ret = prop->info->parse(dev, prop, ptr);
+if (ret != 0) {
+error_set(errp, QERR_INVALID_PARAMETER_VALUE,
+  name, prop->info->name);
+}
+g_free(ptr);
+} else {
+error_propagate(errp, local_err);
+}
+} else {
+error_set(errp, QERR_PERMISSION_DENIED);
+}
+}
+
+/**
+ * @qdev_add_legacy_property - adds a legacy property
+ *
+ * Do not use this is new code!  Properties added through this interface will
+ * be given types in the "legacy<>" type namespace.
+ *
+ * Legacy properties are always processed as strings.  The format of the string
+ * depends on the property type.
+ */
+void qdev_property_add_legacy(DeviceState *dev, Property *prop,
+  Error **errp)
+{
+gchar *type;
+
+type = g_strdup_printf("legacy<%s>", prop->info->name);
+
+qdev_property_add(dev, prop->name, type,
+  qdev_get_legacy_property,
+  qdev_set_legacy_property,
+  NULL,
+  prop, errp);
+
+g_free(type);
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 2df3bb7..3b629d4 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -475,4 +475,11 @@ void qdev_property_set(DeviceState *dev, Visitor *v, const 
char *name,
 const char *qdev_property_get_type(DeviceState *dev, const char *name,
Error **errp);
 
+/**
+ * @qdev_property_add_legacy - add a legacy @Property to a device
+ *
+ * DO NOT USE THIS IN NEW CODE!
+ */
+void qdev_property_add_legacy(DeviceState *dev, Property *prop, Error **errp);
+
 #endif
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 058/197] fixup type registration

2011-12-12 Thread Anthony Liguori
---
 hw/i2c.c   |9 +++--
 hw/i2c.h   |1 +
 hw/smbus.c |2 +-
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/hw/i2c.c b/hw/i2c.c
index cdf88f2..fcb7269 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -177,12 +177,17 @@ static int i2c_slave_qdev_init(DeviceState *dev, 
DeviceInfo *base)
 return info->init(s);
 }
 
-void i2c_register_slave(I2CSlaveInfo *info)
+void i2c_register_slave_subclass(I2CSlaveInfo *info, const char *parent)
 {
 assert(info->qdev.size >= sizeof(I2CSlave));
 info->qdev.init = i2c_slave_qdev_init;
 info->qdev.bus_info = &i2c_bus_info;
-qdev_register(&info->qdev);
+qdev_register_subclass(&info->qdev, parent);
+}
+
+void i2c_register_slave(I2CSlaveInfo *info)
+{
+i2c_register_slave_subclass(info, TYPE_I2C_SLAVE);
 }
 
 DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr)
diff --git a/hw/i2c.h b/hw/i2c.h
index cc4d76b..0c6f2ac 100644
--- a/hw/i2c.h
+++ b/hw/i2c.h
@@ -71,6 +71,7 @@ int i2c_recv(i2c_bus *bus);
 #define FROM_I2C_SLAVE(type, dev) DO_UPCAST(type, i2c, dev)
 
 void i2c_register_slave(I2CSlaveInfo *type);
+void i2c_register_slave_subclass(I2CSlaveInfo *info, const char *parent);
 
 DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr);
 
diff --git a/hw/smbus.c b/hw/smbus.c
index a75d404..2711229 100644
--- a/hw/smbus.c
+++ b/hw/smbus.c
@@ -213,7 +213,7 @@ void smbus_register_device(SMBusDeviceInfo *info)
 info->i2c.event = smbus_i2c_event;
 info->i2c.recv = smbus_i2c_recv;
 info->i2c.send = smbus_i2c_send;
-i2c_register_slave(&info->i2c);
+i2c_register_slave_subclass(&info->i2c, TYPE_SMBUS_DEVICE);
 }
 
 /* Master device commands.  */
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 19/20] qdev: add a qdev_get_type() function and expose as a 'type' property

2011-12-12 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 hw/qdev.c |7 +++
 hw/qdev.h |   14 ++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 0fc20fc..83913c7 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -110,6 +110,8 @@ static DeviceState *qdev_create_from_info(BusState *bus, 
DeviceInfo *info)
 qdev_property_add_legacy(dev, prop, NULL);
 }
 
+qdev_property_add_str(dev, "type", qdev_get_type, NULL, NULL);
+
 return dev;
 }
 
@@ -1031,6 +1033,11 @@ char* qdev_get_fw_dev_path(DeviceState *dev)
 return strdup(path);
 }
 
+char *qdev_get_type(DeviceState *dev, Error **errp)
+{
+return g_strdup(dev->info->name);
+}
+
 void qdev_ref(DeviceState *dev)
 {
 dev->ref++;
diff --git a/hw/qdev.h b/hw/qdev.h
index 9faf2ee..6e18427 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -596,4 +596,18 @@ void qdev_property_add_str(DeviceState *dev, const char 
*name,
void (*set)(DeviceState *, const char *, Error **),
Error **errp);
 
+/**
+ * @qdev_get_type
+ *
+ * Returns the string representation of the type of this object.
+ *
+ * @dev - the device
+ *
+ * @errp - if an error occurs, a pointer to an area to store the error
+ *
+ * Returns: a string representing the type.  This must be freed by the caller
+ *  with g_free().
+ */
+char *qdev_get_type(DeviceState *dev, Error **errp);
+
 #endif
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 031/197] qdev: don't access name through info

2011-12-12 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 hw/e1000.c   |2 +-
 hw/eepro100.c|2 +-
 hw/hda-audio.c   |2 +-
 hw/intel-hda.c   |2 +-
 hw/ne2000-isa.c  |2 +-
 hw/ne2000.c  |2 +-
 hw/pci.c |2 +-
 hw/pcnet.c   |2 +-
 hw/qdev-properties.c |   16 
 hw/qdev.c|   16 
 hw/rtl8139.c |2 +-
 hw/usb-bus.c |2 +-
 hw/usb-net.c |2 +-
 hw/usb-ohci.c|2 +-
 hw/virtio-net.c  |2 +-
 15 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/hw/e1000.c b/hw/e1000.c
index ce30ad8..2f495cd 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1175,7 +1175,7 @@ static int pci_e1000_init(PCIDevice *pci_dev)
 d->eeprom_data[EEPROM_CHECKSUM_REG] = checksum;
 
 d->nic = qemu_new_nic(&net_e1000_info, &d->conf,
-  qdev_get_info(&d->dev.qdev)->name, d->dev.qdev.id, 
d);
+  object_get_type(OBJECT(d)), d->dev.qdev.id, d);
 
 qemu_format_nic_info_str(&d->nic->nc, macaddr);
 
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 287d1f1..1f9f610 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1879,7 +1879,7 @@ static int e100_nic_init(PCIDevice *pci_dev)
 nic_reset(s);
 
 s->nic = qemu_new_nic(&net_eepro100_info, &s->conf,
-  qdev_get_info(&pci_dev->qdev)->name, 
pci_dev->qdev.id, s);
+  object_get_type(OBJECT(pci_dev)), pci_dev->qdev.id, 
s);
 
 qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 TRACE(OTHER, logout("%s\n", s->nic->nc.info_str));
diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index 0bc0a25..ffdd799 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -777,7 +777,7 @@ static int hda_audio_init(HDACodecDevice *hda, const struct 
desc_codec *desc)
 uint32_t i, type;
 
 a->desc = desc;
-a->name = qdev_get_info(&a->hda.qdev)->name;
+a->name = object_get_type(OBJECT(a));
 dprint(a, 1, "%s: cad %d\n", __FUNCTION__, a->hda.cad);
 
 AUD_register_card("hda", &a->card);
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 12dcc84..1b42e10 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -1129,7 +1129,7 @@ static int intel_hda_init(PCIDevice *pci)
 IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
 uint8_t *conf = d->pci.config;
 
-d->name = qdev_get_info(&d->pci.qdev)->name;
+d->name = object_get_type(OBJECT(d));
 
 pci_config_set_interrupt_pin(conf, 1);
 
diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index 60dc333..9e89256 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -76,7 +76,7 @@ static int isa_ne2000_initfn(ISADevice *dev)
 ne2000_reset(s);
 
 s->nic = qemu_new_nic(&net_ne2000_isa_info, &s->c,
-  qdev_get_info(&dev->qdev)->name, dev->qdev.id, s);
+  object_get_type(OBJECT(dev)), dev->qdev.id, s);
 qemu_format_nic_info_str(&s->nic->nc, s->c.macaddr.a);
 
 return 0;
diff --git a/hw/ne2000.c b/hw/ne2000.c
index d016b8e..16dcee2 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -760,7 +760,7 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
 ne2000_reset(s);
 
 s->nic = qemu_new_nic(&net_ne2000_info, &s->c,
-  qdev_get_info(&pci_dev->qdev)->name, 
pci_dev->qdev.id, s);
+  object_get_type(OBJECT(pci_dev)), pci_dev->qdev.id, 
s);
 qemu_format_nic_info_str(&s->nic->nc, s->c.macaddr.a);
 
 if (!pci_dev->qdev.hotplugged) {
diff --git a/hw/pci.c b/hw/pci.c
index 46b7dac..dd8aa48 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1763,7 +1763,7 @@ static int pci_add_option_rom(PCIDevice *pdev, bool 
is_default_rom)
 if (qdev_get_info(&pdev->qdev)->vmsd)
 snprintf(name, sizeof(name), "%s.rom", 
qdev_get_info(&pdev->qdev)->vmsd->name);
 else
-snprintf(name, sizeof(name), "%s.rom", 
qdev_get_info(&pdev->qdev)->name);
+snprintf(name, sizeof(name), "%s.rom", object_get_type(OBJECT(pdev)));
 pdev->has_rom = true;
 memory_region_init_ram(&pdev->rom, &pdev->qdev, name, size);
 ptr = memory_region_get_ram_ptr(&pdev->rom);
diff --git a/hw/pcnet.c b/hw/pcnet.c
index e58b195..c3bf405 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -1718,7 +1718,7 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, 
NetClientInfo *info)
 s->poll_timer = qemu_new_timer_ns(vm_clock, pcnet_poll_timer, s);
 
 qemu_macaddr_default_if_unset(&s->conf.macaddr);
-s->nic = qemu_new_nic(info, &s->conf, qdev_get_info(dev)->name, dev->id, 
s);
+s->nic = qemu_new_nic(info, &s->conf, object_get_type(OBJECT(dev)), 
dev->id, s);
 qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
 add_boot_device_path(s->conf.bootindex, dev, "/ethernet-phy@0");
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index f235a26..ce8cb7c 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -627,7 +627,7 @@ int qdev_prop_parse(DeviceState *dev, c

[Qemu-devel] [PATCH v3 01/20] qom: add a reference count to qdev objects

2011-12-12 Thread Anthony Liguori
To ensure that a device isn't removed from the graph until all of its links are
broken.

Signed-off-by: Anthony Liguori 
---
 hw/qdev.c |   16 
 hw/qdev.h |   26 ++
 2 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 106407f..fdc9843 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -323,6 +323,11 @@ int qdev_unplug(DeviceState *dev)
 }
 assert(dev->info->unplug != NULL);
 
+if (dev->ref != 0) {
+qerror_report(QERR_DEVICE_IN_USE, dev->id?:"");
+return -1;
+}
+
 qdev_hot_removed = true;
 
 return dev->info->unplug(dev);
@@ -962,3 +967,14 @@ char* qdev_get_fw_dev_path(DeviceState *dev)
 
 return strdup(path);
 }
+
+void qdev_ref(DeviceState *dev)
+{
+dev->ref++;
+}
+
+void qdev_unref(DeviceState *dev)
+{
+g_assert(dev->ref > 0);
+dev->ref--;
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 36a4198..2397b4e 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -45,6 +45,12 @@ struct DeviceState {
 QTAILQ_ENTRY(DeviceState) sibling;
 int instance_id_alias;
 int alias_required_for_version;
+
+/**
+ * This tracks the number of references between devices.  See @qdev_ref for
+ * more information.
+ */
+uint32_t ref;
 };
 
 typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
@@ -329,4 +335,24 @@ char *qdev_get_fw_dev_path(DeviceState *dev);
 /* This is a nasty hack to allow passing a NULL bus to qdev_create.  */
 extern struct BusInfo system_bus_info;
 
+/**
+ * @qdev_ref
+ *
+ * Increase the reference count of a device.  A device cannot be freed as long
+ * as its reference count is greater than zero.
+ *
+ * @dev - the device
+ */
+void qdev_ref(DeviceState *dev);
+
+/**
+ * @qdef_unref
+ *
+ * Decrease the reference count of a device.  A device cannot be freed as long
+ * as its reference count is greater than zero.
+ *
+ * @dev - the device
+ */
+void qdev_unref(DeviceState *dev);
+
 #endif
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 016/197] qom: optimize qdev_get_canonical_path using a parent link

2011-12-12 Thread Anthony Liguori
The full tree search was a bit unreasonable.

Signed-off-by: Anthony Liguori 
---
 hw/qdev.c |   56 
 hw/qdev.h |4 
 2 files changed, 28 insertions(+), 32 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 5348f26..1102efd 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1229,6 +1229,8 @@ void qdev_property_add_child(DeviceState *dev, const char 
*name,
   NULL, NULL, child, errp);
 
 qdev_ref(dev);
+g_assert(child->parent == NULL);
+child->parent = dev;
 
 g_free(type);
 }
@@ -1307,48 +1309,38 @@ void qdev_property_add_link(DeviceState *dev, const 
char *name,
 g_free(full_type);
 }
 
-static gchar *qdev_get_path_in(DeviceState *parent, DeviceState *dev)
+gchar *qdev_get_canonical_path(DeviceState *dev)
 {
-DeviceProperty *prop;
+DeviceState *root = qdev_get_root();
+char *newpath = NULL, *path = NULL;
 
-if (parent == dev) {
-return g_strdup("");
-}
+while (dev != root) {
+DeviceProperty *prop = NULL;
 
-QTAILQ_FOREACH(prop, &parent->properties, node) {
-gchar *subpath;
+g_assert(dev->parent != NULL);
 
-if (!strstart(prop->type, "child<", NULL)) {
-continue;
-}
+QTAILQ_FOREACH(prop, &dev->parent->properties, node) {
+if (!strstart(prop->type, "child<", NULL)) {
+continue;
+}
 
-/* Check to see if the device is one of parent's children */
-if (prop->opaque == dev) {
-return g_strdup(prop->name);
+if (prop->opaque == dev) {
+if (path) {
+newpath = g_strdup_printf("%s/%s", prop->name, path);
+g_free(path);
+path = newpath;
+} else {
+path = g_strdup(prop->name);
+}
+break;
+}
 }
 
-/* Check to see if the device is a child of our child */
-subpath = qdev_get_path_in(prop->opaque, dev);
-if (subpath) {
-gchar *path;
+g_assert(prop != NULL);
 
-path = g_strdup_printf("%s/%s", prop->name, subpath);
-g_free(subpath);
-
-return path;
-}
+dev = dev->parent;
 }
 
-return NULL;
-}
-
-gchar *qdev_get_canonical_path(DeviceState *dev)
-{
-gchar *path, *newpath;
-
-path = qdev_get_path_in(qdev_get_root(), dev);
-g_assert(path != NULL);
-
 newpath = g_strdup_printf("/%s", path);
 g_free(path);
 
diff --git a/hw/qdev.h b/hw/qdev.h
index 4351e2e..fdab848 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -92,6 +92,10 @@ struct DeviceState {
 uint32_t ref;
 
 QTAILQ_HEAD(, DeviceProperty) properties;
+
+/* Do not, under any circumstance, use this parent link below anywhere
+ * outside of qdev.c.  You have been warned. */
+DeviceState *parent;
 };
 
 typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent);
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 021/197] qom: add string property type

2011-12-12 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 hw/qdev.c |   59 +++
 hw/qdev.h |   22 ++
 2 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 4004860..0fc20fc 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1449,3 +1449,62 @@ DeviceState *qdev_resolve_path(const char *path, bool 
*ambiguous)
 return dev;
 }
 
+typedef struct StringProperty
+{
+char *(*get)(DeviceState *, Error **);
+void (*set)(DeviceState *, const char *, Error **);
+} StringProperty;
+
+static void qdev_property_get_str(DeviceState *dev, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+StringProperty *prop = opaque;
+char *value;
+
+value = prop->get(dev, errp);
+if (value) {
+visit_type_str(v, &value, name, errp);
+g_free(value);
+}
+}
+
+static void qdev_property_set_str(DeviceState *dev, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+StringProperty *prop = opaque;
+char *value;
+Error *local_err = NULL;
+
+visit_type_str(v, &value, name, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+prop->set(dev, value, errp);
+g_free(value);
+}
+
+static void qdev_property_release_str(DeviceState *dev, const char *name,
+  void *opaque)
+{
+StringProperty *prop = opaque;
+g_free(prop);
+}
+
+void qdev_property_add_str(DeviceState *dev, const char *name,
+   char *(*get)(DeviceState *, Error **),
+   void (*set)(DeviceState *, const char *, Error **),
+   Error **errp)
+{
+StringProperty *prop = g_malloc0(sizeof(*prop));
+
+prop->get = get;
+prop->set = set;
+
+qdev_property_add(dev, name, "string",
+  get ? qdev_property_get_str : NULL,
+  set ? qdev_property_set_str : NULL,
+  qdev_property_release_str,
+  prop, errp);
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index fdab848..9faf2ee 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -574,4 +574,26 @@ void qdev_property_add_link(DeviceState *dev, const char 
*name,
 const char *type, DeviceState **child,
 Error **errp);
 
+/**
+ * @qdev_property_add_str
+ *
+ * Add a string property using getters/setters.  This function will add a
+ * property of type 'string'.
+ *
+ * @dev - the device to add a property to
+ *
+ * @name - the name of the property
+ *
+ * @get - the getter or NULL if the property is write-only.  This function must
+ *return a string to be freed by @g_free().
+ *
+ * @set - the setter or NULL if the property is read-only
+ *
+ * @errp - if an error occurs, a pointer to an area to store the error
+ */
+void qdev_property_add_str(DeviceState *dev, const char *name,
+   char *(*get)(DeviceState *, Error **),
+   void (*set)(DeviceState *, const char *, Error **),
+   Error **errp);
+
 #endif
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 014/197] rtc: make piix3 set the rtc as a child (v2)

2011-12-12 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
v1 -> v2
 - comments (Stefan)
---
 hw/pc_piix.c  |   11 +++
 hw/piix_pci.c |3 +++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 970f43c..2d5ea2c 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -205,6 +205,17 @@ static void pc_init1(MemoryRegion *system_memory,
 }
 }
 
+/* FIXME there's some major spaghetti here.  Somehow we create the devices
+ * on the PIIX before we actually create it.  We create the PIIX3 deep in
+ * the recess of the i440fx creation too and then lose the DeviceState.
+ *
+ * For now, let's "fix" this by making judicious use of paths.  This is not
+ * generally the right way to do this.
+ */
+
+qdev_property_add_child(qdev_resolve_path("/i440fx/piix3", NULL),
+"rtc", (DeviceState *)rtc_state, NULL);
+
 audio_init(gsi, pci_enabled ? pci_bus : NULL);
 
 pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index d183443..d785d4b 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -288,6 +288,7 @@ static PCIBus *i440fx_common_init(const char *device_name,
 address_space_io, 0);
 s->bus = b;
 qdev_init_nofail(dev);
+qdev_property_add_child(qdev_get_root(), "i440fx", dev, NULL);
 
 d = pci_create_simple(b, 0, device_name);
 *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
@@ -323,6 +324,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
 pci_create_simple_multifunction(b, -1, true, "PIIX3"));
 pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
 PIIX_NUM_PIRQS);
+
+qdev_property_add_child(dev, "piix3", &piix3->dev.qdev, NULL);
 }
 piix3->pic = pic;
 
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 066/197] make es1370 more script monkey friendly

2011-12-12 Thread Anthony Liguori
---
 hw/es1370.c |5 -
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/hw/es1370.c b/hw/es1370.c
index c5c16b0..8a7ca65 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -1041,13 +1041,8 @@ static PCIDeviceInfo es1370_info = {
 .vendor_id= PCI_VENDOR_ID_ENSONIQ,
 .device_id= PCI_DEVICE_ID_ENSONIQ_ES1370,
 .class_id = PCI_CLASS_MULTIMEDIA_AUDIO,
-#if 1
 .subsystem_vendor_id = 0x4942,
 .subsystem_id = 0x4c4c,
-#else
-.subsystem_vendor_id = 0x1274,
-.subsystem_id = 0x1371,
-#endif
 };
 
 static void es1370_register (void)
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 019/197] bug fix spotted by paolo

2011-12-12 Thread Anthony Liguori
---
 hw/qdev.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 1102efd..4004860 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1228,7 +1228,7 @@ void qdev_property_add_child(DeviceState *dev, const char 
*name,
 qdev_property_add(dev, name, type, qdev_get_child_property,
   NULL, NULL, child, errp);
 
-qdev_ref(dev);
+qdev_ref(child);
 g_assert(child->parent == NULL);
 child->parent = dev;
 
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 14/20] rtc: make piix3 set the rtc as a child (v2)

2011-12-12 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
v1 -> v2
 - comments (Stefan)
---
 hw/pc_piix.c  |   11 +++
 hw/piix_pci.c |3 +++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 970f43c..2d5ea2c 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -205,6 +205,17 @@ static void pc_init1(MemoryRegion *system_memory,
 }
 }
 
+/* FIXME there's some major spaghetti here.  Somehow we create the devices
+ * on the PIIX before we actually create it.  We create the PIIX3 deep in
+ * the recess of the i440fx creation too and then lose the DeviceState.
+ *
+ * For now, let's "fix" this by making judicious use of paths.  This is not
+ * generally the right way to do this.
+ */
+
+qdev_property_add_child(qdev_resolve_path("/i440fx/piix3", NULL),
+"rtc", (DeviceState *)rtc_state, NULL);
+
 audio_init(gsi, pci_enabled ? pci_bus : NULL);
 
 pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index d183443..d785d4b 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -288,6 +288,7 @@ static PCIBus *i440fx_common_init(const char *device_name,
 address_space_io, 0);
 s->bus = b;
 qdev_init_nofail(dev);
+qdev_property_add_child(qdev_get_root(), "i440fx", dev, NULL);
 
 d = pci_create_simple(b, 0, device_name);
 *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
@@ -323,6 +324,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
 pci_create_simple_multifunction(b, -1, true, "PIIX3"));
 pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
 PIIX_NUM_PIRQS);
+
+qdev_property_add_child(dev, "piix3", &piix3->dev.qdev, NULL);
 }
 piix3->pic = pic;
 
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 18/20] qom: add string property type

2011-12-12 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 hw/qdev.c |   59 +++
 hw/qdev.h |   22 ++
 2 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index 4004860..0fc20fc 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -1449,3 +1449,62 @@ DeviceState *qdev_resolve_path(const char *path, bool 
*ambiguous)
 return dev;
 }
 
+typedef struct StringProperty
+{
+char *(*get)(DeviceState *, Error **);
+void (*set)(DeviceState *, const char *, Error **);
+} StringProperty;
+
+static void qdev_property_get_str(DeviceState *dev, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+StringProperty *prop = opaque;
+char *value;
+
+value = prop->get(dev, errp);
+if (value) {
+visit_type_str(v, &value, name, errp);
+g_free(value);
+}
+}
+
+static void qdev_property_set_str(DeviceState *dev, Visitor *v, void *opaque,
+  const char *name, Error **errp)
+{
+StringProperty *prop = opaque;
+char *value;
+Error *local_err = NULL;
+
+visit_type_str(v, &value, name, &local_err);
+if (local_err) {
+error_propagate(errp, local_err);
+return;
+}
+
+prop->set(dev, value, errp);
+g_free(value);
+}
+
+static void qdev_property_release_str(DeviceState *dev, const char *name,
+  void *opaque)
+{
+StringProperty *prop = opaque;
+g_free(prop);
+}
+
+void qdev_property_add_str(DeviceState *dev, const char *name,
+   char *(*get)(DeviceState *, Error **),
+   void (*set)(DeviceState *, const char *, Error **),
+   Error **errp)
+{
+StringProperty *prop = g_malloc0(sizeof(*prop));
+
+prop->get = get;
+prop->set = set;
+
+qdev_property_add(dev, name, "string",
+  get ? qdev_property_get_str : NULL,
+  set ? qdev_property_set_str : NULL,
+  qdev_property_release_str,
+  prop, errp);
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index fdab848..9faf2ee 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -574,4 +574,26 @@ void qdev_property_add_link(DeviceState *dev, const char 
*name,
 const char *type, DeviceState **child,
 Error **errp);
 
+/**
+ * @qdev_property_add_str
+ *
+ * Add a string property using getters/setters.  This function will add a
+ * property of type 'string'.
+ *
+ * @dev - the device to add a property to
+ *
+ * @name - the name of the property
+ *
+ * @get - the getter or NULL if the property is write-only.  This function must
+ *return a string to be freed by @g_free().
+ *
+ * @set - the setter or NULL if the property is read-only
+ *
+ * @errp - if an error occurs, a pointer to an area to store the error
+ */
+void qdev_property_add_str(DeviceState *dev, const char *name,
+   char *(*get)(DeviceState *, Error **),
+   void (*set)(DeviceState *, const char *, Error **),
+   Error **errp);
+
 #endif
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 053/197] kill off SCSIDeviceInfo

2011-12-12 Thread Anthony Liguori
---
 hw/scsi-bus.c |   12 +-
 hw/scsi-disk.c|   64 ++--
 hw/scsi-generic.c |   16 ++--
 hw/scsi.h |7 +-
 4 files changed, 47 insertions(+), 52 deletions(-)

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index cabdb3c..d017ece 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -183,13 +183,13 @@ static int scsi_qdev_exit(DeviceState *qdev)
 return 0;
 }
 
-void scsi_qdev_register(SCSIDeviceInfo *info)
+void scsi_qdev_register(DeviceInfo *info)
 {
-info->qdev.bus_info = &scsi_bus_info;
-info->qdev.init = scsi_qdev_init;
-info->qdev.unplug   = qdev_simple_unplug_cb;
-info->qdev.exit = scsi_qdev_exit;
-qdev_register_subclass(&info->qdev, TYPE_SCSI_DEVICE);
+info->bus_info = &scsi_bus_info;
+info->init = scsi_qdev_init;
+info->unplug   = qdev_simple_unplug_cb;
+info->exit = scsi_qdev_exit;
+qdev_register_subclass(info, TYPE_SCSI_DEVICE);
 }
 
 /* handle legacy '-drive if=scsi,...' cmd line args */
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 9944d69..4c4cc75 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1739,14 +1739,14 @@ static void scsi_hd_class_initfn(ObjectClass *klass, 
void *data)
 sc->unit_attention_reported = scsi_disk_unit_attention_reported;
 }
 
-static SCSIDeviceInfo scsi_hd_info = {
-.qdev.name= "scsi-hd",
-.qdev.fw_name = "disk",
-.qdev.desc= "virtual SCSI disk",
-.qdev.size= sizeof(SCSIDiskState),
-.qdev.reset   = scsi_disk_reset,
-.qdev.class_init = scsi_hd_class_initfn,
-.qdev.props   = (Property[]) {
+static DeviceInfo scsi_hd_info = {
+.name= "scsi-hd",
+.fw_name = "disk",
+.desc= "virtual SCSI disk",
+.size= sizeof(SCSIDiskState),
+.reset   = scsi_disk_reset,
+.class_init = scsi_hd_class_initfn,
+.props   = (Property[]) {
 DEFINE_SCSI_DISK_PROPERTIES(),
 DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
 DEFINE_PROP_END_OF_LIST(),
@@ -1763,14 +1763,14 @@ static void scsi_cd_class_initfn(ObjectClass *klass, 
void *data)
 sc->unit_attention_reported = scsi_disk_unit_attention_reported;
 }
 
-static SCSIDeviceInfo scsi_cd_info = {
-.qdev.name= "scsi-cd",
-.qdev.fw_name = "disk",
-.qdev.desc= "virtual SCSI CD-ROM",
-.qdev.size= sizeof(SCSIDiskState),
-.qdev.reset   = scsi_disk_reset,
-.qdev.class_init = scsi_cd_class_initfn,
-.qdev.props   = (Property[]) {
+static DeviceInfo scsi_cd_info = {
+.name= "scsi-cd",
+.fw_name = "disk",
+.desc= "virtual SCSI CD-ROM",
+.size= sizeof(SCSIDiskState),
+.reset   = scsi_disk_reset,
+.class_init = scsi_cd_class_initfn,
+.props   = (Property[]) {
 DEFINE_SCSI_DISK_PROPERTIES(),
 DEFINE_PROP_END_OF_LIST(),
 },
@@ -1786,14 +1786,14 @@ static void scsi_block_class_initfn(ObjectClass *klass, 
void *data)
 sc->alloc_req= scsi_block_new_request;
 }
 
-static SCSIDeviceInfo scsi_block_info = {
-.qdev.name= "scsi-block",
-.qdev.fw_name = "disk",
-.qdev.desc= "SCSI block device passthrough",
-.qdev.size= sizeof(SCSIDiskState),
-.qdev.reset   = scsi_disk_reset,
-.qdev.class_init = scsi_block_class_initfn,
-.qdev.props   = (Property[]) {
+static DeviceInfo scsi_block_info = {
+.name= "scsi-block",
+.fw_name = "disk",
+.desc= "SCSI block device passthrough",
+.size= sizeof(SCSIDiskState),
+.reset   = scsi_disk_reset,
+.class_init = scsi_block_class_initfn,
+.props   = (Property[]) {
 DEFINE_SCSI_DISK_PROPERTIES(),
 DEFINE_PROP_END_OF_LIST(),
 },
@@ -1810,14 +1810,14 @@ static void scsi_disk_class_initfn(ObjectClass *klass, 
void *data)
 sc->unit_attention_reported = scsi_disk_unit_attention_reported;
 }
 
-static SCSIDeviceInfo scsi_disk_info = {
-.qdev.name= "scsi-disk", /* legacy -device scsi-disk */
-.qdev.fw_name = "disk",
-.qdev.desc= "virtual SCSI disk or CD-ROM (legacy)",
-.qdev.size= sizeof(SCSIDiskState),
-.qdev.reset   = scsi_disk_reset,
-.qdev.class_init = scsi_disk_class_initfn,
-.qdev.props   = (Property[]) {
+static DeviceInfo scsi_disk_info = {
+.name= "scsi-disk", /* legacy -device scsi-disk */
+.fw_name = "disk",
+.desc= "virtual SCSI disk or CD-ROM (legacy)",
+.size= sizeof(SCSIDiskState),
+.reset   = scsi_disk_reset,
+.class_init = scsi_disk_class_initfn,
+.props   = (Property[]) {
 DEFINE_SCSI_DISK_PROPERTIES(),
 DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
 DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 9fb2a09..8d7a8f3 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -470,14 +470,14 @@ static void scsi_generic_class_initfn(ObjectClass *klass, 
void *data)
 sc->alloc_req= scsi_new_reques

[Qemu-devel] [PATCH v3 02/20] qom: add new dynamic property infrastructure based on Visitors (v2)

2011-12-12 Thread Anthony Liguori
qdev properties are settable only during construction and static to classes.
This isn't flexible enough for QOM.

This patch introduces a property interface for qdev that provides dynamic
properties that are tied to objects, instead of classes.  These properties are
Visitor based instead of string based too.

Signed-off-by: Anthony Liguori 
---
v1 -> v2
 - Etter -> Accessor (Stefan)
 - spelling mistakes (Stefan)
 - switch to qemu-queue (Kevin/Gerd)
---
 hw/qdev.c |   97 +
 hw/qdev.h |  120 +
 qerror.c  |4 ++
 qerror.h  |3 ++
 4 files changed, 224 insertions(+), 0 deletions(-)

diff --git a/hw/qdev.c b/hw/qdev.c
index fdc9843..94f14c1 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -98,6 +98,7 @@ static DeviceState *qdev_create_from_info(BusState *bus, 
DeviceInfo *info)
 qdev_hot_added = true;
 }
 dev->instance_id_alias = -1;
+QTAILQ_INIT(&dev->properties);
 dev->state = DEV_STATE_CREATED;
 return dev;
 }
@@ -395,12 +396,31 @@ void qdev_init_nofail(DeviceState *dev)
 }
 }
 
+static void qdev_property_del_all(DeviceState *dev)
+{
+while (!QTAILQ_EMPTY(&dev->properties)) {
+DeviceProperty *prop = QTAILQ_FIRST(&dev->properties);
+
+QTAILQ_REMOVE(&dev->properties, prop, node);
+
+if (prop->release) {
+prop->release(dev, prop->name, prop->opaque);
+}
+
+g_free(prop->name);
+g_free(prop->type);
+g_free(prop);
+}
+}
+
 /* Unlink device from bus and free the structure.  */
 void qdev_free(DeviceState *dev)
 {
 BusState *bus;
 Property *prop;
 
+qdev_property_del_all(dev);
+
 if (dev->state == DEV_STATE_INITIALIZED) {
 while (dev->num_child_bus) {
 bus = QLIST_FIRST(&dev->child_bus);
@@ -978,3 +998,80 @@ void qdev_unref(DeviceState *dev)
 g_assert(dev->ref > 0);
 dev->ref--;
 }
+
+void qdev_property_add(DeviceState *dev, const char *name, const char *type,
+   DevicePropertyAccessor *get, DevicePropertyAccessor 
*set,
+   DevicePropertyRelease *release,
+   void *opaque, Error **errp)
+{
+DeviceProperty *prop = g_malloc0(sizeof(*prop));
+
+prop->name = g_strdup(name);
+prop->type = g_strdup(type);
+
+prop->get = get;
+prop->set = set;
+prop->release = release;
+prop->opaque = opaque;
+
+QTAILQ_INSERT_TAIL(&dev->properties, prop, node);
+}
+
+static DeviceProperty *qdev_property_find(DeviceState *dev, const char *name)
+{
+DeviceProperty *prop;
+
+QTAILQ_FOREACH(prop, &dev->properties, node) {
+if (strcmp(prop->name, name) == 0) {
+return prop;
+}
+}
+
+return NULL;
+}
+
+void qdev_property_get(DeviceState *dev, Visitor *v, const char *name,
+   Error **errp)
+{
+DeviceProperty *prop = qdev_property_find(dev, name);
+
+if (prop == NULL) {
+error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
+return;
+}
+
+if (!prop->get) {
+error_set(errp, QERR_PERMISSION_DENIED);
+} else {
+prop->get(dev, v, prop->opaque, name, errp);
+}
+}
+
+void qdev_property_set(DeviceState *dev, Visitor *v, const char *name,
+   Error **errp)
+{
+DeviceProperty *prop = qdev_property_find(dev, name);
+
+if (prop == NULL) {
+error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
+return;
+}
+
+if (!prop->set) {
+error_set(errp, QERR_PERMISSION_DENIED);
+} else {
+prop->set(dev, prop->opaque, v, name, errp);
+}
+}
+
+const char *qdev_property_get_type(DeviceState *dev, const char *name, Error 
**errp)
+{
+DeviceProperty *prop = qdev_property_find(dev, name);
+
+if (prop == NULL) {
+error_set(errp, QERR_PROPERTY_NOT_FOUND, dev->id?:"", name);
+return NULL;
+}
+
+return prop->type;
+}
diff --git a/hw/qdev.h b/hw/qdev.h
index 2397b4e..2df3bb7 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -5,6 +5,7 @@
 #include "qemu-queue.h"
 #include "qemu-char.h"
 #include "qemu-option.h"
+#include "qapi/qapi-visit-core.h"
 
 typedef struct Property Property;
 
@@ -27,6 +28,44 @@ enum {
 DEV_NVECTORS_UNSPECIFIED = -1,
 };
 
+/**
+ * @DevicePropertyAccessor - called when trying to get/set a property
+ *
+ * @dev the device that owns the property
+ * @v the visitor that contains the property data
+ * @opaque the device property opaque
+ * @name the name of the property
+ * @errp a pointer to an Error that is filled if getting/setting fails.
+ */
+typedef void (DevicePropertyAccessor)(DeviceState *dev,
+  Visitor *v,
+  void *opaque,
+  const char *name,
+  Error **errp);
+
+/**
+ * @DevicePropertyRelease - called when a property is removed

Re: [Qemu-devel] [PATCH] Mark future contributions to GPLv2-only files as GPLv2+

2011-12-12 Thread Anthony Liguori

On 12/12/2011 03:35 PM, Paolo Bonzini wrote:

On 12/12/2011 05:36 PM, Anthony Liguori wrote:



Even for files are licensed GPLv2-only, let's not play catch with
ourselves, and explicitly declare that future contributions to those
files will also be available as "any later version".

Signed-off-by: Paolo Bonzini


So where do we stand with this?


I guess you have to tell us. :)

I certainly can resubmit with a new date, say 2011-02-25 to make sure that no
commits will be done on exactly that date.


I'm not opposed to this type of change, but the patch doesn't apply regardless 
of the date because of a submodule change that was there.


Regards,

Anthony Liguori



Paolo





[Qemu-devel] [PATCH v3 028/197] more renames

2011-12-12 Thread Anthony Liguori
---
 hw/object.h |4 ++--
 hw/qdev.h   |6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/object.h b/hw/object.h
index 1ac2f92..834e89e 100644
--- a/hw/object.h
+++ b/hw/object.h
@@ -11,8 +11,8 @@
  *
  */
 
-#ifndef QOBJECT_H
-#define QOBJECT_H
+#ifndef QEMU_OBJECT_H
+#define QEMU_OBJECT_H
 
 #include "qemu-common.h"
 
diff --git a/hw/qdev.h b/hw/qdev.h
index 0702b18..aabaaa3 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -6,7 +6,7 @@
 #include "qemu-char.h"
 #include "qemu-option.h"
 #include "qapi/qapi-visit-core.h"
-#include "qobject.h"
+#include "object.h"
 
 typedef struct Property Property;
 
@@ -68,13 +68,13 @@ typedef struct DeviceProperty
 } DeviceProperty;
 
 typedef struct DeviceClass {
-QObjectClass parent_class;
+ObjectClass parent_class;
 } DeviceClass;
 
 /* This structure should not be accessed directly.  We declare it here
so that it can be embedded in individual device state structures.  */
 struct DeviceState {
-QObject parent_obj;
+Object parent_obj;
 
 const char *id;
 enum DevState state;
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 062/197] killall HDACodecDeviceInfo

2011-12-12 Thread Anthony Liguori
---
 hw/hda-audio.c |   58 ++-
 hw/intel-hda.c |   43 +++--
 hw/intel-hda.h |   26 
 3 files changed, 81 insertions(+), 46 deletions(-)

diff --git a/hw/hda-audio.c b/hw/hda-audio.c
index ffdd799..71831a3 100644
--- a/hw/hda-audio.c
+++ b/hw/hda-audio.c
@@ -906,33 +906,47 @@ static int hda_audio_init_duplex(HDACodecDevice *hda)
 return hda_audio_init(hda, &duplex);
 }
 
-static HDACodecDeviceInfo hda_audio_info_output = {
-.qdev.name= "hda-output",
-.qdev.desc= "HDA Audio Codec, output-only",
-.qdev.size= sizeof(HDAAudioState),
-.qdev.vmsd= &vmstate_hda_audio,
-.qdev.props   = hda_audio_properties,
-.init = hda_audio_init_output,
-.exit = hda_audio_exit,
-.command  = hda_audio_command,
-.stream   = hda_audio_stream,
+static void hda_audio_output_class_init(ObjectClass *klass, void *data)
+{
+HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
+
+k->init = hda_audio_init_output;
+k->exit = hda_audio_exit;
+k->command = hda_audio_command;
+k->stream = hda_audio_stream;
+}
+
+static DeviceInfo hda_audio_output_info = {
+.name = "hda-output",
+.desc = "HDA Audio Codec, output-only",
+.size = sizeof(HDAAudioState),
+.vmsd = &vmstate_hda_audio,
+.props = hda_audio_properties,
+.class_init = hda_audio_output_class_init,
 };
 
-static HDACodecDeviceInfo hda_audio_info_duplex = {
-.qdev.name= "hda-duplex",
-.qdev.desc= "HDA Audio Codec, duplex",
-.qdev.size= sizeof(HDAAudioState),
-.qdev.vmsd= &vmstate_hda_audio,
-.qdev.props   = hda_audio_properties,
-.init = hda_audio_init_duplex,
-.exit = hda_audio_exit,
-.command  = hda_audio_command,
-.stream   = hda_audio_stream,
+static void hda_audio_duplex_class_init(ObjectClass *klass, void *data)
+{
+HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass);
+
+k->init = hda_audio_init_duplex;
+k->exit = hda_audio_exit;
+k->command = hda_audio_command;
+k->stream = hda_audio_stream;
+}
+
+static DeviceInfo hda_audio_duplex_info = {
+.name = "hda-duplex",
+.desc = "HDA Audio Codec, duplex",
+.size = sizeof(HDAAudioState),
+.vmsd = &vmstate_hda_audio,
+.props = hda_audio_properties,
+.class_init = hda_audio_duplex_class_init,
 };
 
 static void hda_audio_register(void)
 {
-hda_codec_register(&hda_audio_info_output);
-hda_codec_register(&hda_audio_info_duplex);
+hda_codec_register(&hda_audio_output_info);
+hda_codec_register(&hda_audio_duplex_info);
 }
 device_init(hda_audio_register);
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 09459b8..97a6216 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -50,10 +50,9 @@ void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
 static int hda_codec_dev_init(DeviceState *qdev, DeviceInfo *base)
 {
 HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, qdev->parent_bus);
-HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev);
-HDACodecDeviceInfo *info = DO_UPCAST(HDACodecDeviceInfo, qdev, base);
+HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev);
+HDACodecDeviceClass *hcc = HDA_CODEC_DEVICE_GET_CLASS(dev);
 
-dev->info = info;
 if (dev->cad == -1) {
 dev->cad = bus->next_cad;
 }
@@ -61,25 +60,26 @@ static int hda_codec_dev_init(DeviceState *qdev, DeviceInfo 
*base)
 return -1;
 }
 bus->next_cad = dev->cad + 1;
-return info->init(dev);
+return hcc->init(dev);
 }
 
 static int hda_codec_dev_exit(DeviceState *qdev)
 {
-HDACodecDevice *dev = DO_UPCAST(HDACodecDevice, qdev, qdev);
+HDACodecDevice *dev = HDA_CODEC_DEVICE(qdev);
+HDACodecDeviceClass *hcc = HDA_CODEC_DEVICE_GET_CLASS(dev);
 
-if (dev->info->exit) {
-dev->info->exit(dev);
+if (hcc->exit) {
+hcc->exit(dev);
 }
 return 0;
 }
 
-void hda_codec_register(HDACodecDeviceInfo *info)
+void hda_codec_register(DeviceInfo *info)
 {
-info->qdev.init = hda_codec_dev_init;
-info->qdev.exit = hda_codec_dev_exit;
-info->qdev.bus_info = &hda_codec_bus_info;
-qdev_register(&info->qdev);
+info->init = hda_codec_dev_init;
+info->exit = hda_codec_dev_exit;
+info->bus_info = &hda_codec_bus_info;
+qdev_register_subclass(info, TYPE_HDA_CODEC_DEVICE);
 }
 
 HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad)
@@ -283,6 +283,7 @@ static int intel_hda_send_command(IntelHDAState *d, 
uint32_t verb)
 {
 uint32_t cad, nid, data;
 HDACodecDevice *codec;
+HDACodecDeviceClass *hcc;
 
 cad = (verb >> 28) & 0x0f;
 if (verb & (1 << 27)) {
@@ -298,7 +299,8 @@ static int intel_hda_send_command(IntelHDAState *d, 
uint32_t verb)
 dprint(d, 1, "%s: addressed non-existing codec\n", __FUNCTION__);
 return -1;
 }
-codec->info->command(codec, nid, data);
+h

[Qemu-devel] [PATCH v3 056/197] add I2CSlave to the type hierarchy

2011-12-12 Thread Anthony Liguori
---
 hw/i2c.c |   15 +++
 hw/i2c.h |   13 +
 2 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/hw/i2c.c b/hw/i2c.c
index 9efe70c..cdf88f2 100644
--- a/hw/i2c.c
+++ b/hw/i2c.c
@@ -194,3 +194,18 @@ DeviceState *i2c_create_slave(i2c_bus *bus, const char 
*name, uint8_t addr)
 qdev_init_nofail(dev);
 return dev;
 }
+
+static TypeInfo i2c_slave_type_info = {
+.name = TYPE_I2C_SLAVE,
+.parent = TYPE_DEVICE,
+.instance_size = sizeof(I2CSlave),
+.abstract = true,
+.class_size = sizeof(I2CSlaveClass),
+};
+
+static void i2c_slave_register_devices(void)
+{
+type_register_static(&i2c_slave_type_info);
+}
+
+device_init(i2c_slave_register_devices);
diff --git a/hw/i2c.h b/hw/i2c.h
index 28401f0..cc4d76b 100644
--- a/hw/i2c.h
+++ b/hw/i2c.h
@@ -26,6 +26,19 @@ typedef void (*i2c_event_cb)(I2CSlave *s, enum i2c_event 
event);
 
 typedef int (*i2c_slave_initfn)(I2CSlave *dev);
 
+#define TYPE_I2C_SLAVE "i2c-slave"
+#define I2C_SLAVE(obj) \
+ OBJECT_CHECK(I2CSlave, (obj), TYPE_I2C_SLAVE)
+#define I2C_SLAVE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(I2CSlaveClass, (klass), TYPE_I2C_SLAVE)
+#define I2C_SLAVE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(I2CSlaveClass, (obj), TYPE_I2C_SLAVE)
+
+typedef struct I2CSlaveClass
+{
+DeviceClass parent_class;
+} I2CSlaveClass;
+
 typedef struct {
 DeviceInfo qdev;
 
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 10/20] qmp: add qom-list command

2011-12-12 Thread Anthony Liguori
This can be used to list properties in the device model.

Signed-off-by: Anthony Liguori 
---
 qapi-schema.json |   48 
 qmp-commands.hx  |6 ++
 qmp.c|   28 
 3 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index f358b49..7c979b2 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1168,3 +1168,51 @@
 # Since: 0.14.0
 ##
 { 'command': 'migrate_set_speed', 'data': {'value': 'int'} }
+
+##
+# @DevicePropertyInfo:
+#
+# @name: the name of the property
+#
+# @type: the type of the property.  This will typically come in one of four
+#forms:
+#
+#1) A primitive type such as 'u8', 'u16', 'bool', 'str', or 'double'.
+#   These types are mapped to the appropriate JSON type.
+#
+#2) A legacy type in the form 'legacy' where subtype is the
+#   legacy qdev typename.  These types are always treated as strings.
+#
+#3) A child type in the form 'child' where subtype is a qdev
+#   device type name.  Child properties create the composition tree.
+#
+#4) A link type in the form 'link' where subtype is a qdev
+#   device type name.  Link properties form the device model graph.
+#
+# Since: 1.1
+#
+# Notes: This type is experimental.  Its syntax may change in future releases.
+##
+{ 'type': 'DevicePropertyInfo',
+  'data': { 'name': 'str', 'type': 'str' } }
+
+##
+# @qom-list:
+#
+# This command will list any properties of a device given a path in the device
+# model.
+#
+# @path: the path within the device model.  See @qom-get for a description of
+#this parameter.
+#
+# Returns: a list of @DevicePropertyInfo that describe the properties of the
+#  device.
+#
+# Since: 1.1
+#
+# Notes: This command is experimental.  It's syntax may change in future
+#releases.
+##
+{ 'command': 'qom-list',
+  'data': { 'path': 'str' },
+  'returns': [ 'DevicePropertyInfo' ] }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 002e7e8..c1f0718 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2009,3 +2009,9 @@ EQMP
 .args_type  = "",
 .mhandler.cmd_new = qmp_marshal_input_query_balloon,
 },
+
+{
+.name   = "qom-list",
+.args_type  = "path:s",
+.mhandler.cmd_new = qmp_marshal_input_qom_list,
+},
diff --git a/qmp.c b/qmp.c
index d71ceb4..8e9a595 100644
--- a/qmp.c
+++ b/qmp.c
@@ -16,6 +16,7 @@
 #include "qmp-commands.h"
 #include "kvm.h"
 #include "arch_init.h"
+#include "hw/qdev.h"
 
 NameInfo *qmp_query_name(Error **errp)
 {
@@ -154,3 +155,30 @@ void qmp_cont(Error **errp)
 
 vm_start();
 }
+
+DevicePropertyInfoList *qmp_qom_list(const char *path, Error **errp)
+{
+DeviceState *dev;
+bool ambiguous = false;
+DevicePropertyInfoList *props = NULL;
+DeviceProperty *prop;
+
+dev = qdev_resolve_path(path, &ambiguous);
+if (dev == NULL) {
+error_set(errp, QERR_DEVICE_NOT_FOUND, path);
+return NULL;
+}
+
+QTAILQ_FOREACH(prop, &dev->properties, node) {
+DevicePropertyInfoList *entry = g_malloc0(sizeof(*entry));
+
+entry->value = g_malloc0(sizeof(DevicePropertyInfo));
+entry->next = props;
+props = entry;
+
+entry->value->name = g_strdup(prop->name);
+entry->value->type = g_strdup(prop->type);
+}
+
+return props;
+}
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 15/20] rtc: add a dynamic property for retrieving the date

2011-12-12 Thread Anthony Liguori
This really shows the power of dynamic object properties compared to qdev
static properties.

This property represents a complex structure who's format is preserved over the
wire.  This is enabled by visitors.

It also shows an entirely synthetic property that is not tied to device state.

Signed-off-by: Anthony Liguori 
---
 hw/mc146818rtc.c |   27 +++
 1 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 2aaca2f..0c23cb0 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -614,6 +614,29 @@ static const MemoryRegionOps cmos_ops = {
 .old_portio = cmos_portio
 };
 
+// FIXME add int32 visitor
+static void visit_type_int32(Visitor *v, int *value, const char *name, Error 
**errp)
+{
+int64_t val = *value;
+visit_type_int(v, &val, name, errp);
+}
+
+static void rtc_get_date(DeviceState *dev, Visitor *v, void *opaque,
+ const char *name, Error **errp)
+{
+ISADevice *isa = DO_UPCAST(ISADevice, qdev, dev);
+RTCState *s = DO_UPCAST(RTCState, dev, isa);
+
+visit_start_struct(v, NULL, "struct tm", name, 0, errp);
+visit_type_int32(v, &s->current_tm.tm_year, "tm_year", errp);
+visit_type_int32(v, &s->current_tm.tm_mon, "tm_mon", errp);
+visit_type_int32(v, &s->current_tm.tm_mday, "tm_mday", errp);
+visit_type_int32(v, &s->current_tm.tm_hour, "tm_hour", errp);
+visit_type_int32(v, &s->current_tm.tm_min, "tm_min", errp);
+visit_type_int32(v, &s->current_tm.tm_sec, "tm_sec", errp);
+visit_end_struct(v, errp);
+}
+
 static int rtc_initfn(ISADevice *dev)
 {
 RTCState *s = DO_UPCAST(RTCState, dev, dev);
@@ -647,6 +670,10 @@ static int rtc_initfn(ISADevice *dev)
 
 qdev_set_legacy_instance_id(&dev->qdev, base, 2);
 qemu_register_reset(rtc_reset, s);
+
+qdev_property_add(&s->dev.qdev, "date", "struct tm",
+  rtc_get_date, NULL, NULL, s, NULL);
+
 return 0;
 }
 
-- 
1.7.4.1




[Qemu-devel] [PATCH v3 024/197] i440fx: split out piix3 device

2011-12-12 Thread Anthony Liguori
Signed-off-by: Anthony Liguori 
---
 Makefile.objs   |3 +
 Makefile.target |2 +-
 hw/piix3.c  |  181 ++
 hw/piix3.h  |   37 +
 hw/piix_pci.c   |  236 +--
 5 files changed, 242 insertions(+), 217 deletions(-)
 create mode 100644 hw/piix3.c
 create mode 100644 hw/piix3.h

diff --git a/Makefile.objs b/Makefile.objs
index 10e794c..bdc0e42 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -293,6 +293,9 @@ hw-obj-$(CONFIG_DP8393X) += dp8393x.o
 hw-obj-$(CONFIG_DS1225Y) += ds1225y.o
 hw-obj-$(CONFIG_MIPSNET) += mipsnet.o
 
+# HW
+hw-obj-y += piix_pci.o piix3.o
+
 # Sound
 sound-obj-y =
 sound-obj-$(CONFIG_SB16) += sb16.o
diff --git a/Makefile.target b/Makefile.target
index a111521..7f9cd30 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -231,7 +231,7 @@ obj-$(CONFIG_IVSHMEM) += ivshmem.o
 # Hardware support
 obj-i386-y += vga.o
 obj-i386-y += mc146818rtc.o pc.o
-obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o piix_pci.o
+obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o
 obj-i386-y += vmport.o
 obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
 obj-i386-y += debugcon.o multiboot.o
diff --git a/hw/piix3.c b/hw/piix3.c
new file mode 100644
index 000..8a07259
--- /dev/null
+++ b/hw/piix3.c
@@ -0,0 +1,181 @@
+#include "piix3.h"
+#include "range.h"
+#include "xen.h"
+
+/* PIIX3 PCI to ISA bridge */
+static void piix3_set_irq_pic(PIIX3State *piix3, int pic_irq)
+{
+qemu_set_irq(piix3->pic[pic_irq],
+ !!(piix3->pic_levels &
+(((1ULL << PIIX_NUM_PIRQS) - 1) <<
+ (pic_irq * PIIX_NUM_PIRQS;
+}
+
+void piix3_set_irq_level(PIIX3State *piix3, int pirq, int level)
+{
+int pic_irq;
+uint64_t mask;
+
+pic_irq = piix3->dev.config[PIIX_PIRQC + pirq];
+if (pic_irq >= PIIX_NUM_PIC_IRQS) {
+return;
+}
+
+mask = 1ULL << ((pic_irq * PIIX_NUM_PIRQS) + pirq);
+piix3->pic_levels &= ~mask;
+piix3->pic_levels |= mask * !!level;
+
+piix3_set_irq_pic(piix3, pic_irq);
+}
+
+/* irq routing is changed. so rebuild bitmap */
+static void piix3_update_irq_levels(PIIX3State *piix3)
+{
+int pirq;
+
+piix3->pic_levels = 0;
+for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {
+piix3_set_irq_level(piix3, pirq,
+pci_bus_get_irq_level(piix3->dev.bus, pirq));
+}
+}
+
+static void piix3_write_config(PCIDevice *dev,
+   uint32_t address, uint32_t val, int len)
+{
+pci_default_write_config(dev, address, val, len);
+if (ranges_overlap(address, len, PIIX_PIRQC, 4)) {
+PIIX3State *piix3 = DO_UPCAST(PIIX3State, dev, dev);
+int pic_irq;
+piix3_update_irq_levels(piix3);
+for (pic_irq = 0; pic_irq < PIIX_NUM_PIC_IRQS; pic_irq++) {
+piix3_set_irq_pic(piix3, pic_irq);
+}
+}
+}
+
+static void piix3_write_config_xen(PCIDevice *dev,
+   uint32_t address, uint32_t val, int len)
+{
+xen_piix_pci_write_config_client(address, val, len);
+piix3_write_config(dev, address, val, len);
+}
+
+static void piix3_reset(void *opaque)
+{
+PIIX3State *d = opaque;
+uint8_t *pci_conf = d->dev.config;
+
+pci_conf[0x04] = 0x07; // master, memory and I/O
+pci_conf[0x05] = 0x00;
+pci_conf[0x06] = 0x00;
+pci_conf[0x07] = 0x02; // PCI_status_devsel_medium
+pci_conf[0x4c] = 0x4d;
+pci_conf[0x4e] = 0x03;
+pci_conf[0x4f] = 0x00;
+pci_conf[0x60] = 0x80;
+pci_conf[0x61] = 0x80;
+pci_conf[0x62] = 0x80;
+pci_conf[0x63] = 0x80;
+pci_conf[0x69] = 0x02;
+pci_conf[0x70] = 0x80;
+pci_conf[0x76] = 0x0c;
+pci_conf[0x77] = 0x0c;
+pci_conf[0x78] = 0x02;
+pci_conf[0x79] = 0x00;
+pci_conf[0x80] = 0x00;
+pci_conf[0x82] = 0x00;
+pci_conf[0xa0] = 0x08;
+pci_conf[0xa2] = 0x00;
+pci_conf[0xa3] = 0x00;
+pci_conf[0xa4] = 0x00;
+pci_conf[0xa5] = 0x00;
+pci_conf[0xa6] = 0x00;
+pci_conf[0xa7] = 0x00;
+pci_conf[0xa8] = 0x0f;
+pci_conf[0xaa] = 0x00;
+pci_conf[0xab] = 0x00;
+pci_conf[0xac] = 0x00;
+pci_conf[0xae] = 0x00;
+
+d->pic_levels = 0;
+}
+
+static int piix3_post_load(void *opaque, int version_id)
+{
+PIIX3State *piix3 = opaque;
+piix3_update_irq_levels(piix3);
+return 0;
+}
+
+static void piix3_pre_save(void *opaque)
+{
+int i;
+PIIX3State *piix3 = opaque;
+
+for (i = 0; i < ARRAY_SIZE(piix3->pci_irq_levels_vmstate); i++) {
+piix3->pci_irq_levels_vmstate[i] =
+pci_bus_get_irq_level(piix3->dev.bus, i);
+}
+}
+
+static const VMStateDescription vmstate_piix3 = {
+.name = "PIIX3",
+.version_id = 3,
+.minimum_version_id = 2,
+.minimum_version_id_old = 2,
+.post_load = piix3_post_load,
+.pre_save = piix3_pre_save,
+.fields  = (VMStateField []) {
+VMSTATE_PCI_DEVICE(dev, PIIX3State)

  1   2   3   >