Re: [Qemu-devel] [PATCH 1/4] eth: add speed and duplex definitions

2018-03-07 Thread Jason Baron via Qemu-devel


On 03/06/2018 01:15 PM, Michael S. Tsirkin wrote:
> On Tue, Mar 06, 2018 at 12:53:14PM -0500, Jason Baron wrote:
>>
>>
>> On 03/02/2018 12:54 PM, Michael S. Tsirkin wrote:
>>> On Thu, Mar 01, 2018 at 10:46:33PM -0500, Jason Baron wrote:
>>>> Pull in definitions for SPEED_UNKNOWN, DUPLEX_UNKNOWN, DUPLEX_HALF,
>>>> and DUPLEX_FULL.
>>>>
>>>> Signed-off-by: Jason Baron <jba...@akamai.com>
>>>> Cc: "Michael S. Tsirkin" <m...@redhat.com>
>>>> Cc: Jason Wang <jasow...@redhat.com>
>>>> Cc: virtio-...@lists.oasis-open.org
>>>> ---
>>>>  include/net/eth.h | 7 +++
>>>>  1 file changed, 7 insertions(+)
>>>>
>>>> diff --git a/include/net/eth.h b/include/net/eth.h
>>>> index 09054a5..9843678 100644
>>>> --- a/include/net/eth.h
>>>> +++ b/include/net/eth.h
>>>> @@ -417,4 +417,11 @@ bool
>>>>  eth_parse_ipv6_hdr(const struct iovec *pkt, int pkt_frags,
>>>> size_t ip6hdr_off, eth_ip6_hdr_info *info);
>>>>  
>>>> +/* ethtool defines - from linux/ethtool.h */
>>>> +#define SPEED_UNKNOWN   -1
>>>> +
>>>> +#define DUPLEX_HALF 0x00
>>>> +#define DUPLEX_FULL 0x01
>>>> +#define DUPLEX_UNKNOWN  0xff
>>>> +
>>>>  #endif
>>>
>>> While that's not a lot, I think we should import linux/ethtool.h into
>>> include/standard-headers/linux/ using scripts/update-linux-headers.sh
>>>
>>
>> Ok, I had started down that path, by including
>> include/uapi/linux/ethtool.h but that resulted in a few other headers -
>> kernel.h, sysinfo.h. And so it seemed like a lot of headers for only a
>> few lines. But I will re-visit it...
>>
>> Thanks,
>>
>> -Jason
> 
> I don't know why is sysinfo there. Want to try sending a patch to
> drop it from linux/kernel.h?
> 

Seems like this also ripples into glibc headers, if you look at:
/usr/include/x86_64-linux-gnu/sys/sysinfo.h. It also includes kernel.h
in order to get struct sysinfo. So that would need updating as well.

I've done a v2 that just pulls in sysinfo.h, it doesn't look too bad,
but let me know...

Thanks,

-Jason




[Qemu-devel] [PATCH v2 0/3] virtio-net: allow linkspeed and duplex setting

2018-03-07 Thread Jason Baron via Qemu-devel
Hi,

Linux can now read linkspeed and duplex settings as set by the
hypervisor:

faa9b39 virtio_net: propagate linkspeed/duplex settings from the hypervisor

This series thus adds qemu support.

Also, this patchset depends on this header sync:

https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg07072.html

Thanks,

-Jason

v2
-pull in include/linux/ethtool.h (Michael Tsirkin)

Jason Baron (3):
  scripts/update-linux-headers: add ethtool.h and update to 4.16.0-rc4
  virtio-net: use 64-bit values for feature flags
  virtio-net: add linkspeed and duplex settings to virtio-net

 hw/net/virtio-net.c  |   81 +-
 include/hw/virtio/virtio-net.h   |5 +-
 include/standard-headers/linux/ethtool.h | 1821 ++
 include/standard-headers/linux/input.h   |4 +-
 include/standard-headers/linux/kernel.h  |   15 +
 include/standard-headers/linux/sysinfo.h |   25 +
 linux-headers/asm-x86/kvm_para.h |1 +
 linux-headers/linux/kvm.h|2 +
 scripts/update-linux-headers.sh  |   11 +-
 9 files changed, 1934 insertions(+), 31 deletions(-)
 create mode 100644 include/standard-headers/linux/ethtool.h
 create mode 100644 include/standard-headers/linux/kernel.h
 create mode 100644 include/standard-headers/linux/sysinfo.h

-- 
2.7.4




[Qemu-devel] [PATCH v2 1/3] scripts/update-linux-headers: add ethtool.h and update to 4.16.0-rc4

2018-03-07 Thread Jason Baron via Qemu-devel
A subsequent patch to add support for setting linkspeed/duplex in
virtio-net, requires a few definitions from ethtool.h, which ends up
pulling in kernel.h and sysinfo.h as well.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 include/standard-headers/linux/ethtool.h | 1821 ++
 include/standard-headers/linux/input.h   |4 +-
 include/standard-headers/linux/kernel.h  |   15 +
 include/standard-headers/linux/sysinfo.h |   25 +
 linux-headers/asm-x86/kvm_para.h |1 +
 linux-headers/linux/kvm.h|2 +
 scripts/update-linux-headers.sh  |   11 +-
 7 files changed, 1876 insertions(+), 3 deletions(-)
 create mode 100644 include/standard-headers/linux/ethtool.h
 create mode 100644 include/standard-headers/linux/kernel.h
 create mode 100644 include/standard-headers/linux/sysinfo.h

diff --git a/include/standard-headers/linux/ethtool.h 
b/include/standard-headers/linux/ethtool.h
new file mode 100644
index 000..94aacb7
--- /dev/null
+++ b/include/standard-headers/linux/ethtool.h
@@ -0,0 +1,1821 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/*
+ * ethtool.h: Defines for Linux ethtool.
+ *
+ * Copyright (C) 1998 David S. Miller (da...@redhat.com)
+ * Copyright 2001 Jeff Garzik <jgar...@pobox.com>
+ * Portions Copyright 2001 Sun Microsystems (thoc...@sun.com)
+ * Portions Copyright 2002 Intel (eli.kuperm...@intel.com,
+ *christopher.le...@intel.com,
+ *scott.feld...@intel.com)
+ * Portions Copyright (C) Sun Microsystems 2008
+ */
+
+#ifndef _LINUX_ETHTOOL_H
+#define _LINUX_ETHTOOL_H
+
+#include "net/eth.h"
+
+#include "standard-headers/linux/kernel.h"
+#include "standard-headers/linux/types.h"
+#include "standard-headers/linux/if_ether.h"
+
+#include  /* for INT_MAX */
+
+/* All structures exposed to userland should be defined such that they
+ * have the same layout for 32-bit and 64-bit userland.
+ */
+
+/**
+ * struct ethtool_cmd - DEPRECATED, link control and status
+ * This structure is DEPRECATED, please use struct ethtool_link_settings.
+ * @cmd: Command number = %ETHTOOL_GSET or %ETHTOOL_SSET
+ * @supported: Bitmask of %SUPPORTED_* flags for the link modes,
+ * physical connectors and other link features for which the
+ * interface supports autonegotiation or auto-detection.
+ * Read-only.
+ * @advertising: Bitmask of %ADVERTISED_* flags for the link modes,
+ * physical connectors and other link features that are
+ * advertised through autonegotiation or enabled for
+ * auto-detection.
+ * @speed: Low bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
+ * @duplex: Duplex mode; one of %DUPLEX_*
+ * @port: Physical connector type; one of %PORT_*
+ * @phy_address: MDIO address of PHY (transceiver); 0 or 255 if not
+ * applicable.  For clause 45 PHYs this is the PRTAD.
+ * @transceiver: Historically used to distinguish different possible
+ * PHY types, but not in a consistent way.  Deprecated.
+ * @autoneg: Enable/disable autonegotiation and auto-detection;
+ * either %AUTONEG_DISABLE or %AUTONEG_ENABLE
+ * @mdio_support: Bitmask of %ETH_MDIO_SUPPORTS_* flags for the MDIO
+ * protocols supported by the interface; 0 if unknown.
+ * Read-only.
+ * @maxtxpkt: Historically used to report TX IRQ coalescing; now
+ * obsoleted by  ethtool_coalesce.  Read-only; deprecated.
+ * @maxrxpkt: Historically used to report RX IRQ coalescing; now
+ * obsoleted by  ethtool_coalesce.  Read-only; deprecated.
+ * @speed_hi: High bits of the speed, 1Mb units, 0 to INT_MAX or SPEED_UNKNOWN
+ * @eth_tp_mdix: Ethernet twisted-pair MDI(-X) status; one of
+ * %ETH_TP_MDI_*.  If the status is unknown or not applicable, the
+ * value will be %ETH_TP_MDI_INVALID.  Read-only.
+ * @eth_tp_mdix_ctrl: Ethernet twisted pair MDI(-X) control; one of
+ * %ETH_TP_MDI_*.  If MDI(-X) control is not implemented, reads
+ * yield %ETH_TP_MDI_INVALID and writes may be ignored or rejected.
+ * When written successfully, the link should be renegotiated if
+ * necessary.
+ * @lp_advertising: Bitmask of %ADVERTISED_* flags for the link modes
+ * and other link features that the link partner advertised
+ * through autonegotiation; 0 if unknown or not applicable.
+ * Read-only.
+ *
+ * The link speed in Mbps is split between @speed and @speed_hi.  Use
+ * the ethtool_cmd_speed() and ethtool_cmd_speed_set() functions to
+ * access it.
+ *
+ * If autonegotiation is disabled, the speed and @duplex represent the
+ * fixed link mode and are writable if the driver supports multiple
+ * link modes.  If it is enabled then they are read-only; if the link
+ * is up they represent the negotiated link mode; if the link is down,
+ * t

[Qemu-devel] [PATCH v2 3/3] virtio-net: add linkspeed and duplex settings to virtio-net

2018-03-07 Thread Jason Baron via Qemu-devel
Although linkspeed and duplex can be set in a linux guest via 'ethtool -s',
this requires custom ethtool commands for virtio-net by default.

Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
the hypervisor to export a linkspeed and duplex setting. The user can
subsequently overwrite it later if desired via: 'ethtool -s'.

Linkspeed and duplex settings can be set as:
'-device virtio-net,speed=1,duplex=full'

where speed is [0...INT_MAX], and duplex is ["half"|"full"].

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 hw/net/virtio-net.c| 26 ++
 include/hw/virtio/virtio-net.h |  3 +++
 2 files changed, 29 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 4feaa49..c3ce7d2 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -26,6 +26,7 @@
 #include "qapi-event.h"
 #include "hw/virtio/virtio-access.h"
 #include "migration/misc.h"
+#include "standard-headers/linux/ethtool.h"
 
 #define VIRTIO_NET_VM_VERSION11
 
@@ -61,6 +62,8 @@ static VirtIOFeature feature_sizes[] = {
  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
 {.flags = 1ULL << VIRTIO_NET_F_MTU,
  .end = endof(struct virtio_net_config, mtu)},
+{.flags = 1ULL << VIRTIO_NET_F_SPEED_DUPLEX,
+ .end = endof(struct virtio_net_config, duplex)},
 {}
 };
 
@@ -89,6 +92,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t 
*config)
 virtio_stw_p(vdev, _virtqueue_pairs, n->max_queues);
 virtio_stw_p(vdev, , n->net_conf.mtu);
 memcpy(netcfg.mac, n->mac, ETH_ALEN);
+virtio_stl_p(vdev, , n->net_conf.speed);
+netcfg.duplex = n->net_conf.duplex;
 memcpy(config, , n->config_size);
 }
 
@@ -1941,6 +1946,25 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
 }
 
+if (n->net_conf.duplex_str) {
+if (strncmp(n->net_conf.duplex_str, "half", 5) == 0) {
+n->net_conf.duplex = DUPLEX_HALF;
+} else if (strncmp(n->net_conf.duplex_str, "full", 5) == 0) {
+n->net_conf.duplex = DUPLEX_FULL;
+} else {
+error_setg(errp, "'duplex' must be 'half' or 'full'");
+}
+n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
+} else {
+n->net_conf.duplex = DUPLEX_UNKNOWN;
+}
+
+if (n->net_conf.speed < SPEED_UNKNOWN) {
+error_setg(errp, "'speed' must be between 0 and INT_MAX");
+} else if (n->net_conf.speed >= 0) {
+n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
+}
+
 virtio_net_set_config_size(n, n->host_features);
 virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size);
 
@@ -2161,6 +2185,8 @@ static Property virtio_net_properties[] = {
 DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0),
 DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend,
  true),
+DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
+DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index e7634c9..02484dc 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -38,6 +38,9 @@ typedef struct virtio_net_conf
 uint16_t rx_queue_size;
 uint16_t tx_queue_size;
 uint16_t mtu;
+int32_t speed;
+char *duplex_str;
+uint8_t duplex;
 } virtio_net_conf;
 
 /* Maximum packet size we can receive from tap device: header + 64k */
-- 
2.7.4




[Qemu-devel] [PATCH v2 2/3] virtio-net: use 64-bit values for feature flags

2018-03-07 Thread Jason Baron via Qemu-devel
In prepartion for using some of the high order feature bits, make sure that
virtio-net uses 64-bit values everywhere.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 hw/net/virtio-net.c| 55 +-
 include/hw/virtio/virtio-net.h |  2 +-
 2 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 369d40b..4feaa49 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -48,18 +48,18 @@
 (offsetof(container, field) + sizeof(((container *)0)->field))
 
 typedef struct VirtIOFeature {
-uint32_t flags;
+uint64_t flags;
 size_t end;
 } VirtIOFeature;
 
 static VirtIOFeature feature_sizes[] = {
-{.flags = 1 << VIRTIO_NET_F_MAC,
+{.flags = 1ULL << VIRTIO_NET_F_MAC,
  .end = endof(struct virtio_net_config, mac)},
-{.flags = 1 << VIRTIO_NET_F_STATUS,
+{.flags = 1ULL << VIRTIO_NET_F_STATUS,
  .end = endof(struct virtio_net_config, status)},
-{.flags = 1 << VIRTIO_NET_F_MQ,
+{.flags = 1ULL << VIRTIO_NET_F_MQ,
  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
-{.flags = 1 << VIRTIO_NET_F_MTU,
+{.flags = 1ULL << VIRTIO_NET_F_MTU,
  .end = endof(struct virtio_net_config, mtu)},
 {}
 };
@@ -1938,7 +1938,7 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 int i;
 
 if (n->net_conf.mtu) {
-n->host_features |= (0x1 << VIRTIO_NET_F_MTU);
+n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
 }
 
 virtio_net_set_config_size(n, n->host_features);
@@ -2109,45 +2109,46 @@ static const VMStateDescription vmstate_virtio_net = {
 };
 
 static Property virtio_net_properties[] = {
-DEFINE_PROP_BIT("csum", VirtIONet, host_features, VIRTIO_NET_F_CSUM, true),
-DEFINE_PROP_BIT("guest_csum", VirtIONet, host_features,
+DEFINE_PROP_BIT64("csum", VirtIONet, host_features,
+VIRTIO_NET_F_CSUM, true),
+DEFINE_PROP_BIT64("guest_csum", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_CSUM, true),
-DEFINE_PROP_BIT("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
-DEFINE_PROP_BIT("guest_tso4", VirtIONet, host_features,
+DEFINE_PROP_BIT64("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
+DEFINE_PROP_BIT64("guest_tso4", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_TSO4, true),
-DEFINE_PROP_BIT("guest_tso6", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_tso6", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_TSO6, true),
-DEFINE_PROP_BIT("guest_ecn", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_ecn", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_ECN, true),
-DEFINE_PROP_BIT("guest_ufo", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_ufo", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_UFO, true),
-DEFINE_PROP_BIT("guest_announce", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_announce", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_ANNOUNCE, true),
-DEFINE_PROP_BIT("host_tso4", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_tso4", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_TSO4, true),
-DEFINE_PROP_BIT("host_tso6", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_tso6", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_TSO6, true),
-DEFINE_PROP_BIT("host_ecn", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_ecn", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_ECN, true),
-DEFINE_PROP_BIT("host_ufo", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_ufo", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_UFO, true),
-DEFINE_PROP_BIT("mrg_rxbuf", VirtIONet, host_features,
+DEFINE_PROP_BIT64("mrg_rxbuf", VirtIONet, host_features,
 VIRTIO_NET_F_MRG_RXBUF, true),
-DEFINE_PROP_BIT("status", VirtIONet, host_features,
+DEFINE_PROP_BIT64("status", VirtIONet, host_features,
 VIRTIO_NET_F_STATUS, true),
-DEFINE_PROP_BIT("ctrl_vq", VirtIONet, host_features,
+DEFINE_PROP_BIT64("ctrl_vq", VirtIONet, host_features,
 VIRTIO_NET_F_CTRL_VQ, true),
-DEFINE_PROP_BIT("ctrl_rx", VirtIONet, host_features,
+DEFINE_PROP_BIT64("ctrl_rx", VirtIONet, host_features,
   

Re: [Qemu-devel] [virtio-dev] [PATCH 4/4] virtio-net: add linkspeed and duplex settings to virtio-net

2018-03-06 Thread Jason Baron via Qemu-devel


On 03/04/2018 08:05 AM, Yan Vugenfirer wrote:
> 
> 
>> On 2 Mar 2018, at 22:19, Michael S. Tsirkin <m...@redhat.com
>> <mailto:m...@redhat.com>> wrote:
>>
>> On Fri, Mar 02, 2018 at 03:14:01PM +0800, Jason Wang wrote:
>>>
>>>
>>> On 2018年03月02日 11:46, Jason Baron wrote:
>>>> Although linkspeed and duplex can be set in a linux guest via
>>>> 'ethtool -s',
>>>> this requires custom ethtool commands for virtio-net by default.
>>>>
>>>> Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
>>>> the hypervisor to export a linkspeed and duplex setting. The user can
>>>> subsequently overwrite it later if desired via: 'ethtool -s'.
>>>>
>>>> Linkspeed and duplex settings can be set as:
>>>> '-device virtio-net,speed=1,duplex=full'
>>>
>>> I was thinking whether or not it's better to decide the duplex by the
>>> type
>>> of backends.
>>>
>>> E.g userspace and vhost-kernel implement a in fact half duplex. But dpdk
>>> implement a full duplex.
>>>
>>> Thanks
>>
>> OTOH it's a priority for some people to be able to support migration
>> between different backend types. Breaking that won't be nice.
> 
> I think that in this case we need a way to update the settings of link
> speed and link duplex (maybe add QMP command). Migration between
> different backend types should cause link down\link up events. And this
> is a time for a driver to re-read the settings and update the OS.
> 
> Best regards,
> Yan.
> 

So the virtio_net driver in linux will re-read these settings on link up
events. So I could add a qmp command to set these (in addition to the
command-line) interface, if desired. Is there a consensus that we need
to add a qmp command here? Or can that be treated as a future item, if
somebody wants it?

Thanks,

-Jason



Re: [Qemu-devel] [PATCH 4/4] virtio-net: add linkspeed and duplex settings to virtio-net

2018-03-06 Thread Jason Baron via Qemu-devel


On 03/02/2018 03:22 PM, Michael S. Tsirkin wrote:
> On Fri, Mar 02, 2018 at 11:59:00AM -0500, Jason Baron wrote:
>> On 03/02/2018 02:14 AM, Jason Wang wrote:
>>>
>>>
>>> On 2018年03月02日 11:46, Jason Baron wrote:
>>>> Although linkspeed and duplex can be set in a linux guest via 'ethtool
>>>> -s',
>>>> this requires custom ethtool commands for virtio-net by default.
>>>>
>>>> Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
>>>> the hypervisor to export a linkspeed and duplex setting. The user can
>>>> subsequently overwrite it later if desired via: 'ethtool -s'.
>>>>
>>>> Linkspeed and duplex settings can be set as:
>>>> '-device virtio-net,speed=1,duplex=full'
>>>
>>> I was thinking whether or not it's better to decide the duplex by the
>>> type of backends.
>>>
>>> E.g userspace and vhost-kernel implement a in fact half duplex. But dpdk
>>> implement a full duplex.
>>
>> Interesting - could this be derived only from the backend 'type'. IE:
>> NET_CLIENT_DRIVER_TAP, NET_CLIENT_DRIVER_VHOST_USER...
>>
>>
>> I was also thinking this could be specified as 'duplex=backend', in
>> addition to the proposed 'duplex=full' or 'duplex=half'?
>>
>> Thanks,
>>
>> -Jason
> 
> I'd say it would make more sense to teach backends to obey what's
> specified by the user. E.g. if vhost gets a duplex config,
> create two threads.
> 
> But I think all that's for future, we can just fake it for
> now - the current uses don't seem to particularly care about whether
> virtio actually is or isn't a duplex.
> 
> 

Ok, I wouldn't add 'duplex=backend' when I re-post, and will leave any
automatic settings of duplex to 'future work'.

Thanks,

-Jason



Re: [Qemu-devel] [PATCH 1/4] eth: add speed and duplex definitions

2018-03-06 Thread Jason Baron via Qemu-devel


On 03/02/2018 12:54 PM, Michael S. Tsirkin wrote:
> On Thu, Mar 01, 2018 at 10:46:33PM -0500, Jason Baron wrote:
>> Pull in definitions for SPEED_UNKNOWN, DUPLEX_UNKNOWN, DUPLEX_HALF,
>> and DUPLEX_FULL.
>>
>> Signed-off-by: Jason Baron <jba...@akamai.com>
>> Cc: "Michael S. Tsirkin" <m...@redhat.com>
>> Cc: Jason Wang <jasow...@redhat.com>
>> Cc: virtio-...@lists.oasis-open.org
>> ---
>>  include/net/eth.h | 7 +++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/include/net/eth.h b/include/net/eth.h
>> index 09054a5..9843678 100644
>> --- a/include/net/eth.h
>> +++ b/include/net/eth.h
>> @@ -417,4 +417,11 @@ bool
>>  eth_parse_ipv6_hdr(const struct iovec *pkt, int pkt_frags,
>> size_t ip6hdr_off, eth_ip6_hdr_info *info);
>>  
>> +/* ethtool defines - from linux/ethtool.h */
>> +#define SPEED_UNKNOWN   -1
>> +
>> +#define DUPLEX_HALF 0x00
>> +#define DUPLEX_FULL 0x01
>> +#define DUPLEX_UNKNOWN  0xff
>> +
>>  #endif
> 
> While that's not a lot, I think we should import linux/ethtool.h into
> include/standard-headers/linux/ using scripts/update-linux-headers.sh
> 

Ok, I had started down that path, by including
include/uapi/linux/ethtool.h but that resulted in a few other headers -
kernel.h, sysinfo.h. And so it seemed like a lot of headers for only a
few lines. But I will re-visit it...

Thanks,

-Jason



Re: [Qemu-devel] [PATCH 4/4] virtio-net: add linkspeed and duplex settings to virtio-net

2018-03-02 Thread Jason Baron via Qemu-devel
On 03/02/2018 02:14 AM, Jason Wang wrote:
> 
> 
> On 2018年03月02日 11:46, Jason Baron wrote:
>> Although linkspeed and duplex can be set in a linux guest via 'ethtool
>> -s',
>> this requires custom ethtool commands for virtio-net by default.
>>
>> Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
>> the hypervisor to export a linkspeed and duplex setting. The user can
>> subsequently overwrite it later if desired via: 'ethtool -s'.
>>
>> Linkspeed and duplex settings can be set as:
>> '-device virtio-net,speed=1,duplex=full'
> 
> I was thinking whether or not it's better to decide the duplex by the
> type of backends.
> 
> E.g userspace and vhost-kernel implement a in fact half duplex. But dpdk
> implement a full duplex.

Interesting - could this be derived only from the backend 'type'. IE:
NET_CLIENT_DRIVER_TAP, NET_CLIENT_DRIVER_VHOST_USER...


I was also thinking this could be specified as 'duplex=backend', in
addition to the proposed 'duplex=full' or 'duplex=half'?

Thanks,

-Jason

> 
> Thanks
> 
>>
>> where speed is [0...INT_MAX], and duplex is ["half"|"full"].
>>
>> Signed-off-by: Jason Baron<jba...@akamai.com>
>> Cc: "Michael S. Tsirkin"<m...@redhat.com>
>> Cc: Jason Wang<jasow...@redhat.com>
>> Cc:virtio-...@lists.oasis-open.org
>> ---
> 



[Qemu-devel] [PATCH 3/4] virtio-net: use 64-bit values for feature flags

2018-03-01 Thread Jason Baron via Qemu-devel
In prepartion for using some of the high order feature bits, make sure that
virtio-net uses 64-bit values everywhere.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 hw/net/virtio-net.c| 55 +-
 include/hw/virtio/virtio-net.h |  2 +-
 2 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 369d40b..4feaa49 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -48,18 +48,18 @@
 (offsetof(container, field) + sizeof(((container *)0)->field))
 
 typedef struct VirtIOFeature {
-uint32_t flags;
+uint64_t flags;
 size_t end;
 } VirtIOFeature;
 
 static VirtIOFeature feature_sizes[] = {
-{.flags = 1 << VIRTIO_NET_F_MAC,
+{.flags = 1ULL << VIRTIO_NET_F_MAC,
  .end = endof(struct virtio_net_config, mac)},
-{.flags = 1 << VIRTIO_NET_F_STATUS,
+{.flags = 1ULL << VIRTIO_NET_F_STATUS,
  .end = endof(struct virtio_net_config, status)},
-{.flags = 1 << VIRTIO_NET_F_MQ,
+{.flags = 1ULL << VIRTIO_NET_F_MQ,
  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
-{.flags = 1 << VIRTIO_NET_F_MTU,
+{.flags = 1ULL << VIRTIO_NET_F_MTU,
  .end = endof(struct virtio_net_config, mtu)},
 {}
 };
@@ -1938,7 +1938,7 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 int i;
 
 if (n->net_conf.mtu) {
-n->host_features |= (0x1 << VIRTIO_NET_F_MTU);
+n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
 }
 
 virtio_net_set_config_size(n, n->host_features);
@@ -2109,45 +2109,46 @@ static const VMStateDescription vmstate_virtio_net = {
 };
 
 static Property virtio_net_properties[] = {
-DEFINE_PROP_BIT("csum", VirtIONet, host_features, VIRTIO_NET_F_CSUM, true),
-DEFINE_PROP_BIT("guest_csum", VirtIONet, host_features,
+DEFINE_PROP_BIT64("csum", VirtIONet, host_features,
+VIRTIO_NET_F_CSUM, true),
+DEFINE_PROP_BIT64("guest_csum", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_CSUM, true),
-DEFINE_PROP_BIT("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
-DEFINE_PROP_BIT("guest_tso4", VirtIONet, host_features,
+DEFINE_PROP_BIT64("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
+DEFINE_PROP_BIT64("guest_tso4", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_TSO4, true),
-DEFINE_PROP_BIT("guest_tso6", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_tso6", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_TSO6, true),
-DEFINE_PROP_BIT("guest_ecn", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_ecn", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_ECN, true),
-DEFINE_PROP_BIT("guest_ufo", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_ufo", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_UFO, true),
-DEFINE_PROP_BIT("guest_announce", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_announce", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_ANNOUNCE, true),
-DEFINE_PROP_BIT("host_tso4", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_tso4", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_TSO4, true),
-DEFINE_PROP_BIT("host_tso6", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_tso6", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_TSO6, true),
-DEFINE_PROP_BIT("host_ecn", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_ecn", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_ECN, true),
-DEFINE_PROP_BIT("host_ufo", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_ufo", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_UFO, true),
-DEFINE_PROP_BIT("mrg_rxbuf", VirtIONet, host_features,
+DEFINE_PROP_BIT64("mrg_rxbuf", VirtIONet, host_features,
 VIRTIO_NET_F_MRG_RXBUF, true),
-DEFINE_PROP_BIT("status", VirtIONet, host_features,
+DEFINE_PROP_BIT64("status", VirtIONet, host_features,
 VIRTIO_NET_F_STATUS, true),
-DEFINE_PROP_BIT("ctrl_vq", VirtIONet, host_features,
+DEFINE_PROP_BIT64("ctrl_vq", VirtIONet, host_features,
 VIRTIO_NET_F_CTRL_VQ, true),
-DEFINE_PROP_BIT("ctrl_rx", VirtIONet, host_features,
+DEFINE_PROP_BIT64("ctrl_rx", VirtIONet, host_features,
   

[Qemu-devel] [PATCH 4/4] virtio-net: add linkspeed and duplex settings to virtio-net

2018-03-01 Thread Jason Baron via Qemu-devel
Although linkspeed and duplex can be set in a linux guest via 'ethtool -s',
this requires custom ethtool commands for virtio-net by default.

Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
the hypervisor to export a linkspeed and duplex setting. The user can
subsequently overwrite it later if desired via: 'ethtool -s'.

Linkspeed and duplex settings can be set as:
'-device virtio-net,speed=1,duplex=full'

where speed is [0...INT_MAX], and duplex is ["half"|"full"].

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 hw/net/virtio-net.c| 26 ++
 include/hw/virtio/virtio-net.h |  3 +++
 2 files changed, 29 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 4feaa49..5df90ea 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -26,6 +26,7 @@
 #include "qapi-event.h"
 #include "hw/virtio/virtio-access.h"
 #include "migration/misc.h"
+#include "net/eth.h"
 
 #define VIRTIO_NET_VM_VERSION11
 
@@ -61,6 +62,8 @@ static VirtIOFeature feature_sizes[] = {
  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
 {.flags = 1ULL << VIRTIO_NET_F_MTU,
  .end = endof(struct virtio_net_config, mtu)},
+{.flags = 1ULL << VIRTIO_NET_F_SPEED_DUPLEX,
+ .end = endof(struct virtio_net_config, duplex)},
 {}
 };
 
@@ -89,6 +92,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t 
*config)
 virtio_stw_p(vdev, _virtqueue_pairs, n->max_queues);
 virtio_stw_p(vdev, , n->net_conf.mtu);
 memcpy(netcfg.mac, n->mac, ETH_ALEN);
+virtio_stl_p(vdev, , n->net_conf.speed);
+netcfg.duplex = n->net_conf.duplex;
 memcpy(config, , n->config_size);
 }
 
@@ -1941,6 +1946,25 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
 }
 
+if (n->net_conf.duplex_str) {
+if (strncmp(n->net_conf.duplex_str, "half", 5) == 0) {
+n->net_conf.duplex = DUPLEX_HALF;
+} else if (strncmp(n->net_conf.duplex_str, "full", 5) == 0) {
+n->net_conf.duplex = DUPLEX_FULL;
+} else {
+error_setg(errp, "'duplex' must be 'half' or 'full'");
+}
+n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
+} else {
+n->net_conf.duplex = DUPLEX_UNKNOWN;
+}
+
+if (n->net_conf.speed < SPEED_UNKNOWN) {
+error_setg(errp, "'speed' must be between 0 and INT_MAX");
+} else if (n->net_conf.speed >= 0) {
+n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
+}
+
 virtio_net_set_config_size(n, n->host_features);
 virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size);
 
@@ -2161,6 +2185,8 @@ static Property virtio_net_properties[] = {
 DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0),
 DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend,
  true),
+DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
+DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index e7634c9..02484dc 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -38,6 +38,9 @@ typedef struct virtio_net_conf
 uint16_t rx_queue_size;
 uint16_t tx_queue_size;
 uint16_t mtu;
+int32_t speed;
+char *duplex_str;
+uint8_t duplex;
 } virtio_net_conf;
 
 /* Maximum packet size we can receive from tap device: header + 64k */
-- 
2.7.4




[Qemu-devel] [PATCH 2/4] rocker: drop local duplex definitions

2018-03-01 Thread Jason Baron via Qemu-devel
Make use of duplex definitions from net/eth.h.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: Jiri Pirko <j...@resnulli.us>
Cc: virtio-...@lists.oasis-open.org
---
 hw/net/rocker/rocker_fp.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c
index 4b3c984..13a14a0 100644
--- a/hw/net/rocker/rocker_fp.c
+++ b/hw/net/rocker/rocker_fp.c
@@ -16,17 +16,13 @@
 
 #include "qemu/osdep.h"
 #include "net/clients.h"
+#include "net/eth.h"
 
 #include "rocker.h"
 #include "rocker_hw.h"
 #include "rocker_fp.h"
 #include "rocker_world.h"
 
-enum duplex {
-DUPLEX_HALF = 0,
-DUPLEX_FULL
-};
-
 struct fp_port {
 Rocker *r;
 World *world;
-- 
2.7.4




[Qemu-devel] [PATCH 1/4] eth: add speed and duplex definitions

2018-03-01 Thread Jason Baron via Qemu-devel
Pull in definitions for SPEED_UNKNOWN, DUPLEX_UNKNOWN, DUPLEX_HALF,
and DUPLEX_FULL.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 include/net/eth.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/include/net/eth.h b/include/net/eth.h
index 09054a5..9843678 100644
--- a/include/net/eth.h
+++ b/include/net/eth.h
@@ -417,4 +417,11 @@ bool
 eth_parse_ipv6_hdr(const struct iovec *pkt, int pkt_frags,
size_t ip6hdr_off, eth_ip6_hdr_info *info);
 
+/* ethtool defines - from linux/ethtool.h */
+#define SPEED_UNKNOWN   -1
+
+#define DUPLEX_HALF 0x00
+#define DUPLEX_FULL 0x01
+#define DUPLEX_UNKNOWN  0xff
+
 #endif
-- 
2.7.4




[Qemu-devel] [PATCH 0/4] virtio-net: allow linkspeed and duplex setting

2018-03-01 Thread Jason Baron via Qemu-devel
Hi,

Linux can now read linkspeed and duplex settings as set by the
hypervisor:

faa9b39 virtio_net: propagate linkspeed/duplex settings from the hypervisor

This series thus adds qemu support. Michael Tsirkin requested that we pull
in the linkspeed/duplex defines from include/linux/ethtool.h. I started to
do that and it seems to require a number of addtional headers. It seemed
like a lot of extra headers for only a few defines so I've added them all
to include/net/eth.h.

Also, this patchset depends on this header sync:

https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg07072.html

Thanks,

-Jason

Jason Baron (4):
  eth: add speed and duplex definitions
  rocker: drop local duplex definitions
  virtio-net: use 64-bit values for feature flags
  virtio-net: add linkspeed and duplex settings to virtio-net

 hw/net/rocker/rocker_fp.c  |  6 +---
 hw/net/virtio-net.c| 81 --
 include/hw/virtio/virtio-net.h |  5 ++-
 include/net/eth.h  |  7 
 4 files changed, 66 insertions(+), 33 deletions(-)

-- 
2.7.4




[Qemu-devel] [PATCH v4 3/3] qemu: add linkspeed and duplex settings to virtio-net

2018-01-05 Thread Jason Baron via Qemu-devel
Although linkspeed and duplex can be set in a linux guest via 'ethtool -s',
this requires custom ethtool commands for virtio-net by default.

Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
the hypervisor to export a linkspeed and duplex setting. The user can
subsequently overwrite it later if desired via: 'ethtool -s'.

Linkspeed and duplex settings can be set as:
'-device virtio-net,speed=1,duplex=full'

where speed is [-1...INT_MAX], and duplex is ["half"|"full"].

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 hw/net/virtio-net.c | 32 +
 include/hw/virtio/virtio-net.h  |  3 +++
 include/standard-headers/linux/virtio_net.h | 13 
 3 files changed, 48 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 54823af..cd63659 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -40,6 +40,12 @@
 #define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE
 #define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE
 
+/* duplex and speed */
+#define DUPLEX_UNKNOWN  0xff
+#define DUPLEX_HALF 0x00
+#define DUPLEX_FULL 0x01
+#define SPEED_UNKNOWN   -1
+
 /*
  * Calculate the number of bytes up to and including the given 'field' of
  * 'container'.
@@ -61,6 +67,8 @@ static VirtIOFeature feature_sizes[] = {
  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
 {.flags = 1ULL << VIRTIO_NET_F_MTU,
  .end = endof(struct virtio_net_config, mtu)},
+{.flags = 1ULL << VIRTIO_NET_F_SPEED_DUPLEX,
+ .end = endof(struct virtio_net_config, duplex)},
 {}
 };
 
@@ -89,6 +97,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t 
*config)
 virtio_stw_p(vdev, _virtqueue_pairs, n->max_queues);
 virtio_stw_p(vdev, , n->net_conf.mtu);
 memcpy(netcfg.mac, n->mac, ETH_ALEN);
+virtio_stl_p(vdev, , n->net_conf.speed);
+netcfg.duplex = n->net_conf.duplex;
 memcpy(config, , n->config_size);
 }
 
@@ -1941,6 +1951,26 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
 }
 
+if (n->net_conf.duplex_str) {
+if (strncmp(n->net_conf.duplex_str, "half", 5) == 0) {
+n->net_conf.duplex = DUPLEX_HALF;
+} else if (strncmp(n->net_conf.duplex_str, "full", 5) == 0) {
+n->net_conf.duplex = DUPLEX_FULL;
+} else {
+error_setg(errp, "'duplex' must be 'half' or 'full'");
+}
+n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
+} else {
+n->net_conf.duplex = DUPLEX_UNKNOWN;
+}
+
+if (n->net_conf.speed < SPEED_UNKNOWN) {
+error_setg(errp, "'speed' must be between -1 (SPEED_UNKOWN) and "
+   "INT_MAX");
+} else if (n->net_conf.speed >= 0) {
+n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
+}
+
 virtio_net_set_config_size(n, n->host_features);
 virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size);
 
@@ -2161,6 +2191,8 @@ static Property virtio_net_properties[] = {
 DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0),
 DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend,
  true),
+DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
+DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index e7634c9..02484dc 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -38,6 +38,9 @@ typedef struct virtio_net_conf
 uint16_t rx_queue_size;
 uint16_t tx_queue_size;
 uint16_t mtu;
+int32_t speed;
+char *duplex_str;
+uint8_t duplex;
 } virtio_net_conf;
 
 /* Maximum packet size we can receive from tap device: header + 64k */
diff --git a/include/standard-headers/linux/virtio_net.h 
b/include/standard-headers/linux/virtio_net.h
index 30ff249..17c8531 100644
--- a/include/standard-headers/linux/virtio_net.h
+++ b/include/standard-headers/linux/virtio_net.h
@@ -57,6 +57,8 @@
 * Steering */
 #define VIRTIO_NET_F_CTRL_MAC_ADDR 23  /* Set MAC address */
 
+#define VIRTIO_NET_F_SPEED_DUPLEX 63   /* Device set linkspeed and duplex */
+
 #ifndef VIRTIO_NET_NO_LEGACY
 #define VIRTIO_NET_F_GSO   6   /* Host handles pkts w/ any GSO type */
 #endif /* VIRTIO_NET_NO_LEGACY */
@@ -76,6 +78,17 @@ struct virtio_net_confi

[Qemu-devel] [PATCH net-next v4 1/3] virtio_net: propagate linkspeed/duplex settings from the hypervisor

2018-01-05 Thread Jason Baron via Qemu-devel
The ability to set speed and duplex for virtio_net is useful in various
scenarios as described here:

16032be virtio_net: add ethtool support for set and get of settings

However, it would be nice to be able to set this from the hypervisor,
such that virtio_net doesn't require custom guest ethtool commands.

Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
the hypervisor to export a linkspeed and duplex setting. The user can
subsequently overwrite it later if desired via: 'ethtool -s'.

Note that VIRTIO_NET_F_SPEED_DUPLEX is defined as bit 63, the intention
is that device feature bits are to grow down from bit 63, since the
transports are starting from bit 24 and growing up.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 drivers/net/virtio_net.c| 23 ++-
 include/uapi/linux/virtio_net.h | 13 +
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 6fb7b65..4f27508 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1894,6 +1894,24 @@ static void virtnet_init_settings(struct net_device *dev)
vi->duplex = DUPLEX_UNKNOWN;
 }
 
+static void virtnet_update_settings(struct virtnet_info *vi)
+{
+   u32 speed;
+   u8 duplex;
+
+   if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_SPEED_DUPLEX))
+   return;
+
+   speed = virtio_cread32(vi->vdev, offsetof(struct virtio_net_config,
+ speed));
+   if (ethtool_validate_speed(speed))
+   vi->speed = speed;
+   duplex = virtio_cread8(vi->vdev, offsetof(struct virtio_net_config,
+ duplex));
+   if (ethtool_validate_duplex(duplex))
+   vi->duplex = duplex;
+}
+
 static const struct ethtool_ops virtnet_ethtool_ops = {
.get_drvinfo = virtnet_get_drvinfo,
.get_link = ethtool_op_get_link,
@@ -2147,6 +2165,7 @@ static void virtnet_config_changed_work(struct 
work_struct *work)
vi->status = v;
 
if (vi->status & VIRTIO_NET_S_LINK_UP) {
+   virtnet_update_settings(vi);
netif_carrier_on(vi->dev);
netif_tx_wake_all_queues(vi->dev);
} else {
@@ -2695,6 +2714,7 @@ static int virtnet_probe(struct virtio_device *vdev)
schedule_work(>config_work);
} else {
vi->status = VIRTIO_NET_S_LINK_UP;
+   virtnet_update_settings(vi);
netif_carrier_on(dev);
}
 
@@ -2796,7 +2816,8 @@ static struct virtio_device_id id_table[] = {
VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
VIRTIO_NET_F_CTRL_MAC_ADDR, \
-   VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
+   VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
+   VIRTIO_NET_F_SPEED_DUPLEX
 
 static unsigned int features[] = {
VIRTNET_FEATURES,
diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index fc353b5..5de6ed3 100644
--- a/include/uapi/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
@@ -57,6 +57,8 @@
 * Steering */
 #define VIRTIO_NET_F_CTRL_MAC_ADDR 23  /* Set MAC address */
 
+#define VIRTIO_NET_F_SPEED_DUPLEX 63   /* Device set linkspeed and duplex */
+
 #ifndef VIRTIO_NET_NO_LEGACY
 #define VIRTIO_NET_F_GSO   6   /* Host handles pkts w/ any GSO type */
 #endif /* VIRTIO_NET_NO_LEGACY */
@@ -76,6 +78,17 @@ struct virtio_net_config {
__u16 max_virtqueue_pairs;
/* Default maximum transmit unit advice */
__u16 mtu;
+   /*
+* speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+* Any other value stands for unknown.
+*/
+   __u32 speed;
+   /*
+* 0x00 - half duplex
+* 0x01 - full duplex
+* Any other value stands for unknown.
+*/
+   __u8 duplex;
 } __attribute__((packed));
 
 /*
-- 
2.6.1




[Qemu-devel] [PATCH v4 0/3] virtio_net: allow hypervisor to indicate linkspeed and duplex setting

2018-01-05 Thread Jason Baron via Qemu-devel
We have found it useful to be able to set the linkspeed and duplex
settings from the host-side for virtio_net. This obviates the need
for guest changes and settings for these fields, and does not require
custom ethtool commands for virtio_net.

The ability to set linkspeed and duplex is useful in various cases
as described here:

16032be virtio_net: add ethtool support for set and get of settings

Using 'ethtool -s' continues to over-write the linkspeed/duplex
settings with this patch.

The 1/3 patch is against net-next, while the 2-3/3 patch are the associated
qemu changes that would go in after as update-linux-headers.sh should
be run first. So the qemu patches are a demonstration of how I intend this
to work.

Thanks,

-Jason

linux changes:

changes from v3:
* break the speed/duplex read into a function and also call from virtnet_probe
  when status bit is not negotiated
* only do speed/duplex read in virtnet_config_changed_work() on LINK_UP

changes from v2:
* move speed/duplex read into virtnet_config_changed_work() so link up changes
  are detected

Jason Baron (1):
  virtio_net: propagate linkspeed/duplex settings from the hypervisor

 drivers/net/virtio_net.c| 23 ++-
 include/uapi/linux/virtio_net.h | 13 +
 2 files changed, 35 insertions(+), 1 deletion(-)


qemu changes:

Jason Baron (2):
  qemu: virtio-net: use 64-bit values for feature flags
  qemu: add linkspeed and duplex settings to virtio-net

 hw/net/virtio-net.c | 87 -
 include/hw/virtio/virtio-net.h  |  5 +-
 include/standard-headers/linux/virtio_net.h | 13 +
 3 files changed, 77 insertions(+), 28 deletions(-)

-- 
2.6.1




[Qemu-devel] [PATCH v4 2/3] qemu: virtio-net: use 64-bit values for feature flags

2018-01-05 Thread Jason Baron via Qemu-devel
In prepartion for using some of the high order feature bits, make sure that
virtio-net uses 64-bit values everywhere.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 hw/net/virtio-net.c| 55 +-
 include/hw/virtio/virtio-net.h |  2 +-
 2 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 38674b0..54823af 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -48,18 +48,18 @@
 (offsetof(container, field) + sizeof(((container *)0)->field))
 
 typedef struct VirtIOFeature {
-uint32_t flags;
+uint64_t flags;
 size_t end;
 } VirtIOFeature;
 
 static VirtIOFeature feature_sizes[] = {
-{.flags = 1 << VIRTIO_NET_F_MAC,
+{.flags = 1ULL << VIRTIO_NET_F_MAC,
  .end = endof(struct virtio_net_config, mac)},
-{.flags = 1 << VIRTIO_NET_F_STATUS,
+{.flags = 1ULL << VIRTIO_NET_F_STATUS,
  .end = endof(struct virtio_net_config, status)},
-{.flags = 1 << VIRTIO_NET_F_MQ,
+{.flags = 1ULL << VIRTIO_NET_F_MQ,
  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
-{.flags = 1 << VIRTIO_NET_F_MTU,
+{.flags = 1ULL << VIRTIO_NET_F_MTU,
  .end = endof(struct virtio_net_config, mtu)},
 {}
 };
@@ -1938,7 +1938,7 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 int i;
 
 if (n->net_conf.mtu) {
-n->host_features |= (0x1 << VIRTIO_NET_F_MTU);
+n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
 }
 
 virtio_net_set_config_size(n, n->host_features);
@@ -2109,45 +2109,46 @@ static const VMStateDescription vmstate_virtio_net = {
 };
 
 static Property virtio_net_properties[] = {
-DEFINE_PROP_BIT("csum", VirtIONet, host_features, VIRTIO_NET_F_CSUM, true),
-DEFINE_PROP_BIT("guest_csum", VirtIONet, host_features,
+DEFINE_PROP_BIT64("csum", VirtIONet, host_features,
+VIRTIO_NET_F_CSUM, true),
+DEFINE_PROP_BIT64("guest_csum", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_CSUM, true),
-DEFINE_PROP_BIT("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
-DEFINE_PROP_BIT("guest_tso4", VirtIONet, host_features,
+DEFINE_PROP_BIT64("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
+DEFINE_PROP_BIT64("guest_tso4", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_TSO4, true),
-DEFINE_PROP_BIT("guest_tso6", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_tso6", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_TSO6, true),
-DEFINE_PROP_BIT("guest_ecn", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_ecn", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_ECN, true),
-DEFINE_PROP_BIT("guest_ufo", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_ufo", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_UFO, true),
-DEFINE_PROP_BIT("guest_announce", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_announce", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_ANNOUNCE, true),
-DEFINE_PROP_BIT("host_tso4", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_tso4", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_TSO4, true),
-DEFINE_PROP_BIT("host_tso6", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_tso6", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_TSO6, true),
-DEFINE_PROP_BIT("host_ecn", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_ecn", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_ECN, true),
-DEFINE_PROP_BIT("host_ufo", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_ufo", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_UFO, true),
-DEFINE_PROP_BIT("mrg_rxbuf", VirtIONet, host_features,
+DEFINE_PROP_BIT64("mrg_rxbuf", VirtIONet, host_features,
 VIRTIO_NET_F_MRG_RXBUF, true),
-DEFINE_PROP_BIT("status", VirtIONet, host_features,
+DEFINE_PROP_BIT64("status", VirtIONet, host_features,
 VIRTIO_NET_F_STATUS, true),
-DEFINE_PROP_BIT("ctrl_vq", VirtIONet, host_features,
+DEFINE_PROP_BIT64("ctrl_vq", VirtIONet, host_features,
 VIRTIO_NET_F_CTRL_VQ, true),
-DEFINE_PROP_BIT("ctrl_rx", VirtIONet, host_features,
+DEFINE_PROP_BIT64("ctrl_rx", VirtIONet, host_features,
   

Re: [Qemu-devel] [PATCH net-next v3 1/3] virtio_net: propagate linkspeed/duplex settings from the hypervisor

2018-01-04 Thread Jason Baron via Qemu-devel


On 01/04/2018 01:22 PM, Michael S. Tsirkin wrote:
> On Thu, Jan 04, 2018 at 01:12:30PM -0500, Jason Baron wrote:
>>
>>
>> On 01/04/2018 12:05 PM, Michael S. Tsirkin wrote:
>>> On Thu, Jan 04, 2018 at 12:16:44AM -0500, Jason Baron wrote:
>>>> The ability to set speed and duplex for virtio_net is useful in various
>>>> scenarios as described here:
>>>>
>>>> 16032be virtio_net: add ethtool support for set and get of settings
>>>>
>>>> However, it would be nice to be able to set this from the hypervisor,
>>>> such that virtio_net doesn't require custom guest ethtool commands.
>>>>
>>>> Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
>>>> the hypervisor to export a linkspeed and duplex setting. The user can
>>>> subsequently overwrite it later if desired via: 'ethtool -s'.
>>>>
>>>> Note that VIRTIO_NET_F_SPEED_DUPLEX is defined as bit 63, the intention
>>>> is that device feature bits are to grow down from bit 63, since the
>>>> transports are starting from bit 24 and growing up.
>>>>
>>>> Signed-off-by: Jason Baron <jba...@akamai.com>
>>>> Cc: "Michael S. Tsirkin" <m...@redhat.com>
>>>> Cc: Jason Wang <jasow...@redhat.com>
>>>> Cc: virtio-...@lists.oasis-open.org
>>>> ---
>>>>  drivers/net/virtio_net.c| 19 ++-
>>>>  include/uapi/linux/virtio_net.h | 13 +
>>>>  2 files changed, 31 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
>>>> index 6fb7b65..0b2d314 100644
>>>> --- a/drivers/net/virtio_net.c
>>>> +++ b/drivers/net/virtio_net.c
>>>> @@ -2146,6 +2146,22 @@ static void virtnet_config_changed_work(struct 
>>>> work_struct *work)
>>>>  
>>>>vi->status = v;
>>>>  
>>>> +  if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_SPEED_DUPLEX)) {
>>>
>>> BTW we can avoid this read for when link goes down.
>>> Not a big deal but still.
>>
>> So you are saying that we can just set vi->speed and vi->duplex to
>> 'unknown' when the link goes down and not check for the presence of
>> VIRTIO_NET_F_SPEED_DUPLEX?
>>
>> If so, that could over-write what the user may have configured in the
>> guest via 'ethtool -s' when the link goes down, so that would be a
>> change in behavior, but perhaps that is ok?
> 
> No - what I am saying is that your patch overwrites the values
> set by user when link goes down.
> 
> I suggest limiting this call to when
> 
> if (vi->status & VIRTIO_NET_S_LINK_UP)
> 
> and then the values are overwritten when link goes up
> which seems closer to what a user might expect.
ok, will update this for v4.

Thanks,

-Jason

> 
>>
>> I think I would prefer to have the link down event still check for
>> VIRTIO_NET_F_SPEED_DUPLEX before changing speed/duplex. That way we
>> still have 2 modes for updating the fields:
>>
>> 1) completely guest controlled. Same as we have now and host does not
>> change any values and does not set VIRTIO_NET_F_SPEED_DUPLEX flag (hence
>> don't remove above check).
>>
>> 2) if speed or duplex or speed is set in the qemu command line, then set
>> the VIRTIO_NET_F_SPEED_DUPLEX and have host control the settings of
>> speed/duplex (with ability of guest to over-write if it wanted to).
>>
>>
>>>
>>>> +  u32 speed;
>>>> +  u8 duplex;
>>>> +
>>>> +  speed = virtio_cread32(vi->vdev,
>>>> + offsetof(struct virtio_net_config,
>>>> +  speed));
>>>> +  if (ethtool_validate_speed(speed))
>>>> +  vi->speed = speed;
>>>> +  duplex = virtio_cread8(vi->vdev,
>>>> + offsetof(struct virtio_net_config,
>>>> +  duplex));
>>>> +  if (ethtool_validate_duplex(duplex))
>>>> +  vi->duplex = duplex;
>>>> +  }
>>>> +
>>>>if (vi->status & VIRTIO_NET_S_LINK_UP) {
>>>>netif_carrier_on(vi->dev);
>>>>netif_tx_wake_all_queues(vi->dev);
>>>
>>> OK so this handles the case when VIRTIO_NET_F_STATUS is set,
>>&g

Re: [Qemu-devel] [PATCH net-next v3 1/3] virtio_net: propagate linkspeed/duplex settings from the hypervisor

2018-01-04 Thread Jason Baron via Qemu-devel


On 01/04/2018 12:05 PM, Michael S. Tsirkin wrote:
> On Thu, Jan 04, 2018 at 12:16:44AM -0500, Jason Baron wrote:
>> The ability to set speed and duplex for virtio_net is useful in various
>> scenarios as described here:
>>
>> 16032be virtio_net: add ethtool support for set and get of settings
>>
>> However, it would be nice to be able to set this from the hypervisor,
>> such that virtio_net doesn't require custom guest ethtool commands.
>>
>> Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
>> the hypervisor to export a linkspeed and duplex setting. The user can
>> subsequently overwrite it later if desired via: 'ethtool -s'.
>>
>> Note that VIRTIO_NET_F_SPEED_DUPLEX is defined as bit 63, the intention
>> is that device feature bits are to grow down from bit 63, since the
>> transports are starting from bit 24 and growing up.
>>
>> Signed-off-by: Jason Baron <jba...@akamai.com>
>> Cc: "Michael S. Tsirkin" <m...@redhat.com>
>> Cc: Jason Wang <jasow...@redhat.com>
>> Cc: virtio-...@lists.oasis-open.org
>> ---
>>  drivers/net/virtio_net.c| 19 ++-
>>  include/uapi/linux/virtio_net.h | 13 +
>>  2 files changed, 31 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
>> index 6fb7b65..0b2d314 100644
>> --- a/drivers/net/virtio_net.c
>> +++ b/drivers/net/virtio_net.c
>> @@ -2146,6 +2146,22 @@ static void virtnet_config_changed_work(struct 
>> work_struct *work)
>>  
>>  vi->status = v;
>>  
>> +if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_SPEED_DUPLEX)) {
> 
> BTW we can avoid this read for when link goes down.
> Not a big deal but still.

So you are saying that we can just set vi->speed and vi->duplex to
'unknown' when the link goes down and not check for the presence of
VIRTIO_NET_F_SPEED_DUPLEX?

If so, that could over-write what the user may have configured in the
guest via 'ethtool -s' when the link goes down, so that would be a
change in behavior, but perhaps that is ok?

I think I would prefer to have the link down event still check for
VIRTIO_NET_F_SPEED_DUPLEX before changing speed/duplex. That way we
still have 2 modes for updating the fields:

1) completely guest controlled. Same as we have now and host does not
change any values and does not set VIRTIO_NET_F_SPEED_DUPLEX flag (hence
don't remove above check).

2) if speed or duplex or speed is set in the qemu command line, then set
the VIRTIO_NET_F_SPEED_DUPLEX and have host control the settings of
speed/duplex (with ability of guest to over-write if it wanted to).


> 
>> +u32 speed;
>> +u8 duplex;
>> +
>> +speed = virtio_cread32(vi->vdev,
>> +   offsetof(struct virtio_net_config,
>> +speed));
>> +if (ethtool_validate_speed(speed))
>> +vi->speed = speed;
>> +duplex = virtio_cread8(vi->vdev,
>> +   offsetof(struct virtio_net_config,
>> +duplex));
>> +if (ethtool_validate_duplex(duplex))
>> +vi->duplex = duplex;
>> +}
>> +
>>  if (vi->status & VIRTIO_NET_S_LINK_UP) {
>>  netif_carrier_on(vi->dev);
>>  netif_tx_wake_all_queues(vi->dev);
> 
> OK so this handles the case when VIRTIO_NET_F_STATUS is set,
> but when it's clear we need to call this from virtnet_probe.
> 
> I propose moving this chunk to a function and calling from two places.
> 

good point. will update.

Thanks,

-Jason

> 
>> @@ -2796,7 +2812,8 @@ static struct virtio_device_id id_table[] = {
>>  VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
>>  VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
>>  VIRTIO_NET_F_CTRL_MAC_ADDR, \
>> -VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
>> +VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
>> +VIRTIO_NET_F_SPEED_DUPLEX
>>  
>>  static unsigned int features[] = {
>>  VIRTNET_FEATURES,
>> diff --git a/include/uapi/linux/virtio_net.h 
>> b/include/uapi/linux/virtio_net.h
>> index fc353b5..5de6ed3 100644
>> --- a/include/uapi/linux/virtio_net.h
>> +++ b/include/uapi/linux/virtio_net.h
>> @@ -57,6 +57,8 @@
>>   * Steering */
>>  #define VIRTIO_NET_F_CTRL_MAC_ADDR 23   /* Set MAC address */
>>  
>> +#define VIRTIO_NET_F_SPEED_DUPLEX 63

Re: [Qemu-devel] [PATCH net-next v3 1/3] virtio_net: propagate linkspeed/duplex settings from the hypervisor

2018-01-04 Thread Jason Baron via Qemu-devel


On 01/04/2018 11:27 AM, Michael S. Tsirkin wrote:
> On Thu, Jan 04, 2018 at 12:16:44AM -0500, Jason Baron wrote:
>> The ability to set speed and duplex for virtio_net is useful in various
>> scenarios as described here:
>>
>> 16032be virtio_net: add ethtool support for set and get of settings
>>
>> However, it would be nice to be able to set this from the hypervisor,
>> such that virtio_net doesn't require custom guest ethtool commands.
>>
>> Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
>> the hypervisor to export a linkspeed and duplex setting. The user can
>> subsequently overwrite it later if desired via: 'ethtool -s'.
>>
>> Note that VIRTIO_NET_F_SPEED_DUPLEX is defined as bit 63, the intention
>> is that device feature bits are to grow down from bit 63, since the
>> transports are starting from bit 24 and growing up.
>>
>> Signed-off-by: Jason Baron <jba...@akamai.com>
>> Cc: "Michael S. Tsirkin" <m...@redhat.com>
>> Cc: Jason Wang <jasow...@redhat.com>
>> Cc: virtio-...@lists.oasis-open.org
>> ---
>>  drivers/net/virtio_net.c| 19 ++-
>>  include/uapi/linux/virtio_net.h | 13 +
>>  2 files changed, 31 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
>> index 6fb7b65..0b2d314 100644
>> --- a/drivers/net/virtio_net.c
>> +++ b/drivers/net/virtio_net.c
>> @@ -2146,6 +2146,22 @@ static void virtnet_config_changed_work(struct 
>> work_struct *work)
>>  
>>  vi->status = v;
>>  
>> +if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_SPEED_DUPLEX)) {
>> +u32 speed;
>> +u8 duplex;
>> +
>> +speed = virtio_cread32(vi->vdev,
>> +   offsetof(struct virtio_net_config,
>> +speed));
>> +if (ethtool_validate_speed(speed))
>> +vi->speed = speed;
>> +duplex = virtio_cread8(vi->vdev,
>> +   offsetof(struct virtio_net_config,
>> +duplex));
>> +if (ethtool_validate_duplex(duplex))
>> +vi->duplex = duplex;
>> +}
>> +
>>  if (vi->status & VIRTIO_NET_S_LINK_UP) {
>>  netif_carrier_on(vi->dev);
>>  netif_tx_wake_all_queues(vi->dev);
>> @@ -2796,7 +2812,8 @@ static struct virtio_device_id id_table[] = {
>>  VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
>>  VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
>>  VIRTIO_NET_F_CTRL_MAC_ADDR, \
>> -VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
>> +VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
>> +VIRTIO_NET_F_SPEED_DUPLEX
>>  
>>  static unsigned int features[] = {
>>  VIRTNET_FEATURES,
> 
> Still missing the update from virtnet_config_changed_work, and I think
> it's important to reflex host changes within guest when the
> feature bit has been acked.
> 

I update vi->speed and vi->duplex in virtnet_config_changed_work(). And
I tested using the 'set_link' on/off from the qemu monitor.
Specifically, an 'off' sets the speed and link to 'unknown', and an 'on'
returns the speed and link to the configured speed and duplex. So they
are being updated dynamically now. What host changes are you referring
to that are not reflected?

Thanks,

-Jason


>> diff --git a/include/uapi/linux/virtio_net.h 
>> b/include/uapi/linux/virtio_net.h
>> index fc353b5..5de6ed3 100644
>> --- a/include/uapi/linux/virtio_net.h
>> +++ b/include/uapi/linux/virtio_net.h
>> @@ -57,6 +57,8 @@
>>   * Steering */
>>  #define VIRTIO_NET_F_CTRL_MAC_ADDR 23   /* Set MAC address */
>>  
>> +#define VIRTIO_NET_F_SPEED_DUPLEX 63/* Device set linkspeed and 
>> duplex */
>> +
>>  #ifndef VIRTIO_NET_NO_LEGACY
>>  #define VIRTIO_NET_F_GSO6   /* Host handles pkts w/ any GSO type */
>>  #endif /* VIRTIO_NET_NO_LEGACY */
>> @@ -76,6 +78,17 @@ struct virtio_net_config {
>>  __u16 max_virtqueue_pairs;
>>  /* Default maximum transmit unit advice */
>>  __u16 mtu;
>> +/*
>> + * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
>> + * Any other value stands for unknown.
>> + */
>> +__u32 speed;
>> +/*
>> + * 0x00 - half duplex
>> + * 0x01 - full duplex
>> + * Any other value stands for unknown.
>> + */
>> +__u8 duplex;
>>  } __attribute__((packed));
>>  
>>  /*
>> -- 
>> 2.6.1



[Qemu-devel] [PATCH v3 2/3] qemu: virtio-net: use 64-bit values for feature flags

2018-01-03 Thread Jason Baron via Qemu-devel
In prepartion for using some of the high order feature bits, make sure that
virtio-net uses 64-bit values everywhere.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 hw/net/virtio-net.c| 54 +-
 include/hw/virtio/virtio-net.h |  2 +-
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 38674b0..adc20df 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -48,18 +48,18 @@
 (offsetof(container, field) + sizeof(((container *)0)->field))
 
 typedef struct VirtIOFeature {
-uint32_t flags;
+uint64_t flags;
 size_t end;
 } VirtIOFeature;
 
 static VirtIOFeature feature_sizes[] = {
-{.flags = 1 << VIRTIO_NET_F_MAC,
+{.flags = 1ULL << VIRTIO_NET_F_MAC,
  .end = endof(struct virtio_net_config, mac)},
-{.flags = 1 << VIRTIO_NET_F_STATUS,
+{.flags = 1ULL << VIRTIO_NET_F_STATUS,
  .end = endof(struct virtio_net_config, status)},
-{.flags = 1 << VIRTIO_NET_F_MQ,
+{.flags = 1ULL << VIRTIO_NET_F_MQ,
  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
-{.flags = 1 << VIRTIO_NET_F_MTU,
+{.flags = 1ULL << VIRTIO_NET_F_MTU,
  .end = endof(struct virtio_net_config, mtu)},
 {}
 };
@@ -1938,7 +1938,7 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 int i;
 
 if (n->net_conf.mtu) {
-n->host_features |= (0x1 << VIRTIO_NET_F_MTU);
+n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
 }
 
 virtio_net_set_config_size(n, n->host_features);
@@ -2109,45 +2109,45 @@ static const VMStateDescription vmstate_virtio_net = {
 };
 
 static Property virtio_net_properties[] = {
-DEFINE_PROP_BIT("csum", VirtIONet, host_features, VIRTIO_NET_F_CSUM, true),
-DEFINE_PROP_BIT("guest_csum", VirtIONet, host_features,
+DEFINE_PROP_BIT64("csum", VirtIONet, host_features, VIRTIO_NET_F_CSUM, 
true),
+DEFINE_PROP_BIT64("guest_csum", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_CSUM, true),
-DEFINE_PROP_BIT("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
-DEFINE_PROP_BIT("guest_tso4", VirtIONet, host_features,
+DEFINE_PROP_BIT64("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
+DEFINE_PROP_BIT64("guest_tso4", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_TSO4, true),
-DEFINE_PROP_BIT("guest_tso6", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_tso6", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_TSO6, true),
-DEFINE_PROP_BIT("guest_ecn", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_ecn", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_ECN, true),
-DEFINE_PROP_BIT("guest_ufo", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_ufo", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_UFO, true),
-DEFINE_PROP_BIT("guest_announce", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_announce", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_ANNOUNCE, true),
-DEFINE_PROP_BIT("host_tso4", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_tso4", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_TSO4, true),
-DEFINE_PROP_BIT("host_tso6", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_tso6", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_TSO6, true),
-DEFINE_PROP_BIT("host_ecn", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_ecn", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_ECN, true),
-DEFINE_PROP_BIT("host_ufo", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_ufo", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_UFO, true),
-DEFINE_PROP_BIT("mrg_rxbuf", VirtIONet, host_features,
+DEFINE_PROP_BIT64("mrg_rxbuf", VirtIONet, host_features,
 VIRTIO_NET_F_MRG_RXBUF, true),
-DEFINE_PROP_BIT("status", VirtIONet, host_features,
+DEFINE_PROP_BIT64("status", VirtIONet, host_features,
 VIRTIO_NET_F_STATUS, true),
-DEFINE_PROP_BIT("ctrl_vq", VirtIONet, host_features,
+DEFINE_PROP_BIT64("ctrl_vq", VirtIONet, host_features,
 VIRTIO_NET_F_CTRL_VQ, true),
-DEFINE_PROP_BIT("ctrl_rx", VirtIONet, host_features,
+DEFINE_PROP_BIT64("ctrl_rx", VirtIONet, host_features,
 V

[Qemu-devel] [PATCH v3 0/3] virtio_net: allow hypervisor to indicate linkspeed and duplex setting

2018-01-03 Thread Jason Baron via Qemu-devel
We have found it useful to be able to set the linkspeed and duplex
settings from the host-side for virtio_net. This obviates the need
for guest changes and settings for these fields, and does not require
custom ethtool commands for virtio_net.

The ability to set linkspeed and duplex is useful in various cases
as described here:

16032be virtio_net: add ethtool support for set and get of settings 

  
Using 'ethtool -s' continues to over-write the linkspeed/duplex
settings with this patch.

The 1/3 patch is against net-next, while the 2-3/3 patch are the associated
qemu changes that would go in after as update-linux-headers.sh should
be run first. So the qemu patches are a demonstration of how I intend this
to work.

Thanks,

-Jason  

linux changes:

changes from v2:
* move speed/duplex read into virtnet_config_changed_work() so link up changes
  are detected

Jason Baron (1):
  virtio_net: propagate linkspeed/duplex settings from the hypervisor

 drivers/net/virtio_net.c| 19 ++-
 include/uapi/linux/virtio_net.h | 13 +
 2 files changed, 31 insertions(+), 1 deletion(-)

qemu changes:

changes from v2:
* if link up return configured speed/duplex, else return UNKNOWN speed and 
duplex

Jason Baron (2):
  qemu: virtio-net: use 64-bit values for feature flags
  qemu: add linkspeed and duplex settings to virtio-net

 hw/net/virtio-net.c | 89 -
 include/hw/virtio/virtio-net.h  |  5 +-
 include/standard-headers/linux/virtio_net.h | 13 +
 3 files changed, 79 insertions(+), 28 deletions(-)


-- 
2.6.1




[Qemu-devel] [PATCH net-next v3 1/3] virtio_net: propagate linkspeed/duplex settings from the hypervisor

2018-01-03 Thread Jason Baron via Qemu-devel
The ability to set speed and duplex for virtio_net is useful in various
scenarios as described here:

16032be virtio_net: add ethtool support for set and get of settings

However, it would be nice to be able to set this from the hypervisor,
such that virtio_net doesn't require custom guest ethtool commands.

Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
the hypervisor to export a linkspeed and duplex setting. The user can
subsequently overwrite it later if desired via: 'ethtool -s'.

Note that VIRTIO_NET_F_SPEED_DUPLEX is defined as bit 63, the intention
is that device feature bits are to grow down from bit 63, since the
transports are starting from bit 24 and growing up.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 drivers/net/virtio_net.c| 19 ++-
 include/uapi/linux/virtio_net.h | 13 +
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 6fb7b65..0b2d314 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2146,6 +2146,22 @@ static void virtnet_config_changed_work(struct 
work_struct *work)
 
vi->status = v;
 
+   if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_SPEED_DUPLEX)) {
+   u32 speed;
+   u8 duplex;
+
+   speed = virtio_cread32(vi->vdev,
+  offsetof(struct virtio_net_config,
+   speed));
+   if (ethtool_validate_speed(speed))
+   vi->speed = speed;
+   duplex = virtio_cread8(vi->vdev,
+  offsetof(struct virtio_net_config,
+   duplex));
+   if (ethtool_validate_duplex(duplex))
+   vi->duplex = duplex;
+   }
+
if (vi->status & VIRTIO_NET_S_LINK_UP) {
netif_carrier_on(vi->dev);
netif_tx_wake_all_queues(vi->dev);
@@ -2796,7 +2812,8 @@ static struct virtio_device_id id_table[] = {
VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
VIRTIO_NET_F_CTRL_MAC_ADDR, \
-   VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
+   VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
+   VIRTIO_NET_F_SPEED_DUPLEX
 
 static unsigned int features[] = {
VIRTNET_FEATURES,
diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index fc353b5..5de6ed3 100644
--- a/include/uapi/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
@@ -57,6 +57,8 @@
 * Steering */
 #define VIRTIO_NET_F_CTRL_MAC_ADDR 23  /* Set MAC address */
 
+#define VIRTIO_NET_F_SPEED_DUPLEX 63   /* Device set linkspeed and duplex */
+
 #ifndef VIRTIO_NET_NO_LEGACY
 #define VIRTIO_NET_F_GSO   6   /* Host handles pkts w/ any GSO type */
 #endif /* VIRTIO_NET_NO_LEGACY */
@@ -76,6 +78,17 @@ struct virtio_net_config {
__u16 max_virtqueue_pairs;
/* Default maximum transmit unit advice */
__u16 mtu;
+   /*
+* speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+* Any other value stands for unknown.
+*/
+   __u32 speed;
+   /*
+* 0x00 - half duplex
+* 0x01 - full duplex
+* Any other value stands for unknown.
+*/
+   __u8 duplex;
 } __attribute__((packed));
 
 /*
-- 
2.6.1




[Qemu-devel] [PATCH v3 3/3] qemu: add linkspeed and duplex settings to virtio-net

2018-01-03 Thread Jason Baron via Qemu-devel
Although linkspeed and duplex can be set in a linux guest via 'ethtool -s',
this requires custom ethtool commands for virtio-net by default.

Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
the hypervisor to export a linkspeed and duplex setting. The user can
subsequently overwrite it later if desired via: 'ethtool -s'.

Linkspeed and duplex settings can be set as:
'-device virtio-net,speed=1,duplex=full'

where speed is [-1...INT_MAX], and duplex is ["half"|"full"].

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
Cc: virtio-...@lists.oasis-open.org
---
 hw/net/virtio-net.c | 35 +
 include/hw/virtio/virtio-net.h  |  3 +++
 include/standard-headers/linux/virtio_net.h | 13 +++
 3 files changed, 51 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index adc20df..eec8422 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -40,6 +40,12 @@
 #define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE
 #define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE
 
+/* duplex and speed */
+#define DUPLEX_UNKNOWN  0xff
+#define DUPLEX_HALF 0x00
+#define DUPLEX_FULL 0x01
+#define SPEED_UNKNOWN   -1
+
 /*
  * Calculate the number of bytes up to and including the given 'field' of
  * 'container'.
@@ -61,6 +67,8 @@ static VirtIOFeature feature_sizes[] = {
  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
 {.flags = 1ULL << VIRTIO_NET_F_MTU,
  .end = endof(struct virtio_net_config, mtu)},
+{.flags = 1ULL << VIRTIO_NET_F_SPEED_DUPLEX,
+ .end = endof(struct virtio_net_config, duplex)},
 {}
 };
 
@@ -89,6 +97,14 @@ static void virtio_net_get_config(VirtIODevice *vdev, 
uint8_t *config)
 virtio_stw_p(vdev, _virtqueue_pairs, n->max_queues);
 virtio_stw_p(vdev, , n->net_conf.mtu);
 memcpy(netcfg.mac, n->mac, ETH_ALEN);
+if (n->status & VIRTIO_NET_S_LINK_UP) {
+virtio_stl_p(vdev, , n->net_conf.speed);
+netcfg.duplex = n->net_conf.duplex;
+} else {
+virtio_stl_p(vdev, , SPEED_UNKNOWN);
+netcfg.duplex = DUPLEX_UNKNOWN;
+}
+
 memcpy(config, , n->config_size);
 }
 
@@ -1941,6 +1957,23 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
 }
 
+n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
+if (n->net_conf.duplex_str) {
+if (strncmp(n->net_conf.duplex_str, "half", 5) == 0) {
+n->net_conf.duplex = DUPLEX_HALF;
+} else if (strncmp(n->net_conf.duplex_str, "full", 5) == 0) {
+n->net_conf.duplex = DUPLEX_FULL;
+} else {
+error_setg(errp, "'duplex' must be 'half' or 'full'");
+}
+} else {
+n->net_conf.duplex = DUPLEX_UNKNOWN;
+}
+if (n->net_conf.speed < SPEED_UNKNOWN) {
+error_setg(errp, "'speed' must be between -1 (SPEED_UNKOWN) and "
+   "INT_MAX");
+}
+
 virtio_net_set_config_size(n, n->host_features);
 virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size);
 
@@ -2160,6 +2193,8 @@ static Property virtio_net_properties[] = {
 DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0),
 DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend,
  true),
+DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
+DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index e7634c9..02484dc 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -38,6 +38,9 @@ typedef struct virtio_net_conf
 uint16_t rx_queue_size;
 uint16_t tx_queue_size;
 uint16_t mtu;
+int32_t speed;
+char *duplex_str;
+uint8_t duplex;
 } virtio_net_conf;
 
 /* Maximum packet size we can receive from tap device: header + 64k */
diff --git a/include/standard-headers/linux/virtio_net.h 
b/include/standard-headers/linux/virtio_net.h
index 30ff249..17c8531 100644
--- a/include/standard-headers/linux/virtio_net.h
+++ b/include/standard-headers/linux/virtio_net.h
@@ -57,6 +57,8 @@
 * Steering */
 #define VIRTIO_NET_F_CTRL_MAC_ADDR 23  /* Set MAC address */
 
+#define VIRTIO_NET_F_SPEED_DUPLEX 63   /* Device set linkspeed and duplex */
+
 #ifndef VIRTIO_NET_NO_LEGACY
 #define VIRTIO_NET_F_GSO   6   /* Host handles pkts w/ any GSO type */
 #endif /* VIRTIO_NET_NO_LEGACY */
@@ 

Re: [Qemu-devel] [PATCH net-next v2 1/3] virtio_net: propagate linkspeed/duplex settings from the hypervisor

2017-12-28 Thread Jason Baron via Qemu-devel


On 12/27/2017 04:43 PM, David Miller wrote:
> From: Jason Baron <jba...@akamai.com>
> Date: Fri, 22 Dec 2017 16:54:01 -0500
> 
>> The ability to set speed and duplex for virtio_net in useful in various
>> scenarios as described here:
>>
>> 16032be virtio_net: add ethtool support for set and get of settings
>>
>> However, it would be nice to be able to set this from the hypervisor,
>> such that virtio_net doesn't require custom guest ethtool commands.
>>
>> Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
>> the hypervisor to export a linkspeed and duplex setting. The user can
>> subsequently overwrite it later if desired via: 'ethtool -s'.
>>
>> Signed-off-by: Jason Baron <jba...@akamai.com>
>> Cc: "Michael S. Tsirkin" <m...@redhat.com>
>> Cc: Jason Wang <jasow...@redhat.com>
> 
> Looks mostly fine to me but need some virtio_net reviewers on this one.
> 
>> @@ -57,6 +57,8 @@
>>   * Steering */
>>  #define VIRTIO_NET_F_CTRL_MAC_ADDR 23   /* Set MAC address */
>>  
>> +#define VIRTIO_NET_F_SPEED_DUPLEX 63/* Host set linkspeed and 
>> duplex */
>> +
> 
> Why use a value so far away from the largest existing one?
> 
> Just curious.
> 

So that came from a discussion with Michael about which bit to use for
this, and he suggested using 63:

"
Transports started from bit 24 and are growing up.
So I would say devices should start from bit 63 and grow down.
"

https://patchwork.ozlabs.org/patch/848814/#1826669

I will add a comment to explain it.

Thanks,

-Jason




[Qemu-devel] [PATCH v2 0/3] virtio_net: allow hypervisor to indicate linkspeed and duplex setting

2017-12-22 Thread Jason Baron via Qemu-devel
We have found it useful to be able to set the linkspeed and duplex
settings from the host-side for virtio_net. This obviates the need
for guest changes and settings for these fields, and does not require
custom ethtool commands for virtio_net.

  
The ability to set linkspeed and duplex is useful in various cases
as described here:  
  

  
16032be virtio_net: add ethtool support for set and get of settings 
  

  
Using 'ethtool -s' continues to over-write the linkspeed/duplex 
  
settings with this patch.   
   

  
The 1/3 patch is against net-next, while the 2-3/3 patch are the associated
qemu changes that would go in after as update-linux-headers.sh should
be run first. So the qemu patches are a demonstration of how I intend this
to work.

  
Thanks, 
  

  
-Jason  
  

  
 linux changes: 
  

Jason Baron (1):
  virtio_net: propagate linkspeed/duplex settings from the hypervisor

 drivers/net/virtio_net.c| 17 -
 include/uapi/linux/virtio_net.h |  5 +
 2 files changed, 21 insertions(+), 1 deletion(-)

  

  
 qemu changes:  
  

Jason Baron (2):
  qemu: virtio-net: use 64-bit values for feature flags
  qemu: add linkspeed and duplex settings to virtio-net

 hw/net/virtio-net.c | 83 +++--
 include/hw/virtio/virtio-net.h  |  5 +-
 include/standard-headers/linux/virtio_net.h |  4 ++
 3 files changed, 64 insertions(+), 28 deletions(-)



[Qemu-devel] [PATCH 2/3] qemu: use 64-bit values for feature flags in virtio-net

2017-12-22 Thread Jason Baron via Qemu-devel
In prepartion for using some of the high order feature bits, make sure that
virtio-net uses 64-bit values everywhere.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
---
 hw/net/virtio-net.c| 54 +-
 include/hw/virtio/virtio-net.h |  2 +-
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 38674b0..adc20df 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -48,18 +48,18 @@
 (offsetof(container, field) + sizeof(((container *)0)->field))
 
 typedef struct VirtIOFeature {
-uint32_t flags;
+uint64_t flags;
 size_t end;
 } VirtIOFeature;
 
 static VirtIOFeature feature_sizes[] = {
-{.flags = 1 << VIRTIO_NET_F_MAC,
+{.flags = 1ULL << VIRTIO_NET_F_MAC,
  .end = endof(struct virtio_net_config, mac)},
-{.flags = 1 << VIRTIO_NET_F_STATUS,
+{.flags = 1ULL << VIRTIO_NET_F_STATUS,
  .end = endof(struct virtio_net_config, status)},
-{.flags = 1 << VIRTIO_NET_F_MQ,
+{.flags = 1ULL << VIRTIO_NET_F_MQ,
  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
-{.flags = 1 << VIRTIO_NET_F_MTU,
+{.flags = 1ULL << VIRTIO_NET_F_MTU,
  .end = endof(struct virtio_net_config, mtu)},
 {}
 };
@@ -1938,7 +1938,7 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 int i;
 
 if (n->net_conf.mtu) {
-n->host_features |= (0x1 << VIRTIO_NET_F_MTU);
+n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
 }
 
 virtio_net_set_config_size(n, n->host_features);
@@ -2109,45 +2109,45 @@ static const VMStateDescription vmstate_virtio_net = {
 };
 
 static Property virtio_net_properties[] = {
-DEFINE_PROP_BIT("csum", VirtIONet, host_features, VIRTIO_NET_F_CSUM, true),
-DEFINE_PROP_BIT("guest_csum", VirtIONet, host_features,
+DEFINE_PROP_BIT64("csum", VirtIONet, host_features, VIRTIO_NET_F_CSUM, 
true),
+DEFINE_PROP_BIT64("guest_csum", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_CSUM, true),
-DEFINE_PROP_BIT("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
-DEFINE_PROP_BIT("guest_tso4", VirtIONet, host_features,
+DEFINE_PROP_BIT64("gso", VirtIONet, host_features, VIRTIO_NET_F_GSO, true),
+DEFINE_PROP_BIT64("guest_tso4", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_TSO4, true),
-DEFINE_PROP_BIT("guest_tso6", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_tso6", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_TSO6, true),
-DEFINE_PROP_BIT("guest_ecn", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_ecn", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_ECN, true),
-DEFINE_PROP_BIT("guest_ufo", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_ufo", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_UFO, true),
-DEFINE_PROP_BIT("guest_announce", VirtIONet, host_features,
+DEFINE_PROP_BIT64("guest_announce", VirtIONet, host_features,
 VIRTIO_NET_F_GUEST_ANNOUNCE, true),
-DEFINE_PROP_BIT("host_tso4", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_tso4", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_TSO4, true),
-DEFINE_PROP_BIT("host_tso6", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_tso6", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_TSO6, true),
-DEFINE_PROP_BIT("host_ecn", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_ecn", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_ECN, true),
-DEFINE_PROP_BIT("host_ufo", VirtIONet, host_features,
+DEFINE_PROP_BIT64("host_ufo", VirtIONet, host_features,
 VIRTIO_NET_F_HOST_UFO, true),
-DEFINE_PROP_BIT("mrg_rxbuf", VirtIONet, host_features,
+DEFINE_PROP_BIT64("mrg_rxbuf", VirtIONet, host_features,
 VIRTIO_NET_F_MRG_RXBUF, true),
-DEFINE_PROP_BIT("status", VirtIONet, host_features,
+DEFINE_PROP_BIT64("status", VirtIONet, host_features,
 VIRTIO_NET_F_STATUS, true),
-DEFINE_PROP_BIT("ctrl_vq", VirtIONet, host_features,
+DEFINE_PROP_BIT64("ctrl_vq", VirtIONet, host_features,
 VIRTIO_NET_F_CTRL_VQ, true),
-DEFINE_PROP_BIT("ctrl_rx", VirtIONet, host_features,
+DEFINE_PROP_BIT64("ctrl_rx", VirtIONet, host_features,
 VIRTIO_NET_F_CTRL_RX, true),

[Qemu-devel] [PATCH net-next v2 1/3] virtio_net: propagate linkspeed/duplex settings from the hypervisor

2017-12-22 Thread Jason Baron via Qemu-devel
The ability to set speed and duplex for virtio_net in useful in various
scenarios as described here:

16032be virtio_net: add ethtool support for set and get of settings

However, it would be nice to be able to set this from the hypervisor,
such that virtio_net doesn't require custom guest ethtool commands.

Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
the hypervisor to export a linkspeed and duplex setting. The user can
subsequently overwrite it later if desired via: 'ethtool -s'.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
---
 drivers/net/virtio_net.c| 17 -
 include/uapi/linux/virtio_net.h |  5 +
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 511f833..4168d82 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2621,6 +2621,20 @@ static int virtnet_probe(struct virtio_device *vdev)
netif_set_real_num_rx_queues(dev, vi->curr_queue_pairs);
 
virtnet_init_settings(dev);
+   if (virtio_has_feature(vdev, VIRTIO_NET_F_SPEED_DUPLEX)) {
+   u32 speed;
+   u8 duplex;
+
+   speed = virtio_cread32(vdev, offsetof(struct virtio_net_config,
+  speed));
+   if (ethtool_validate_speed(speed))
+   vi->speed = speed;
+   duplex = virtio_cread8(vdev,
+  offsetof(struct virtio_net_config,
+  duplex));
+   if (ethtool_validate_duplex(duplex))
+   vi->duplex = duplex;
+   }
 
err = register_netdev(dev);
if (err) {
@@ -2746,7 +2760,8 @@ static struct virtio_device_id id_table[] = {
VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
VIRTIO_NET_F_CTRL_MAC_ADDR, \
-   VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
+   VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
+   VIRTIO_NET_F_SPEED_DUPLEX
 
 static unsigned int features[] = {
VIRTNET_FEATURES,
diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index fc353b5..0f1548e 100644
--- a/include/uapi/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
@@ -57,6 +57,8 @@
 * Steering */
 #define VIRTIO_NET_F_CTRL_MAC_ADDR 23  /* Set MAC address */
 
+#define VIRTIO_NET_F_SPEED_DUPLEX 63   /* Host set linkspeed and duplex */
+
 #ifndef VIRTIO_NET_NO_LEGACY
 #define VIRTIO_NET_F_GSO   6   /* Host handles pkts w/ any GSO type */
 #endif /* VIRTIO_NET_NO_LEGACY */
@@ -76,6 +78,9 @@ struct virtio_net_config {
__u16 max_virtqueue_pairs;
/* Default maximum transmit unit advice */
__u16 mtu;
+   /* Host exported linkspeed and duplex */
+   __u32 speed;
+   __u8 duplex;
 } __attribute__((packed));
 
 /*
-- 
2.6.1




[Qemu-devel] [PATCH 3/3] qemu: add linkspeed and duplex settings to virtio-net

2017-12-22 Thread Jason Baron via Qemu-devel
Although linkspeed and duplex can be set in a linux guest via 'ethtool -s',
this requires custom ethtool commands for virtio-net by default.

Introduce a new feature flag, VIRTIO_NET_F_SPEED_DUPLEX, which allows
the hypervisor to export a linkspeed and duplex setting. The user can
subsequently overwrite it later if desired via: 'ethtool -s'.

Linkspeed and duplex settings can be set as:
'-device virtio-net,speed=1,duplex=full'

where speed is [-1...INT_MAX], and duplex is ["half"|"full"].

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
---
 hw/net/virtio-net.c | 29 +
 include/hw/virtio/virtio-net.h  |  3 +++
 include/standard-headers/linux/virtio_net.h |  4 
 3 files changed, 36 insertions(+)
 create mode 16 pixman

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index adc20df..7fafe6e 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -40,6 +40,12 @@
 #define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE
 #define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE
 
+/* duplex and speed defines */
+#define DUPLEX_UNKNOWN  0xff
+#define DUPLEX_HALF 0x00
+#define DUPLEX_FULL 0x01
+#define SPEED_UNKNOWN   -1
+
 /*
  * Calculate the number of bytes up to and including the given 'field' of
  * 'container'.
@@ -61,6 +67,8 @@ static VirtIOFeature feature_sizes[] = {
  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
 {.flags = 1ULL << VIRTIO_NET_F_MTU,
  .end = endof(struct virtio_net_config, mtu)},
+{.flags = 1ULL << VIRTIO_NET_F_SPEED_DUPLEX,
+ .end = endof(struct virtio_net_config, duplex)},
 {}
 };
 
@@ -88,6 +96,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t 
*config)
 virtio_stw_p(vdev, , n->status);
 virtio_stw_p(vdev, _virtqueue_pairs, n->max_queues);
 virtio_stw_p(vdev, , n->net_conf.mtu);
+virtio_stl_p(vdev, , n->net_conf.speed);
+netcfg.duplex = n->net_conf.duplex;
 memcpy(netcfg.mac, n->mac, ETH_ALEN);
 memcpy(config, , n->config_size);
 }
@@ -1941,6 +1951,23 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 n->host_features |= (1ULL << VIRTIO_NET_F_MTU);
 }
 
+n->host_features |= (1ULL << VIRTIO_NET_F_SPEED_DUPLEX);
+if (n->net_conf.duplex_str) {
+if (strncmp(n->net_conf.duplex_str, "half", 5) == 0) {
+n->net_conf.duplex = DUPLEX_HALF;
+} else if (strncmp(n->net_conf.duplex_str, "full", 5) == 0) {
+n->net_conf.duplex = DUPLEX_FULL;
+} else {
+error_setg(errp, "'duplex' must be 'half' or 'full'");
+}
+} else {
+n->net_conf.duplex = DUPLEX_UNKNOWN;
+}
+if (n->net_conf.speed < SPEED_UNKNOWN) {
+error_setg(errp, "'speed' must be between -1 (SPEED_UNKOWN) and "
+   "INT_MAX");
+}
+
 virtio_net_set_config_size(n, n->host_features);
 virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size);
 
@@ -2160,6 +2187,8 @@ static Property virtio_net_properties[] = {
 DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0),
 DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend,
  true),
+DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
+DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index e7634c9..02484dc 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -38,6 +38,9 @@ typedef struct virtio_net_conf
 uint16_t rx_queue_size;
 uint16_t tx_queue_size;
 uint16_t mtu;
+int32_t speed;
+char *duplex_str;
+uint8_t duplex;
 } virtio_net_conf;
 
 /* Maximum packet size we can receive from tap device: header + 64k */
diff --git a/include/standard-headers/linux/virtio_net.h 
b/include/standard-headers/linux/virtio_net.h
index 30ff249..0ff1447 100644
--- a/include/standard-headers/linux/virtio_net.h
+++ b/include/standard-headers/linux/virtio_net.h
@@ -36,6 +36,7 @@
 #define VIRTIO_NET_F_GUEST_CSUM1   /* Guest handles pkts w/ 
partial csum */
 #define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
 #define VIRTIO_NET_F_MTU   3   /* Initial MTU advice */
+#define VIRTIO_NET_F_SPEED_DUPLEX 4/* Host set linkspeed and duplex */
 #define VIRTIO_NET_F_MAC   5   /* Host has given MAC address. */
 #define VIRTIO_NET_F_GUEST_TSO47   /* Guest can handle TSOv4 in. */
 #defi

Re: [Qemu-devel] [PATCH 2/2] qemu: add linkspeed and duplex setting to virtio-net

2017-12-21 Thread Jason Baron via Qemu-devel


On 12/20/2017 09:33 AM, Yan Vugenfirer wrote:
> 
>> On 20 Dec 2017, at 16:31, Michael S. Tsirkin <m...@redhat.com> wrote:
>>
>> On Tue, Dec 19, 2017 at 11:52:39AM -0500, Jason Baron wrote:
>>>
>>>
>>> On 12/19/2017 04:19 AM, Yan Vugenfirer wrote:
>>>>
>>>>> On 18 Dec 2017, at 18:04, Jason Baron via Qemu-devel
>>>>> <qemu-devel@nongnu.org <mailto:qemu-devel@nongnu.org>> wrote:
>>>>>
>>>>>
>>>>>
>>>>> On 12/18/2017 06:34 AM, Yan Vugenfirer wrote:
>>>>>>
>>>>>>> On 14 Dec 2017, at 21:33, Jason Baron via Qemu-devel
>>>>>>> <qemu-devel@nongnu.org <mailto:qemu-devel@nongnu.org>> wrote:
>>>>>>>
>>>>>>> Although they can be currently set in linux via 'ethtool -s', this
>>>>>>> requires
>>>>>>> guest changes, and thus it would be nice to extend this
>>>>>>> functionality such
>>>>>>> that it can be configured automatically from the host (as other network
>>>>>>> do).
>>>>>>>
>>>>>>> Linkspeed and duplex settings can be set as:
>>>>>>> '-device virtio-net,speed=1,duplex=full'
>>>>>>>
>>>>>>> where speed is [-1...INT_MAX], and duplex is ["half"|"full"].
>>>>>>>
>>>>>>> Signed-off-by: Jason Baron <jba...@akamai.com
>>>>>>> <mailto:jba...@akamai.com>>
>>>>>>> Cc: "Michael S. Tsirkin" <m...@redhat.com <mailto:m...@redhat.com>>
>>>>>>> Cc: Jason Wang <jasow...@redhat.com <mailto:jasow...@redhat.com>>
>>>>>>> ---
>>>>>>> hw/net/virtio-net.c | 29
>>>>>>> +
>>>>>>> include/hw/virtio/virtio-net.h  |  3 +++
>>>>>>> include/standard-headers/linux/virtio_net.h |  4 
>>>>>>> 3 files changed, 36 insertions(+)
>>>>>>>
>>>>>>> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
>>>>>>> index 38674b0..d63e790 100644
>>>>>>> --- a/hw/net/virtio-net.c
>>>>>>> +++ b/hw/net/virtio-net.c
>>>>>>> @@ -40,6 +40,12 @@
>>>>>>> #define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE
>>>>>>> #define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE
>>>>>>>
>>>>>>> +/* duplex and speed defines */
>>>>>>> +#define DUPLEX_UNKNOWN  0xff
>>>>>>> +#define DUPLEX_HALF 0x00
>>>>>>> +#define DUPLEX_FULL 0x01
>>>>>>> +#define SPEED_UNKNOWN   -1
>>>>>>> +
>>>>>>> /*
>>>>>>> * Calculate the number of bytes up to and including the given 'field' of
>>>>>>> * 'container'.
>>>>>>> @@ -61,6 +67,8 @@ static VirtIOFeature feature_sizes[] = {
>>>>>>> .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
>>>>>>>{.flags = 1 << VIRTIO_NET_F_MTU,
>>>>>>> .end = endof(struct virtio_net_config, mtu)},
>>>>>>> +{.flags = 1 << VIRTIO_NET_F_SPEED_DUPLEX,
>>>>>>> + .end = endof(struct virtio_net_config, duplex)},
>>>>>>>{}
>>>>>>> };
>>>>>>>
>>>>>>> @@ -88,6 +96,8 @@ static void virtio_net_get_config(VirtIODevice
>>>>>>> *vdev, uint8_t *config)
>>>>>>>virtio_stw_p(vdev, , n->status);
>>>>>>>virtio_stw_p(vdev, _virtqueue_pairs, n->max_queues);
>>>>>>>virtio_stw_p(vdev, , n->net_conf.mtu);
>>>>>>> +virtio_stl_p(vdev, , n->net_conf.speed);
>>>>>>> +netcfg.duplex = n->net_conf.duplex;
>>>>>>>memcpy(netcfg.mac, n->mac, ETH_ALEN);
>>>>>>>memcpy(config, , n->config_size);
>>>>>>> }
>>>>>>> @@ -1941,6 +1951,23 @@ static void
>>>>>>> virtio_net_device_realize(DeviceState *dev, Error **errp)
>>>>>>>n->host_features |= (0x1 << VIRT

Re: [Qemu-devel] [PATCH net-next 1/2] virtio_net: allow hypervisor to indicate linkspeed and duplex setting

2017-12-20 Thread Jason Baron via Qemu-devel


On 12/20/2017 12:52 PM, Michael S. Tsirkin wrote:
> On Wed, Dec 20, 2017 at 12:07:55PM -0500, Jason Baron wrote:
>>
>>
>> On 12/20/2017 09:57 AM, Michael S. Tsirkin wrote:
>>> On Thu, Dec 14, 2017 at 02:33:53PM -0500, Jason Baron wrote:
>>>> If the hypervisor exports the link and duplex speed, let's use that instead
>>>> of the default unknown speed. The user can still overwrite it later if
>>>> desired via: 'ethtool -s'. This allows the hypervisor to set the default
>>>> link speed and duplex setting without requiring guest changes and is
>>>> consistent with how other network drivers operate. We ran into some cases
>>>> where the guest software was failing due to a lack of linkspeed and had to
>>>> fall back to a fully emulated network device that does export a linkspeed
>>>> and duplex setting.
>>>>
>>>> Implement by adding a new VIRTIO_NET_F_SPEED_DUPLEX feature flag, to
>>>> indicate that a linkspeed and duplex setting are present.
>>>>
>>>> Signed-off-by: Jason Baron <jba...@akamai.com>
>>>> Cc: "Michael S. Tsirkin" <m...@redhat.com>
>>>> Cc: Jason Wang <jasow...@redhat.com>
>>>> ---
>>>>  drivers/net/virtio_net.c| 11 ++-
>>>>  include/uapi/linux/virtio_net.h |  4 
>>>>  2 files changed, 14 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
>>>> index 6fb7b65..e7a2ad6 100644
>>>> --- a/drivers/net/virtio_net.c
>>>> +++ b/drivers/net/virtio_net.c
>>>> @@ -2671,6 +2671,14 @@ static int virtnet_probe(struct virtio_device *vdev)
>>>>netif_set_real_num_rx_queues(dev, vi->curr_queue_pairs);
>>>>  
>>>>virtnet_init_settings(dev);
>>>> +  if (virtio_has_feature(vdev, VIRTIO_NET_F_SPEED_DUPLEX)) {
>>>> +  vi->speed = virtio_cread32(vdev,
>>>> +  offsetof(struct virtio_net_config,
>>>> +  speed));
>>>> +  vi->duplex = virtio_cread8(vdev,
>>>> +  offsetof(struct virtio_net_config,
>>>> +  duplex));
>>>> +  }
>>>>  
>>>>err = register_netdev(dev);
>>>>if (err) {
>>>
>>> How are we going to validate speed values? Imagine host
>>> using a new 1000Gbit device and exposing that to guest.
>>>
>>> Need to think what do we want guest to do.
>>> I think that ideally we'd say it's a 100Gbit device.
>>>
>>> For duplex, force to one of 3 valid values?
>>
>> So I didn't provide validation here b/c as you point out its not clear
>> how we would validate it. I don't believe h/w drivers do any validation
>> here either.
> 
> Right but hardware tends not to change as quickly as the hypervisors :)
> For virtual device drivers, we need some way to handle forward
> compatibility since hypervisors do change quite quickly.
> 
>> They simply propagate the value from the the underlying
>> device. So that seemed reasonable to me.
>>
>> Why do you divide by 10 in the above example? Would you propose always
>> dividing what the device reports by 10?
> 
> No, that was just an example. I was just suggesting rounding down to
> next valid known speed.

I see, but virtio currently uses ethtool_validate_speed() which allows
arbitrary values up to INT_MAX in units of Mbps. That seems to leave
plenty of headroom. So I could use that function for validation as well
as well as ethtool_validate_duplex() and if they fail fall back to
SPEED_UNKNOWN and DUPLEX_UNKNOWN?

> 
>>>
>>>
>>>> @@ -2796,7 +2804,8 @@ static struct virtio_device_id id_table[] = {
>>>>VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
>>>>VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
>>>>VIRTIO_NET_F_CTRL_MAC_ADDR, \
>>>> -  VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
>>>> +  VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
>>>> +  VIRTIO_NET_F_SPEED_DUPLEX
>>>>  
>>>>  static unsigned int features[] = {
>>>>VIRTNET_FEATURES,
>>>> diff --git a/include/uapi/linux/virtio_net.h 
>>>> b/include/uapi/linux/virtio_net.h
>>>> index fc353b5..acfcf68 100644
>>>> --- a/include/uapi/linux/virtio_net.h
>>>> +++ b/include/uapi/linux/virtio_net.h
>>>> 

Re: [Qemu-devel] [PATCH net-next 1/2] virtio_net: allow hypervisor to indicate linkspeed and duplex setting

2017-12-20 Thread Jason Baron via Qemu-devel


On 12/20/2017 09:57 AM, Michael S. Tsirkin wrote:
> On Thu, Dec 14, 2017 at 02:33:53PM -0500, Jason Baron wrote:
>> If the hypervisor exports the link and duplex speed, let's use that instead
>> of the default unknown speed. The user can still overwrite it later if
>> desired via: 'ethtool -s'. This allows the hypervisor to set the default
>> link speed and duplex setting without requiring guest changes and is
>> consistent with how other network drivers operate. We ran into some cases
>> where the guest software was failing due to a lack of linkspeed and had to
>> fall back to a fully emulated network device that does export a linkspeed
>> and duplex setting.
>>
>> Implement by adding a new VIRTIO_NET_F_SPEED_DUPLEX feature flag, to
>> indicate that a linkspeed and duplex setting are present.
>>
>> Signed-off-by: Jason Baron <jba...@akamai.com>
>> Cc: "Michael S. Tsirkin" <m...@redhat.com>
>> Cc: Jason Wang <jasow...@redhat.com>
>> ---
>>  drivers/net/virtio_net.c| 11 ++-
>>  include/uapi/linux/virtio_net.h |  4 
>>  2 files changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
>> index 6fb7b65..e7a2ad6 100644
>> --- a/drivers/net/virtio_net.c
>> +++ b/drivers/net/virtio_net.c
>> @@ -2671,6 +2671,14 @@ static int virtnet_probe(struct virtio_device *vdev)
>>  netif_set_real_num_rx_queues(dev, vi->curr_queue_pairs);
>>  
>>  virtnet_init_settings(dev);
>> +if (virtio_has_feature(vdev, VIRTIO_NET_F_SPEED_DUPLEX)) {
>> +vi->speed = virtio_cread32(vdev,
>> +offsetof(struct virtio_net_config,
>> +speed));
>> +vi->duplex = virtio_cread8(vdev,
>> +offsetof(struct virtio_net_config,
>> +duplex));
>> +}
>>  
>>  err = register_netdev(dev);
>>  if (err) {
> 
> How are we going to validate speed values? Imagine host
> using a new 1000Gbit device and exposing that to guest.
> 
> Need to think what do we want guest to do.
> I think that ideally we'd say it's a 100Gbit device.
> 
> For duplex, force to one of 3 valid values?

So I didn't provide validation here b/c as you point out its not clear
how we would validate it. I don't believe h/w drivers do any validation
here either. They simply propagate the value from the the underlying
device. So that seemed reasonable to me.

Why do you divide by 10 in the above example? Would you propose always
dividing what the device reports by 10?

> 
> 
>> @@ -2796,7 +2804,8 @@ static struct virtio_device_id id_table[] = {
>>  VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
>>  VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
>>  VIRTIO_NET_F_CTRL_MAC_ADDR, \
>> -VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
>> +VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
>> +VIRTIO_NET_F_SPEED_DUPLEX
>>  
>>  static unsigned int features[] = {
>>  VIRTNET_FEATURES,
>> diff --git a/include/uapi/linux/virtio_net.h 
>> b/include/uapi/linux/virtio_net.h
>> index fc353b5..acfcf68 100644
>> --- a/include/uapi/linux/virtio_net.h
>> +++ b/include/uapi/linux/virtio_net.h
>> @@ -36,6 +36,7 @@
>>  #define VIRTIO_NET_F_GUEST_CSUM 1   /* Guest handles pkts w/ 
>> partial csum */
>>  #define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload 
>> configuration. */
>>  #define VIRTIO_NET_F_MTU3   /* Initial MTU advice */
>> +#define VIRTIO_NET_F_SPEED_DUPLEX 4 /* Host set linkspeed and duplex */
>>  #define VIRTIO_NET_F_MAC5   /* Host has given MAC address. */
>>  #define VIRTIO_NET_F_GUEST_TSO4 7   /* Guest can handle TSOv4 in. */
>>  #define VIRTIO_NET_F_GUEST_TSO6 8   /* Guest can handle TSOv6 in. */
> 
> I think I'd prefer a high feature bit - low bits are ones that can
> be backported to legacy interfaces, so I think we should hang on to
> these for fixing issues that break communication completely (like the
> mtu).
> 

So I went with a low bit here b/c in the virtio spec 'section 2.2
Feature Bits':


 0 to 23
Feature bits for the specific device type
24 to 32
Feature bits reserved for extensions to the queue and feature
negotiation mechanisms
33 and above
Feature bits reserved for future extensions.

So virtio_net already goes up to 23 (but omits 4 and 6), and I wasn't
sure if it was reasonable to use the higher bits. It looks like the code
would handle the higher bits ok, so I can try that - bit 33 perhaps ?

Thanks,

-Jason


> 
>> @@ -76,6 +77,9 @@ struct virtio_net_config {
>>  __u16 max_virtqueue_pairs;
>>  /* Default maximum transmit unit advice */
>>  __u16 mtu;
>> +/* Host exported linkspeed and duplex */
>> +__u32 speed;
>> +__u8 duplex;
>>  } __attribute__((packed));
>>  
>>  /*
>> -- 
>> 2.6.1



Re: [Qemu-devel] [PATCH 2/2] qemu: add linkspeed and duplex setting to virtio-net

2017-12-19 Thread Jason Baron via Qemu-devel


On 12/19/2017 04:19 AM, Yan Vugenfirer wrote:
> 
>> On 18 Dec 2017, at 18:04, Jason Baron via Qemu-devel
>> <qemu-devel@nongnu.org <mailto:qemu-devel@nongnu.org>> wrote:
>>
>>
>>
>> On 12/18/2017 06:34 AM, Yan Vugenfirer wrote:
>>>
>>>> On 14 Dec 2017, at 21:33, Jason Baron via Qemu-devel
>>>> <qemu-devel@nongnu.org <mailto:qemu-devel@nongnu.org>> wrote:
>>>>
>>>> Although they can be currently set in linux via 'ethtool -s', this
>>>> requires
>>>> guest changes, and thus it would be nice to extend this
>>>> functionality such
>>>> that it can be configured automatically from the host (as other network
>>>> do).
>>>>
>>>> Linkspeed and duplex settings can be set as:
>>>> '-device virtio-net,speed=1,duplex=full'
>>>>
>>>> where speed is [-1...INT_MAX], and duplex is ["half"|"full"].
>>>>
>>>> Signed-off-by: Jason Baron <jba...@akamai.com
>>>> <mailto:jba...@akamai.com>>
>>>> Cc: "Michael S. Tsirkin" <m...@redhat.com <mailto:m...@redhat.com>>
>>>> Cc: Jason Wang <jasow...@redhat.com <mailto:jasow...@redhat.com>>
>>>> ---
>>>> hw/net/virtio-net.c | 29
>>>> +
>>>> include/hw/virtio/virtio-net.h  |  3 +++
>>>> include/standard-headers/linux/virtio_net.h |  4 
>>>> 3 files changed, 36 insertions(+)
>>>>
>>>> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
>>>> index 38674b0..d63e790 100644
>>>> --- a/hw/net/virtio-net.c
>>>> +++ b/hw/net/virtio-net.c
>>>> @@ -40,6 +40,12 @@
>>>> #define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE
>>>> #define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE
>>>>
>>>> +/* duplex and speed defines */
>>>> +#define DUPLEX_UNKNOWN  0xff
>>>> +#define DUPLEX_HALF 0x00
>>>> +#define DUPLEX_FULL 0x01
>>>> +#define SPEED_UNKNOWN   -1
>>>> +
>>>> /*
>>>> * Calculate the number of bytes up to and including the given 'field' of
>>>> * 'container'.
>>>> @@ -61,6 +67,8 @@ static VirtIOFeature feature_sizes[] = {
>>>> .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
>>>>    {.flags = 1 << VIRTIO_NET_F_MTU,
>>>> .end = endof(struct virtio_net_config, mtu)},
>>>> +    {.flags = 1 << VIRTIO_NET_F_SPEED_DUPLEX,
>>>> + .end = endof(struct virtio_net_config, duplex)},
>>>>    {}
>>>> };
>>>>
>>>> @@ -88,6 +96,8 @@ static void virtio_net_get_config(VirtIODevice
>>>> *vdev, uint8_t *config)
>>>>    virtio_stw_p(vdev, , n->status);
>>>>    virtio_stw_p(vdev, _virtqueue_pairs, n->max_queues);
>>>>    virtio_stw_p(vdev, , n->net_conf.mtu);
>>>> +    virtio_stl_p(vdev, , n->net_conf.speed);
>>>> +    netcfg.duplex = n->net_conf.duplex;
>>>>    memcpy(netcfg.mac, n->mac, ETH_ALEN);
>>>>    memcpy(config, , n->config_size);
>>>> }
>>>> @@ -1941,6 +1951,23 @@ static void
>>>> virtio_net_device_realize(DeviceState *dev, Error **errp)
>>>>    n->host_features |= (0x1 << VIRTIO_NET_F_MTU);
>>>>    }
>>>>
>>>> +    n->host_features |= (0x1 << VIRTIO_NET_F_SPEED_DUPLEX);
>>>> +    if (n->net_conf.duplex_str) {
>>>> +    if (strncmp(n->net_conf.duplex_str, "half", 5) == 0) {
>>>> +    n->net_conf.duplex = DUPLEX_HALF;
>>>> +    } else if (strncmp(n->net_conf.duplex_str, "full", 5) == 0) {
>>>> +    n->net_conf.duplex = DUPLEX_FULL;
>>>> +    } else {
>>>> +    error_setg(errp, "'duplex' must be 'half' or 'full'");
>>>> +    }
>>>> +    } else {
>>>> +    n->net_conf.duplex = DUPLEX_UNKNOWN;
>>>> +    }
>>>> +    if (n->net_conf.speed < SPEED_UNKNOWN) {
>>>> +    error_setg(errp, "'speed' must be between -1
>>>> (SPEED_UNKOWN) and "
>>>> +   "INT_MAX");
>>>> +    }
>>>> +
>>>>

Re: [Qemu-devel] [PATCH 2/2] qemu: add linkspeed and duplex setting to virtio-net

2017-12-18 Thread Jason Baron via Qemu-devel


On 12/18/2017 06:34 AM, Yan Vugenfirer wrote:
> 
>> On 14 Dec 2017, at 21:33, Jason Baron via Qemu-devel <qemu-devel@nongnu.org> 
>> wrote:
>>
>> Although they can be currently set in linux via 'ethtool -s', this requires
>> guest changes, and thus it would be nice to extend this functionality such
>> that it can be configured automatically from the host (as other network
>> do).
>>
>> Linkspeed and duplex settings can be set as:
>> '-device virtio-net,speed=1,duplex=full'
>>
>> where speed is [-1...INT_MAX], and duplex is ["half"|"full"].
>>
>> Signed-off-by: Jason Baron <jba...@akamai.com>
>> Cc: "Michael S. Tsirkin" <m...@redhat.com>
>> Cc: Jason Wang <jasow...@redhat.com>
>> ---
>> hw/net/virtio-net.c | 29 
>> +
>> include/hw/virtio/virtio-net.h  |  3 +++
>> include/standard-headers/linux/virtio_net.h |  4 
>> 3 files changed, 36 insertions(+)
>>
>> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
>> index 38674b0..d63e790 100644
>> --- a/hw/net/virtio-net.c
>> +++ b/hw/net/virtio-net.c
>> @@ -40,6 +40,12 @@
>> #define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE
>> #define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE
>>
>> +/* duplex and speed defines */
>> +#define DUPLEX_UNKNOWN  0xff
>> +#define DUPLEX_HALF 0x00
>> +#define DUPLEX_FULL 0x01
>> +#define SPEED_UNKNOWN   -1
>> +
>> /*
>>  * Calculate the number of bytes up to and including the given 'field' of
>>  * 'container'.
>> @@ -61,6 +67,8 @@ static VirtIOFeature feature_sizes[] = {
>>  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
>> {.flags = 1 << VIRTIO_NET_F_MTU,
>>  .end = endof(struct virtio_net_config, mtu)},
>> +{.flags = 1 << VIRTIO_NET_F_SPEED_DUPLEX,
>> + .end = endof(struct virtio_net_config, duplex)},
>> {}
>> };
>>
>> @@ -88,6 +96,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, 
>> uint8_t *config)
>> virtio_stw_p(vdev, , n->status);
>> virtio_stw_p(vdev, _virtqueue_pairs, n->max_queues);
>> virtio_stw_p(vdev, , n->net_conf.mtu);
>> +virtio_stl_p(vdev, , n->net_conf.speed);
>> +netcfg.duplex = n->net_conf.duplex;
>> memcpy(netcfg.mac, n->mac, ETH_ALEN);
>> memcpy(config, , n->config_size);
>> }
>> @@ -1941,6 +1951,23 @@ static void virtio_net_device_realize(DeviceState 
>> *dev, Error **errp)
>> n->host_features |= (0x1 << VIRTIO_NET_F_MTU);
>> }
>>
>> +n->host_features |= (0x1 << VIRTIO_NET_F_SPEED_DUPLEX);
>> +if (n->net_conf.duplex_str) {
>> +if (strncmp(n->net_conf.duplex_str, "half", 5) == 0) {
>> +n->net_conf.duplex = DUPLEX_HALF;
>> +} else if (strncmp(n->net_conf.duplex_str, "full", 5) == 0) {
>> +n->net_conf.duplex = DUPLEX_FULL;
>> +} else {
>> +error_setg(errp, "'duplex' must be 'half' or 'full'");
>> +}
>> +} else {
>> +n->net_conf.duplex = DUPLEX_UNKNOWN;
>> +}
>> +if (n->net_conf.speed < SPEED_UNKNOWN) {
>> +error_setg(errp, "'speed' must be between -1 (SPEED_UNKOWN) and 
>> "
>> +   "INT_MAX");
>> +}
>> +
>> virtio_net_set_config_size(n, n->host_features);
>> virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size);
>>
>> @@ -2160,6 +2187,8 @@ static Property virtio_net_properties[] = {
>> DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0),
>> DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend,
>>  true),
>> +DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
> 
> From Windows guest perspective I prefer to have some reasonable default (10G 
> for example). 


hmmm, I didn't want to change/set the default here in case it broke
something, but I'm ok setting it to some 'reasonable' value - (10G and
duplex?), if the consensus is that that would be safe.

Thanks,

-Jason

> 
> Thanks,
> Yan.
> 
>> +DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
>> DEFINE_PROP_END_OF_LIST(),
>> };
>>
>> diff --git a/include/hw/vir

[Qemu-devel] [PATCH net-next 1/2] virtio_net: allow hypervisor to indicate linkspeed and duplex setting

2017-12-14 Thread Jason Baron via Qemu-devel
If the hypervisor exports the link and duplex speed, let's use that instead
of the default unknown speed. The user can still overwrite it later if
desired via: 'ethtool -s'. This allows the hypervisor to set the default
link speed and duplex setting without requiring guest changes and is
consistent with how other network drivers operate. We ran into some cases
where the guest software was failing due to a lack of linkspeed and had to
fall back to a fully emulated network device that does export a linkspeed
and duplex setting.

Implement by adding a new VIRTIO_NET_F_SPEED_DUPLEX feature flag, to
indicate that a linkspeed and duplex setting are present.

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
---
 drivers/net/virtio_net.c| 11 ++-
 include/uapi/linux/virtio_net.h |  4 
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 6fb7b65..e7a2ad6 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2671,6 +2671,14 @@ static int virtnet_probe(struct virtio_device *vdev)
netif_set_real_num_rx_queues(dev, vi->curr_queue_pairs);
 
virtnet_init_settings(dev);
+   if (virtio_has_feature(vdev, VIRTIO_NET_F_SPEED_DUPLEX)) {
+   vi->speed = virtio_cread32(vdev,
+   offsetof(struct virtio_net_config,
+   speed));
+   vi->duplex = virtio_cread8(vdev,
+   offsetof(struct virtio_net_config,
+   duplex));
+   }
 
err = register_netdev(dev);
if (err) {
@@ -2796,7 +2804,8 @@ static struct virtio_device_id id_table[] = {
VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
VIRTIO_NET_F_CTRL_MAC_ADDR, \
-   VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS
+   VIRTIO_NET_F_MTU, VIRTIO_NET_F_CTRL_GUEST_OFFLOADS, \
+   VIRTIO_NET_F_SPEED_DUPLEX
 
 static unsigned int features[] = {
VIRTNET_FEATURES,
diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h
index fc353b5..acfcf68 100644
--- a/include/uapi/linux/virtio_net.h
+++ b/include/uapi/linux/virtio_net.h
@@ -36,6 +36,7 @@
 #define VIRTIO_NET_F_GUEST_CSUM1   /* Guest handles pkts w/ 
partial csum */
 #define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
 #define VIRTIO_NET_F_MTU   3   /* Initial MTU advice */
+#define VIRTIO_NET_F_SPEED_DUPLEX 4/* Host set linkspeed and duplex */
 #define VIRTIO_NET_F_MAC   5   /* Host has given MAC address. */
 #define VIRTIO_NET_F_GUEST_TSO47   /* Guest can handle TSOv4 in. */
 #define VIRTIO_NET_F_GUEST_TSO68   /* Guest can handle TSOv6 in. */
@@ -76,6 +77,9 @@ struct virtio_net_config {
__u16 max_virtqueue_pairs;
/* Default maximum transmit unit advice */
__u16 mtu;
+   /* Host exported linkspeed and duplex */
+   __u32 speed;
+   __u8 duplex;
 } __attribute__((packed));
 
 /*
-- 
2.6.1




[Qemu-devel] [PATCH 2/2] qemu: add linkspeed and duplex setting to virtio-net

2017-12-14 Thread Jason Baron via Qemu-devel
Although they can be currently set in linux via 'ethtool -s', this requires
guest changes, and thus it would be nice to extend this functionality such
that it can be configured automatically from the host (as other network
do).

Linkspeed and duplex settings can be set as:
'-device virtio-net,speed=1,duplex=full'

where speed is [-1...INT_MAX], and duplex is ["half"|"full"].

Signed-off-by: Jason Baron <jba...@akamai.com>
Cc: "Michael S. Tsirkin" <m...@redhat.com>
Cc: Jason Wang <jasow...@redhat.com>
---
 hw/net/virtio-net.c | 29 +
 include/hw/virtio/virtio-net.h  |  3 +++
 include/standard-headers/linux/virtio_net.h |  4 
 3 files changed, 36 insertions(+)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 38674b0..d63e790 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -40,6 +40,12 @@
 #define VIRTIO_NET_RX_QUEUE_MIN_SIZE VIRTIO_NET_RX_QUEUE_DEFAULT_SIZE
 #define VIRTIO_NET_TX_QUEUE_MIN_SIZE VIRTIO_NET_TX_QUEUE_DEFAULT_SIZE
 
+/* duplex and speed defines */
+#define DUPLEX_UNKNOWN  0xff
+#define DUPLEX_HALF 0x00
+#define DUPLEX_FULL 0x01
+#define SPEED_UNKNOWN   -1
+
 /*
  * Calculate the number of bytes up to and including the given 'field' of
  * 'container'.
@@ -61,6 +67,8 @@ static VirtIOFeature feature_sizes[] = {
  .end = endof(struct virtio_net_config, max_virtqueue_pairs)},
 {.flags = 1 << VIRTIO_NET_F_MTU,
  .end = endof(struct virtio_net_config, mtu)},
+{.flags = 1 << VIRTIO_NET_F_SPEED_DUPLEX,
+ .end = endof(struct virtio_net_config, duplex)},
 {}
 };
 
@@ -88,6 +96,8 @@ static void virtio_net_get_config(VirtIODevice *vdev, uint8_t 
*config)
 virtio_stw_p(vdev, , n->status);
 virtio_stw_p(vdev, _virtqueue_pairs, n->max_queues);
 virtio_stw_p(vdev, , n->net_conf.mtu);
+virtio_stl_p(vdev, , n->net_conf.speed);
+netcfg.duplex = n->net_conf.duplex;
 memcpy(netcfg.mac, n->mac, ETH_ALEN);
 memcpy(config, , n->config_size);
 }
@@ -1941,6 +1951,23 @@ static void virtio_net_device_realize(DeviceState *dev, 
Error **errp)
 n->host_features |= (0x1 << VIRTIO_NET_F_MTU);
 }
 
+n->host_features |= (0x1 << VIRTIO_NET_F_SPEED_DUPLEX);
+if (n->net_conf.duplex_str) {
+if (strncmp(n->net_conf.duplex_str, "half", 5) == 0) {
+n->net_conf.duplex = DUPLEX_HALF;
+} else if (strncmp(n->net_conf.duplex_str, "full", 5) == 0) {
+n->net_conf.duplex = DUPLEX_FULL;
+} else {
+error_setg(errp, "'duplex' must be 'half' or 'full'");
+}
+} else {
+n->net_conf.duplex = DUPLEX_UNKNOWN;
+}
+if (n->net_conf.speed < SPEED_UNKNOWN) {
+error_setg(errp, "'speed' must be between -1 (SPEED_UNKOWN) and "
+   "INT_MAX");
+}
+
 virtio_net_set_config_size(n, n->host_features);
 virtio_init(vdev, "virtio-net", VIRTIO_ID_NET, n->config_size);
 
@@ -2160,6 +2187,8 @@ static Property virtio_net_properties[] = {
 DEFINE_PROP_UINT16("host_mtu", VirtIONet, net_conf.mtu, 0),
 DEFINE_PROP_BOOL("x-mtu-bypass-backend", VirtIONet, mtu_bypass_backend,
  true),
+DEFINE_PROP_INT32("speed", VirtIONet, net_conf.speed, SPEED_UNKNOWN),
+DEFINE_PROP_STRING("duplex", VirtIONet, net_conf.duplex_str),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index b81b6a4..af74a94 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -38,6 +38,9 @@ typedef struct virtio_net_conf
 uint16_t rx_queue_size;
 uint16_t tx_queue_size;
 uint16_t mtu;
+int32_t speed;
+char *duplex_str;
+uint8_t duplex;
 } virtio_net_conf;
 
 /* Maximum packet size we can receive from tap device: header + 64k */
diff --git a/include/standard-headers/linux/virtio_net.h 
b/include/standard-headers/linux/virtio_net.h
index 30ff249..0ff1447 100644
--- a/include/standard-headers/linux/virtio_net.h
+++ b/include/standard-headers/linux/virtio_net.h
@@ -36,6 +36,7 @@
 #define VIRTIO_NET_F_GUEST_CSUM1   /* Guest handles pkts w/ 
partial csum */
 #define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
 #define VIRTIO_NET_F_MTU   3   /* Initial MTU advice */
+#define VIRTIO_NET_F_SPEED_DUPLEX 4/* Host set linkspeed and duplex */
 #define VIRTIO_NET_F_MAC   5   /* Host has given MAC address. */
 #define VIRTIO_NET_F_GUEST_TSO47   /* Guest can handle TSOv4 in. */
 #define VIRTIO_NET_F_GUEST_TSO68   /* Guest can handle TSOv6 in. */
@@ -76,6 +77,9 @@ struct virtio_net_config {
uint16_t max_virtqueue_pairs;
/* Default maximum transmit unit advice */
uint16_t mtu;
+   /* Host exported linkspeed and duplex */
+   uint32_t speed;
+   uint8_t duplex;
 } QEMU_PACKED;
 
 /*
-- 
2.6.1




[Qemu-devel] [PATCH 0/2] virtio_net: allow hypervisor to indicate linkspeed and duplex setting

2017-12-14 Thread Jason Baron via Qemu-devel
We have found it useful to be able to set the linkspeed and duplex
settings from the host-side for virtio_net. This obviates the need
for guest changes and settings for these fields.

The ability to set linkspeed and duplex was introduced by:

16032be virtio_net: add ethtool support for set and get of settings

And using 'ethtool -s' continues to over-write the linkspeed/duplex
settings with this patch.

The 1/2 patch is against net-next, while the 2/2 patch is the associated
qemu changes that would go in after as update-linux-headers.sh should
be run first. So 2/2 is more meant as a demonstration of how I intend this
to work.

Thanks,

-Jason

Jason Baron (2):
  virtio_net: allow hypervisor to indicate linkspeed and duplex setting
  qemu: add linkspeed and duplex setting to virtio-net

 linux changes:

 drivers/net/virtio_net.c| 11 ++-
 include/uapi/linux/virtio_net.h |  4 
 2 files changed, 14 insertions(+), 1 deletion(-)

 qemu changes:

 hw/net/virtio-net.c | 29 + 
   
 include/hw/virtio/virtio-net.h  |  3 +++   
   
 include/standard-headers/linux/virtio_net.h |  4   
   
 3 files changed, 36 insertions(+)  

-- 
2.6.1




[Qemu-devel] [PATCH v3 1/2] ahci: remove unused AHCIDevice fields

2013-01-04 Thread Jason Baron
From: Jason Baron jba...@redhat.com

'dma_status' and 'dma_cb' are written to, but never read.
Remove these fields in preparation for AHCI migration bits.

Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/ide/ahci.c |8 ++--
 hw/ide/ahci.h |2 --
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index d072449..72cd1c8 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1035,11 +1035,10 @@ out:
 static void ahci_start_dma(IDEDMA *dma, IDEState *s,
BlockDriverCompletionFunc *dma_cb)
 {
+#ifdef DEBUG_AHCI
 AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
-
+#endif
 DPRINTF(ad-port_no, \n);
-ad-dma_cb = dma_cb;
-ad-dma_status |= BM_STATUS_DMAING;
 s-io_buffer_offset = 0;
 dma_cb(s, 0);
 }
@@ -1095,7 +1094,6 @@ static int ahci_dma_set_unit(IDEDMA *dma, int unit)
 static int ahci_dma_add_status(IDEDMA *dma, int status)
 {
 AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
-ad-dma_status |= status;
 DPRINTF(ad-port_no, set status: %x\n, status);
 
 if (status  BM_STATUS_INT) {
@@ -1114,8 +1112,6 @@ static int ahci_dma_set_inactive(IDEDMA *dma)
 /* update d2h status */
 ahci_write_fis_d2h(ad, NULL);
 
-ad-dma_cb = NULL;
-
 if (!ad-check_bh) {
 /* maybe we still have something to process, check later */
 ad-check_bh = qemu_bh_new(ahci_check_cmd_bh, ad);
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index 1200a56..735b379 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -281,11 +281,9 @@ struct AHCIDevice {
 QEMUBH *check_bh;
 uint8_t *lst;
 uint8_t *res_fis;
-int dma_status;
 int done_atapi_packet;
 int busy_slot;
 int init_d2h_sent;
-BlockDriverCompletionFunc *dma_cb;
 AHCICmdHdr *cur_cmd;
 NCQTransferState ncq_tfs[AHCI_MAX_CMDS];
 };
-- 
1.7.1




[Qemu-devel] [PATCH v3 0/2] add ahci migration

2013-01-04 Thread Jason Baron
Hi,

Add migration bits for ahci. This allows q35 to be migratable. I also
have been working on some qtest migration tests, to show that this does
something. I will re-post those separately.

Thanks,

-Jason

Jason Baron (2):
  ahci: remove unused AHCIDevice fields
  ahci: add migration support

 hw/ide/ahci.c |   88 
 hw/ide/ahci.h |   12 ++-
 hw/ide/ich.c  |   11 +--
 3 files changed, 99 insertions(+), 12 deletions(-)




[Qemu-devel] [PATCH v3 2/2] ahci: add migration support

2013-01-04 Thread Jason Baron
From: Jason Baron jba...@redhat.com

I've tested these patches by migrating Windows 7 and Fedora 17 guests (while
uunder i/o) on both piix with ahci attached and on q35 (which has a built-in
ahci controller).

Changes from v2:
 -migrate all relevant ahci fields
 -flush any pending i/o in 'post_load'

Changes from v1:
 -extend Andreas Färber's patch

Signed-off-by: Jason Baron jba...@redhat.com
Signed-off-by: Andreas Färber afaer...@suse.de
Cc: Alexander Graf ag...@suse.de
Cc: Kevin Wolf kw...@redhat.com
Cc: Juan Quintela quint...@redhat.com
Cc: Igor Mitsyanko i.mitsya...@samsung.com
---
 hw/ide/ahci.c |   80 -
 hw/ide/ahci.h |   10 +++
 hw/ide/ich.c  |   11 +--
 3 files changed, 97 insertions(+), 4 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 72cd1c8..96f224b 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1199,6 +1199,81 @@ void ahci_reset(AHCIState *s)
 }
 }
 
+static const VMStateDescription vmstate_ahci_device = {
+.name = ahci port,
+.version_id = 1,
+.fields = (VMStateField []) {
+VMSTATE_IDE_BUS(port, AHCIDevice),
+VMSTATE_UINT32(port_state, AHCIDevice),
+VMSTATE_UINT32(finished, AHCIDevice),
+VMSTATE_UINT32(port_regs.lst_addr, AHCIDevice),
+VMSTATE_UINT32(port_regs.lst_addr_hi, AHCIDevice),
+VMSTATE_UINT32(port_regs.fis_addr, AHCIDevice),
+VMSTATE_UINT32(port_regs.fis_addr_hi, AHCIDevice),
+VMSTATE_UINT32(port_regs.irq_stat, AHCIDevice),
+VMSTATE_UINT32(port_regs.irq_mask, AHCIDevice),
+VMSTATE_UINT32(port_regs.cmd, AHCIDevice),
+VMSTATE_UINT32(port_regs.tfdata, AHCIDevice),
+VMSTATE_UINT32(port_regs.sig, AHCIDevice),
+VMSTATE_UINT32(port_regs.scr_stat, AHCIDevice),
+VMSTATE_UINT32(port_regs.scr_ctl, AHCIDevice),
+VMSTATE_UINT32(port_regs.scr_err, AHCIDevice),
+VMSTATE_UINT32(port_regs.scr_act, AHCIDevice),
+VMSTATE_UINT32(port_regs.cmd_issue, AHCIDevice),
+VMSTATE_INT32(done_atapi_packet, AHCIDevice),
+VMSTATE_INT32(busy_slot, AHCIDevice),
+VMSTATE_INT32(init_d2h_sent, AHCIDevice),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static int ahci_state_post_load(void *opaque, int version_id)
+{
+int i;
+struct AHCIDevice *ad;
+AHCIState *s = opaque;
+
+for (i = 0; i  s-ports; i++) {
+ad = s-dev[i];
+AHCIPortRegs *pr = ad-port_regs;
+
+map_page(ad-lst,
+ ((uint64_t)pr-lst_addr_hi  32) | pr-lst_addr, 1024);
+map_page(ad-res_fis,
+ ((uint64_t)pr-fis_addr_hi  32) | pr-fis_addr, 256);
+/*
+ * All pending i/o should be flushed out on a migrate. However,
+ * we might not have cleared the busy_slot since this is done
+ * in a bh. Also, issue i/o against any slots that are pending.
+ */
+if (ad-busy_slot != -1) {
+pr-cmd_issue = ~(1  ad-busy_slot);
+ad-busy_slot = -1;
+}
+check_cmd(s, i);
+}
+
+return 0;
+}
+
+const VMStateDescription vmstate_ahci = {
+.name = ahci,
+.version_id = 1,
+.post_load = ahci_state_post_load,
+.fields = (VMStateField []) {
+VMSTATE_STRUCT_VARRAY_POINTER_INT32(dev, AHCIState, ports,
+ vmstate_ahci_device, AHCIDevice),
+VMSTATE_UINT32(control_regs.cap, AHCIState),
+VMSTATE_UINT32(control_regs.ghc, AHCIState),
+VMSTATE_UINT32(control_regs.irqstatus, AHCIState),
+VMSTATE_UINT32(control_regs.impl, AHCIState),
+VMSTATE_UINT32(control_regs.version, AHCIState),
+VMSTATE_UINT32(idp_index, AHCIState),
+VMSTATE_INT32(ports, AHCIState),
+VMSTATE_END_OF_LIST()
+},
+};
+
 typedef struct SysbusAHCIState {
 SysBusDevice busdev;
 AHCIState ahci;
@@ -1207,7 +1282,10 @@ typedef struct SysbusAHCIState {
 
 static const VMStateDescription vmstate_sysbus_ahci = {
 .name = sysbus-ahci,
-.unmigratable = 1,
+.fields = (VMStateField []) {
+VMSTATE_AHCI(ahci, AHCIPCIState),
+VMSTATE_END_OF_LIST()
+},
 };
 
 static void sysbus_ahci_reset(DeviceState *dev)
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index 735b379..67b818f 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -305,6 +305,16 @@ typedef struct AHCIPCIState {
 AHCIState ahci;
 } AHCIPCIState;
 
+extern const VMStateDescription vmstate_ahci;
+
+#define VMSTATE_AHCI(_field, _state) {   \
+.name   = (stringify(_field)),   \
+.size   = sizeof(AHCIState), \
+.vmsd   = vmstate_ahci, \
+.flags  = VMS_STRUCT,\
+.offset = vmstate_offset_value(_state, _field, AHCIState),   \
+}
+
 typedef struct NCQFrame {
 uint8_t fis_type;
 uint8_t c;
diff --git a/hw/ide

[Qemu-devel] [PATCH v2 1/3] qtest: Enable creation of multiple qemu instances

2012-12-20 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Currently, the qtest harness can only spawn 1 qemu instance at a time because
the parent pid is used to create the socket files. Use 'mkdtemp()' in
combination with the parent pid to avoid conflicts.

Signed-off-by: Jason Baron jba...@redhat.com
---
 tests/libqtest.c |   15 +--
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index 71b84c1..57665c9 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -41,6 +41,7 @@ struct QTestState
 GString *rx;
 gchar *pid_file;
 char *socket_path, *qmp_socket_path;
+char *tmp_dir;
 };
 
 #define g_assert_no_errno(ret) do { \
@@ -105,7 +106,6 @@ QTestState *qtest_init(const char *extra_args)
 {
 QTestState *s;
 int sock, qmpsock, ret, i;
-gchar *pid_file;
 gchar *command;
 const char *qemu_binary;
 pid_t pid;
@@ -115,9 +115,11 @@ QTestState *qtest_init(const char *extra_args)
 
 s = g_malloc(sizeof(*s));
 
-s-socket_path = g_strdup_printf(/tmp/qtest-%d.sock, getpid());
-s-qmp_socket_path = g_strdup_printf(/tmp/qtest-%d.qmp, getpid());
-pid_file = g_strdup_printf(/tmp/qtest-%d.pid, getpid());
+s-tmp_dir = g_strdup_printf(/tmp/qtest-%d-XX, getpid());
+g_assert(mkdtemp(s-tmp_dir) != NULL);
+s-socket_path = g_strdup_printf(%s/%s, s-tmp_dir, sock);
+s-qmp_socket_path = g_strdup_printf(%s/%s, s-tmp_dir, qmp);
+s-pid_file = g_strdup_printf(%s/%s, s-tmp_dir, pid);
 
 sock = init_socket(s-socket_path);
 qmpsock = init_socket(s-qmp_socket_path);
@@ -131,7 +133,7 @@ QTestState *qtest_init(const char *extra_args)
   -pidfile %s 
   -machine accel=qtest 
   %s, qemu_binary, s-socket_path,
-  s-qmp_socket_path, pid_file,
+  s-qmp_socket_path, s-pid_file,
   extra_args ?: );
 
 ret = system(command);
@@ -143,7 +145,6 @@ QTestState *qtest_init(const char *extra_args)
 s-qmp_fd = socket_accept(qmpsock);
 
 s-rx = g_string_new();
-s-pid_file = pid_file;
 for (i = 0; i  MAX_IRQ; i++) {
 s-irq_level[i] = false;
 }
@@ -172,9 +173,11 @@ void qtest_quit(QTestState *s)
 unlink(s-pid_file);
 unlink(s-socket_path);
 unlink(s-qmp_socket_path);
+unlink(s-tmp_dir);
 g_free(s-pid_file);
 g_free(s-socket_path);
 g_free(s-qmp_socket_path);
+g_free(s-tmp_dir);
 }
 
 static void socket_sendf(int fd, const char *fmt, va_list ap)
-- 
1.7.1




[Qemu-devel] [PATCH v2 0/3] qtest: add migration testing

2012-12-20 Thread Jason Baron
Hi,

Add a basic qtest for migration testing. Currently, it just tests a migrate of
machine 'pc' on the same host. Would be nice to extend to multiple machine
versions, but that requires multiple binaries, which could be done, but is
perhaps a bit awkward from qtest? Testing different machine versions within
the same binary doesn't seem like a real world test case to me. Currently,
the test aborts, if the migrate takes more than 2 minutes.

In any case, the test currently fails for q35, since ahci migration suport
isn't in place. Thus, I intend to add q35 testing here, once those ahci
migration patches are accepted.

Thanks,

-Jason

v2:
 * move core migration functions to libqtest.c
 * simplify Makefile dependencies
 * use 'mkdtemp()' instead of child pid to identify qemu instances

Jason Baron (3):
  qtest: Enable creation of multiple qemu instances
  qtest: extend qtest_qmp() to fill in the reply
  qtest: add migrate-test

 tests/Makefile   |4 +-
 tests/libqtest.c |  130 --
 tests/libqtest.h |   30 ++--
 tests/migrate-test.c |   68 ++
 4 files changed, 212 insertions(+), 20 deletions(-)
 create mode 100644 tests/migrate-test.c




[Qemu-devel] [PATCH v2 3/3] qtest: add migrate-test

2012-12-20 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Tests a single 'pc' machine migration on the same host.

Would be nice to extend the test matrix to various machine versions, but that
requires building multiple qemu binaries, which is a bit awkward in the
context of qtest. Testing migration between different machine versions with the
same binary doesn't seem too useful.

Signed-off-by: Jason Baron jba...@redhat.com
---
 tests/Makefile   |2 +
 tests/libqtest.c |   98 -
 tests/libqtest.h |   15 +++-
 tests/migrate-test.c |   68 ++
 4 files changed, 179 insertions(+), 4 deletions(-)
 create mode 100644 tests/migrate-test.c

diff --git a/tests/Makefile b/tests/Makefile
index 1756b47..3f0c5a2 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -25,6 +25,7 @@ check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
 check-qtest-i386-y = tests/fdc-test$(EXESUF)
 check-qtest-i386-y += tests/hd-geo-test$(EXESUF)
 check-qtest-i386-y += tests/rtc-test$(EXESUF)
+check-qtest-i386-y += tests/migrate-test$(EXESUF)
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 check-qtest-sparc-y = tests/m48t59-test$(EXESUF)
 check-qtest-sparc64-y = tests/m48t59-test$(EXESUF)
@@ -78,6 +79,7 @@ tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y)
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y)
 tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y)
 tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o $(trace-obj-y)
+tests/migrate-test$(EXESUF): tests/migrate-test.o
 
 # QTest rules
 
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 994cd2f..28cbea9 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -28,6 +28,9 @@
 
 #include compiler.h
 #include osdep.h
+#include qjson.h
+#include qdict.h
+#include qbool.h
 
 #define MAX_IRQ 256
 
@@ -42,6 +45,8 @@ struct QTestState
 gchar *pid_file;
 char *socket_path, *qmp_socket_path;
 char *tmp_dir;
+/* uri to use for incoming migration */
+char *incoming_uri;
 };
 
 #define g_assert_no_errno(ret) do { \
@@ -102,7 +107,7 @@ static pid_t qtest_qemu_pid(QTestState *s)
 return pid;
 }
 
-QTestState *qtest_init(const char *extra_args)
+QTestState *qtest_init(const char *extra_args, const char *incoming_uri)
 {
 QTestState *s;
 int sock, qmpsock, ret, i;
@@ -113,13 +118,14 @@ QTestState *qtest_init(const char *extra_args)
 qemu_binary = getenv(QTEST_QEMU_BINARY);
 g_assert(qemu_binary != NULL);
 
-s = g_malloc(sizeof(*s));
+s = g_malloc0(sizeof(*s));
 
 s-tmp_dir = g_strdup_printf(/tmp/qtest-%d-XX, getpid());
 g_assert(mkdtemp(s-tmp_dir) != NULL);
 s-socket_path = g_strdup_printf(%s/%s, s-tmp_dir, sock);
 s-qmp_socket_path = g_strdup_printf(%s/%s, s-tmp_dir, qmp);
 s-pid_file = g_strdup_printf(%s/%s, s-tmp_dir, pid);
+s-incoming_uri = g_strdup(incoming_uri);
 
 sock = init_socket(s-socket_path);
 qmpsock = init_socket(s-qmp_socket_path);
@@ -178,6 +184,7 @@ void qtest_quit(QTestState *s)
 g_free(s-socket_path);
 g_free(s-qmp_socket_path);
 g_free(s-tmp_dir);
+g_free(s-incoming_uri);
 }
 
 static void socket_sendf(int fd, const char *fmt, va_list ap)
@@ -482,3 +489,90 @@ void qtest_memwrite(QTestState *s, uint64_t addr, const 
void *data, size_t size)
 qtest_sendf(s, \n);
 qtest_rsp(s, 0);
 }
+
+/**
+ * is_running:
+ * @mch: QTestState instance to check.
+ *
+ * Returns 1, if mch is running, 0 if its not running. -1 means retry.
+ */
+static int is_running(QTestState *mch)
+{
+QString *resp = qstring_new();
+QObject *resp_obj;
+QObject *ret_obj;
+QObject *run_obj;
+int ret;
+
+resp = qstring_new();
+qtest_qmp_resp(mch, resp, { 'execute': 'query-status' }, NULL);
+
+resp_obj = qobject_from_json(qstring_get_str(resp));
+if ((!resp_obj) || (qobject_type(resp_obj) != QTYPE_QDICT)) {
+ret = -1;
+goto out;
+}
+
+ret_obj = qdict_get(qobject_to_qdict(resp_obj), return);
+if ((!ret_obj) || (qobject_type(ret_obj) != QTYPE_QDICT)) {
+ret = -1;
+goto out;
+}
+
+run_obj = qdict_get(qobject_to_qdict(ret_obj), running);
+if ((!run_obj) || (qobject_type(run_obj) != QTYPE_QBOOL)) {
+ret = -1;
+goto out;
+}
+ret = qbool_get_int(qobject_to_qbool(run_obj));
+
+out:
+qobject_decref(resp_obj);
+QDECREF(resp);
+return ret;
+}
+
+#define SLEEP_INTERVAL 2
+/* Abort after 2 minutes */
+#define SLEEP_MAX (60 * 2)
+
+int test_migrate(QTestState *mach_src, QTestState *mach_dst)
+{
+int src_run = 0;
+int dst_run = 0;
+int iter = 0;
+gchar *migrate_str;
+
+if (!mach_dst-incoming_uri) {
+fprintf(stderr, do_migrate: Error: mach_dst-incoming_uri not set\n);
+return -1;
+}
+
+/* is running on mach_src ? */
+if (is_running(mach_src) != 1) {
+fprintf(stderr, do_migrate: Error: not running on src\n

[Qemu-devel] [PATCH v2 2/3] qtest: extend qtest_qmp() to fill in the reply

2012-12-20 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Introduce:

Add void qtest_qmp_resp(QTestState *s, QString *resp, const char *fmt, ...)

which allows a response string to be filled in.

Signed-off-by: Jason Baron jba...@redhat.com
---
 tests/Makefile   |2 +-
 tests/libqtest.c |   17 ++---
 tests/libqtest.h |   15 +--
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/tests/Makefile b/tests/Makefile
index b60f0fb..1756b47 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -85,7 +85,7 @@ TARGETS=$(patsubst %-softmmu,%, $(filter 
%-softmmu,$(TARGET_DIRS)))
 QTEST_TARGETS=$(foreach TARGET,$(TARGETS), $(if $(check-qtest-$(TARGET)-y), 
$(TARGET),))
 check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), 
$(check-qtest-$(TARGET)-y))
 
-qtest-obj-y = tests/libqtest.o $(oslib-obj-y) libqemustub.a
+qtest-obj-y = tests/libqtest.o $(oslib-obj-y) libqemustub.a $(test-qapi-obj-y) 
$(qom-obj-y)
 $(check-qtest-y): $(qtest-obj-y)
 
 .PHONY: check-help
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 57665c9..994cd2f 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -288,7 +288,7 @@ redo:
 return words;
 }
 
-void qtest_qmp(QTestState *s, const char *fmt, ...)
+void qtest_qmp_resp(QTestState *s, QString *resp, const char *fmt, ...)
 {
 va_list ap;
 bool has_reply = false;
@@ -313,16 +313,19 @@ void qtest_qmp(QTestState *s, const char *fmt, ...)
 fprintf(stderr, Broken pipe\n);
 exit(1);
 }
-
-switch (c) {
-case '{':
+if (c == '{') {
 nesting++;
 has_reply = true;
-break;
-case '}':
+}
+if (c == '}') {
 nesting--;
-break;
 }
+if (has_reply  resp) {
+qstring_append_chr(resp, c);
+}
+}
+if (has_reply  resp) {
+qstring_append_chr(resp, '\0');
 }
 }
 
diff --git a/tests/libqtest.h b/tests/libqtest.h
index c8ade85..972ba5d 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -18,6 +18,7 @@
 #include stdint.h
 #include stdbool.h
 #include sys/types.h
+#include qstring.h
 
 typedef struct QTestState QTestState;
 
@@ -38,13 +39,14 @@ QTestState *qtest_init(const char *extra_args);
 void qtest_quit(QTestState *s);
 
 /**
- * qtest_qmp:
+ * qtest_qmp_resp:
  * @s: QTestState instance to operate on.
+ * @resp: Fills in response string if provided
  * @fmt...: QMP message to send to qemu
  *
  * Sends a QMP message to QEMU
  */
-void qtest_qmp(QTestState *s, const char *fmt, ...);
+void qtest_qmp_resp(QTestState *s, QString *resp, const char *fmt, ...);
 
 /**
  * qtest_get_irq:
@@ -349,4 +351,13 @@ void qtest_add_func(const char *str, void (*fn));
  */
 #define clock_set(val) qtest_clock_set(global_qtest, val)
 
+/**
+ * qtest_qmp:
+ * @s: QTestState instance to operate on.
+ * @fmt...: QMP message to send to qemu
+ *
+ * Sends a QMP message to QEMU
+ */
+#define qtest_qmp(s, fmt, ...) qtest_qmp_resp(s, NULL, fmt, ## __VA_ARGS__)
+
 #endif
-- 
1.7.1




Re: [Qemu-devel] [PATCH v2 1/3] qtest: Enable creation of multiple qemu instances

2012-12-20 Thread Jason Baron
On Thu, Dec 20, 2012 at 08:07:02PM +, Blue Swirl wrote:
 On Thu, Dec 20, 2012 at 5:14 PM, Jason Baron jba...@redhat.com wrote:
  From: Jason Baron jba...@redhat.com
 
  Currently, the qtest harness can only spawn 1 qemu instance at a time 
  because
  the parent pid is used to create the socket files. Use 'mkdtemp()' in
 
 But mkdtemp() is not available on Win32.

So this case important even for qtest?

 
  combination with the parent pid to avoid conflicts.
 
  Signed-off-by: Jason Baron jba...@redhat.com
  ---
   tests/libqtest.c |   15 +--
   1 files changed, 9 insertions(+), 6 deletions(-)
 
  diff --git a/tests/libqtest.c b/tests/libqtest.c
  index 71b84c1..57665c9 100644
  --- a/tests/libqtest.c
  +++ b/tests/libqtest.c
  @@ -41,6 +41,7 @@ struct QTestState
   GString *rx;
   gchar *pid_file;
   char *socket_path, *qmp_socket_path;
  +char *tmp_dir;
   };
 
   #define g_assert_no_errno(ret) do { \
  @@ -105,7 +106,6 @@ QTestState *qtest_init(const char *extra_args)
   {
   QTestState *s;
   int sock, qmpsock, ret, i;
  -gchar *pid_file;
   gchar *command;
   const char *qemu_binary;
   pid_t pid;
  @@ -115,9 +115,11 @@ QTestState *qtest_init(const char *extra_args)
 
   s = g_malloc(sizeof(*s));
 
  -s-socket_path = g_strdup_printf(/tmp/qtest-%d.sock, getpid());
  -s-qmp_socket_path = g_strdup_printf(/tmp/qtest-%d.qmp, getpid());
  -pid_file = g_strdup_printf(/tmp/qtest-%d.pid, getpid());
  +s-tmp_dir = g_strdup_printf(/tmp/qtest-%d-XX, getpid());
  +g_assert(mkdtemp(s-tmp_dir) != NULL);
  +s-socket_path = g_strdup_printf(%s/%s, s-tmp_dir, sock);
  +s-qmp_socket_path = g_strdup_printf(%s/%s, s-tmp_dir, qmp);
  +s-pid_file = g_strdup_printf(%s/%s, s-tmp_dir, pid);
 
   sock = init_socket(s-socket_path);
   qmpsock = init_socket(s-qmp_socket_path);
  @@ -131,7 +133,7 @@ QTestState *qtest_init(const char *extra_args)
 -pidfile %s 
 -machine accel=qtest 
 %s, qemu_binary, s-socket_path,
  -  s-qmp_socket_path, pid_file,
  +  s-qmp_socket_path, s-pid_file,
 extra_args ?: );
 
   ret = system(command);
  @@ -143,7 +145,6 @@ QTestState *qtest_init(const char *extra_args)
   s-qmp_fd = socket_accept(qmpsock);
 
   s-rx = g_string_new();
  -s-pid_file = pid_file;
   for (i = 0; i  MAX_IRQ; i++) {
   s-irq_level[i] = false;
   }
  @@ -172,9 +173,11 @@ void qtest_quit(QTestState *s)
   unlink(s-pid_file);
   unlink(s-socket_path);
   unlink(s-qmp_socket_path);
  +unlink(s-tmp_dir);
 
 -EISDIR, rmdir() would be needed instead.
 

'unlink()' tested fine on Linux. But yes, it might not be as portable.

I looked at tempnam() and mktemp(), but they both generate linker warnings.
'mkstemp()' could be used but its awkward to delete the file right after
its created so that bind() can create it. Plus, it could be a greater
security risk in that the filename is easier to determine.

We could write our own random file string generator then, if mkdtemp(),
isn't ok.

   g_free(s-pid_file);
   g_free(s-socket_path);
   g_free(s-qmp_socket_path);
  +g_free(s-tmp_dir);
   }
 
   static void socket_sendf(int fd, const char *fmt, va_list ap)
  --
  1.7.1
 



Re: [Qemu-devel] Q35, Mac OS X, and the War On Entropy

2012-12-19 Thread Jason Baron
On Wed, Dec 19, 2012 at 02:32:42PM -0500, Gabriel L. Somlo wrote:
 Hi,
 
 I'm working on getting OS X to run on KVM, and the latest
 q35-qemu tree from GitHub, plus additionally applied commit
 40862309a9d733cb0e878c79f477de003897b5d2 from mainline works
 great, with the following command line:
 
 bin/qemu-system-x86_64 -enable-kvm -m 2048 -cpu core2duo \
   -M q35 -L seabios-mac/out -kernel ./chameleon_2.0_boot \
   -usb -device usb-kbd -device usb-mouse \
   -device isa-applesmc,osk=... \
   -device ide-drive,bus=ide.0,drive=MacHDD \
   -drive id=MacHDD,if=none,snapshot=on,file=./mac_10.6.img
 
 
 However, current mainline QEMU git master does not. I need a
 slightly modified command line to even start (had to add
 -L share/qemu as a fallback bios path to avoid could not
 open option rom ... errors):
 
 bin/qemu-system-x86_64 -enable-kvm -m 2048 -cpu core2duo \
   -M q35 -L seabios-mac/out -L share/qemu -kernel ./chameleon_2.0_boot \
   -usb -device usb-kbd -device usb-mouse \
   -device isa-applesmc,osk=... \
   -device ide-drive,bus=ide.0,drive=MacHDD \
   -drive id=MacHDD,if=none,snapshot=on,file=./mac_10.6.img
 
 This seems to be equivalent: 
 
 bin/qemu-system-x86_64 -enable-kvm -m 2048 -cpu core2duo \
   -M q35 -bios bios-mac.bin -kernel ./chameleon_2.0_boot \
   -usb -device usb-kbd -device usb-mouse \
   -device isa-applesmc,osk=... \
   -device ide-drive,bus=ide.0,drive=MacHDD \
   -drive id=MacHDD,if=none,snapshot=on,file=./mac_10.6.img
 
 (I use the latest SeaBIOS git plus this patch:
 http://www.contrib.andrew.cmu.edu/~somlo/OSXKVM/seabios-mac-20121206.patch
 for all examples, working *and* non-working).
 
 With mainline and -M q35, OS X gives me:
 
 Waiting for boot volume with UUID ...
 
 and
 
 Still waiting for root device
 
 I don't know if there's a way to do a bisect across the two different
 trees, and I couldn't find a working -M q35 state in mainline to begin
 bisecting from there. I get the above errors immediately after commits
 df2d8b3ed4d2b6406335d274f9537d78ac4e3c0c,
 a1c9304683161a68c1fc1d9c3bc174ec8e26a61a, and
 21bcfdd9a43041720f9370831c694bcb2e11eea4
 where -M q35 was added to mainline...
 
 BTW, leaving out -M q35 in mainline still seems to work fine (if I
 explicitly add -device ahci,id=ide instead...
 
 Between the working GitHub -M q35 and the non-working mainline -M q35,
 dev: ich9-ahci from info qtree looks identical, save for the
 dev: ide-drive version under ide.0 (1.3.50 on github vs. 1.2.50 in
 mainline). Not sure if that's even relevant...
 
 Any advice as to what else I could do to narrow it down further would be
 appreciated !
 
 Thanks,
 --Gabriel

I think you are missing:

-acpitable file=seabios/out/q35-acpi-dsdt.aml

Thanks,

-Jason



Re: [Qemu-devel] [PATCH 1/3] qtest: Enable creation of multiple qemu instances

2012-12-17 Thread Jason Baron
On Sat, Dec 15, 2012 at 09:20:13AM +, Blue Swirl wrote:
 On Sat, Dec 15, 2012 at 9:14 AM, Paolo Bonzini pbonz...@redhat.com wrote:
   +#define QTEST_FILE_TEMP /tmp/qtest-%d.sock
   +#define QTEST_QMP_FILE_TEMP /tmp/qtest-%d.qmp
   +#define QTEST_PID_FILE_TEMP /tmp/qtest-%d.pid
 
  These filenames are too predictable from security point of view,
 
  This need not be secure as long as the file is created with 0600
  permissions.  In fact, inspecting the pid file from the shell can
  be useful.
 
 Permissions do not help at all because the attacker could for example
 target overwriting of a critical file.
 
 
  However, using mkstemp() on a prefix that includes the parent pid
  can indeed be the best of both worlds.
 
 Yes.
 
 
  Paolo
 

Yes, but mkstemp() creates the file, and bind() returns EADDRINUSE, if the file
already exists.

Using mktemp() in this case, with bind() should be ok, since bind() checks if
the file exists and then creates it, if not, all within the bind() system call
(so its atomic).

Thanks,

-Jason



Re: [Qemu-devel] [PATCH 2/3] qtest: extend qtest_qmp() to fill in the reply

2012-12-14 Thread Jason Baron
On Fri, Dec 14, 2012 at 01:07:24AM +0100, Andreas Färber wrote:
 Am 13.12.2012 23:02, schrieb Jason Baron:
  diff --git a/tests/Makefile b/tests/Makefile
  index b60f0fb..30a101d 100644
  --- a/tests/Makefile
  +++ b/tests/Makefile
  @@ -74,10 +74,10 @@ tests/test-qmp-input-strict$(EXESUF): 
  tests/test-qmp-input-strict.o $(test-qapi-
   tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o 
  tests/test-qmp-marshal.o $(test-qapi-obj-y)
   tests/test-visitor-serialization$(EXESUF): 
  tests/test-visitor-serialization.o $(test-qapi-obj-y)
   
  -tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y)
  +tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y) qstring.o
   tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y)
  -tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y)
  -tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o 
  $(trace-obj-y)
  +tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y) 
  qstring.o
  +tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o 
  $(trace-obj-y) qstring.o
 
 Adding a dependency to every qtest is calling for a $(qtest-obj-y) to
 administer that list in a central location. I am expecting the number of
 tests to grow significantly over time.
 
 Andreas
 

ok, seems as though we can add $(test-qapi-obj-y) $(qom-obj-y), etc. to the
qtest-obj-y target, to simplify things a bit. I'll re-post that as a
separate patch.

Thanks,

-Jason



Re: [Qemu-devel] [PATCH 3/3] qtest: add migrate-test

2012-12-14 Thread Jason Baron
On Fri, Dec 14, 2012 at 03:08:21AM -0500, Paolo Bonzini wrote:
  Tests a single 'pc' machine migration on the same host. Currently,
  the test
  fail for q35 since the ahci controller doesn't yet migrate. Will add
  support
  for q35 once the ahci support is accepted.
  
  Would be nice to extend the test matrix to various machine versions,
  but that
  requires building multiple qemu binaries, which is a bit awkward in
  the
  context of qtest. Testing migration between different machine
  versions with the
  same binary doesn't seem too useful.
  
  Signed-off-by: Jason Baron jba...@redhat.com
  ---
   tests/Makefile   |2 +
   tests/migrate-test.c |  140
   ++
   2 files changed, 142 insertions(+), 0 deletions(-)
   create mode 100644 tests/migrate-test.c
  
  diff --git a/tests/Makefile b/tests/Makefile
  index 30a101d..d50dff0 100644
  --- a/tests/Makefile
  +++ b/tests/Makefile
  @@ -25,6 +25,7 @@ check-block-$(CONFIG_POSIX) +=
  tests/qemu-iotests-quick.sh
   check-qtest-i386-y = tests/fdc-test$(EXESUF)
   check-qtest-i386-y += tests/hd-geo-test$(EXESUF)
   check-qtest-i386-y += tests/rtc-test$(EXESUF)
  +check-qtest-i386-y += tests/migrate-test$(EXESUF)
   check-qtest-x86_64-y = $(check-qtest-i386-y)
   check-qtest-sparc-y = tests/m48t59-test$(EXESUF)
   check-qtest-sparc64-y = tests/m48t59-test$(EXESUF)
  @@ -78,6 +79,7 @@ tests/rtc-test$(EXESUF): tests/rtc-test.o
  $(trace-obj-y) qstring.o
   tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y)
   tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o
   $(trace-obj-y) qstring.o
   tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o
   $(trace-obj-y) qstring.o
  +tests/migrate-test$(EXESUF): tests/migrate-test.o $(test-qapi-obj-y)
  $(qom-obj-y)
   
   # QTest rules
   
  diff --git a/tests/migrate-test.c b/tests/migrate-test.c
  new file mode 100644
  index 000..c62d5af
  --- /dev/null
  +++ b/tests/migrate-test.c
  @@ -0,0 +1,140 @@
  +/*
  + * Migration tests
  + *
  + * Copyright Red Hat, Inc. 2012
  + *
  + * Authors:
  + *  Jason Baron   jba...@redhat.com
  + *
  + * 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 libqtest.h
  +
  +#include glib.h
  +#include stdio.h
  +#include string.h
  +#include stdlib.h
  +#include unistd.h
  +
  +#include qjson.h
  +#include error.h
  +#include qemu/object.h
  +#include qdict.h
  +#include qbool.h
  +
  +#define migrate_assert(cond) \
  +if (!(cond)) {   \
  +migrate_cleanup();   \
  +fprintf(stderr, %s:%d %s\n, __FILE__, __LINE__, #cond); \
  +abort(); \
  +}\
  +
  +static QTestState *mach_a;
  +static QTestState *mach_b;
  +
  +static void migrate_cleanup(void)
  +{
  +if (mach_a) {
  +qtest_quit(mach_a);
  +}
  +if (mach_b) {
  +qtest_quit(mach_b);
  +}
  +}
  +
  +static int expected_qobject(QObject *obj, qtype_code type)
  +{
  +if (!obj) {
  +return 0;
  +}
  +return (qobject_type(obj) == type);
  +}
  +
  +/*
  + * Return vals:
  + * 1: yes
  + * 0: no
  + * -1: retry
  + */
  +static int is_running(QTestState *mch)
  +{
  +QString *resp = qstring_new();
  +QObject *resp_obj;
  +QObject *ret_obj;
  +QObject *run_obj;
  +int ret;
  +
  +resp = qstring_new();
  +qtest_qmp_resp(mch, resp, { 'execute': 'query-status' },
  NULL);
  +
  +resp_obj = qobject_from_json(qstring_get_str(resp));
  +if (!expected_qobject(resp_obj, QTYPE_QDICT)) {
  +ret = -1;
  +goto out;
  +}
  +
  +ret_obj = qdict_get(qobject_to_qdict(resp_obj), return);
  +if (!expected_qobject(ret_obj, QTYPE_QDICT)) {
  +ret = -1;
  +goto out;
  +}
  +
  +run_obj = qdict_get(qobject_to_qdict(ret_obj), running);
  +if (!expected_qobject(run_obj, QTYPE_QBOOL)) {
  +ret = -1;
  +goto out;
  +}
  +ret = qbool_get_int(qobject_to_qbool(run_obj));
  +
  +out:
  +qobject_decref(resp_obj);
  +QDECREF(resp);
  +return ret;
  +}
  +
  +#define SLEEP_INTERVAL 2
  +/* Abort after 2 minutes */
  +#define SLEEP_MAX (60 * 2)
  +
  +static void migrate_a_to_b(void)
 
 Do you think this function could be turned into a libqtest call?

Seems like a good idea.

 It would take mach_a as an argument, add -incoming tcp:localhost:
 to the command line of mach_a, use that to spawn mach_b, and

why add to mach_a? I thought -incoming is just for the destination.

 return mach_b as the return value (or perhaps change mach_a to
 refer to the new machine).

I think it makes sense for the caller to create and pass the machines
and then just call a library function to do the migrate. That way the
caller 'owns' the machines. But maybe I'm missing something.

 
 The reason is that I can anticipate having many migration

[Qemu-devel] [PATCH 2/3] qtest: extend qtest_qmp() to fill in the reply

2012-12-13 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Introduce:

Add void qtest_qmp_resp(QTestState *s, QString *resp, const char *fmt, ...)

which allows a response string to be filled in.

Signed-off-by: Jason Baron jba...@redhat.com
---
 tests/Makefile   |6 +++---
 tests/libqtest.c |   17 ++---
 tests/libqtest.h |4 +++-
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/tests/Makefile b/tests/Makefile
index b60f0fb..30a101d 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -74,10 +74,10 @@ tests/test-qmp-input-strict$(EXESUF): 
tests/test-qmp-input-strict.o $(test-qapi-
 tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o 
tests/test-qmp-marshal.o $(test-qapi-obj-y)
 tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o 
$(test-qapi-obj-y)
 
-tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y)
+tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y) qstring.o
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y)
-tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y)
-tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o $(trace-obj-y)
+tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y) 
qstring.o
+tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o 
$(trace-obj-y) qstring.o
 
 # QTest rules
 
diff --git a/tests/libqtest.c b/tests/libqtest.c
index f3dd4e4..71c9eb4 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -288,7 +288,7 @@ redo:
 return words;
 }
 
-void qtest_qmp(QTestState *s, const char *fmt, ...)
+void qtest_qmp_resp(QTestState *s, QString *resp, const char *fmt, ...)
 {
 va_list ap;
 bool has_reply = false;
@@ -313,16 +313,19 @@ void qtest_qmp(QTestState *s, const char *fmt, ...)
 fprintf(stderr, Broken pipe\n);
 exit(1);
 }
-
-switch (c) {
-case '{':
+if (c == '{') {
 nesting++;
 has_reply = true;
-break;
-case '}':
+}
+if (c == '}') {
 nesting--;
-break;
 }
+if (has_reply  resp) {
+qstring_append_chr(resp, c);
+}
+}
+if (has_reply  resp) {
+qstring_append_chr(resp, '\0');
 }
 }
 
diff --git a/tests/libqtest.h b/tests/libqtest.h
index c8ade85..6441e50 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -18,6 +18,7 @@
 #include stdint.h
 #include stdbool.h
 #include sys/types.h
+#include qstring.h
 
 typedef struct QTestState QTestState;
 
@@ -44,7 +45,8 @@ void qtest_quit(QTestState *s);
  *
  * Sends a QMP message to QEMU
  */
-void qtest_qmp(QTestState *s, const char *fmt, ...);
+void qtest_qmp_resp(QTestState *s, QString *resp, const char *fmt, ...);
+#define qtest_qmp(s, fmt, ...) qtest_qmp_resp(s, NULL, fmt, ## __VA_ARGS__)
 
 /**
  * qtest_get_irq:
-- 
1.7.1




[Qemu-devel] [PATCH 1/3] qtest: Enable creation of multiple qemu instances

2012-12-13 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Currently, the qtest harness can only spawn 1 qemu instance at a time because
the parent pid is used to create the socket files. Use the child pid instead,
so we can remove that limitation.

Signed-off-by: Jason Baron jba...@redhat.com
---
 tests/libqtest.c |   31 +--
 1 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index 71b84c1..f3dd4e4 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -101,6 +101,10 @@ static pid_t qtest_qemu_pid(QTestState *s)
 return pid;
 }
 
+#define QTEST_FILE_TEMP /tmp/qtest-%d.sock
+#define QTEST_QMP_FILE_TEMP /tmp/qtest-%d.qmp
+#define QTEST_PID_FILE_TEMP /tmp/qtest-%d.pid
+
 QTestState *qtest_init(const char *extra_args)
 {
 QTestState *s;
@@ -113,25 +117,16 @@ QTestState *qtest_init(const char *extra_args)
 qemu_binary = getenv(QTEST_QEMU_BINARY);
 g_assert(qemu_binary != NULL);
 
-s = g_malloc(sizeof(*s));
-
-s-socket_path = g_strdup_printf(/tmp/qtest-%d.sock, getpid());
-s-qmp_socket_path = g_strdup_printf(/tmp/qtest-%d.qmp, getpid());
-pid_file = g_strdup_printf(/tmp/qtest-%d.pid, getpid());
-
-sock = init_socket(s-socket_path);
-qmpsock = init_socket(s-qmp_socket_path);
-
 pid = fork();
 if (pid == 0) {
 command = g_strdup_printf(%s 
-  -qtest unix:%s,nowait 
+  -qtest unix: QTEST_FILE_TEMP ,nowait 
   -qtest-log /dev/null 
-  -qmp unix:%s,nowait 
-  -pidfile %s 
+  -qmp unix: QTEST_QMP_FILE_TEMP ,nowait 
+  -pidfile  QTEST_PID_FILE_TEMP  
   -machine accel=qtest 
-  %s, qemu_binary, s-socket_path,
-  s-qmp_socket_path, pid_file,
+  %s, qemu_binary, getpid(),
+  getpid(), getpid(),
   extra_args ?: );
 
 ret = system(command);
@@ -139,6 +134,14 @@ QTestState *qtest_init(const char *extra_args)
 g_free(command);
 }
 
+s = g_malloc(sizeof(*s));
+s-socket_path = g_strdup_printf(QTEST_FILE_TEMP, pid);
+s-qmp_socket_path = g_strdup_printf(QTEST_QMP_FILE_TEMP, pid);
+pid_file = g_strdup_printf(QTEST_PID_FILE_TEMP, pid);
+
+sock = init_socket(s-socket_path);
+qmpsock = init_socket(s-qmp_socket_path);
+
 s-fd = socket_accept(sock);
 s-qmp_fd = socket_accept(qmpsock);
 
-- 
1.7.1




[Qemu-devel] [PATCH 0/3] qtest: add migration testing

2012-12-13 Thread Jason Baron
Hi,

Add a basic qtest for migration testing. Currently, it just tests a migrate of
machine 'pc' on the same host. Would be nice to extend to multiple machine
versions, but that requires multiple binaries, which could be done, but is
perhaps a bit awkward from qtest? Testing different machine versions within
the same binary doesn't seem like a real world test case to me. Currently,
the test aborts, if the migrate takes more than 2 minutes.

In any case, the test currently fails for q35, since ahci migration suport
isn't in place. Thus, I intend to add q35 testing here, once those ahci
migration patches are accepted.

Thanks,

-Jason


Jason Baron (3):
  qtest: Enable creation of multiple qemu instances
  qtest: extend qtest_qmp() to fill in the reply
  qtest: add migrate-test

 tests/Makefile   |8 ++-
 tests/libqtest.c |   48 ++
 tests/libqtest.h |4 +-
 tests/migrate-test.c |  140 ++
 4 files changed, 175 insertions(+), 25 deletions(-)
 create mode 100644 tests/migrate-test.c




[Qemu-devel] [PATCH 3/3] qtest: add migrate-test

2012-12-13 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Tests a single 'pc' machine migration on the same host. Currently, the test
fail for q35 since the ahci controller doesn't yet migrate. Will add support
for q35 once the ahci support is accepted.

Would be nice to extend the test matrix to various machine versions, but that
requires building multiple qemu binaries, which is a bit awkward in the
context of qtest. Testing migration between different machine versions with the
same binary doesn't seem too useful.

Signed-off-by: Jason Baron jba...@redhat.com
---
 tests/Makefile   |2 +
 tests/migrate-test.c |  140 ++
 2 files changed, 142 insertions(+), 0 deletions(-)
 create mode 100644 tests/migrate-test.c

diff --git a/tests/Makefile b/tests/Makefile
index 30a101d..d50dff0 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -25,6 +25,7 @@ check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
 check-qtest-i386-y = tests/fdc-test$(EXESUF)
 check-qtest-i386-y += tests/hd-geo-test$(EXESUF)
 check-qtest-i386-y += tests/rtc-test$(EXESUF)
+check-qtest-i386-y += tests/migrate-test$(EXESUF)
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 check-qtest-sparc-y = tests/m48t59-test$(EXESUF)
 check-qtest-sparc64-y = tests/m48t59-test$(EXESUF)
@@ -78,6 +79,7 @@ tests/rtc-test$(EXESUF): tests/rtc-test.o $(trace-obj-y) 
qstring.o
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o $(trace-obj-y)
 tests/fdc-test$(EXESUF): tests/fdc-test.o tests/libqtest.o $(trace-obj-y) 
qstring.o
 tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o tests/libqtest.o 
$(trace-obj-y) qstring.o
+tests/migrate-test$(EXESUF): tests/migrate-test.o $(test-qapi-obj-y) 
$(qom-obj-y)
 
 # QTest rules
 
diff --git a/tests/migrate-test.c b/tests/migrate-test.c
new file mode 100644
index 000..c62d5af
--- /dev/null
+++ b/tests/migrate-test.c
@@ -0,0 +1,140 @@
+/*
+ * Migration tests
+ *
+ * Copyright Red Hat, Inc. 2012
+ *
+ * Authors:
+ *  Jason Baron   jba...@redhat.com
+ *
+ * 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 libqtest.h
+
+#include glib.h
+#include stdio.h
+#include string.h
+#include stdlib.h
+#include unistd.h
+
+#include qjson.h
+#include error.h
+#include qemu/object.h
+#include qdict.h
+#include qbool.h
+
+#define migrate_assert(cond) \
+if (!(cond)) {   \
+migrate_cleanup();   \
+fprintf(stderr, %s:%d %s\n, __FILE__, __LINE__, #cond); \
+abort(); \
+}\
+
+static QTestState *mach_a;
+static QTestState *mach_b;
+
+static void migrate_cleanup(void)
+{
+if (mach_a) {
+qtest_quit(mach_a);
+}
+if (mach_b) {
+qtest_quit(mach_b);
+}
+}
+
+static int expected_qobject(QObject *obj, qtype_code type)
+{
+if (!obj) {
+return 0;
+}
+return (qobject_type(obj) == type);
+}
+
+/*
+ * Return vals:
+ * 1: yes
+ * 0: no
+ * -1: retry
+ */
+static int is_running(QTestState *mch)
+{
+QString *resp = qstring_new();
+QObject *resp_obj;
+QObject *ret_obj;
+QObject *run_obj;
+int ret;
+
+resp = qstring_new();
+qtest_qmp_resp(mch, resp, { 'execute': 'query-status' }, NULL);
+
+resp_obj = qobject_from_json(qstring_get_str(resp));
+if (!expected_qobject(resp_obj, QTYPE_QDICT)) {
+ret = -1;
+goto out;
+}
+
+ret_obj = qdict_get(qobject_to_qdict(resp_obj), return);
+if (!expected_qobject(ret_obj, QTYPE_QDICT)) {
+ret = -1;
+goto out;
+}
+
+run_obj = qdict_get(qobject_to_qdict(ret_obj), running);
+if (!expected_qobject(run_obj, QTYPE_QBOOL)) {
+ret = -1;
+goto out;
+}
+ret = qbool_get_int(qobject_to_qbool(run_obj));
+
+out:
+qobject_decref(resp_obj);
+QDECREF(resp);
+return ret;
+}
+
+#define SLEEP_INTERVAL 2
+/* Abort after 2 minutes */
+#define SLEEP_MAX (60 * 2)
+
+static void migrate_a_to_b(void)
+{
+int a_run = 0;
+int b_run = 0;
+int iter = 0;
+
+/* is running on A ? */
+migrate_assert(is_running(mach_a));
+
+/* do migrate */
+qtest_qmp(mach_a, { 'execute': 'migrate',
+  'arguments': { 'uri': 'tcp:0:' } }, NULL);
+
+while (iter  SLEEP_MAX) {
+a_run = is_running(mach_a);
+b_run = is_running(mach_b);
+if ((a_run == 0)  (b_run == 1)) {
+break;
+}
+sleep(SLEEP_INTERVAL);
+iter += SLEEP_INTERVAL;
+}
+migrate_assert((a_run == 0)  (b_run == 1));
+}
+
+int main(int argc, char **argv)
+{
+int ret;
+
+g_test_init(argc, argv, NULL);
+
+mach_a = qtest_start(-display none -machine pc);
+mach_b = qtest_start(-display none -machine pc -incoming tcp:0:);
+
+qtest_add_func(/migrate/a-to-b, migrate_a_to_b);
+ret = g_test_run();
+
+migrate_cleanup();
+return ret;
+}
-- 
1.7.1




Re: [Qemu-devel] qemu 1.3: windows 2003 SP2 x64 boot crash with hpet enabled (was ok with qemu-kvm 1.2)

2012-12-11 Thread Jason Baron
On Tue, Dec 11, 2012 at 08:02:12AM +0100, Alexandre DERUMIER wrote:
 seem to be related to seabios update:
 
 seabios: q35 update
 http://lists.gnu.org/archive/html/qemu-devel/2012-12/msg00113.html
 

This is most likely due to SeaBIOS commit:

commit d9f5cdbdf55d61aef9a1a534d9123ef734427478

Which I believe was pulled into qemu-1.3, so that probably explains why
you are seeing this on 1.3.

SeaBIOS recently committed a fix (revert) for this. So, if its possible to pull
the latest SeaBIOS, and pass -bios seabios patch/bios.bin. We can
verify that.

Thanks,

-Jason



 
 
 - Mail original -
 
 De: Alexandre DERUMIER aderum...@odiso.com
 À: qemu-devel qemu-devel@nongnu.org
 Envoyé: Mardi 11 Décembre 2012 07:30:58
 Objet: Re: [Qemu-devel] qemu 1.3: windows 2003 SP2 x64 boot crash with hpet 
 enabled (was ok with qemu-kvm 1.2)
 
 My bsod screenshot was not full, here a new one:
 
 this seem to hang on acpi.sys
 
 ACPI.SYS address F735EE64 base at F7352000)
 
 I have tested xith host kernel 3.2,26,27 and 2.6.32 from rhel6, same problem.
 
 
 
 - Mail original -
 
 De: Alexandre DERUMIER aderum...@odiso.com
 À: qemu-devel qemu-devel@nongnu.org
 Envoyé: Lundi 10 Décembre 2012 19:08:37
 Objet: [Qemu-devel] qemu 1.3: windows 2003 SP2 R2 x64 boot crash with hpet 
 enabled (was ok with qemu-kvm 1.2)
 
 Hi list,
 
 I have a bsod when booting windows 2003 SP2 R2 x64 with hpet enabled, with 
 qemu 1.3. (screenshot attached)
 
 /usr/bin/kvm -id 9 -chardev 
 socket,id=qmp,path=/var/run/qemu-server/9.qmp,server,nowait -mon 
 chardev=qmp,mode=control -vnc 
 unix:/var/run/qemu-server/9.vnc,x509,password -pidfile 
 /var/run/qemu-server/9.pid -daemonize -name win2003-32bit-proxmox2 -smp 
 sockets=2,cores=1 -nodefaults -boot menu=on -vga cirrus -k fr -m 4000 
 -usbdevice tablet -drive if=none,id=drive-ide2,media=cdrom,aio=native -device 
 ide-cd,bus=ide.1,unit=0,drive=drive-ide2,id=ide2,bootindex=200 -drive 
 file=/dev/disk/by-id/scsi-3600144f0f62f0e004f6ec6fe00ba,if=none,id=drive-virtio0,aio=native,cache=none
  -device 
 virtio-blk-pci,drive=drive-virtio0,id=virtio0,bus=pci.0,addr=0xa,bootindex=100
  -netdev 
 type=tap,id=net0,ifname=tap9i0,script=/var/lib/qemu-server/pve-bridge,vhost=on
  -device 
 virtio-net-pci,mac=BA:BD:4F:AE:DF:FD,netdev=net0,bus=pci.0,addr=0x12,id=net0,bootindex=300
  -netdev 
 type=tap,id=net1,ifname=tap9i1,script=/var/lib/qemu-server/pve-bridge,vhost=on
  -device 
 virtio-net-pci,mac=4E:68:E9:4B:57:7C,netdev=net1,bus=pci.0,addr=0x13,id=net1,bootindex=301
  -rtc driftfix=slew,base=localtime
 
 
 it's booting fine with adding -no-hpet to above command line.
 
 
 above command line works fine with qemu-kvm 1.2.
 
 
 One proxmox user report also win2003 R2 SP2 X32 high cpu usage with smp guest 
 and hpet enabled. (qemu-kvm 1.2 or qemu 1.3)
 
 
 Maybe it's in-kernel irqchip related ?
 
 Any advise about enabling or disabling hpet on win2003 with in-kernel irqchip.
 
 
 Best Regards,
 
 Alexandre



Re: [Qemu-devel] [PULL for-1.3 0/3] seabios: q35 update

2012-12-04 Thread Jason Baron
On Tue, Dec 04, 2012 at 08:40:27AM +0100, Gerd Hoffmann wrote:
   Hi,
 
  1) legacy ide mode
  
  I can currently create a ide controller on the command-line using
  '-device'. However, on the real h/w there is an IDE compatibility mode
  which essentially advertises an ide controller at the same location that
  the ahci lives at. In fact, it changes the PCI device id. To deal with
  the fact that AHCI has 6 ports and thus 6 possible devices, it then adds
  a second controller for the remaining 2 disks. This shouldn't be too
  hard to emulate. But I'm wondering what we want the qemu interface
  to look like? A -machine options such as:
  '-machine q35,diskmode=ahci,ide,raid'? 
 
 I'm wondering whenever we want to deal with that at all?
 
 If your guest is too old to handle ahci natively, just stick to piix.
 is a sensible policy IMHO.
 

There was some discussion of trying to make q35 the default for 1.4, in
which case it may be important to support older OS's such as WinXP.

Anthony, do you have any opinion on this?


  2) HPET ACPI error
  
  This line: 'IRQNoFlags () {2, 8}' in the HPET acpi table is causing the
  folloing ACPI message (removing it makes it go away):
 
 Hmm.  That was added to make macos x happy and is also present on real
 hardware, so I'm wondering what is going on here.
 

I also noticed that on Windows 7, the 'IRQNoFlags' line above makes the RTC
clock complain that it does not have resources available. While removing the
above line, removes that error.

thanks,

-Jason



Re: [Qemu-devel] [PULL for-1.3 0/3] seabios: q35 update

2012-12-03 Thread Jason Baron
On Mon, Dec 03, 2012 at 11:11:55AM +0100, Gerd Hoffmann wrote:
   Hi,
 
 Most q35 seabios patches just landed upstream.  So here we go with a
 last-minute pull to plumb the missing q35 bits.  It obviously updates
 seabios again.  It also adds autoloading for the acpi dsdt table.
 
 With this pull qemu -M q35 JustWorks[tm].
 
 please pull,
   Gerd
 

Hi,

Feel free to add my Acked-by: Jason Baron jba...@redhat.com
to the series.

I've just been looking at WindowsXP support and there are a few issues
that need to be resolved to make it work with the current q35 code.

1) legacy ide mode

I can currently create a ide controller on the command-line using
'-device'. However, on the real h/w there is an IDE compatibility mode
which essentially advertises an ide controller at the same location that
the ahci lives at. In fact, it changes the PCI device id. To deal with
the fact that AHCI has 6 ports and thus 6 possible devices, it then adds
a second controller for the remaining 2 disks. This shouldn't be too
hard to emulate. But I'm wondering what we want the qemu interface
to look like? A -machine options such as:
'-machine q35,diskmode=ahci,ide,raid'? 

2) HPET ACPI error

This line: 'IRQNoFlags () {2, 8}' in the HPET acpi table is causing the
folloing ACPI message (removing it makes it go away):


A problem has been detected and windows has been shut down to prevent damage
to your computer.

If this is the first time you've seen this Stop error screen,
restart your computer. If this screen appears again, follow
these steps:

Check To be sure you have adequate disk space. If a driver is
identified in The stop message, disable the driver or check
with the manufacturer for driver updates. Try changing video
adapters.

Check with your hardware vendor for any BIOS updates. Disable
BIOS memory options such as caching or shadowing. If you need
to use safe mode to remove or disable components, restart your
computer, press F8 To select Advanced startup opTions, and then
select safe mode.

Technical information:


*** STOP: Ox007E (OxC005,OxFADF8FCEDA83,OxFADF90631540,O
xFADF90630F50)



***acpi.sys - Address FADF8FCEDA83 base at FADF8FCDA000, DateStamp
42435eae


3) irq table

The irq table commit that makes windows 7 work, upsets Windows XP. If
I back out seabios commit: 2114f50148c42e374586359d23b522483ca10e8d
I do not get the following error:


A problem has been detected and windows has been shut down To prevent damage
to your computer.

If this is The first time you've seen this stop error screen,
restart your computer. If this screen appears again, follow
these steps:

The BIOS in this sysTem is not fully ACPI compliant. Please contact your
system vendor for an updated BIOS.  If you are unable to obtain an
updated BIOS or the latest BIOS supplied by your vendor is not ACPI
compliant, you can turn off ACPI mode during textmode setup.  To do this,
press The F7 key when you are prompted To install storage drivers. The
system will not notify you that the F7 key was pressed - it will silently
disable ACPI and allow you to continue your installation.

Technical informaTion:

*** STOP: 0x00A5 (Ox00010006,OxFADF9C461108,0x,0
x)



Thanks,

-Jason



Re: [Qemu-devel] [PATCH V10 2/8] hw/apm.c: replace register_ioport*

2012-11-27 Thread Jason Baron
On Tue, Nov 27, 2012 at 01:10:16AM +0100, Andreas Färber wrote:
 Am 19.09.2012 13:50, schrieb Julien Grall:
  This patch replaces all register_ioport* by a MemorySection.
  It permits to use the new Memory stuff like listener.
  
  Moreover, the PCI is added as an argument for apm_init, so we
  can register IO inside the pci IO address space.
  
  Signed-off-by: Julien Grall julien.gr...@citrix.com
 
 Following today's q35 merge I needed the following diff to fix the build:
 
 diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c
 index 2fc83a4..7de5427 100644
 --- a/hw/lpc_ich9.c
 +++ b/hw/lpc_ich9.c
 @@ -472,7 +472,7 @@ static int ich9_lpc_initfn(PCIDevice *d)
  lpc-isa_bus = isa_bus;
 
  ich9_cc_init(lpc);
 -apm_init(lpc-apm, ich9_apm_ctrl_changed, lpc);
 +apm_init(d, lpc-apm, ich9_apm_ctrl_changed, lpc);
  return 0;
  }
 
 Julien/Jason, can you please verify that this is the correct device to pass?
 

Looks correct to me.

Thanks,

-Jason



Re: [Qemu-devel] [PATCH v4 05/14 (re-post)] ich9: Add acpi support and definitions

2012-11-22 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Lay the groundwork for subsequent ich9 support.

Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---

 hw/Makefile.objs |2 
 hw/acpi_ich9.c   |  315 ++
 hw/acpi_ich9.h   |   47 
 hw/ich9.h|  207 +++
 hw/pci_ids.h |   12 ++
 5 files changed, 582 insertions(+), 1 deletions(-)
 create mode 100644 hw/acpi_ich9.c
 create mode 100644 hw/acpi_ich9.h
 create mode 100644 hw/ich9.h


diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index be9ef83..650ff0d 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -27,7 +27,7 @@ common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
 common-obj-$(CONFIG_PCSPK) += pcspk.o
 common-obj-$(CONFIG_PCKBD) += pckbd.o
 common-obj-$(CONFIG_FDC) += fdc.o
-common-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
+common-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o acpi_ich9.o
 common-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 common-obj-$(CONFIG_DMA) += dma.o
 common-obj-$(CONFIG_I82374) += i82374.o
diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
new file mode 100644
index 000..c45921c
--- /dev/null
+++ b/hw/acpi_ich9.c
@@ -0,0 +1,315 @@
+/*
+ * ACPI implementation
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 http://www.gnu.org/licenses/
+ */
+/*
+ *  Copyright (c) 2009 Isaku Yamahata yamahata at valinux co jp
+ * VA Linux Systems Japan K.K.
+ *  Copyright (C) 2012 Jason Baron jba...@redhat.com
+ *
+ *  This is based on acpi.c.
+ */
+#include hw.h
+#include pc.h
+#include pci.h
+#include qemu-timer.h
+#include sysemu.h
+#include acpi.h
+
+#include ich9.h
+
+//#define DEBUG
+
+#ifdef DEBUG
+#define ICH9_DEBUG(fmt, ...) \
+do { printf(%s fmt, __func__, ## __VA_ARGS__); } while (0)
+#else
+#define ICH9_DEBUG(fmt, ...)do { } while (0)
+#endif
+
+static void pm_ioport_write_fallback(void *opaque, uint32_t addr, int len,
+ uint32_t val);
+static uint32_t pm_ioport_read_fallback(void *opaque, uint32_t addr, int len);
+
+static void pm_update_sci(ICH9LPCPMRegs *pm)
+{
+int sci_level, pm1a_sts;
+
+pm1a_sts = acpi_pm1_evt_get_sts(pm-acpi_regs);
+
+sci_level = (((pm1a_sts  pm-acpi_regs.pm1.evt.en) 
+  (ACPI_BITMASK_RT_CLOCK_ENABLE |
+   ACPI_BITMASK_POWER_BUTTON_ENABLE |
+   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
+   ACPI_BITMASK_TIMER_ENABLE)) != 0);
+qemu_set_irq(pm-irq, sci_level);
+
+/* schedule a timer interruption if needed */
+acpi_pm_tmr_update(pm-acpi_regs,
+   (pm-acpi_regs.pm1.evt.en  ACPI_BITMASK_TIMER_ENABLE) 

+   !(pm1a_sts  ACPI_BITMASK_TIMER_STATUS));
+}
+
+static void ich9_pm_update_sci_fn(ACPIREGS *regs)
+{
+ICH9LPCPMRegs *pm = container_of(regs, ICH9LPCPMRegs, acpi_regs);
+pm_update_sci(pm);
+}
+
+static void pm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+ICH9LPCPMRegs *pm = opaque;
+
+switch (addr  ICH9_PMIO_MASK) {
+case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN - 1):
+acpi_gpe_ioport_writeb(pm-acpi_regs, addr, val);
+break;
+default:
+break;
+}
+
+ICH9_DEBUG(port=0x%04x val=0x%04x\n, addr, val);
+}
+
+static uint32_t pm_ioport_readb(void *opaque, uint32_t addr)
+{
+ICH9LPCPMRegs *pm = opaque;
+uint32_t val = 0;
+
+switch (addr  ICH9_PMIO_MASK) {
+case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN - 1):
+val = acpi_gpe_ioport_readb(pm-acpi_regs, addr);
+break;
+default:
+val = 0;
+break;
+}
+ICH9_DEBUG(port=0x%04x val=0x%04x\n, addr, val);
+return val;
+}
+
+static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
+{
+ICH9LPCPMRegs *pm = opaque;
+
+switch (addr  ICH9_PMIO_MASK) {
+case ICH9_PMIO_PM1_STS:
+acpi_pm1_evt_write_sts(pm-acpi_regs, val);
+pm_update_sci(pm);
+break;
+case ICH9_PMIO_PM1_EN:
+pm-acpi_regs.pm1.evt.en = val;
+pm_update_sci(pm);
+break;
+case ICH9_PMIO_PM1_CNT:
+acpi_pm1_cnt_write(pm-acpi_regs, val, 0);
+break;
+default:
+pm_ioport_write_fallback(opaque, addr, 2, val);
+break;
+}
+ICH9_DEBUG(port=0x%04x val=0x%04x\n, addr, val

Re: [Qemu-devel] [PATCH v4 07/14 (re-post)] ich9: Add smbus

2012-11-22 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Add support for the ich9 smbus chip.

Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---

 hw/Makefile.objs |2 -
 hw/smbus_ich9.c  |  159 ++
 2 files changed, 160 insertions(+), 1 deletions(-)
 create mode 100644 hw/smbus_ich9.c


diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 650ff0d..e593596 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -27,7 +27,7 @@ common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
 common-obj-$(CONFIG_PCSPK) += pcspk.o
 common-obj-$(CONFIG_PCKBD) += pckbd.o
 common-obj-$(CONFIG_FDC) += fdc.o
-common-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o acpi_ich9.o
+common-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o acpi_ich9.o smbus_ich9.o
 common-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 common-obj-$(CONFIG_DMA) += dma.o
 common-obj-$(CONFIG_I82374) += i82374.o
diff --git a/hw/smbus_ich9.c b/hw/smbus_ich9.c
new file mode 100644
index 000..6940583
--- /dev/null
+++ b/hw/smbus_ich9.c
@@ -0,0 +1,159 @@
+/*
+ * ACPI implementation
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 http://www.gnu.org/licenses/
+ */
+/*
+ *  Copyright (c) 2009 Isaku Yamahata yamahata at valinux co jp
+ * VA Linux Systems Japan K.K.
+ *  Copyright (C) 2012 Jason Baron jba...@redhat.com
+ *
+ *  This is based on acpi.c, but heavily rewritten.
+ */
+#include hw.h
+#include pc.h
+#include pm_smbus.h
+#include pci.h
+#include sysemu.h
+#include i2c.h
+#include smbus.h
+
+#include ich9.h
+
+#define TYPE_ICH9_SMB_DEVICE ICH9 SMB
+#define ICH9_SMB_DEVICE(obj) \
+ OBJECT_CHECK(ICH9SMBState, (obj), TYPE_ICH9_SMB_DEVICE)
+
+typedef struct ICH9SMBState {
+PCIDevice dev;
+
+PMSMBus smb;
+MemoryRegion mem_bar;
+} ICH9SMBState;
+
+static const VMStateDescription vmstate_ich9_smbus = {
+.name = ich9_smb,
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_PCI_DEVICE(dev, struct ICH9SMBState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void ich9_smb_ioport_writeb(void *opaque, hwaddr addr,
+   uint64_t val, unsigned size)
+{
+ICH9SMBState *s = opaque;
+uint8_t hostc = s-dev.config[ICH9_SMB_HOSTC];
+
+if ((hostc  ICH9_SMB_HOSTC_HST_EN)  !(hostc  ICH9_SMB_HOSTC_I2C_EN)) {
+uint64_t offset = addr - s-dev.io_regions[ICH9_SMB_SMB_BASE_BAR].addr;
+smb_ioport_writeb(s-smb, offset, val);
+}
+}
+
+static uint64_t ich9_smb_ioport_readb(void *opaque, hwaddr addr,
+  unsigned size)
+{
+ICH9SMBState *s = opaque;
+uint8_t hostc = s-dev.config[ICH9_SMB_HOSTC];
+
+if ((hostc  ICH9_SMB_HOSTC_HST_EN)  !(hostc  ICH9_SMB_HOSTC_I2C_EN)) {
+uint64_t offset = addr - s-dev.io_regions[ICH9_SMB_SMB_BASE_BAR].addr;
+return smb_ioport_readb(s-smb, offset);
+}
+
+return 0xff;
+}
+
+static const MemoryRegionOps lpc_smb_mmio_ops = {
+.read = ich9_smb_ioport_readb,
+.write = ich9_smb_ioport_writeb,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.impl = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
+};
+
+static int ich9_smbus_initfn(PCIDevice *d)
+{
+ICH9SMBState *s = ICH9_SMB_DEVICE(d);
+
+/* TODO? D31IP.SMIP in chipset configuration space */
+pci_config_set_interrupt_pin(d-config, 0x01); /* interrupt pin 1 */
+
+pci_set_byte(d-config + ICH9_SMB_HOSTC, 0);
+
+/*
+ * update parameters based on
+ * paralell_hds[0]
+ * serial_hds[0]
+ * serial_hds[0]
+ * fdc
+ *
+ * Is there any OS that depends on them?
+ */
+
+/* TODO smb_io_base */
+pci_set_byte(d-config + ICH9_SMB_HOSTC, 0);
+/* TODO bar0, bar1: 64bit BAR support*/
+
+memory_region_init_io(s-mem_bar, lpc_smb_mmio_ops, s, ich9-smbus-bar,
+ICH9_SMB_SMB_BASE_SIZE);
+pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
+s-mem_bar);
+pm_smbus_init(d-qdev, s-smb);
+return 0;
+}
+
+static void ich9_smb_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+k-vendor_id = PCI_VENDOR_ID_INTEL;
+k-device_id = PCI_DEVICE_ID_INTEL_ICH9_6;
+k-revision

Re: [Qemu-devel] [PATCH v4 00/14] Add Q35 base support

2012-11-22 Thread Jason Baron
On Thu, Nov 22, 2012 at 12:24:43PM +0100, Gerd Hoffmann wrote:
  These patches are intened to give us a base set of patches for Q35 upon 
  which
  to build. The major change in this series is to add the memory controller 
  hub,
  or 'mch' as proper member of the q35 host structure. This change refactors 
  the
 
 Fails to build with all targets enabled:
 
 [ ... ]
 
   LINK  alpha-softmmu/qemu-system-alpha
 ../hw/acpi_ich9.o: In function `ich9_pm_init':
 acpi_ich9.c:(.text+0x5d): undefined reference to `acpi_pm_tmr_init'
 acpi_ich9.c:(.text+0x65): undefined reference to `acpi_pm1_cnt_init'
 acpi_ich9.c:(.text+0x72): undefined reference to `acpi_gpe_init'
 
 [ ... ]
 
 cheers,
   Gerd
 

Adding the patch below fixes this:


diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 0e17fbe..6c4cf09 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -28,7 +28,7 @@ common-obj-$(CONFIG_I8254) += i8254_common.o i8254.o
 common-obj-$(CONFIG_PCSPK) += pcspk.o
 common-obj-$(CONFIG_PCKBD) += pckbd.o
 common-obj-$(CONFIG_FDC) += fdc.o
-common-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o
+common-obj-$(CONFIG_ACPI) += acpi.o acpi_piix4.o acpi_ich9.o smbus_ich9.o
 common-obj-$(CONFIG_APM) += pm_smbus.o apm.o
 common-obj-$(CONFIG_DMA) += dma.o
 common-obj-$(CONFIG_I82374) += i82374.o
@@ -39,7 +39,6 @@ common-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
 common-obj-$(CONFIG_I8259) += i8259_common.o i8259.o
 common-obj-y += fifo.o
 common-obj-y += pam.o
-common-obj-y += acpi_ich9.o smbus_ich9.o
 
 # PPC devices
 common-obj-$(CONFIG_PREP_PCI) += prep_pci.o



I've also re-posted patches 5  7, to reflect this update. Thanks for
pointing this out.

Thanks,

-Jason



Re: [Qemu-devel] TCP based PCIE request forwarding

2012-11-20 Thread Jason Baron
On Fri, Nov 16, 2012 at 09:39:07AM +0100, lementec fabien wrote:
 Hi,
 
 I am a software engineer who works in an electronic group. Using QEMU
 to emulate devices allows me to start writing and testing LINUX software
 before the device is actually available. In the group, we are mostly
 working with XILINX FPGAs, communicating with the host via PCIE. The
 devices are implemented in VHDL.

As you know the current PCI config space is limited to 256 bytes on x86. I was
wondering then, if you needed to work around this limitation in any way
since you've mentioned you're using PCIE (which has a 4k config space)?

Thanks,

-Jason




[Qemu-devel] [PATCH v4 00/14] Add Q35 base support

2012-11-14 Thread Jason Baron
Hi,

These patches are intened to give us a base set of patches for Q35 upon which
to build. The major change in this series is to add the memory controller hub,
or 'mch' as proper member of the q35 host structure. This change refactors the
code a bit, and moves more intialization out of pc_q35.c and into q35.c. We
probably could go further and introduce a generic north bridge class and make
the 'mch' a child of it, but I'm not proposing that kind of change this late in
the development cycle.

I've also dropped as many non-essential bits as possible, such as if=ahci from
the patch series. Patches 13-14 allow the use of the '-L' option to specify
the directory of the q35 dsdt table. These aren't strictly necessary. As one
could pass:

-bios /root/seabios/seabios/out/bios.bin
-acpitable file=/root/seabios/seabios/out/q35-acpi-dsdt.aml

But its rather cumbersome, and including the automatic load of the dsdt table,
is the future direction. That is, once the seabios bits are included we can
pull the q35 dsdt table into the qemu tree, and avoid extra options altogether.

Testing:

I've booted f16, f17, Windows7, Windows 8. (BSDs and Win xp work with a
piix3-ide controller). And Gabriel Somlo has reported success with Mac OS X.
I'm also going to look at writing qtest cases.

Thanks,

-Jason

Git trees:

git://github.com/jibaron/q35-qemu.git
git://github.com/jibaron/q35-seabios.git

Todo:

-add ahci migration back (need to cover more fields, but basically works)
-add ACPI hotplug support (pcie hotplug is currently working)
-add qtest test cases

Changes from v3:
 -Compose 'mch' as part of the q35 host strucuture
 -cleanup naming
 -drop if=ahci

Changes from v2:
 -Patch restructure (broke out ich9 chips + data structures separately)
 -added passthrough support
 -add support for -usb to fill out host pci bus
 -Dropped automatic load of dsdt table for piix
 -cleanups
 -dropped wmask on smbus (mst)
 -sparse host bus

Changes from v1:
 -Updated end of low mem from 0xe000 - 0xb000 (Gerd Hoffmann)
-so 0xb00-0xc00 is memconfig
-0xc00-0xfec0 is 32-bit pci window
 -style/various cleanups
 -introduced IF_AHCI
 -introduced mach_if
 -split dsdt out of bios, now passed for piix4 as well (Paolo, Gerd)
 -Removed add opaque argument to pci_map_irq_fn (Michael S. Tsirkin)
 -removed patches that were merged in v1

Isaku Yamahata (3):
  pc, pc_piix: split out pc nic initialization
  pc/piix_pci: factor out smram/pam logic
  q35: Introduce q35 pc based chipset emulator

Jan Kiszka (3):
  q35: Suppress SMM BIOS initialization under KVM
  q35: Fix non-PCI IRQ processing in ich9_lpc_update_apic
  q35: Add kvmclock support

Jason Baron (8):
  pc: Move ioapic_init() from pc_piix.c to pc.c
  pc_piix: Move kvm irq routing functions out of pc_piix.c
  ich9: Add acpi support and definitions
  ich9: Add the lpc chip
  ich9: Add smbus
  ich9: Add i82801b11 dmi-to-pci bridge
  Add a fallback bios file search, if -L fails.
  q35: automatically load the q35 dsdt table

 hw/Makefile.objs  |3 +
 hw/acpi_ich9.c|  322 ++
 hw/acpi_ich9.h|   47 +
 hw/i386/Makefile.objs |1 +
 hw/i82801b11.c|  125 
 hw/ich9.h |  207 +++
 hw/kvm/ioapic.c   |   40 
 hw/lpc_ich9.c |  525 +
 hw/pam.c  |   87 
 hw/pam.h  |   97 +
 hw/pc.c   |   58 ++
 hw/pc.h   |5 +
 hw/pc_piix.c  |   79 +---
 hw/pc_q35.c   |  230 +
 hw/pci_ids.h  |   14 ++
 hw/piix_pci.c |   68 ++-
 hw/q35.c  |  309 +
 hw/q35.h  |  150 ++
 hw/smbus_ich9.c   |  159 +++
 kvm.h |2 +
 vl.c  |   36 +++-
 21 files changed, 2425 insertions(+), 139 deletions(-)
 create mode 100644 hw/acpi_ich9.c
 create mode 100644 hw/acpi_ich9.h
 create mode 100644 hw/i82801b11.c
 create mode 100644 hw/ich9.h
 create mode 100644 hw/lpc_ich9.c
 create mode 100644 hw/pam.c
 create mode 100644 hw/pam.h
 create mode 100644 hw/pc_q35.c
 create mode 100644 hw/q35.c
 create mode 100644 hw/q35.h
 create mode 100644 hw/smbus_ich9.c




[Qemu-devel] [PATCH v4 06/14] ich9: Add the lpc chip

2012-11-14 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Add support for the ICH9 LPC chip.

Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/i386/Makefile.objs |1 +
 hw/lpc_ich9.c |  523 +
 2 files changed, 524 insertions(+), 0 deletions(-)
 create mode 100644 hw/lpc_ich9.c

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 8c764bb..9543a69 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -6,6 +6,7 @@ obj-y += pci-hotplug.o smbios.o wdt_ib700.o
 obj-y += debugcon.o multiboot.o
 obj-y += pc_piix.o
 obj-y += pc_sysfw.o
+obj-y += lpc_ich9.o
 obj-$(CONFIG_XEN) += xen_platform.o xen_apic.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o
diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c
new file mode 100644
index 000..f8f06b3
--- /dev/null
+++ b/hw/lpc_ich9.c
@@ -0,0 +1,523 @@
+/*
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the Software), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/*
+ * QEMU ICH9 Emulation
+ *
+ *  Copyright (c) 2009, 2010, 2011
+ *Isaku Yamahata yamahata at valinux co jp
+ *VA Linux Systems Japan K.K.
+ *  Copyright (C) 2012 Jason Baron jba...@redhat.com
+ *
+ *  This is based on piix_pci.c, but heavily modified.
+ *
+ * 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 http://www.gnu.org/licenses/
+ */
+
+#include qemu-common.h
+#include hw.h
+#include range.h
+#include isa.h
+#include sysbus.h
+#include pc.h
+#include apm.h
+#include ioapic.h
+#include pci.h
+#include pcie_host.h
+#include pci_bridge.h
+#include ich9.h
+#include acpi.h
+#include acpi_ich9.h
+#include pam.h
+#include pci_internals.h
+#include exec-memory.h
+
+static int ich9_lpc_sci_irq(ICH9LPCState *lpc);
+
+/*/
+/* ICH9 LPC PCI to ISA bridge */
+
+static void ich9_lpc_reset(DeviceState *qdev);
+
+/* chipset configuration register
+ * to access chipset configuration registers, pci_[sg]et_{byte, word, long}
+ * are used.
+ * Although it's not pci configuration space, it's little endian as Intel.
+ */
+
+static void ich9_cc_update_ir(uint8_t irr[PCI_NUM_PINS], uint16_t ir)
+{
+int intx;
+for (intx = 0; intx  PCI_NUM_PINS; intx++) {
+irr[intx] = (ir  (intx * ICH9_CC_DIR_SHIFT))  ICH9_CC_DIR_MASK;
+}
+}
+
+static void ich9_cc_update(ICH9LPCState *lpc)
+{
+int slot;
+int pci_intx;
+
+const int reg_offsets[] = {
+ICH9_CC_D25IR,
+ICH9_CC_D26IR,
+ICH9_CC_D27IR,
+ICH9_CC_D28IR,
+ICH9_CC_D29IR,
+ICH9_CC_D30IR,
+ICH9_CC_D31IR,
+};
+const int *offset;
+
+/* D{25 - 31}IR, but D30IR is read only to 0. */
+for (slot = 25, offset = reg_offsets; slot  32; slot++, offset++) {
+if (slot == 30) {
+continue;
+}
+ich9_cc_update_ir(lpc-irr[slot],
+  pci_get_word(lpc-chip_config + *offset));
+}
+
+/*
+ * D30: DMI2PCI bridge
+ * It is arbitrarily decided how INTx lines of PCI devicesbehind the bridge
+ * are connected to pirq lines. Our choice is PIRQ[E-H].
+ * INT[A-D] are connected to PIRQ[E-H]
+ */
+for (pci_intx = 0; pci_intx

[Qemu-devel] [PATCH v4 11/14] q35: Fix non-PCI IRQ processing in ich9_lpc_update_apic

2012-11-14 Thread Jason Baron
From: Jan Kiszka jan.kis...@siemens.com

Avoid passing a non-PCI IRQ to ich9_gsi_to_pirq. It's wrong and triggers
an assertion.

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/lpc_ich9.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c
index f8f06b3..2fc83a4 100644
--- a/hw/lpc_ich9.c
+++ b/hw/lpc_ich9.c
@@ -264,9 +264,11 @@ static int ich9_gsi_to_pirq(int gsi)
 
 static void ich9_lpc_update_apic(ICH9LPCState *lpc, int gsi)
 {
-int level;
+int level = 0;
 
-level = pci_bus_get_irq_level(lpc-d.bus, ich9_gsi_to_pirq(gsi));
+if (gsi = ICH9_LPC_PIC_NUM_PINS) {
+level |= pci_bus_get_irq_level(lpc-d.bus, ich9_gsi_to_pirq(gsi));
+}
 if (gsi == ich9_lpc_sci_irq(lpc)) {
 level |= lpc-sci_level;
 }
-- 
1.7.1




[Qemu-devel] [PATCH v4 01/14] pc, pc_piix: split out pc nic initialization

2012-11-14 Thread Jason Baron
From: Isaku Yamahata yamah...@valinux.co.jp

Factor out pc nic initialization.
This simplifies the pc initialization and will reduce the code
duplication of q35 pc initialization.

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Reviewed-by: Anthony Liguori aligu...@us.ibm.com
Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/pc.c  |   15 +++
 hw/pc.h  |1 +
 hw/pc_piix.c |9 +
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 4aca498..04553f8 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1058,6 +1058,21 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
 *floppy = fdctrl_init_isa(isa_bus, fd);
 }
 
+void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus)
+{
+int i;
+
+for (i = 0; i  nb_nics; i++) {
+NICInfo *nd = nd_table[i];
+
+if (!pci_bus || (nd-model  strcmp(nd-model, ne2k_isa) == 0)) {
+pc_init_ne2k_isa(isa_bus, nd);
+} else {
+pci_nic_init_nofail(nd, e1000, NULL);
+}
+}
+}
+
 void pc_pci_device_init(PCIBus *pci_bus)
 {
 int max_bus;
diff --git a/hw/pc.h b/hw/pc.h
index e7993ca..d6639a6 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -98,6 +98,7 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
above_4g_mem_size,
   const char *boot_device,
   ISADevice *floppy, BusState *ide0, BusState *ide1,
   ISADevice *s);
+void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus);
 void pc_pci_device_init(PCIBus *pci_bus);
 
 typedef void (*cpu_set_smm_t)(int smm, void *arg);
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index cfa839c..910d417 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -234,14 +234,7 @@ static void pc_init1(MemoryRegion *system_memory,
 /* init basic PC hardware */
 pc_basic_device_init(isa_bus, gsi, rtc_state, floppy, xen_enabled());
 
-for(i = 0; i  nb_nics; i++) {
-NICInfo *nd = nd_table[i];
-
-if (!pci_enabled || (nd-model  strcmp(nd-model, ne2k_isa) == 0))
-pc_init_ne2k_isa(isa_bus, nd);
-else
-pci_nic_init_nofail(nd, e1000, NULL);
-}
+pc_nic_init(isa_bus, pci_bus);
 
 ide_drive_get(hd, MAX_IDE_BUS);
 if (pci_enabled) {
-- 
1.7.1




[Qemu-devel] [PATCH v4 03/14] pc_piix: Move kvm irq routing functions out of pc_piix.c

2012-11-14 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Rename: kvm_piix3_gsi_handlei() - kvm_pc_gsi_handler()
kvm_piix3_setup_irq_routing() - kvm_pc_setup_irq_routing()

This is in preparation for other users, namely q35 at this time.

Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/kvm/ioapic.c |   40 
 hw/pc_piix.c|   45 ++---
 kvm.h   |2 ++
 3 files changed, 44 insertions(+), 43 deletions(-)

diff --git a/hw/kvm/ioapic.c b/hw/kvm/ioapic.c
index 6c3b8fe..f95c157 100644
--- a/hw/kvm/ioapic.c
+++ b/hw/kvm/ioapic.c
@@ -15,6 +15,46 @@
 #include hw/apic_internal.h
 #include kvm.h
 
+/* PC Utility function */
+void kvm_pc_setup_irq_routing(bool pci_enabled)
+{
+KVMState *s = kvm_state;
+int i;
+
+if (kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) {
+for (i = 0; i  8; ++i) {
+if (i == 2) {
+continue;
+}
+kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_MASTER, i);
+}
+for (i = 8; i  16; ++i) {
+kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
+}
+if (pci_enabled) {
+for (i = 0; i  24; ++i) {
+if (i == 0) {
+kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, 2);
+} else if (i != 2) {
+kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, i);
+}
+}
+}
+}
+}
+
+void kvm_pc_gsi_handler(void *opaque, int n, int level)
+{
+GSIState *s = opaque;
+
+if (n  ISA_NUM_IRQS) {
+/* Kernel will forward to both PIC and IOAPIC */
+qemu_set_irq(s-i8259_irq[n], level);
+} else {
+qemu_set_irq(s-ioapic_irq[n], level);
+}
+}
+
 typedef struct KVMIOAPICState KVMIOAPICState;
 
 struct KVMIOAPICState {
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index e460799..aa3e7f4 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -54,47 +54,6 @@ static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
 static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
 static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
 
-static void kvm_piix3_setup_irq_routing(bool pci_enabled)
-{
-#ifdef CONFIG_KVM
-KVMState *s = kvm_state;
-int i;
-
-if (kvm_check_extension(s, KVM_CAP_IRQ_ROUTING)) {
-for (i = 0; i  8; ++i) {
-if (i == 2) {
-continue;
-}
-kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_MASTER, i);
-}
-for (i = 8; i  16; ++i) {
-kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_PIC_SLAVE, i - 8);
-}
-if (pci_enabled) {
-for (i = 0; i  24; ++i) {
-if (i == 0) {
-kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, 2);
-} else if (i != 2) {
-kvm_irqchip_add_irq_route(s, i, KVM_IRQCHIP_IOAPIC, i);
-}
-}
-}
-}
-#endif /* CONFIG_KVM */
-}
-
-static void kvm_piix3_gsi_handler(void *opaque, int n, int level)
-{
-GSIState *s = opaque;
-
-if (n  ISA_NUM_IRQS) {
-/* Kernel will forward to both PIC and IOAPIC */
-qemu_set_irq(s-i8259_irq[n], level);
-} else {
-qemu_set_irq(s-ioapic_irq[n], level);
-}
-}
-
 /* PC hardware initialisation */
 static void pc_init1(MemoryRegion *system_memory,
  MemoryRegion *system_io,
@@ -160,8 +119,8 @@ static void pc_init1(MemoryRegion *system_memory,
 
 gsi_state = g_malloc0(sizeof(*gsi_state));
 if (kvm_irqchip_in_kernel()) {
-kvm_piix3_setup_irq_routing(pci_enabled);
-gsi = qemu_allocate_irqs(kvm_piix3_gsi_handler, gsi_state,
+kvm_pc_setup_irq_routing(pci_enabled);
+gsi = qemu_allocate_irqs(kvm_pc_gsi_handler, gsi_state,
  GSI_NUM_PINS);
 } else {
 gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
diff --git a/kvm.h b/kvm.h
index 1e7f244..72d866a 100644
--- a/kvm.h
+++ b/kvm.h
@@ -275,4 +275,6 @@ void kvm_irqchip_release_virq(KVMState *s, int virq);
 
 int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, int virq);
 int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq);
+void kvm_pc_gsi_handler(void *opaque, int n, int level);
+void kvm_pc_setup_irq_routing(bool pci_enabled);
 #endif
-- 
1.7.1




[Qemu-devel] [PATCH v4 07/14] ich9: Add smbus

2012-11-14 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Add support for the ich9 smbus chip.

Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/Makefile.objs |2 +-
 hw/smbus_ich9.c  |  159 ++
 2 files changed, 160 insertions(+), 1 deletions(-)
 create mode 100644 hw/smbus_ich9.c

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 0d1348c..02424ac 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -38,7 +38,7 @@ common-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
 common-obj-$(CONFIG_I8259) += i8259_common.o i8259.o
 common-obj-y += fifo.o
 common-obj-y += pam.o
-common-obj-y += acpi_ich9.o
+common-obj-y += acpi_ich9.o smbus_ich9.o
 
 # PPC devices
 common-obj-$(CONFIG_PREP_PCI) += prep_pci.o
diff --git a/hw/smbus_ich9.c b/hw/smbus_ich9.c
new file mode 100644
index 000..6940583
--- /dev/null
+++ b/hw/smbus_ich9.c
@@ -0,0 +1,159 @@
+/*
+ * ACPI implementation
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 http://www.gnu.org/licenses/
+ */
+/*
+ *  Copyright (c) 2009 Isaku Yamahata yamahata at valinux co jp
+ * VA Linux Systems Japan K.K.
+ *  Copyright (C) 2012 Jason Baron jba...@redhat.com
+ *
+ *  This is based on acpi.c, but heavily rewritten.
+ */
+#include hw.h
+#include pc.h
+#include pm_smbus.h
+#include pci.h
+#include sysemu.h
+#include i2c.h
+#include smbus.h
+
+#include ich9.h
+
+#define TYPE_ICH9_SMB_DEVICE ICH9 SMB
+#define ICH9_SMB_DEVICE(obj) \
+ OBJECT_CHECK(ICH9SMBState, (obj), TYPE_ICH9_SMB_DEVICE)
+
+typedef struct ICH9SMBState {
+PCIDevice dev;
+
+PMSMBus smb;
+MemoryRegion mem_bar;
+} ICH9SMBState;
+
+static const VMStateDescription vmstate_ich9_smbus = {
+.name = ich9_smb,
+.version_id = 1,
+.minimum_version_id = 1,
+.minimum_version_id_old = 1,
+.fields = (VMStateField[]) {
+VMSTATE_PCI_DEVICE(dev, struct ICH9SMBState),
+VMSTATE_END_OF_LIST()
+}
+};
+
+static void ich9_smb_ioport_writeb(void *opaque, hwaddr addr,
+   uint64_t val, unsigned size)
+{
+ICH9SMBState *s = opaque;
+uint8_t hostc = s-dev.config[ICH9_SMB_HOSTC];
+
+if ((hostc  ICH9_SMB_HOSTC_HST_EN)  !(hostc  ICH9_SMB_HOSTC_I2C_EN)) {
+uint64_t offset = addr - s-dev.io_regions[ICH9_SMB_SMB_BASE_BAR].addr;
+smb_ioport_writeb(s-smb, offset, val);
+}
+}
+
+static uint64_t ich9_smb_ioport_readb(void *opaque, hwaddr addr,
+  unsigned size)
+{
+ICH9SMBState *s = opaque;
+uint8_t hostc = s-dev.config[ICH9_SMB_HOSTC];
+
+if ((hostc  ICH9_SMB_HOSTC_HST_EN)  !(hostc  ICH9_SMB_HOSTC_I2C_EN)) {
+uint64_t offset = addr - s-dev.io_regions[ICH9_SMB_SMB_BASE_BAR].addr;
+return smb_ioport_readb(s-smb, offset);
+}
+
+return 0xff;
+}
+
+static const MemoryRegionOps lpc_smb_mmio_ops = {
+.read = ich9_smb_ioport_readb,
+.write = ich9_smb_ioport_writeb,
+.endianness = DEVICE_LITTLE_ENDIAN,
+.impl = {
+.min_access_size = 1,
+.max_access_size = 1,
+},
+};
+
+static int ich9_smbus_initfn(PCIDevice *d)
+{
+ICH9SMBState *s = ICH9_SMB_DEVICE(d);
+
+/* TODO? D31IP.SMIP in chipset configuration space */
+pci_config_set_interrupt_pin(d-config, 0x01); /* interrupt pin 1 */
+
+pci_set_byte(d-config + ICH9_SMB_HOSTC, 0);
+
+/*
+ * update parameters based on
+ * paralell_hds[0]
+ * serial_hds[0]
+ * serial_hds[0]
+ * fdc
+ *
+ * Is there any OS that depends on them?
+ */
+
+/* TODO smb_io_base */
+pci_set_byte(d-config + ICH9_SMB_HOSTC, 0);
+/* TODO bar0, bar1: 64bit BAR support*/
+
+memory_region_init_io(s-mem_bar, lpc_smb_mmio_ops, s, ich9-smbus-bar,
+ICH9_SMB_SMB_BASE_SIZE);
+pci_register_bar(d, ICH9_SMB_SMB_BASE_BAR, PCI_BASE_ADDRESS_SPACE_IO,
+s-mem_bar);
+pm_smbus_init(d-qdev, s-smb);
+return 0;
+}
+
+static void ich9_smb_class_init(ObjectClass *klass, void *data)
+{
+DeviceClass *dc = DEVICE_CLASS(klass);
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+k-vendor_id = PCI_VENDOR_ID_INTEL;
+k-device_id = PCI_DEVICE_ID_INTEL_ICH9_6;
+k-revision = ICH9_A2_SMB_REVISION;
+k-class_id = PCI_CLASS_SERIAL_SMBUS;
+dc-no_user = 1;
+dc-vmsd = vmstate_ich9_smbus;
+dc-desc = ICH9

[Qemu-devel] [PATCH v4 02/14] pc: Move ioapic_init() from pc_piix.c to pc.c

2012-11-14 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Move ioapic_init() from pc_piix.c to pc.c, to make it a common function.
Rename ioapic_init() - ioapic_init_gsi().
Move to pc.h so q35 can use them as well.

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/pc.c  |   24 
 hw/pc.h  |2 ++
 hw/pc_piix.c |   25 +
 3 files changed, 27 insertions(+), 24 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 04553f8..2b5bbbf 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1083,3 +1083,27 @@ void pc_pci_device_init(PCIBus *pci_bus)
 pci_create_simple(pci_bus, -1, lsi53c895a);
 }
 }
+
+void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
+{
+DeviceState *dev;
+SysBusDevice *d;
+unsigned int i;
+
+if (kvm_irqchip_in_kernel()) {
+dev = qdev_create(NULL, kvm-ioapic);
+} else {
+dev = qdev_create(NULL, ioapic);
+}
+if (parent_name) {
+object_property_add_child(object_resolve_path(parent_name, NULL),
+  ioapic, OBJECT(dev), NULL);
+}
+qdev_init_nofail(dev);
+d = sysbus_from_qdev(dev);
+sysbus_mmio_map(d, 0, 0xfec0);
+
+for (i = 0; i  IOAPIC_NUM_PINS; i++) {
+gsi_state-ioapic_irq[i] = qdev_get_gpio_in(dev, i);
+}
+}
diff --git a/hw/pc.h b/hw/pc.h
index d6639a6..2237e86 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -104,6 +104,8 @@ void pc_pci_device_init(PCIBus *pci_bus);
 typedef void (*cpu_set_smm_t)(int smm, void *arg);
 void cpu_smm_register(cpu_set_smm_t callback, void *arg);
 
+void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
+
 /* acpi.c */
 extern int acpi_enabled;
 extern char *acpi_tables;
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 910d417..e460799 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -95,29 +95,6 @@ static void kvm_piix3_gsi_handler(void *opaque, int n, int 
level)
 }
 }
 
-static void ioapic_init(GSIState *gsi_state)
-{
-DeviceState *dev;
-SysBusDevice *d;
-unsigned int i;
-
-if (kvm_irqchip_in_kernel()) {
-dev = qdev_create(NULL, kvm-ioapic);
-} else {
-dev = qdev_create(NULL, ioapic);
-}
-/* FIXME: this should be under the piix3.  */
-object_property_add_child(object_resolve_path(i440fx, NULL),
-  ioapic, OBJECT(dev), NULL);
-qdev_init_nofail(dev);
-d = sysbus_from_qdev(dev);
-sysbus_mmio_map(d, 0, 0xfec0);
-
-for (i = 0; i  IOAPIC_NUM_PINS; i++) {
-gsi_state-ioapic_irq[i] = qdev_get_gpio_in(dev, i);
-}
-}
-
 /* PC hardware initialisation */
 static void pc_init1(MemoryRegion *system_memory,
  MemoryRegion *system_io,
@@ -221,7 +198,7 @@ static void pc_init1(MemoryRegion *system_memory,
 gsi_state-i8259_irq[i] = i8259[i];
 }
 if (pci_enabled) {
-ioapic_init(gsi_state);
+ioapic_init_gsi(gsi_state, i440fx);
 }
 
 pc_register_ferr_irq(gsi[13]);
-- 
1.7.1




[Qemu-devel] [PATCH v4 14/14] q35: automatically load the q35 dsdt table

2012-11-14 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Automatically, locate the required q35 dsdt table on load. Otherwise we error
out. This could be done in the bios, but its harder to produce a good error
message.

Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/pc.c |   19 +++
 hw/pc.h |2 ++
 hw/pc_q35.c |7 +++
 3 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 2b5bbbf..35760f0 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1107,3 +1107,22 @@ void ioapic_init_gsi(GSIState *gsi_state, const char 
*parent_name)
 gsi_state-ioapic_irq[i] = qdev_get_gpio_in(dev, i);
 }
 }
+
+int find_and_load_dsdt(const char *dsdt_name)
+{
+char *filename;
+char buf[1024];
+
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dsdt_name);
+if (!filename) {
+return -1;
+}
+snprintf(buf, sizeof(buf), file=%s, filename);
+g_free(filename);
+if (acpi_table_add(buf)  0) {
+fprintf(stderr, Wrong acpi table provided\n);
+return -1;
+}
+
+return 0;
+}
diff --git a/hw/pc.h b/hw/pc.h
index 2237e86..990882d 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -185,5 +185,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory);
 #define E820_UNUSABLE   5
 
 int e820_add_entry(uint64_t, uint64_t, uint32_t);
+int find_and_load_dsdt(const char *dsdt_name);
+
 
 #endif
diff --git a/hw/pc_q35.c b/hw/pc_q35.c
index 3429a9a..e577ec7 100644
--- a/hw/pc_q35.c
+++ b/hw/pc_q35.c
@@ -86,6 +86,13 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 PCIDevice *ahci;
 qemu_irq *cmos_s3;
 
+/* let's first see if we can find the proper dsdt */
+if (find_and_load_dsdt(q35-acpi-dsdt.aml)) {
+fprintf(stderr, Couldn't find q35 dsdt table!\n
+Try updating your bios.\n);
+exit(1);
+}
+
 pc_cpus_init(cpu_model);
 
 kvmclock_create();
-- 
1.7.1




[Qemu-devel] [PATCH v4 13/14] Add a fallback bios file search, if -L fails.

2012-11-14 Thread Jason Baron
From: Jason Baron jba...@redhat.com

If -L dir is specified, and qemu does not find the bios file in dir, then
the search fails. Add infrastructure such that the search will continue in
the default paths, if not found in the -L path.

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Jason Baron jba...@redhat.com
---
 vl.c |   36 +---
 1 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/vl.c b/vl.c
index 4f03a72..56e0492 100644
--- a/vl.c
+++ b/vl.c
@@ -177,6 +177,7 @@ int main(int argc, char **argv)
 #define MAX_VIRTIO_CONSOLES 1
 
 static const char *data_dir;
+static const char *data_dir_fallback;
 const char *bios_name = NULL;
 enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
 DisplayType display_type = DT_DEFAULT;
@@ -2009,16 +2010,16 @@ static int balloon_parse(const char *arg)
 return -1;
 }
 
-char *qemu_find_file(int type, const char *name)
+static char *qemu_find_file_in_dir(int type, const char *name, const char *dir)
 {
 int len;
 const char *subdir;
 char *buf;
 
-/* Try the name as a straight path first */
-if (access(name, R_OK) == 0) {
-return g_strdup(name);
+if (!dir) {
+return NULL;
 }
+
 switch (type) {
 case QEMU_FILE_TYPE_BIOS:
 subdir = ;
@@ -2029,9 +2030,9 @@ char *qemu_find_file(int type, const char *name)
 default:
 abort();
 }
-len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
+len = strlen(dir) + strlen(name) + strlen(subdir) + 2;
 buf = g_malloc0(len);
-snprintf(buf, len, %s/%s%s, data_dir, subdir, name);
+snprintf(buf, len, %s/%s%s, dir, subdir, name);
 if (access(buf, R_OK)) {
 g_free(buf);
 return NULL;
@@ -2039,6 +2040,21 @@ char *qemu_find_file(int type, const char *name)
 return buf;
 }
 
+char *qemu_find_file(int type, const char *name)
+{
+char *filename;
+
+/* Try the name as a straight path first */
+if (access(name, R_OK) == 0) {
+return g_strdup(name);
+}
+filename = qemu_find_file_in_dir(type, name, data_dir);
+if (!filename) {
+filename = qemu_find_file_in_dir(type, name, data_dir_fallback);
+}
+return filename;
+}
+
 static int device_help_func(QemuOpts *opts, void *opaque)
 {
 return qdev_device_help(opts);
@@ -3538,12 +3554,10 @@ int main(int argc, char **argv, char **envp)
 
 /* If no data_dir is specified then try to find it relative to the
executable path.  */
-if (!data_dir) {
-data_dir = os_find_datadir(argv[0]);
-}
+data_dir_fallback = os_find_datadir(argv[0]);
 /* If all else fails use the install path specified when building. */
-if (!data_dir) {
-data_dir = CONFIG_QEMU_DATADIR;
+if (!data_dir_fallback) {
+data_dir_fallback = CONFIG_QEMU_DATADIR;
 }
 
 /*
-- 
1.7.1




[Qemu-devel] [PATCH v4 08/14] q35: Introduce q35 pc based chipset emulator

2012-11-14 Thread Jason Baron
From: Isaku Yamahata yamah...@valinux.co.jp

pc q35 based chipset emulator to support pci express natively. Based on
Anthony Liguori's suggestion, the machine name is 'q35-next', with an alias
of 'q35'. At this point, there are no compatibility guarantees. When the
chipset stabilizes more, we will begin to version the machine names.

Major features which still need to be added:

-Migration support (mostly around ahci)
-ACPI hotplug support (pcie hotplug support is working)
-Passthrough support

Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/i386/Makefile.objs |2 +-
 hw/pc_q35.c   |  220 +++
 hw/pci_ids.h  |2 +
 hw/q35.c  |  309 +
 hw/q35.h  |  150 
 5 files changed, 682 insertions(+), 1 deletions(-)
 create mode 100644 hw/pc_q35.c
 create mode 100644 hw/q35.c
 create mode 100644 hw/q35.h

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 9543a69..0d3f6a8 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -6,7 +6,7 @@ obj-y += pci-hotplug.o smbios.o wdt_ib700.o
 obj-y += debugcon.o multiboot.o
 obj-y += pc_piix.o
 obj-y += pc_sysfw.o
-obj-y += lpc_ich9.o
+obj-y += lpc_ich9.o q35.o pc_q35.o
 obj-$(CONFIG_XEN) += xen_platform.o xen_apic.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o
diff --git a/hw/pc_q35.c b/hw/pc_q35.c
new file mode 100644
index 000..142bf8a
--- /dev/null
+++ b/hw/pc_q35.c
@@ -0,0 +1,220 @@
+/*
+ * Q35 chipset based pc system emulator
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2009, 2010
+ *   Isaku Yamahata yamahata at valinux co jp
+ *   VA Linux Systems Japan K.K.
+ * Copyright (C) 2012 Jason Baron jba...@redhat.com
+ *
+ * This is based on pc.c, but heavily modified.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the Software), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include hw.h
+#include arch_init.h
+#include smbus.h
+#include boards.h
+#include mc146818rtc.h
+#include xen.h
+#include kvm.h
+#include q35.h
+#include exec-memory.h
+#include ich9.h
+#include hw/ide/pci.h
+#include hw/ide/ahci.h
+#include hw/usb.h
+
+/* ICH9 AHCI has 6 ports */
+#define MAX_SATA_PORTS 6
+
+/* set CMOS shutdown status register (index 0xF) as S3_resume(0xFE)
+ *BIOS will read it and start S3 resume at POST Entry */
+static void pc_cmos_set_s3_resume(void *opaque, int irq, int level)
+{
+ISADevice *s = opaque;
+
+if (level) {
+rtc_set_memory(s, 0xF, 0xFE);
+}
+}
+
+/* PC hardware initialisation */
+static void pc_q35_init(QEMUMachineInitArgs *args)
+{
+ram_addr_t ram_size = args-ram_size;
+const char *cpu_model = args-cpu_model;
+const char *kernel_filename = args-kernel_filename;
+const char *kernel_cmdline = args-kernel_cmdline;
+const char *initrd_filename = args-initrd_filename;
+const char *boot_device = args-boot_device;
+ram_addr_t below_4g_mem_size, above_4g_mem_size;
+Q35PCIHost *q35_host;
+PCIBus *host_bus;
+PCIDevice *lpc;
+BusState *idebus[MAX_SATA_PORTS];
+ISADevice *rtc_state;
+ISADevice *floppy;
+MemoryRegion *pci_memory;
+MemoryRegion *rom_memory;
+MemoryRegion *ram_memory;
+GSIState *gsi_state;
+ISABus *isa_bus;
+int pci_enabled = 1;
+qemu_irq *cpu_irq;
+qemu_irq *gsi;
+qemu_irq *i8259;
+int i;
+ICH9LPCState *ich9_lpc;
+PCIDevice *ahci;
+qemu_irq *cmos_s3;
+
+pc_cpus_init(cpu_model);
+
+if (ram_size = 0xb000) {
+above_4g_mem_size = ram_size - 0xb000;
+below_4g_mem_size = 0xb000;
+} else {
+above_4g_mem_size = 0;
+below_4g_mem_size = ram_size;
+}
+
+/* pci enabled */
+if (pci_enabled) {
+pci_memory = g_new(MemoryRegion, 1

[Qemu-devel] [PATCH v4 05/14] ich9: Add acpi support and definitions

2012-11-14 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Lay the groundwork for subsequent ich9 support.

Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/Makefile.objs |1 +
 hw/acpi_ich9.c   |  315 ++
 hw/acpi_ich9.h   |   47 
 hw/ich9.h|  207 +++
 hw/pci_ids.h |   12 ++
 5 files changed, 582 insertions(+), 0 deletions(-)
 create mode 100644 hw/acpi_ich9.c
 create mode 100644 hw/acpi_ich9.h
 create mode 100644 hw/ich9.h

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index be9ef83..0d1348c 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -38,6 +38,7 @@ common-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
 common-obj-$(CONFIG_I8259) += i8259_common.o i8259.o
 common-obj-y += fifo.o
 common-obj-y += pam.o
+common-obj-y += acpi_ich9.o
 
 # PPC devices
 common-obj-$(CONFIG_PREP_PCI) += prep_pci.o
diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
new file mode 100644
index 000..c45921c
--- /dev/null
+++ b/hw/acpi_ich9.c
@@ -0,0 +1,315 @@
+/*
+ * ACPI implementation
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 http://www.gnu.org/licenses/
+ */
+/*
+ *  Copyright (c) 2009 Isaku Yamahata yamahata at valinux co jp
+ * VA Linux Systems Japan K.K.
+ *  Copyright (C) 2012 Jason Baron jba...@redhat.com
+ *
+ *  This is based on acpi.c.
+ */
+#include hw.h
+#include pc.h
+#include pci.h
+#include qemu-timer.h
+#include sysemu.h
+#include acpi.h
+
+#include ich9.h
+
+//#define DEBUG
+
+#ifdef DEBUG
+#define ICH9_DEBUG(fmt, ...) \
+do { printf(%s fmt, __func__, ## __VA_ARGS__); } while (0)
+#else
+#define ICH9_DEBUG(fmt, ...)do { } while (0)
+#endif
+
+static void pm_ioport_write_fallback(void *opaque, uint32_t addr, int len,
+ uint32_t val);
+static uint32_t pm_ioport_read_fallback(void *opaque, uint32_t addr, int len);
+
+static void pm_update_sci(ICH9LPCPMRegs *pm)
+{
+int sci_level, pm1a_sts;
+
+pm1a_sts = acpi_pm1_evt_get_sts(pm-acpi_regs);
+
+sci_level = (((pm1a_sts  pm-acpi_regs.pm1.evt.en) 
+  (ACPI_BITMASK_RT_CLOCK_ENABLE |
+   ACPI_BITMASK_POWER_BUTTON_ENABLE |
+   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
+   ACPI_BITMASK_TIMER_ENABLE)) != 0);
+qemu_set_irq(pm-irq, sci_level);
+
+/* schedule a timer interruption if needed */
+acpi_pm_tmr_update(pm-acpi_regs,
+   (pm-acpi_regs.pm1.evt.en  ACPI_BITMASK_TIMER_ENABLE) 

+   !(pm1a_sts  ACPI_BITMASK_TIMER_STATUS));
+}
+
+static void ich9_pm_update_sci_fn(ACPIREGS *regs)
+{
+ICH9LPCPMRegs *pm = container_of(regs, ICH9LPCPMRegs, acpi_regs);
+pm_update_sci(pm);
+}
+
+static void pm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+ICH9LPCPMRegs *pm = opaque;
+
+switch (addr  ICH9_PMIO_MASK) {
+case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN - 1):
+acpi_gpe_ioport_writeb(pm-acpi_regs, addr, val);
+break;
+default:
+break;
+}
+
+ICH9_DEBUG(port=0x%04x val=0x%04x\n, addr, val);
+}
+
+static uint32_t pm_ioport_readb(void *opaque, uint32_t addr)
+{
+ICH9LPCPMRegs *pm = opaque;
+uint32_t val = 0;
+
+switch (addr  ICH9_PMIO_MASK) {
+case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN - 1):
+val = acpi_gpe_ioport_readb(pm-acpi_regs, addr);
+break;
+default:
+val = 0;
+break;
+}
+ICH9_DEBUG(port=0x%04x val=0x%04x\n, addr, val);
+return val;
+}
+
+static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
+{
+ICH9LPCPMRegs *pm = opaque;
+
+switch (addr  ICH9_PMIO_MASK) {
+case ICH9_PMIO_PM1_STS:
+acpi_pm1_evt_write_sts(pm-acpi_regs, val);
+pm_update_sci(pm);
+break;
+case ICH9_PMIO_PM1_EN:
+pm-acpi_regs.pm1.evt.en = val;
+pm_update_sci(pm);
+break;
+case ICH9_PMIO_PM1_CNT:
+acpi_pm1_cnt_write(pm-acpi_regs, val, 0);
+break;
+default:
+pm_ioport_write_fallback(opaque, addr, 2, val);
+break;
+}
+ICH9_DEBUG(port=0x%04x val=0x%04x\n, addr, val);
+}
+
+static uint32_t pm_ioport_readw(void *opaque, uint32_t addr)
+{
+ICH9LPCPMRegs *pm = opaque;
+uint32_t val;
+
+switch (addr

[Qemu-devel] [PATCH v4 10/14] q35: Suppress SMM BIOS initialization under KVM

2012-11-14 Thread Jason Baron
From: Jan Kiszka jan.kis...@siemens.com

Same as for i44fx: KVM does not support SMM yet. Signal it initialized
to Seabios to avoid failures.

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/acpi_ich9.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index c45921c..61034d3 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -28,6 +28,7 @@
 #include qemu-timer.h
 #include sysemu.h
 #include acpi.h
+#include kvm.h
 
 #include ich9.h
 
@@ -292,6 +293,12 @@ static void pm_reset(void *opaque)
 acpi_pm_tmr_reset(pm-acpi_regs);
 acpi_gpe_reset(pm-acpi_regs);
 
+if (kvm_enabled()) {
+/* Mark SMM as already inited to prevent SMM from running. KVM does not
+ * support SMM mode. */
+pm-smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
+}
+
 pm_update_sci(pm);
 }
 
-- 
1.7.1




[Qemu-devel] [PATCH v4 09/14] ich9: Add i82801b11 dmi-to-pci bridge

2012-11-14 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Add the dmi-to-pci i82801b11 bridge chip. This is the pci bridge chip
that q35 uses on its host bus for PCI bus arbitration.

Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/Makefile.objs |1 +
 hw/i82801b11.c   |  125 ++
 2 files changed, 126 insertions(+), 0 deletions(-)
 create mode 100644 hw/i82801b11.c

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index 02424ac..0e17fbe 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -9,6 +9,7 @@ common-obj-$(CONFIG_PCI) += shpc.o
 common-obj-$(CONFIG_PCI) += slotid_cap.o
 common-obj-$(CONFIG_PCI) += pci_host.o pcie_host.o
 common-obj-$(CONFIG_PCI) += ioh3420.o xio3130_upstream.o xio3130_downstream.o
+common-obj-$(CONFIG_PCI) += i82801b11.o
 common-obj-y += watchdog.o
 common-obj-$(CONFIG_ISA_MMIO) += isa_mmio.o
 common-obj-$(CONFIG_ECC) += ecc.o
diff --git a/hw/i82801b11.c b/hw/i82801b11.c
new file mode 100644
index 000..3d1f996
--- /dev/null
+++ b/hw/i82801b11.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the Software), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+/*
+ * QEMU i82801b11 dmi-to-pci Bridge Emulation
+ *
+ *  Copyright (c) 2009, 2010, 2011
+ *Isaku Yamahata yamahata at valinux co jp
+ *VA Linux Systems Japan K.K.
+ *  Copyright (C) 2012 Jason Baron jba...@redhat.com
+ *
+ * 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 http://www.gnu.org/licenses/
+ */
+
+#include pci.h
+#include ich9.h
+
+
+/*/
+/* ICH9 DMI-to-PCI bridge */
+#define I82801ba_SSVID_OFFSET   0x50
+#define I82801ba_SSVID_SVID 0
+#define I82801ba_SSVID_SSID 0
+
+typedef struct I82801b11Bridge {
+PCIBridge br;
+} I82801b11Bridge;
+
+static int i82801b11_bridge_initfn(PCIDevice *d)
+{
+int rc;
+
+rc = pci_bridge_initfn(d);
+if (rc  0) {
+return rc;
+}
+
+rc = pci_bridge_ssvid_init(d, I82801ba_SSVID_OFFSET,
+   I82801ba_SSVID_SVID, I82801ba_SSVID_SSID);
+if (rc  0) {
+goto err_bridge;
+}
+pci_config_set_prog_interface(d-config, PCI_CLASS_BRDIGE_PCI_INF_SUB);
+return 0;
+
+err_bridge:
+pci_bridge_exitfn(d);
+
+return rc;
+}
+
+static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
+{
+PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+k-is_bridge = 1;
+k-vendor_id = PCI_VENDOR_ID_INTEL;
+k-device_id = PCI_DEVICE_ID_INTEL_82801BA_11;
+k-revision = ICH9_D2P_A2_REVISION;
+k-init = i82801b11_bridge_initfn;
+}
+
+static const TypeInfo i82801b11_bridge_info = {
+.name  = i82801b11-bridge,
+.parent= TYPE_PCI_DEVICE,
+.instance_size = sizeof(I82801b11Bridge),
+.class_init= i82801b11_bridge_class_init,
+};
+
+PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus)
+{
+PCIDevice *d;
+PCIBridge *br;
+char buf[16];
+DeviceState *qdev;
+
+d = pci_create_multifunction(bus, devfn, true, i82801b11-bridge);
+if (!d) {
+return NULL;
+}
+br = DO_UPCAST(PCIBridge, dev, d);
+qdev = br-dev.qdev;
+
+snprintf(buf, sizeof(buf), pci.%d, sec_bus);
+pci_bridge_map_irq(br, buf, pci_swizzle_map_irq_fn

[Qemu-devel] [PATCH v4 04/14] pc/piix_pci: factor out smram/pam logic

2012-11-14 Thread Jason Baron
From: Isaku Yamahata yamah...@valinux.co.jp

Factor out smram/pam logic for use by other chipsets, namely q35
at this point.

Note: Should be factored out into a generic North Bridge Class.

[jba...@redhat.com: changes for updated memory API]
Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/Makefile.objs |1 +
 hw/pam.c |   87 
 hw/pam.h |   97 ++
 hw/piix_pci.c|   68 -
 4 files changed, 200 insertions(+), 53 deletions(-)
 create mode 100644 hw/pam.c
 create mode 100644 hw/pam.h

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index af4ab0c..be9ef83 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -37,6 +37,7 @@ common-obj-$(CONFIG_SMARTCARD) += ccid-card-passthru.o
 common-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
 common-obj-$(CONFIG_I8259) += i8259_common.o i8259.o
 common-obj-y += fifo.o
+common-obj-y += pam.o
 
 # PPC devices
 common-obj-$(CONFIG_PREP_PCI) += prep_pci.o
diff --git a/hw/pam.c b/hw/pam.c
new file mode 100644
index 000..a95e2cf
--- /dev/null
+++ b/hw/pam.c
@@ -0,0 +1,87 @@
+/*
+ * QEMU i440FX/PIIX3 PCI Bridge Emulation
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2011 Isaku Yamahata yamahata at valinux co jp
+ *VA Linux Systems Japan K.K.
+ * Copyright (c) 2012 Jason Baron jba...@redhat.com
+ *
+ * Split out from piix_pci.c
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the Software), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include sysemu.h
+#include pam.h
+
+void smram_update(MemoryRegion *smram_region, uint8_t smram,
+  uint8_t smm_enabled)
+{
+bool smram_enabled;
+
+smram_enabled = ((smm_enabled  (smram  SMRAM_G_SMRAME)) ||
+(smram  SMRAM_D_OPEN));
+memory_region_set_enabled(smram_region, !smram_enabled);
+}
+
+void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
+   MemoryRegion *smram_region)
+{
+uint8_t smm_enabled = (smm != 0);
+if (*host_smm_enabled != smm_enabled) {
+*host_smm_enabled = smm_enabled;
+smram_update(smram_region, smram, *host_smm_enabled);
+}
+}
+
+void init_pam(MemoryRegion *ram_memory, MemoryRegion *system_memory,
+  MemoryRegion *pci_address_space, PAMMemoryRegion *mem,
+  uint32_t start, uint32_t size)
+{
+int i;
+
+/* RAM */
+memory_region_init_alias(mem-alias[3], pam-ram, ram_memory,
+ start, size);
+/* ROM (XXX: not quite correct) */
+memory_region_init_alias(mem-alias[1], pam-rom, ram_memory,
+ start, size);
+memory_region_set_readonly(mem-alias[1], true);
+
+/* XXX: should distinguish read/write cases */
+memory_region_init_alias(mem-alias[0], pam-pci, pci_address_space,
+ start, size);
+memory_region_init_alias(mem-alias[2], pam-pci, pci_address_space,
+ start, size);
+
+for (i = 0; i  4; ++i) {
+memory_region_set_enabled(mem-alias[i], false);
+memory_region_add_subregion_overlap(system_memory, start,
+mem-alias[i], 1);
+}
+mem-current = 0;
+}
+
+void pam_update(PAMMemoryRegion *pam, int idx, uint8_t val)
+{
+assert(0 = idx  idx = 12);
+
+memory_region_set_enabled(pam-alias[pam-current], false);
+pam-current = (val  ((!(idx  1)) * 4))  PAM_ATTR_MASK;
+memory_region_set_enabled(pam-alias[pam-current], true);
+}
diff --git a/hw/pam.h b/hw/pam.h
new file mode 100644
index 000..2d77ebe
--- /dev/null
+++ b/hw/pam.h
@@ -0,0 +1,97 @@
+#ifndef QEMU_PAM_H
+#define QEMU_PAM_H
+
+/*
+ * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2011 Isaku Yamahata yamahata at valinux co jp
+ *   VA Linux Systems Japan K.K.
+ * Copyright (c

[Qemu-devel] [PATCH v4 12/14] q35: Add kvmclock support

2012-11-14 Thread Jason Baron
From: Jan Kiszka jan.kis...@siemens.com

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/pc_q35.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/hw/pc_q35.c b/hw/pc_q35.c
index 142bf8a..3429a9a 100644
--- a/hw/pc_q35.c
+++ b/hw/pc_q35.c
@@ -34,6 +34,7 @@
 #include mc146818rtc.h
 #include xen.h
 #include kvm.h
+#include kvm/clock.h
 #include q35.h
 #include exec-memory.h
 #include ich9.h
@@ -87,6 +88,8 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 
 pc_cpus_init(cpu_model);
 
+kvmclock_create();
+
 if (ram_size = 0xb000) {
 above_4g_mem_size = ram_size - 0xb000;
 below_4g_mem_size = 0xb000;
-- 
1.7.1




Re: [Qemu-devel] [PATCH v1 00/13] q35 patches for pci tree

2012-10-31 Thread Jason Baron
On Wed, Oct 31, 2012 at 07:55:13AM -0500, Anthony Liguori wrote:
 Michael S. Tsirkin m...@redhat.com writes:
 
  On Tue, Oct 30, 2012 at 02:20:35PM -0500, Anthony Liguori wrote:
  Jason Baron jba...@redhat.com writes:
  
   Hi,
  
   Re-base of my previous q35 patches on top of Michael Tsirkin's pci
   tree.
  
  I don't want this to come in through the pci tree.
 
  OK so you want to merge directly?
 
 Yes.
 
 
  This is not just
  another PCI device and the ramifications are pretty big since this will
  become the main machine model.
 
  OTOH it's not going to be the main machine model in 1.3 so maybe they
  are not that big, yet.
 
 I think it's important to avoid introducing a lot of unmodelled code
 regardless of whether it's the main machine model or not.
 
 There's plenty of time to fix it for 1.3 though so it shouldn't be a big deal.
 
 Regards,
 
 Anthony Liguori
 
 

I was looking at some of past pc refactoring patches, and they are
fairly involved: 

Subject:[Qemu-devel] [PATCH 0/6] refactor PC machine, i440fx and piix3 
to take advantage of QOM
http://lists.gnu.org/archive/html/qemu-devel/2012-03/msg04711.html

I'm not sure that level of modeling/refactoring can be safely be done in
1.3. I'm hoping you had something less invasive in mind.

It might be helpful to look at the core 'q35' data structures:


'Northbridge':

q35.h:

typedef struct GMCHPCIHost {
PCIExpressHost  host;
PCIDevice*dev; //points to the GMCHPCIState
} GMCHPCIHost;

q35.h:

typedef struct GMCHPCIState {
PCIDevice   d;
/*
 * GMCH_PCIHost   *gmch_host;
 * In order to get GMCH_PCIHost
 *  PCIDevice - qdev - parent_bus - qdev -upcast- GMCH_PCIHost
 */
MemoryRegion *ram_memory;
MemoryRegion *pci_address_space;
MemoryRegion *system_memory;
PAMMemoryRegion pam_regions[13];
MemoryRegion smram_region;
MemoryRegion pci_hole;
MemoryRegion pci_hole_64bit;
uint8_t smm_enabled;
} GMCHPCIState;

So the memory controller is really the GMCHPCIState structure. We could
create a generic 'MemoryController' class and embed it in GMCHPCIState,
and then embed GMCHPCIState into GMCHPCIHost. Adding the PAM routines
to the 'MemoryController'.

Then when we initialize GMCHPCIHost, we can also initialize GMCHPCIState
and the 'MemoryController'. Next, set the user passed parameters and then
finishing initializing all 3 structures?


'SouthBride':

ich9.h:

typedef struct ICH9LPCState {
/* ICH9 LPC PCI to ISA bridge */
PCIDevice d;

/* (pci device, intx) - pirq
 * In real chipset case, the unused slots are never used
 * as ICH9 supports only D25-D32 irq routing.
 * On the other hand in qemu case, any slot/function can be
 * populated
 * via command line option.
 * So fallback interrupt routing for any devices in any slots is
 * necessary.
*/
uint8_t irr[PCI_SLOT_MAX][PCI_NUM_PINS];

APMState apm;
ICH9LPCPMRegs pm;
uint32_t sci_level; /* track sci level */

/* 10.1 Chipset Configuration registers(Memory Space)
 which is pointed by RCBA */
uint8_t chip_config[ICH9_CC_SIZE];
/* isa bus */
ISABus *isa_bus;
MemoryRegion rbca_mem;

qemu_irq *pic;
qemu_irq *ioapic;
} ICH9LPCState;

hw/smbus_ich9.c:

typedef struct ICH9SMBState {
PCIDevice dev;

PMSMBus smb;
MemoryRegion mem_bar;
} ICH9SMBState;

hw/ide/ahci.h:

typedef struct AHCIPCIState {
PCIDevice card;
AHCIState ahci;
} AHCIPCIState;


Here too, we probably could create a generic 'ICH9' device and embed the
LPC, SMB, and ahci controller in it. Initialize all the devices, set
the desired parameters, and finalize their creation.

That would still be a lot of code churn. Maybe you can be more specific
about what you're looking for?

Also, will this include refactoring i440fx/piix3? 

Thanks,

-Jason



Re: [Qemu-devel] On block interface types in general, IF_AHCI in particular

2012-10-30 Thread Jason Baron
On Tue, Oct 30, 2012 at 03:43:20PM +0100, Markus Armbruster wrote:
 The primary purpose of this memo is a brain dump on how block interface
 types are used, and what that means for AHCI.  A secondary purpose is to
 disabuse Alex of the notion that -drive is simple ;)
 
 
 BlockInterfaceType really just serves -drive and its monitor cousins
 drive_add and pci_add[*].
 
 Note: we have a whole zoo of convenience options to define drives, but
 they're all just shorthand for -drive, so let's ignore them here.
 
 
 Let's start with -drive.  -drive creates a block backend, and leaves it
 in a place where board code can find it if it cares.
 
 That place is indexed by a triple (BlockInterfaceType type, int bus, int
 unit), corresponding to -drive options if, bus, unit.
 
 The actual work is done by drive_init().  Its opts argument comes
 straight from -drive's argument.
 
 If option if is missing, type is set to a board-specific default.
 
 If option bus is missing, bus is set to zero.
 
 If option unit is missing, the system picks the first unused bus, unit
 starting with (bus, 0).
 
 For type IF_IDE, unit must be 0 or 1.
 
 For type IF_SCSI, unit must be 0..6.  Note that the range is fine for
 8-bit SCSI, and inappropriate for anything else.
 
 Complication: option index.  This is an alternate way to specify bus and
 unit.
 
 For type IF_IDE, bus = index / 2, unit = index % 2.
 
 For type IF_SCSI, bus = index / 7, unit = index % 7.  Again, fine for
 8-bit SCSI, not fine for everything else.
 
 For any other type, bus = 0, unit = index.  There's no way to specify
 bus  0 with index.
 
 This mapping from index to (bus, unit) is ABI.
 
 (type, bus, unit) also get put into the drive ID when the user doesn't
 specify one (again ABI), but let's ignore that here.
 
 
 Now examine what board code does with (type, bus, unit) triples.  In
 general, board code looks up the triples it knows, and it finds a
 backend, it creates a suitable device model connected to the it.
 
 Same thing, different perspective: a board has a fixed set of onboard
 devices.  They may be associated with a well-known number of (type, bus,
 unit) triples.  The association is ABI.
 
 Example: connex associates (IF_PFLASH, 0, 0) with its CFI parallel
 flash.  It errors out when the triple isn't found.
 
 Example: g3beige associates its PMAC IDE's master with (IF_IDE, 0, 0),
 the slave with (IF_IDE, 0, 1), its CMD646's primary master with (IF_IDE,
 1, 0), its slave with (IF_IDE, 1, 1).  A suitable IDE device is created
 when a triple is found.  It doesn't associate its secondary master and
 slave with any triple (which means you can't put drives there with
 -drive if=ide).
 
 Boards never associate (IF_NONE, ...) with anything.  The backends
 behind these tripes are for use with -device.
 
 Some boards create additional device models when they find certain
 triples.  What gets created when is ABI.
 
 Example: pc finds the maximum bus N that occurs in any (IF_SCSI, ...)
 triple, then creates N+1 lsi53c895a SCSI HBAs, and connects all
 (IF_SCSI, B, U) to a suitable SCSI device model with SCSI ID U on the
 B-th HBA.
 
 Example: spapr does the same, except it creates spapr-vscsi HBAs.
 
 Boards generally ignore triples they don't associate with anything
 silently, but there are exceptions.
 
 Example: sun4m errors out if it finds (IF_SCSI, B, U) with B0.
 
 Ignored triples can still be used with -device.
 
 Example: pc silently ignores the (IF_SD, ...), but these drives are
 still usable with -device ide-cd,drive=sd0 and such.  Filed under
 stupid stunts.  It's ABI all the same.
 
 There's a twist for (IF_SCSI, B, U) triples ignored by the board:
 creating the B-th a SCSI HBA with -device also creates a suitable SCSI
 device model with SCSI ID U on that HBA.
 
 Example: sun4u doesn't provide a SCSI HBA, and normally ignores
 (IF_SCSI, 0, 0) silently.  But if you then create a SCSI HBA with
 -device, this also creates a suitable SCSI device model with SCSI ID 0
 on that HBA.
 
 Boards can associate block interface types with whatever device models
 they choose, even totally different kinds than the name of the block
 interface type suggests.  You may call that abuse.  I call it ABI.
 
 Example: s390-virtio creates virtio-blk-s390 device models for
 (IF_IDE, ...) triples.
 
 Some boards may do weird shit not covered here.  What weird shit gets
 done when is ABI.
 
 The important lesson here is that the meaning of -drive parameters if,
 bus, unit and index depends entirely on the board (except for -drive
 if=none, of course), and is part of the board's ABI.
 
 
 Next are drive_add and pci_add.  These commands are quite limited in
 what they can do.
 
 drive_add  if=none,OPTS... works just like -drive if=none,OPTS...: it
 creates a block backend for use with device_add.
 
 drive_add ADDR if=scsi,OPTS... resembles -drive if=scsi,OPTS..., except
 it doesn't leave device model creation to the board code: it creates a
 suitable SCSI device connected to the SCSI 

Re: [Qemu-devel] [PATCH v1 12/13] q35: fill in usb pci slots with -usb

2012-10-30 Thread Jason Baron
On Tue, Oct 30, 2012 at 07:34:26AM +0100, Gerd Hoffmann wrote:
   Hi,
 
  +uhci_devname[sizeof(uhci_devname) - 2] = ((char)'1') + i;
 
 snprintf(devname, sizeof(devname), ...%d, i) is more readable.

ok.

 
  +qdev_prop_set_string(usb_qdev, masterbus, ich9-usb-bus.0);
 
 Any reason why you rename the usb bus?
 

I wasn't sure if the user created usb devices on the command-line via
-device if that would break naming here. Thus, I added a 'private' name.
If the naming is stable, that works. It would be 'usb-bus.0', in that
case?

Thanks,

-Jason



Re: [Qemu-devel] [PATCH v1 12/13] q35: fill in usb pci slots with -usb

2012-10-30 Thread Jason Baron
On Tue, Oct 30, 2012 at 05:19:01PM +0100, Gerd Hoffmann wrote:
 On 10/30/12 16:19, Jason Baron wrote:
  On Tue, Oct 30, 2012 at 07:34:26AM +0100, Gerd Hoffmann wrote:
Hi,
 
  +uhci_devname[sizeof(uhci_devname) - 2] = ((char)'1') + i;
 
  snprintf(devname, sizeof(devname), ...%d, i) is more readable.
  
  ok.
  
 
  +qdev_prop_set_string(usb_qdev, masterbus, 
  ich9-usb-bus.0);
 
  Any reason why you rename the usb bus?
 
  
  I wasn't sure if the user created usb devices on the command-line via
  -device if that would break naming here. Thus, I added a 'private' name.
  If the naming is stable, that works. It would be 'usb-bus.0', in that
  case?
 
 usb.0 would be the default name, but you don't need to know it, you
 can just look up what qdev created.  See here:
 
 http://www.kraxel.org/cgit/qemu/commit/?h=rebase/usb-nextid=70b9867011c4793787c5acee3d2005a6bc951f59

yes, much better :)

 
 [ This is part of the usb patch queue patch series posted today,
   depending on how the qom discussions go and how fast it goes in
   you might just call the function the patch provides.  Or do
   something simliar in pc_q35.c and I'll drop the patch. ]
 
 -usb for -M pc creates a usb.0 bus too, so I don't expect trouble.
 

I think your patch, is a generally useful helper function. Thus, I plan to
incorporate something similar to your patch, but less general in pc_q35.c. So
usb can get testing, and when your patch lands I will drop the extra usb
bits in pc_q35.c.

Thanks,

-Jason



[Qemu-devel] [PATCH v1 00/13] q35 patches for pci tree

2012-10-29 Thread Jason Baron
Hi,

Re-base of my previous q35 patches on top of Michael Tsirkin's pci tree.

Qemu bits for q35 support, I'm posting the seabios changes separately. The
patches require '-M q35' and -L 'seabios dir with q35 changes' on the
qemu command line. Hopefully, we can make it the default for x86 at some future
point when we feel comfortable with it. I'm hoping these patches can be
included for the 1.3 soft freeze.

The current patches have been tested with basic install testing and memory 
testing
on f16, f17, windows 7 and windows 8. They can be run on the various BSD flavors
by adding a 'piix4-ide' device to the pci bus. ie: -device piix4-ide. Patches
have also been reported to work with a small dsdt change on OSX 10.6 as well.

I've also dropped ACPI hotplug support completely - I simply haven't gotten a
chance to clean this up yet. Hopefully, it is ok for this to come in a bit
later.

Git trees:

git://github.com/jibaron/q35-qemu.git
git://github.com/jibaron/q35-seabios.git

Major Todo Items:

-add ahci migration back (need to cover more fields, but basically works)
-add ACPI hotplug support (pcie hotplug is currently working)


Isaku Yamahata (3):
  pc/piix_pci: factor out smram/pam logic
  pc, pc_piix: split out pc nic initialization
  q35: Introduce q35 pc based chipset emulator

Jan Kiszka (2):
  q35: Suppress SMM BIOS initialization under KVM
  q35: Add kvmclock support

Jason Baron (8):
  Back out add of i21154
  blockdev: Introduce QEMUMachine-default_drive_if
  blockdev: Introduce IF_AHCI
  pc: Move ioapic_init() from pc_piix.c to pc.c
  Add a fallback bios file search, if -L fails.
  q35: automatically load the q35 dsdt table
  q35: fill in usb pci slots with -usb
  Fixup q35/ich9 Licenses

 blockdev.c|   23 +++-
 blockdev.h|   22 +++
 hw/Makefile.objs  |2 +-
 hw/acpi_ich9.c|   20 ++-
 hw/boards.h   |2 +-
 hw/device-hotplug.c   |2 +-
 hw/highbank.c |2 +-
 hw/i21154.c   |  113 
 hw/i21154.h   |9 --
 hw/i386/Makefile.objs |3 +-
 hw/ich9.h |5 +-
 hw/ide.h  |1 +
 hw/ide/core.c |9 ++
 hw/ide/pci.c  |   19 +++
 hw/ide/pci.h  |1 +
 hw/leon3.c|1 -
 hw/lpc_ich9.c |   32 +
 hw/mips_jazz.c|4 +-
 hw/pam.c  |   87 
 hw/pam.h  |   97 ++
 hw/pc.c   |   58 
 hw/pc.h   |7 +
 hw/pc_piix.c  |   38 +-
 hw/pc_q35.c   |  354 +
 hw/pc_sysfw.c |2 +-
 hw/pci_ids.h  |2 +
 hw/piix_pci.c |   68 ++
 hw/puv3.c |1 -
 hw/q35.c  |  315 +++
 hw/q35.h  |  161 ++
 hw/realview.c |6 +-
 hw/smbus_ich9.c   |   14 +-
 hw/spapr.c|2 +-
 hw/sun4m.c|   24 ++--
 hw/versatilepb.c  |4 +-
 hw/vexpress.c |4 +-
 hw/xilinx_zynq.c  |2 +-
 vl.c  |   56 +---
 38 files changed, 1272 insertions(+), 300 deletions(-)
 delete mode 100644 hw/i21154.c
 delete mode 100644 hw/i21154.h
 create mode 100644 hw/pam.c
 create mode 100644 hw/pam.h
 create mode 100644 hw/pc_q35.c
 create mode 100644 hw/q35.c
 create mode 100644 hw/q35.h




[Qemu-devel] [PATCH v1 05/13] pc, pc_piix: split out pc nic initialization

2012-10-29 Thread Jason Baron
From: Isaku Yamahata yamah...@valinux.co.jp

Factor out pc nic initialization.
This simplifies the pc initialization and will reduce the code
duplication of q35 pc initialization.

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/pc.c  |   15 +++
 hw/pc.h  |1 +
 hw/pc_piix.c |9 +
 3 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index a02b397..cb7fa68 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1104,6 +1104,21 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
 *floppy = fdctrl_init_isa(isa_bus, fd);
 }
 
+void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus)
+{
+int i;
+
+for (i = 0; i  nb_nics; i++) {
+NICInfo *nd = nd_table[i];
+
+if (!pci_bus || (nd-model  strcmp(nd-model, ne2k_isa) == 0)) {
+pc_init_ne2k_isa(isa_bus, nd);
+} else {
+pci_nic_init_nofail(nd, e1000, NULL);
+}
+}
+}
+
 void pc_pci_device_init(PCIBus *pci_bus)
 {
 int max_bus;
diff --git a/hw/pc.h b/hw/pc.h
index e7993ca..d6639a6 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -98,6 +98,7 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
above_4g_mem_size,
   const char *boot_device,
   ISADevice *floppy, BusState *ide0, BusState *ide1,
   ISADevice *s);
+void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus);
 void pc_pci_device_init(PCIBus *pci_bus);
 
 typedef void (*cpu_set_smm_t)(int smm, void *arg);
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 85529b2..acb1e92 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -234,14 +234,7 @@ static void pc_init1(MemoryRegion *system_memory,
 /* init basic PC hardware */
 pc_basic_device_init(isa_bus, gsi, rtc_state, floppy, xen_enabled());
 
-for(i = 0; i  nb_nics; i++) {
-NICInfo *nd = nd_table[i];
-
-if (!pci_enabled || (nd-model  strcmp(nd-model, ne2k_isa) == 0))
-pc_init_ne2k_isa(isa_bus, nd);
-else
-pci_nic_init_nofail(nd, e1000, NULL);
-}
+pc_nic_init(isa_bus, pci_bus);
 
 ide_drive_get(hd, MAX_IDE_BUS);
 if (pci_enabled) {
-- 
1.7.1




[Qemu-devel] [PATCH v1 06/13] pc: Move ioapic_init() from pc_piix.c to pc.c

2012-10-29 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Move ioapic_init from pc_piix.c to pc.c, to make it a common function.
Rename ioapic_init - ioapic_init_gsi.

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/pc.c  |   24 
 hw/pc.h  |2 ++
 hw/pc_piix.c |   25 +
 3 files changed, 27 insertions(+), 24 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index cb7fa68..af1a076 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1129,3 +1129,27 @@ void pc_pci_device_init(PCIBus *pci_bus)
 pci_create_simple(pci_bus, -1, lsi53c895a);
 }
 }
+
+void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
+{
+DeviceState *dev;
+SysBusDevice *d;
+unsigned int i;
+
+if (kvm_irqchip_in_kernel()) {
+dev = qdev_create(NULL, kvm-ioapic);
+} else {
+dev = qdev_create(NULL, ioapic);
+}
+if (parent_name) {
+object_property_add_child(object_resolve_path(parent_name, NULL),
+  ioapic, OBJECT(dev), NULL);
+}
+qdev_init_nofail(dev);
+d = sysbus_from_qdev(dev);
+sysbus_mmio_map(d, 0, 0xfec0);
+
+for (i = 0; i  IOAPIC_NUM_PINS; i++) {
+gsi_state-ioapic_irq[i] = qdev_get_gpio_in(dev, i);
+}
+}
diff --git a/hw/pc.h b/hw/pc.h
index d6639a6..2237e86 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -104,6 +104,8 @@ void pc_pci_device_init(PCIBus *pci_bus);
 typedef void (*cpu_set_smm_t)(int smm, void *arg);
 void cpu_smm_register(cpu_set_smm_t callback, void *arg);
 
+void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
+
 /* acpi.c */
 extern int acpi_enabled;
 extern char *acpi_tables;
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index acb1e92..7bcac87 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -95,29 +95,6 @@ static void kvm_piix3_gsi_handler(void *opaque, int n, int 
level)
 }
 }
 
-static void ioapic_init(GSIState *gsi_state)
-{
-DeviceState *dev;
-SysBusDevice *d;
-unsigned int i;
-
-if (kvm_irqchip_in_kernel()) {
-dev = qdev_create(NULL, kvm-ioapic);
-} else {
-dev = qdev_create(NULL, ioapic);
-}
-/* FIXME: this should be under the piix3.  */
-object_property_add_child(object_resolve_path(i440fx, NULL),
-  ioapic, OBJECT(dev), NULL);
-qdev_init_nofail(dev);
-d = sysbus_from_qdev(dev);
-sysbus_mmio_map(d, 0, 0xfec0);
-
-for (i = 0; i  IOAPIC_NUM_PINS; i++) {
-gsi_state-ioapic_irq[i] = qdev_get_gpio_in(dev, i);
-}
-}
-
 /* PC hardware initialisation */
 static void pc_init1(MemoryRegion *system_memory,
  MemoryRegion *system_io,
@@ -221,7 +198,7 @@ static void pc_init1(MemoryRegion *system_memory,
 gsi_state-i8259_irq[i] = i8259[i];
 }
 if (pci_enabled) {
-ioapic_init(gsi_state);
+ioapic_init_gsi(gsi_state, i440fx);
 }
 
 pc_register_ferr_irq(gsi[13]);
-- 
1.7.1




[Qemu-devel] [PATCH v1 03/13] blockdev: Introduce QEMUMachine-default_drive_if

2012-10-29 Thread Jason Baron
From: Jason Baron jba...@redhat.com

The current QEMUMachine definition has a 'use_scsi' field to indicate if a
machine type should use scsi by default. However, Q35 wants to use ahci by
default. Thus, introdue a new field in the QEMUMachine defintion,
default_drive_if.

Please use 'static inline int get_default_drive_if(int default_drive_if)', when
accesssing the new default_drive_if field. The field should be initialized by 
the
machine type to the default interface type which it wants to use
(IF_SCSI, IF_AHCI, etc.). If no default_drive_if is specified, we assume IF_IDE.
In the future, we should go through all of the machines types and explicitly
define their desired default interface, thus eliminating the need for
get_default_drive_if() interface.

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Jason Baron jba...@redhat.com
---
 blockdev.c  |4 ++--
 blockdev.h  |   20 
 hw/boards.h |2 +-
 hw/device-hotplug.c |2 +-
 hw/highbank.c   |2 +-
 hw/leon3.c  |1 -
 hw/mips_jazz.c  |4 ++--
 hw/pc_sysfw.c   |2 +-
 hw/puv3.c   |1 -
 hw/realview.c   |6 +++---
 hw/spapr.c  |2 +-
 hw/sun4m.c  |   24 
 hw/versatilepb.c|4 ++--
 hw/vexpress.c   |4 ++--
 hw/xilinx_zynq.c|2 +-
 vl.c|   20 +++-
 16 files changed, 60 insertions(+), 40 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 99828ad..2977e2f 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -275,7 +275,7 @@ static bool do_check_io_limits(BlockIOLimit *io_limits)
 return true;
 }
 
-DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
+DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType default_drive_if)
 {
 const char *buf;
 const char *file = NULL;
@@ -325,7 +325,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
 return NULL;
}
 } else {
-type = default_to_scsi ? IF_SCSI : IF_IDE;
+type = get_default_drive_if(default_drive_if);
 }
 
 max_devs = if_max_devs[type];
diff --git a/blockdev.h b/blockdev.h
index 5f27b64..658380d 100644
--- a/blockdev.h
+++ b/blockdev.h
@@ -40,6 +40,26 @@ struct DriveInfo {
 int refcount;
 };
 
+/*
+ * Each qemu machine type defines a default_drive_if field for its default
+ * interface type. When accessing the default_drive_if field, please make use
+ * of get_default_drive_if(). If default_drive_if is unspecified, we set it to
+ * IF_IDE.
+ *
+ * Left as a 'todo': We should convert those that are unspecified to their
+ * proper default values, thus eliminating the need for get_default_drive_if().
+ */
+static inline int get_default_drive_if(int default_drive_if)
+{
+assert(default_drive_if  IF_COUNT);
+assert(default_drive_if = IF_NONE);
+
+if (default_drive_if == 0) {
+return IF_IDE;
+}
+return default_drive_if;
+}
+
 DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
 DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
 int drive_get_max_bus(BlockInterfaceType type);
diff --git a/hw/boards.h b/hw/boards.h
index 813d0e5..cd3f79f 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -24,7 +24,7 @@ typedef struct QEMUMachine {
 const char *desc;
 QEMUMachineInitFunc *init;
 QEMUMachineResetFunc *reset;
-int use_scsi;
+int default_drive_if;
 int max_cpus;
 unsigned int no_serial:1,
 no_parallel:1,
diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c
index eec0fe3..53ee6c3 100644
--- a/hw/device-hotplug.c
+++ b/hw/device-hotplug.c
@@ -39,7 +39,7 @@ DriveInfo *add_init_drive(const char *optstr)
 if (!opts)
 return NULL;
 
-dinfo = drive_init(opts, current_machine-use_scsi);
+dinfo = drive_init(opts, current_machine-default_drive_if);
 if (!dinfo) {
 qemu_opts_del(opts);
 return NULL;
diff --git a/hw/highbank.c b/hw/highbank.c
index afbb005..03ae3d8 100644
--- a/hw/highbank.c
+++ b/hw/highbank.c
@@ -326,7 +326,7 @@ static QEMUMachine highbank_machine = {
 .name = highbank,
 .desc = Calxeda Highbank (ECX-1000),
 .init = highbank_init,
-.use_scsi = 1,
+.default_drive_if = IF_SCSI,
 .max_cpus = 4,
 };
 
diff --git a/hw/leon3.c b/hw/leon3.c
index 7742738..ef83dff 100644
--- a/hw/leon3.c
+++ b/hw/leon3.c
@@ -212,7 +212,6 @@ static QEMUMachine leon3_generic_machine = {
 .name = leon3_generic,
 .desc = Leon-3 generic,
 .init = leon3_generic_hw_init,
-.use_scsi = 0,
 };
 
 static void leon3_machine_init(void)
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index 0847427..f72358c 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -324,14 +324,14 @@ static QEMUMachine mips_magnum_machine = {
 .name = magnum,
 .desc = MIPS Magnum,
 .init = mips_magnum_init,
-.use_scsi = 1,
+.default_drive_if = IF_SCSI,
 };
 
 static QEMUMachine mips_pica61_machine

[Qemu-devel] [PATCH v1 04/13] blockdev: Introduce IF_AHCI

2012-10-29 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Introduce IF_AHCI so that q35 can differentiate between ide and ahci disks.
This allows q35 to specify its default disk type. It also allows q35 to
differentiate between ahci and ide disks, such that -drive if=ide does not
result in the creating of an ahci disk. This is important, since we don't want
to have the meaning of if=ide changing once q35 is introduced. Thus, its
important for this to be applied before we introduce q35.

This patch also adds:

1)

void ahci_drive_get(DriveInfo **hd, int bus, int nports);

To populate hd with with the drives on bus 'bus', with up to 'nports'.

2)

pci_ahci_create_devs(PCIDevice *pci_dev, DriveInfo **hd_table, int
table_size);

Which provides a convient way of attaching ahci drives to an
ahci controller.

3)

drive_get_max_unit(BlockInterfaceType type);

Allows q35 to error if too many units are specified.

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Jason Baron jba...@redhat.com
---
 blockdev.c|   19 ++-
 blockdev.h|2 ++
 hw/ide.h  |1 +
 hw/ide/core.c |9 +
 hw/ide/pci.c  |   19 +++
 hw/ide/pci.h  |1 +
 6 files changed, 50 insertions(+), 1 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 2977e2f..e37d93d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -33,6 +33,7 @@ static const char *const if_name[IF_COUNT] = {
 [IF_SD] = sd,
 [IF_VIRTIO] = virtio,
 [IF_XEN] = xen,
+[IF_AHCI] = ahci,
 };
 
 static const int if_max_devs[IF_COUNT] = {
@@ -158,6 +159,21 @@ int drive_get_max_bus(BlockInterfaceType type)
 return max_bus;
 }
 
+int drive_get_max_unit(BlockInterfaceType type)
+{
+int max_unit;
+DriveInfo *dinfo;
+
+max_unit = -1;
+QTAILQ_FOREACH(dinfo, drives, next) {
+if (dinfo-type == type 
+dinfo-unit  max_unit) {
+ max_unit = dinfo-unit;
+}
+}
+return max_unit;
+}
+
 /* Get a block device.  This should only be used for single-drive devices
(e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
appropriate bus.  */
@@ -518,7 +534,7 @@ DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType 
default_drive_if)
 } else {
 /* no id supplied - create one */
 dinfo-id = g_malloc0(32);
-if (type == IF_IDE || type == IF_SCSI)
+if (type == IF_IDE || type == IF_SCSI || type == IF_AHCI)
 mediastr = (media == MEDIA_CDROM) ? -cd : -hd;
 if (max_devs)
 snprintf(dinfo-id, 32, %s%i%s%i,
@@ -550,6 +566,7 @@ DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType 
default_drive_if)
 
 switch(type) {
 case IF_IDE:
+case IF_AHCI:
 case IF_SCSI:
 case IF_XEN:
 case IF_NONE:
diff --git a/blockdev.h b/blockdev.h
index 658380d..0c7985d 100644
--- a/blockdev.h
+++ b/blockdev.h
@@ -21,6 +21,7 @@ typedef enum {
 IF_DEFAULT = -1,/* for use with drive_add() only */
 IF_NONE,
 IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
+IF_AHCI,
 IF_COUNT
 } BlockInterfaceType;
 
@@ -63,6 +64,7 @@ static inline int get_default_drive_if(int default_drive_if)
 DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
 DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
 int drive_get_max_bus(BlockInterfaceType type);
+int drive_get_max_unit(BlockInterfaceType type);
 DriveInfo *drive_get_next(BlockInterfaceType type);
 void drive_get_ref(DriveInfo *dinfo);
 void drive_put_ref(DriveInfo *dinfo);
diff --git a/hw/ide.h b/hw/ide.h
index add742c..6c43a57 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -35,5 +35,6 @@ int ide_get_bios_chs_trans(BusState *bus, int unit);
 
 /* ide/core.c */
 void ide_drive_get(DriveInfo **hd, int max_bus);
+void ahci_drive_get(DriveInfo **hd, int bus, int nports);
 
 #endif /* HW_IDE_H */
diff --git a/hw/ide/core.c b/hw/ide/core.c
index d683a8c..4a56517 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2354,3 +2354,12 @@ void ide_drive_get(DriveInfo **hd, int max_bus)
 hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
 }
 }
+
+void ahci_drive_get(DriveInfo **hd, int bus, int nports)
+{
+int i;
+
+for (i = 0; i  nports; i++) {
+hd[i] = drive_get(IF_AHCI, bus, i);
+}
+}
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index bcdd70e..9218989 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -28,8 +28,10 @@
 #include hw/isa.h
 #include block.h
 #include dma.h
+#include blockdev.h
 
 #include hw/ide/pci.h
+#include hw/ide/ahci.h
 
 #define BMDMA_PAGE_SIZE 4096
 
@@ -504,6 +506,23 @@ void pci_ide_create_devs(PCIDevice *dev, DriveInfo 
**hd_table)
 }
 }
 
+void pci_ahci_create_devs(PCIDevice *pci_dev, DriveInfo **hd_table, int 
table_size)
+{
+struct AHCIPCIState *dev = DO_UPCAST(struct AHCIPCIState, card, pci_dev);
+int i;
+DriveInfo *drive;
+
+for (i = 0; i  table_size; i++) {
+if (hd_table[i] == NULL) {
+continue

[Qemu-devel] [PATCH v1 10/13] Add a fallback bios file search, if -L fails.

2012-10-29 Thread Jason Baron
From: Jason Baron jba...@redhat.com

If -L dir is specified, and qemu does not find the bios file in dir, then
the search fails. Add infrastructure such that the search will continue in
the default paths, if not found in the -L path.

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Jason Baron jba...@redhat.com
---
 vl.c |   36 +---
 1 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/vl.c b/vl.c
index 824d8ae..59e8d2f 100644
--- a/vl.c
+++ b/vl.c
@@ -177,6 +177,7 @@ int main(int argc, char **argv)
 #define MAX_VIRTIO_CONSOLES 1
 
 static const char *data_dir;
+static const char *data_dir_fallback;
 const char *bios_name = NULL;
 enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
 DisplayType display_type = DT_DEFAULT;
@@ -1904,16 +1905,16 @@ static int balloon_parse(const char *arg)
 return -1;
 }
 
-char *qemu_find_file(int type, const char *name)
+static char *qemu_find_file_in_dir(int type, const char *name, const char *dir)
 {
 int len;
 const char *subdir;
 char *buf;
 
-/* Try the name as a straight path first */
-if (access(name, R_OK) == 0) {
-return g_strdup(name);
+if (!dir) {
+return NULL;
 }
+
 switch (type) {
 case QEMU_FILE_TYPE_BIOS:
 subdir = ;
@@ -1924,9 +1925,9 @@ char *qemu_find_file(int type, const char *name)
 default:
 abort();
 }
-len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
+len = strlen(dir) + strlen(name) + strlen(subdir) + 2;
 buf = g_malloc0(len);
-snprintf(buf, len, %s/%s%s, data_dir, subdir, name);
+snprintf(buf, len, %s/%s%s, dir, subdir, name);
 if (access(buf, R_OK)) {
 g_free(buf);
 return NULL;
@@ -1934,6 +1935,21 @@ char *qemu_find_file(int type, const char *name)
 return buf;
 }
 
+char *qemu_find_file(int type, const char *name)
+{
+char *filename;
+
+/* Try the name as a straight path first */
+if (access(name, R_OK) == 0) {
+return g_strdup(name);
+}
+filename = qemu_find_file_in_dir(type, name, data_dir);
+if (!filename) {
+filename = qemu_find_file_in_dir(type, name, data_dir_fallback);
+}
+return filename;
+}
+
 static int device_help_func(QemuOpts *opts, void *opaque)
 {
 return qdev_device_help(opts);
@@ -3377,12 +3393,10 @@ int main(int argc, char **argv, char **envp)
 
 /* If no data_dir is specified then try to find it relative to the
executable path.  */
-if (!data_dir) {
-data_dir = os_find_datadir(argv[0]);
-}
+data_dir_fallback = os_find_datadir(argv[0]);
 /* If all else fails use the install path specified when building. */
-if (!data_dir) {
-data_dir = CONFIG_QEMU_DATADIR;
+if (!data_dir_fallback) {
+data_dir_fallback = CONFIG_QEMU_DATADIR;
 }
 
 /*
-- 
1.7.1




[Qemu-devel] [PATCH v1 08/13] q35: Suppress SMM BIOS initialization under KVM

2012-10-29 Thread Jason Baron
From: Jan Kiszka jan.kis...@siemens.com

Same as for i44fx: KVM does not support SMM yet. Signal it initialized
to Seabios to avoid failures.

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/acpi_ich9.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index c45921c..61034d3 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -28,6 +28,7 @@
 #include qemu-timer.h
 #include sysemu.h
 #include acpi.h
+#include kvm.h
 
 #include ich9.h
 
@@ -292,6 +293,12 @@ static void pm_reset(void *opaque)
 acpi_pm_tmr_reset(pm-acpi_regs);
 acpi_gpe_reset(pm-acpi_regs);
 
+if (kvm_enabled()) {
+/* Mark SMM as already inited to prevent SMM from running. KVM does not
+ * support SMM mode. */
+pm-smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
+}
+
 pm_update_sci(pm);
 }
 
-- 
1.7.1




[Qemu-devel] [PATCH v1 09/13] q35: Add kvmclock support

2012-10-29 Thread Jason Baron
From: Jan Kiszka jan.kis...@siemens.com

Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Jan Kiszka jan.kis...@siemens.com
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/pc_q35.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/hw/pc_q35.c b/hw/pc_q35.c
index cf0d361..1f31486 100644
--- a/hw/pc_q35.c
+++ b/hw/pc_q35.c
@@ -52,6 +52,7 @@
 #include mc146818rtc.h
 #include xen.h
 #include kvm.h
+#include kvm/clock.h
 
 #include q35.h
 #include exec-memory.h
@@ -233,6 +234,8 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 
 pc_cpus_init(cpu_model);
 
+kvmclock_create();
+
 if (ram_size = 0xb000) {
 above_4g_mem_size = ram_size - 0xb000;
 below_4g_mem_size = 0xb000;
-- 
1.7.1




[Qemu-devel] [PATCH v1 11/13] q35: automatically load the q35 dsdt table

2012-10-29 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Automatically, locate the required q35 dsdt table on load. Otherwise we error
out. This could be done in the bios, but its harder to produce a good error
message.

Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/pc.c |   19 +++
 hw/pc.h |2 ++
 hw/pc_q35.c |7 +++
 3 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index af1a076..743d771 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1153,3 +1153,22 @@ void ioapic_init_gsi(GSIState *gsi_state, const char 
*parent_name)
 gsi_state-ioapic_irq[i] = qdev_get_gpio_in(dev, i);
 }
 }
+
+int find_and_load_dsdt(const char *dsdt_name)
+{
+char *filename;
+char buf[1024];
+
+filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dsdt_name);
+if (!filename) {
+return -1;
+}
+snprintf(buf, sizeof(buf), file=%s, filename);
+g_free(filename);
+if (acpi_table_add(buf)  0) {
+fprintf(stderr, Wrong acpi table provided\n);
+return -1;
+}
+
+return 0;
+}
diff --git a/hw/pc.h b/hw/pc.h
index e1bf2fc..1a3db90 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -187,5 +187,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory);
 #define E820_UNUSABLE   5
 
 int e820_add_entry(uint64_t, uint64_t, uint32_t);
+int find_and_load_dsdt(const char *dsdt_name);
+
 
 #endif
diff --git a/hw/pc_q35.c b/hw/pc_q35.c
index 1f31486..a9a7f6c 100644
--- a/hw/pc_q35.c
+++ b/hw/pc_q35.c
@@ -232,6 +232,13 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 qemu_irq *i8259;
 int i;
 
+/* let's first see if we can find the proper dsdt */
+if (find_and_load_dsdt(q35-acpi-dsdt.aml)) {
+fprintf(stderr, Couldn't find q35 dsdt table!\n
+Try updating your bios.\n);
+exit(1);
+}
+
 pc_cpus_init(cpu_model);
 
 kvmclock_create();
-- 
1.7.1




[Qemu-devel] [PATCH v1 13/13] Fixup q35/ich9 Licenses

2012-10-29 Thread Jason Baron
From: Jason Baron jba...@redhat.com

Cleanup the q35/ich9 license headers.

Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/acpi_ich9.c  |   13 +++--
 hw/lpc_ich9.c   |   32 
 hw/smbus_ich9.c |   14 --
 3 files changed, 23 insertions(+), 36 deletions(-)

diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c
index 61034d3..25c9d36 100644
--- a/hw/acpi_ich9.c
+++ b/hw/acpi_ich9.c
@@ -2,6 +2,11 @@
  * ACPI implementation
  *
  * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2009 Isaku Yamahata yamahata at valinux co jp
+ *VA Linux Systems Japan K.K.
+ * Copyright (C) 2012 Jason Baron jba...@redhat.com
+ *
+ * This is based on acpi.c.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -14,13 +19,9 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see http://www.gnu.org/licenses/
- */
-/*
- *  Copyright (c) 2009 Isaku Yamahata yamahata at valinux co jp
- * VA Linux Systems Japan K.K.
- *  Copyright (C) 2012 Jason Baron jba...@redhat.com
  *
- *  This is based on acpi.c.
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
  */
 #include hw.h
 #include pc.h
diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c
index 4116c50..90129db 100644
--- a/hw/lpc_ich9.c
+++ b/hw/lpc_ich9.c
@@ -1,5 +1,13 @@
 /*
+ * QEMU ICH9 Emulation
+ *
  * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2009, 2010, 2011
+ *   Isaku Yamahata yamahata at valinux co jp
+ *   VA Linux Systems Japan K.K.
+ * Copyright (C) 2012 Jason Baron jba...@redhat.com
+ *
+ * This is based on piix_pci.c, but heavily modified.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the Software), to 
deal
@@ -19,30 +27,6 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-/*
- * QEMU ICH9 Emulation
- *
- *  Copyright (c) 2009, 2010, 2011
- *Isaku Yamahata yamahata at valinux co jp
- *VA Linux Systems Japan K.K.
- *  Copyright (C) 2012 Jason Baron jba...@redhat.com
- *
- *  This is based on piix_pci.c, but heavily modified.
- *
- * 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 http://www.gnu.org/licenses/
- */
-
 #include qemu-common.h
 #include hw.h
 #include range.h
diff --git a/hw/smbus_ich9.c b/hw/smbus_ich9.c
index 6940583..6d31e24 100644
--- a/hw/smbus_ich9.c
+++ b/hw/smbus_ich9.c
@@ -2,6 +2,11 @@
  * ACPI implementation
  *
  * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2009 Isaku Yamahata yamahata at valinux co jp
+ *   VA Linux Systems Japan K.K.
+ * Copyright (C) 2012 Jason Baron jba...@redhat.com
+ *
+ * This is based on acpi.c, but heavily rewritten.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -14,13 +19,10 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see http://www.gnu.org/licenses/
- */
-/*
- *  Copyright (c) 2009 Isaku Yamahata yamahata at valinux co jp
- * VA Linux Systems Japan K.K.
- *  Copyright (C) 2012 Jason Baron jba...@redhat.com
  *
- *  This is based on acpi.c, but heavily rewritten.
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
+ *
  */
 #include hw.h
 #include pc.h
-- 
1.7.1




[Qemu-devel] [PATCH v1 07/13] q35: Introduce q35 pc based chipset emulator

2012-10-29 Thread Jason Baron
From: Isaku Yamahata yamah...@valinux.co.jp

pc q35 based chipset emulator to support pci express natively. Based on
Anthony Liguori's suggestion, the machine name is 'q35-next', with an alias
of 'q35'. At this point, there are no compatibility guarantees. When the
chipset stabilizes more, we will begin to version the machine names.

Major features which still need to be added:

-Migration support (mostly around ahci)
-ACPI hotplug support (pcie hotplug support is working)
-Passthrough support

Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/i386/Makefile.objs |2 +-
 hw/pc.h   |2 +
 hw/pc_piix.c  |4 +-
 hw/pc_q35.c   |  326 +
 hw/pci_ids.h  |2 +
 hw/q35.c  |  315 +++
 hw/q35.h  |  161 
 7 files changed, 809 insertions(+), 3 deletions(-)
 create mode 100644 hw/pc_q35.c
 create mode 100644 hw/q35.c
 create mode 100644 hw/q35.h

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 693bd18..469b127 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -7,7 +7,7 @@ obj-y += debugcon.o multiboot.o
 obj-y += pc_piix.o
 obj-y += pc_sysfw.o
 obj-y += pam.o
-obj-y += acpi_ich9.o lpc_ich9.o smbus_ich9.o
+obj-y += acpi_ich9.o lpc_ich9.o smbus_ich9.o q35.o pc_q35.o
 obj-$(CONFIG_XEN) += xen_platform.o xen_apic.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_msi.o
diff --git a/hw/pc.h b/hw/pc.h
index 2237e86..e1bf2fc 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -42,6 +42,8 @@ int pic_read_irq(DeviceState *d);
 int pic_get_output(DeviceState *d);
 void pic_info(Monitor *mon);
 void irq_info(Monitor *mon);
+void kvm_piix3_gsi_handler(void *opaque, int n, int level);
+void kvm_piix3_setup_irq_routing(bool pci_enabled);
 
 /* Global System Interrupts */
 
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 7bcac87..26565a1 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -54,7 +54,7 @@ static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
 static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
 static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
 
-static void kvm_piix3_setup_irq_routing(bool pci_enabled)
+void kvm_piix3_setup_irq_routing(bool pci_enabled)
 {
 #ifdef CONFIG_KVM
 KVMState *s = kvm_state;
@@ -83,7 +83,7 @@ static void kvm_piix3_setup_irq_routing(bool pci_enabled)
 #endif /* CONFIG_KVM */
 }
 
-static void kvm_piix3_gsi_handler(void *opaque, int n, int level)
+void kvm_piix3_gsi_handler(void *opaque, int n, int level)
 {
 GSIState *s = opaque;
 
diff --git a/hw/pc_q35.c b/hw/pc_q35.c
new file mode 100644
index 000..cf0d361
--- /dev/null
+++ b/hw/pc_q35.c
@@ -0,0 +1,326 @@
+/*
+ * Q35 chipset based pc system emulator
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2009, 2010
+ *   Isaku Yamahata yamahata at valinux co jp
+ *   VA Linux Systems Japan K.K.
+ * Copyright (C) 2012 Jason Baron jba...@redhat.com
+ *
+ * This is based on pc.c, but heavily modified.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the Software), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include hw.h
+#include arch_init.h
+#include pc.h
+#include fdc.h
+#include pci.h
+#include pci_bridge.h
+#include ioh3420.h
+#include xio3130_upstream.h
+#include xio3130_downstream.h
+#include block.h
+#include blockdev.h
+#include sysemu.h
+#include audio/audio.h
+#include net.h
+#include smbus.h
+#include boards.h
+#include monitor.h
+#include fw_cfg.h
+#include hpet_emul.h
+#include watchdog.h
+#include smbios.h
+#include ide.h
+#include mc146818rtc.h
+#include xen.h
+#include kvm.h
+
+#include q35.h
+#include exec-memory.h
+#include ich9.h
+#include hw/ide/pci.h
+#include hw/ide/ahci.h
+
+/* ICH9 AHCI has 6 ports */
+#define MAX_SATA_PORTS 6
+
+static void

[Qemu-devel] [PATCH v1 02/13] Back out add of i21154

2012-10-29 Thread Jason Baron
From: Jason Baron jba...@redhat.com

As pointed out by Andreas Färber this is covered by dec_pci.c.

Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/Makefile.objs |2 +-
 hw/i21154.c  |  113 --
 hw/i21154.h  |9 
 3 files changed, 1 insertions(+), 123 deletions(-)
 delete mode 100644 hw/i21154.c
 delete mode 100644 hw/i21154.h

diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index e951eba..a816e7e 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -9,7 +9,7 @@ common-obj-$(CONFIG_PCI) += shpc.o
 common-obj-$(CONFIG_PCI) += slotid_cap.o
 common-obj-$(CONFIG_PCI) += pci_host.o pcie_host.o
 common-obj-$(CONFIG_PCI) += ioh3420.o xio3130_upstream.o xio3130_downstream.o
-common-obj-$(CONFIG_PCI) += i82801b11.o i21154.o
+common-obj-$(CONFIG_PCI) += i82801b11.o
 common-obj-y += watchdog.o
 common-obj-$(CONFIG_ISA_MMIO) += isa_mmio.o
 common-obj-$(CONFIG_ECC) += ecc.o
diff --git a/hw/i21154.c b/hw/i21154.c
deleted file mode 100644
index 93faa59..000
--- a/hw/i21154.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the Software), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-/*
- * QEMU i21154 PCI Bridge Emulation
- *
- *  Copyright (c) 2009, 2010, 2011
- *Isaku Yamahata yamahata at valinux co jp
- *VA Linux Systems Japan K.K.
- *  Copyright (C) 2012 Jason Baron jba...@redhat.com
- *
- * 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 http://www.gnu.org/licenses/
- */
-
-#include i21154.h
-#include pci_ids.h
-#include pci.h
-#include pci_bridge.h
-#include pci_internals.h
-
-/* i21154 pci bridge*/
-
-typedef struct I21154Bridge {
-PCIBridge br;
-} I21154Bridge;
-
-static int i21154_bridge_initfn(PCIDevice *d)
-{
-int rc;
-
-rc = pci_bridge_initfn(d);
-if (rc  0) {
-return rc;
-}
-
-return 0;
-}
-
-#define I21154_REV0x05
-#define I21154_PI 0x00
-
-static void i21154_bridge_class_init(ObjectClass *klass, void *data)
-{
-PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-k-is_bridge = 1;
-k-vendor_id = PCI_VENDOR_ID_DEC;
-k-device_id = PCI_DEVICE_ID_DEC_21154;
-k-revision = I21154_REV;
-k-init = i21154_bridge_initfn;
-}
-
-static const TypeInfo i21154_bridge_info = {
-.name  = i21154-bridge,
-.parent= TYPE_PCI_DEVICE,
-.instance_size = sizeof(I21154Bridge),
-.class_init= i21154_bridge_class_init,
-};
-
-PCIBridge *i21154_init(PCIBus *bus, int devfn, const char *bus_name,
-  bool multifunction)
-{
-PCIDevice *d;
-PCIBridge *br;
-DeviceState *qdev;
-
-d = pci_create_multifunction(bus, devfn, multifunction, i21154-bridge);
-if (!d) {
-return NULL;
-}
-br = DO_UPCAST(PCIBridge, dev, d);
-qdev = br-dev.qdev;
-
-pci_bridge_map_irq(br, bus_name, pci_swizzle_map_irq_fn);
-qdev_init_nofail(qdev);
-
-return br;
-}
-
-static void i21154_register(void)
-{
-type_register_static(i21154_bridge_info);
-}
-type_init(i21154_register);
diff --git a/hw/i21154.h b/hw/i21154.h
deleted file mode 100644
index 0cf8753..000
--- a/hw/i21154.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef QEMU_I21154_H
-#define QEMU_I21154_H
-
-#include pci.h
-
-PCIBridge *i21154_init(PCIBus *bus, int devfn, const char *bus_name

[Qemu-devel] [PATCH v1 01/13] pc/piix_pci: factor out smram/pam logic

2012-10-29 Thread Jason Baron
From: Isaku Yamahata yamah...@valinux.co.jp

Factor out smram/pam logic for later use.
Which will be used by q35 too.

[jba...@redhat.com: changes for updated memory API]
Signed-off-by: Isaku Yamahata yamah...@valinux.co.jp
Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/i386/Makefile.objs |1 +
 hw/pam.c  |   87 
 hw/pam.h  |   97 +
 hw/piix_pci.c |   68 ---
 4 files changed, 200 insertions(+), 53 deletions(-)
 create mode 100644 hw/pam.c
 create mode 100644 hw/pam.h

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index d400d1a..693bd18 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -6,6 +6,7 @@ obj-y += pci-hotplug.o smbios.o wdt_ib700.o
 obj-y += debugcon.o multiboot.o
 obj-y += pc_piix.o
 obj-y += pc_sysfw.o
+obj-y += pam.o
 obj-y += acpi_ich9.o lpc_ich9.o smbus_ich9.o
 obj-$(CONFIG_XEN) += xen_platform.o xen_apic.o
 obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o
diff --git a/hw/pam.c b/hw/pam.c
new file mode 100644
index 000..a95e2cf
--- /dev/null
+++ b/hw/pam.c
@@ -0,0 +1,87 @@
+/*
+ * QEMU i440FX/PIIX3 PCI Bridge Emulation
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2011 Isaku Yamahata yamahata at valinux co jp
+ *VA Linux Systems Japan K.K.
+ * Copyright (c) 2012 Jason Baron jba...@redhat.com
+ *
+ * Split out from piix_pci.c
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the Software), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include sysemu.h
+#include pam.h
+
+void smram_update(MemoryRegion *smram_region, uint8_t smram,
+  uint8_t smm_enabled)
+{
+bool smram_enabled;
+
+smram_enabled = ((smm_enabled  (smram  SMRAM_G_SMRAME)) ||
+(smram  SMRAM_D_OPEN));
+memory_region_set_enabled(smram_region, !smram_enabled);
+}
+
+void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
+   MemoryRegion *smram_region)
+{
+uint8_t smm_enabled = (smm != 0);
+if (*host_smm_enabled != smm_enabled) {
+*host_smm_enabled = smm_enabled;
+smram_update(smram_region, smram, *host_smm_enabled);
+}
+}
+
+void init_pam(MemoryRegion *ram_memory, MemoryRegion *system_memory,
+  MemoryRegion *pci_address_space, PAMMemoryRegion *mem,
+  uint32_t start, uint32_t size)
+{
+int i;
+
+/* RAM */
+memory_region_init_alias(mem-alias[3], pam-ram, ram_memory,
+ start, size);
+/* ROM (XXX: not quite correct) */
+memory_region_init_alias(mem-alias[1], pam-rom, ram_memory,
+ start, size);
+memory_region_set_readonly(mem-alias[1], true);
+
+/* XXX: should distinguish read/write cases */
+memory_region_init_alias(mem-alias[0], pam-pci, pci_address_space,
+ start, size);
+memory_region_init_alias(mem-alias[2], pam-pci, pci_address_space,
+ start, size);
+
+for (i = 0; i  4; ++i) {
+memory_region_set_enabled(mem-alias[i], false);
+memory_region_add_subregion_overlap(system_memory, start,
+mem-alias[i], 1);
+}
+mem-current = 0;
+}
+
+void pam_update(PAMMemoryRegion *pam, int idx, uint8_t val)
+{
+assert(0 = idx  idx = 12);
+
+memory_region_set_enabled(pam-alias[pam-current], false);
+pam-current = (val  ((!(idx  1)) * 4))  PAM_ATTR_MASK;
+memory_region_set_enabled(pam-alias[pam-current], true);
+}
diff --git a/hw/pam.h b/hw/pam.h
new file mode 100644
index 000..2d77ebe
--- /dev/null
+++ b/hw/pam.h
@@ -0,0 +1,97 @@
+#ifndef QEMU_PAM_H
+#define QEMU_PAM_H
+
+/*
+ * Copyright (c) 2006 Fabrice Bellard
+ * Copyright (c) 2011 Isaku Yamahata yamahata at valinux co jp
+ *   VA Linux Systems Japan K.K.
+ * Copyright (c) 2012 Jason Baron jba...@redhat.com

[Qemu-devel] [PATCH v1 12/13] q35: fill in usb pci slots with -usb

2012-10-29 Thread Jason Baron
From: Jason Baron jba...@redhat.com

This fills out the usb slots on q35, when -usb is passed.
We now have (lspci output):

00:1d.0 USB Controller: Intel Corporation 82801I (ICH9 Family) USB UHCI 
Controller #1 (rev 03)
00:1d.1 USB Controller: Intel Corporation 82801I (ICH9 Family) USB UHCI 
Controller #2 (rev 03)
00:1d.2 USB Controller: Intel Corporation 82801I (ICH9 Family) USB UHCI 
Controller #3 (rev 03)
00:1d.7 USB Controller: Intel Corporation 82801I (ICH9 Family) USB2 EHCI 
Controller #1 (rev 03)

Signed-off-by: Jason Baron jba...@redhat.com
---
 hw/ich9.h   |5 -
 hw/pc_q35.c |   26 ++
 2 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/hw/ich9.h b/hw/ich9.h
index 10c6d47..c4d04a7 100644
--- a/hw/ich9.h
+++ b/hw/ich9.h
@@ -86,8 +86,11 @@ typedef struct ICH9LPCState {
 
 
 /* D29:F0 USB UHCI Controller #1 */
-#define ICH9_USB_UHCI1_DEV  29
+#define ICH9_USB_DEV29
 #define ICH9_USB_UHCI1_FUNC 0
+#define ICH9_USB_UHCI2_FUNC 1
+#define ICH9_USB_UHCI3_FUNC 2
+#define ICH9_USB_EHCI1_FUNC 7
 
 /* D30:F0 DMI-to-PCI brdige */
 #define ICH9_D2P_BRIDGE ICH9 D2P BRIDGE
diff --git a/hw/pc_q35.c b/hw/pc_q35.c
index a9a7f6c..714aeaf 100644
--- a/hw/pc_q35.c
+++ b/hw/pc_q35.c
@@ -191,11 +191,29 @@ static void pc_q35_init_late(BusState **idebus, ISADevice 
*rtc_state,
 idebus[1] = qdev_get_child_bus(ahci-qdev, ide.1);
 
 if (usb_enabled(false)) {
+int i;
+PCIDevice *usb;
+DeviceState *usb_qdev;
+char uhci_devname[] = ich9-usb-uhciX;
+
 /* Should we create 6 UHCI according to ich9 spec? */
-pci_create_simple_multifunction(
-host_bus, PCI_DEVFN(ICH9_USB_UHCI1_DEV, ICH9_USB_UHCI1_FUNC),
-true, ich9-usb-uhci1);
-/* XXX: EHCI */
+usb = pci_create_multifunction(
+host_bus, PCI_DEVFN(ICH9_USB_DEV, ICH9_USB_EHCI1_FUNC),
+true, ich9-usb-ehci1);
+usb_qdev = usb-qdev;
+usb_qdev-id = g_strdup(ich9-usb-bus);
+qdev_init_nofail(usb_qdev);
+
+for (i = 0; i  3; i++) {
+uhci_devname[sizeof(uhci_devname) - 2] = ((char)'1') + i;
+usb = pci_create_multifunction(
+host_bus, PCI_DEVFN(ICH9_USB_DEV, ICH9_USB_UHCI1_FUNC + i),
+true, uhci_devname);
+usb_qdev = usb-qdev;
+qdev_prop_set_string(usb_qdev, masterbus, ich9-usb-bus.0);
+qdev_prop_set_uint32(usb_qdev, firstport, i * 2);
+qdev_init_nofail(usb_qdev);
+}
 }
 
 /* TODO: Populate SPD eeprom data.  */
-- 
1.7.1




Re: [Qemu-devel] q35: usb keyboard trouble

2012-10-26 Thread Jason Baron
On Wed, Oct 24, 2012 at 10:55:28AM -0400, Gabriel L. Somlo wrote:
 Jason,
 
 Commit d8b0dbdba325773469733222a167b54aca74de55 in the q35 tree breaks
 '-usbdevice keyboard' for me. Instead of being able to type at the VM,
 none of the keypresses make it through, and qemu stderr soon starts
 logging this error: usb-kbd: warning: key event queue full.
 
 Specifically, it's the introduction of ich9-usb-ehci1 that causes the
 issue (in hw/pc_q35.c, line 197):
 
 +pci_create_simple_multifunction(
 +host_bus, PCI_DEVFN(ICH9_USB_DEV, ICH9_USB_EHCI1_FUNC),
 +true, ich9-usb-ehci1);
 
 Commenting out the above makes the problem go away.
 
 Thanks much,
 --Gabriel
 
 

Thanks for the bug report! What OS are you running? I'm not seeing any
issue with -usbdevice keyboard on Fedora.

Paolo pointed out that I was missing some ich9 specific initialization
from docs/ich9-ehci-uhci.cfg. I've added that in the patch below. I have
no idea if that will resolve this issue for you.

Thanks,

-Jason


diff --git a/hw/pc_q35.c b/hw/pc_q35.c
index a72ad36..22b72ed 100644
--- a/hw/pc_q35.c
+++ b/hw/pc_q35.c
@@ -200,20 +200,27 @@ static void pc_q35_init_late(BusState **idebus, ISADevice 
*rtc_state,
 idebus[1] = qdev_get_child_bus(ahci-qdev, ide.1);
 
 if (usb_enabled) {
+int i;
+PCIDevice *usb;
+DeviceState *usb_qdev;
+
 /* Should we create 6 UHCI according to ich9 spec? */
-pci_create_simple_multifunction(
-host_bus, PCI_DEVFN(ICH9_USB_DEV, ICH9_USB_UHCI1_FUNC),
-true, ich9-usb-uhci1);
-pci_create_simple_multifunction(
-host_bus, PCI_DEVFN(ICH9_USB_DEV, ICH9_USB_UHCI2_FUNC),
-true, ich9-usb-uhci2);
-pci_create_simple_multifunction(
-host_bus, PCI_DEVFN(ICH9_USB_DEV, ICH9_USB_UHCI3_FUNC),
-true, ich9-usb-uhci3);
-pci_create_simple_multifunction(
+usb = pci_create_multifunction(
 host_bus, PCI_DEVFN(ICH9_USB_DEV, ICH9_USB_EHCI1_FUNC),
 true, ich9-usb-ehci1);
-/* XXX: EHCI */
+usb_qdev = usb-qdev;
+usb_qdev-id = g_strdup(ich9-usb-bus);
+qdev_init_nofail(usb_qdev);
+
+for (i = 0; i  3; i++) {
+usb = pci_create_multifunction(
+host_bus, PCI_DEVFN(ICH9_USB_DEV, ICH9_USB_UHCI1_FUNC + i),
+true, ich9-usb-uhci1);
+usb_qdev = usb-qdev;
+qdev_prop_set_string(usb_qdev, masterbus, ich9-usb-bus.0);
+qdev_prop_set_uint32(usb_qdev, firstport, i * 2);
+qdev_init_nofail(usb_qdev);
+}
 }
 
 /* TODO: Populate SPD eeprom data.  */



Re: [Qemu-devel] [PATCH v3 02/26] blockdev: Introduce IF_AHCI

2012-10-24 Thread Jason Baron
On Wed, Oct 24, 2012 at 05:50:25PM +0200, Markus Armbruster wrote:
 Jason Baron jba...@redhat.com writes:
 
  On Mon, Oct 22, 2012 at 01:40:21PM +0200, Kevin Wolf wrote:
   From: Jason Baron jba...@redhat.com
  
   Introduce IF_AHCI so that q35 can differentiate between ide and ahci 
   disks.
   This allows q35 to specify its default disk type. It also allows q35 to
   differentiate between ahci and ide disks, such that -drive if=ide does 
   not
   result in the creating of an ahci disk. This is important, since
   we don't want
   to have the meaning of if=ide changing once q35 is introduced. Thus, its
   important for this to be applied before we introduce q35.
 
 This isn't the real argument for IF_AHCI.  The real argument is that the
 (bus, unit) namespace for if=ide makes no sense for AHCI.
 
 A board can have any number of IDE controllers.  Each IDE controller
 provides one or two buses, and each bus takes up to two units.
 Together, we get a a board-specific number of buses, where each bus
 takes up to two units.
 
 A board can have any number of AHCI controllers.  Each AHCI controller
 provides a device-specific number of ports.  Together, we get a
 board-specific number of buses, where each bus can takes a bus-specific
 number of units.
 
 Plain q35 doesn't really need to differentiate between IDE and AHCI; it
 has only AHCI.  What it needs is a one bus with six units namespace.
 
 We could fix this by relaxing if=ide's rigid two units per bus for new
 machine types.
 
 You fix it by introducing if=ahci.  Probably simpler.  But what's the
 plan for the next generation of controller?  Yet another interface type?

Next generation might require a new interface type. But taking you're
suggestions, if=ahci is now machine dependent, so it shouldn't be so bad
(see incremental patch at end).

 
 Note that SCSI suffers from similar rigidity: seven units per bus.
 That's fine for SCSI-1, but not for some of the other variants.
 
 Differentiate comes into play when a board sports both AHCI and IDE
 controllers.  Which q35 doesn't, does it?

Yes, there is no ide controller by default. That said i've used the
piix-ide controller to install windows xp, for example, on q35.

 
 Then, the new if=ahci lets users select the kind of controller more
 easily than bus numbers would.
 
 Drawback: existing command lines upgrade from pc to plain q35 gracefully
 only if they don't specify if=ide explicitly.  Upgrading to some q35
 variant with IDE controller on board is even worse: it works, but
 performance sucks.  Some regard this as a feature.
 

well if=ide could give a warning on q35, suggesting using if=ahci, if
we're not going to create an ide controller for if=ide (which I wasn't
intending).

   This patch also adds:
  
   pci_ahci_create_devs(PCIDevice *pci_dev, DriveInfo **hd_table)
  
   Which provides a convient way of attaching ahci drives to an
   ahci controller.
  
   Reviewed-by: Paolo Bonzini pbonz...@redhat.com
   Signed-off-by: Jason Baron jba...@redhat.com
   ---
   
   Kevin, could you review/ack this patch pls?
   
blockdev.c|   13 -
blockdev.h|2 ++
hw/ide.h  |6 ++
hw/ide/ahci.c |   18 ++
hw/ide/core.c |   23 ++-
5 files changed, 56 insertions(+), 6 deletions(-)
  
   diff --git a/blockdev.c b/blockdev.c
   index c9a49c8..b684348 100644
   --- a/blockdev.c
   +++ b/blockdev.c
   @@ -33,6 +33,7 @@ static const char *const if_name[IF_COUNT] = {
[IF_SD] = sd,
[IF_VIRTIO] = virtio,
[IF_XEN] = xen,
   +[IF_AHCI] = ahci,
};

static const int if_max_devs[IF_COUNT] = {
   @@ -52,8 +53,17 @@ static const int if_max_devs[IF_COUNT] = {
/*
 * Do not change these numbers!  They govern how drive option
 * index maps to unit and bus.  That mapping is ABI.
 *
 * All controllers used to imlement if=T drives need to support
 * if_max_devs[T] units, for any T with if_max_devs[T] != 0.
 * Otherwise, some index values map to impossible bus, unit
 * values.
 *
 * For instance, if you change [IF_SCSI] to 255, -drive
 * if=scsi,index=12 no longer means bus=1,unit=5, but
 * bus=0,unit=12.  With an lsi53c895a controller (7 units max),
 * the drive can't be set up.  Regression.
 */
[IF_IDE] = 2,
[IF_SCSI] = 7,
   +[IF_AHCI] = 6,
};
  
  What are the implications of this if we decided to add another AHCI
  controller which had a different number of ports? I suspect that a
  controller with less than 6 ports breaks when you add more drives than a
  single controller can handle, and one with more than 6 ports doesn't use
  up all of its ports before it adds another controller.
  
  Markus?
  
 
  My plan was to make this field, machine dependent if/when we wanted a 
  different
  size. I don't think it breaks

Re: [Qemu-devel] [PATCH v3 01/26] blockdev: Introduce a default machine blockdev interface field, QEMUMachine-mach_if

2012-10-24 Thread Jason Baron
On Wed, Oct 24, 2012 at 03:12:36PM +0200, Markus Armbruster wrote:
 Jason Baron jba...@redhat.com writes:
 
  From: Jason Baron jba...@redhat.com
 
  The current QEMUMachine definition has a 'use_scsi' field to indicate if a
  machine type should use scsi by default. However, Q35 wants to use ahci by
  default. Thus, introdue a new field in the QEMUMachine defintion, mach_if.
 
 Even though q35's desire to default to IF_AHCI is driving this patch,
 generalizing the default interface type makes sense on its own.  Even if
 we IF_AHCI should turn out to need more discussion.
 
  This field should be initialized by the machine type to the default 
  interface
  type which it wants to use (IF_SCSI, IF_AHCI, etc.). If no mach_if is 
  defined,
  or it is set to 'IF_DEFAULT' or 'IF_NONE', we currently assume IF_IDE.
 
  Please use 'static inline int get_mach_if(int mach_if)', when accesssing the
  new mach_if field.
 
  Reviewed-by: Paolo Bonzini pbonz...@redhat.com
  Signed-off-by: Jason Baron jba...@redhat.com
  ---
   blockdev.c  |4 ++--
   blockdev.h  |   19 +++
   hw/boards.h |2 +-
   hw/device-hotplug.c |2 +-
   hw/highbank.c   |2 +-
   hw/leon3.c  |2 +-
   hw/mips_jazz.c  |4 ++--
   hw/pc_sysfw.c   |2 +-
   hw/puv3.c   |2 +-
   hw/realview.c   |6 +++---
   hw/spapr.c  |2 +-
   hw/sun4m.c  |   24 
   hw/versatilepb.c|4 ++--
   hw/vexpress.c   |4 ++--
   hw/xilinx_zynq.c|2 +-
   vl.c|   20 +++-
   16 files changed, 61 insertions(+), 40 deletions(-)
 
  diff --git a/blockdev.c b/blockdev.c
  index 99828ad..c9a49c8 100644
  --- a/blockdev.c
  +++ b/blockdev.c
  @@ -275,7 +275,7 @@ static bool do_check_io_limits(BlockIOLimit *io_limits)
   return true;
   }
   
  -DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
  +DriveInfo *drive_init(QemuOpts *opts, int mach_if)
 
 BlockInterfaceType mach_if
 
 Suggest to rename mach_if to something more descriptive.  Kevin's
 default_drive_if works for me.
 

ok.

 
   {
   const char *buf;
   const char *file = NULL;
  @@ -325,7 +325,7 @@ DriveInfo *drive_init(QemuOpts *opts, int 
  default_to_scsi)
   return NULL;
  }
   } else {
  -type = default_to_scsi ? IF_SCSI : IF_IDE;
  +type = get_mach_if(mach_if);
   }
   
   max_devs = if_max_devs[type];
  diff --git a/blockdev.h b/blockdev.h
  index 5f27b64..8b126ad 100644
  --- a/blockdev.h
  +++ b/blockdev.h
  @@ -40,6 +40,22 @@ struct DriveInfo {
   int refcount;
   };
   
  +/*
  + * Each qemu machine type defines a mach_if field for its default
  + * interface type. If its unspecified, we set it to IF_IDE.
  + */
  +static inline int get_mach_if(int mach_if)
 
 BlockInterfaceType mach_if, and return type.
 
  +{
  +assert(mach_if  IF_COUNT);
  +assert(mach_if = IF_DEFAULT);
  +
  +if ((mach_if == IF_NONE) || (mach_if == IF_DEFAULT)) {
  +return IF_IDE;
  +}
  +
  +return mach_if;
  +}
  +
 
 I'm not sure we should map IF_NONE to IF_IDE.
 
 get_mach_if() should return an interface type the board supports.  In
 theory, we could have a board that doesn't define any controllers, but
 still lets the user define some with -device (say because the board
 sports a PCI bus).  Then IF_NONE would be the only interface type that
 makes any sense, and therefore the only sensible value of get_mach_if().
 

Ok, but no boards use IF_NONE in that sense currently. But planning for
the future is good :)

 If we drop the magic mapping of IF_NONE, only IF_DEFAULT is left, and
 that one's clearly marked for use with drive_add() only.  No real need
 for magic mapping then.  Could drop get_mach_if() and use mach_if
 directly.

Meaning explicity set mach_if or default_drive_if to IF_IDE for all
machine types that are currently either IF_NONE, IF_DEFAULT, or not
explicitly defined?

Thanks,

-Jason



Re: [Qemu-devel] [PATCH v3 01/26] blockdev: Introduce a default machine blockdev interface field, QEMUMachine-mach_if

2012-10-22 Thread Jason Baron
On Mon, Oct 22, 2012 at 01:26:29PM +0200, Kevin Wolf wrote:
 Am 22.10.2012 12:47, schrieb Michael S. Tsirkin:
  On Fri, Oct 19, 2012 at 04:43:26PM -0400, Jason Baron wrote:
  From: Jason Baron jba...@redhat.com
 
  The current QEMUMachine definition has a 'use_scsi' field to indicate if a
  machine type should use scsi by default. However, Q35 wants to use ahci by
  default. Thus, introdue a new field in the QEMUMachine defintion, mach_if.
 
  This field should be initialized by the machine type to the default 
  interface
  type which it wants to use (IF_SCSI, IF_AHCI, etc.). If no mach_if is 
  defined,
  or it is set to 'IF_DEFAULT' or 'IF_NONE', we currently assume IF_IDE.
 
 Is this default mechanism necessary? Can't we make sure that each
 machine does define its preferred interface, and doesn't define it as
 IF_DEFAULT (which would be the same as an explicit IF_IDE anyway)?
 

IF_NONE is currently defined as 0, so I wanted to make sure that any
machine types that didn't explicity define the 'mach_if' field would be
mapped to IF_IDE. If you don't like having 'IF_DEFAULT' there, I can
simply drop 2 'IF_DEFAULT' settings that I had. Would that be ok with
you?

 Also, 'mach_if' isn't a very descriptive name. Something like
 'default_drive_if' would be better.
 

ok, will update.

  Please use 'static inline int get_mach_if(int mach_if)', when accesssing 
  the
  new mach_if field.
 
  Reviewed-by: Paolo Bonzini pbonz...@redhat.com
  Signed-off-by: Jason Baron jba...@redhat.com
  
  Kevin, could you review/ack this patch pls?
  
  ---
   blockdev.c  |4 ++--
   blockdev.h  |   19 +++
   hw/boards.h |2 +-
   hw/device-hotplug.c |2 +-
   hw/highbank.c   |2 +-
   hw/leon3.c  |2 +-
   hw/mips_jazz.c  |4 ++--
   hw/pc_sysfw.c   |2 +-
   hw/puv3.c   |2 +-
   hw/realview.c   |6 +++---
   hw/spapr.c  |2 +-
   hw/sun4m.c  |   24 
   hw/versatilepb.c|4 ++--
   hw/vexpress.c   |4 ++--
   hw/xilinx_zynq.c|2 +-
   vl.c|   20 +++-
   16 files changed, 61 insertions(+), 40 deletions(-)
 
  diff --git a/blockdev.c b/blockdev.c
  index 99828ad..c9a49c8 100644
  --- a/blockdev.c
  +++ b/blockdev.c
  @@ -275,7 +275,7 @@ static bool do_check_io_limits(BlockIOLimit *io_limits)
   return true;
   }
   
  -DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
  +DriveInfo *drive_init(QemuOpts *opts, int mach_if)
 
 BlockInterfaceType, not int.
 

ok.

   {
   const char *buf;
   const char *file = NULL;
  @@ -325,7 +325,7 @@ DriveInfo *drive_init(QemuOpts *opts, int 
  default_to_scsi)
   return NULL;
 }
   } else {
  -type = default_to_scsi ? IF_SCSI : IF_IDE;
  +type = get_mach_if(mach_if);
   }
   
   max_devs = if_max_devs[type];
  diff --git a/blockdev.h b/blockdev.h
  index 5f27b64..8b126ad 100644
  --- a/blockdev.h
  +++ b/blockdev.h
  @@ -40,6 +40,22 @@ struct DriveInfo {
   int refcount;
   };
   
  +/*
  + * Each qemu machine type defines a mach_if field for its default
  + * interface type. If its unspecified, we set it to IF_IDE.
  + */
  +static inline int get_mach_if(int mach_if)
  +{
  +assert(mach_if  IF_COUNT);
  +assert(mach_if = IF_DEFAULT);
  +
  +if ((mach_if == IF_NONE) || (mach_if == IF_DEFAULT)) {
  +return IF_IDE;
  +}
  +
  +return mach_if;
  +}
  +
   DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
   DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
   int drive_get_max_bus(BlockInterfaceType type);
  @@ -61,4 +77,7 @@ void qmp_change_blockdev(const char *device, const char 
  *filename,
bool has_format, const char *format, Error 
  **errp);
   void do_commit(Monitor *mon, const QDict *qdict);
   int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
  +
  +
  +
   #endif
  diff --git a/hw/boards.h b/hw/boards.h
  index a2e0a54..969fd67 100644
  --- a/hw/boards.h
  +++ b/hw/boards.h
  @@ -20,7 +20,7 @@ typedef struct QEMUMachine {
   const char *desc;
   QEMUMachineInitFunc *init;
   QEMUMachineResetFunc *reset;
  -int use_scsi;
  +int mach_if;
 
 Same here.
 
 Kevin

ok.

Thanks,

-Jason



Re: [Qemu-devel] [PATCH v3 02/26] blockdev: Introduce IF_AHCI

2012-10-22 Thread Jason Baron
On Mon, Oct 22, 2012 at 01:40:21PM +0200, Kevin Wolf wrote:
  From: Jason Baron jba...@redhat.com
 
  Introduce IF_AHCI so that q35 can differentiate between ide and ahci disks.
  This allows q35 to specify its default disk type. It also allows q35 to
  differentiate between ahci and ide disks, such that -drive if=ide does not
  result in the creating of an ahci disk. This is important, since we don't 
  want
  to have the meaning of if=ide changing once q35 is introduced. Thus, its
  important for this to be applied before we introduce q35.
 
  This patch also adds:
 
  pci_ahci_create_devs(PCIDevice *pci_dev, DriveInfo **hd_table)
 
  Which provides a convient way of attaching ahci drives to an
  ahci controller.
 
  Reviewed-by: Paolo Bonzini pbonz...@redhat.com
  Signed-off-by: Jason Baron jba...@redhat.com
  ---
  
  Kevin, could you review/ack this patch pls?
  
   blockdev.c|   13 -
   blockdev.h|2 ++
   hw/ide.h  |6 ++
   hw/ide/ahci.c |   18 ++
   hw/ide/core.c |   23 ++-
   5 files changed, 56 insertions(+), 6 deletions(-)
 
  diff --git a/blockdev.c b/blockdev.c
  index c9a49c8..b684348 100644
  --- a/blockdev.c
  +++ b/blockdev.c
  @@ -33,6 +33,7 @@ static const char *const if_name[IF_COUNT] = {
   [IF_SD] = sd,
   [IF_VIRTIO] = virtio,
   [IF_XEN] = xen,
  +[IF_AHCI] = ahci,
   };
   
   static const int if_max_devs[IF_COUNT] = {
  @@ -52,8 +53,17 @@ static const int if_max_devs[IF_COUNT] = {
*/
   [IF_IDE] = 2,
   [IF_SCSI] = 7,
  +[IF_AHCI] = 6,
   };
 
 What are the implications of this if we decided to add another AHCI
 controller which had a different number of ports? I suspect that a
 controller with less than 6 ports breaks when you add more drives than a
 single controller can handle, and one with more than 6 ports doesn't use
 up all of its ports before it adds another controller.
 
 Markus?
 

My plan was to make this field, machine dependent if/when we wanted a different
size. I don't think it breaks anything to make this change at a later
point. But please correct me, if I am wrong.


  +int get_if_max_devs(BlockInterfaceType if_type)
  +{
  +assert(if_type  IF_COUNT);
  +assert(if_type = IF_DEFAULT);
  +
  +return if_max_devs[if_type];
  +}
 
 if_max_devs has a specific obvious meaning within blockdev.c, but
 outside it's not as obvious. So this function could use a rename.

ok.

 
   /*
* We automatically delete the drive when a device using it gets
* unplugged.  Questionable feature, but we can't just drop it.
  @@ -518,7 +528,7 @@ DriveInfo *drive_init(QemuOpts *opts, int mach_if)
   } else {
   /* no id supplied - create one */
   dinfo-id = g_malloc0(32);
  -if (type == IF_IDE || type == IF_SCSI)
  +if (type == IF_IDE || type == IF_SCSI || type == IF_AHCI)
   mediastr = (media == MEDIA_CDROM) ? -cd : -hd;
   if (max_devs)
   snprintf(dinfo-id, 32, %s%i%s%i,
  @@ -550,6 +560,7 @@ DriveInfo *drive_init(QemuOpts *opts, int mach_if)
   
   switch(type) {
   case IF_IDE:
  +case IF_AHCI:
   case IF_SCSI:
   case IF_XEN:
   case IF_NONE:
  diff --git a/blockdev.h b/blockdev.h
  index 8b126ad..bbd1017 100644
  --- a/blockdev.h
  +++ b/blockdev.h
  @@ -21,6 +21,7 @@ typedef enum {
   IF_DEFAULT = -1,/* for use with drive_add() only */
   IF_NONE,
   IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, 
  IF_XEN,
  +IF_AHCI,
   IF_COUNT
   } BlockInterfaceType;
   
  @@ -56,6 +57,7 @@ static inline int get_mach_if(int mach_if)
   return mach_if;
   }
   
  +int get_if_max_devs(BlockInterfaceType if_type);
   DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
   DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
   int drive_get_max_bus(BlockInterfaceType type);
  diff --git a/hw/ide.h b/hw/ide.h
  index 2db4079..0b7e000 100644
  --- a/hw/ide.h
  +++ b/hw/ide.h
  @@ -4,6 +4,7 @@
   #include isa.h
   #include pci.h
   #include memory.h
  +#include blockdev.h
   
   #define MAX_IDE_DEVS  2
   
  @@ -34,6 +35,11 @@ int ide_get_geometry(BusState *bus, int unit,
   int ide_get_bios_chs_trans(BusState *bus, int unit);
   
   /* ide/core.c */
  +void ata_drive_get(DriveInfo **hd, int max_bus, BlockInterfaceType type);
   void ide_drive_get(DriveInfo **hd, int max_bus);
  +void ahci_drive_get(DriveInfo **hd, int max_bus);
  +
  +/* ide/ahci.c */
  +void pci_ahci_create_devs(PCIDevice *pci_dev, DriveInfo **hd_table);
   
   #endif /* HW_IDE_H */
  diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
  index 68671bc..824b86f 100644
  --- a/hw/ide/ahci.c
  +++ b/hw/ide/ahci.c
  @@ -26,6 +26,7 @@
   #include hw/pc.h
   #include hw/pci.h
   #include hw/sysbus.h
  +#include blockdev.h
   
   #include monitor.h
   #include dma.h
  @@ -1260,3 +1261,20 @@ static void sysbus_ahci_register_types(void

  1   2   3   >