Re: [PATCH] firmware: qemu_fw_cfg: make kobj_type structure constant

2023-03-03 Thread Gabriel L. Somlo
On Mon, Feb 27, 2023 at 03:19:56AM +, Thomas Weißschuh wrote:
> Since commit ee6d3dd4ed48 ("driver core: make kobj_type constant.")
> the driver core allows the usage of const struct kobj_type.
> 
> Take advantage of this to constify the structure definition to prevent
> modification at runtime.
> 
> Signed-off-by: Thomas Weißschuh 
> ---
>  drivers/firmware/qemu_fw_cfg.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> index a69399a6b7c0..f41de793f41b 100644
> --- a/drivers/firmware/qemu_fw_cfg.c
> +++ b/drivers/firmware/qemu_fw_cfg.c
> @@ -452,7 +452,7 @@ static void fw_cfg_sysfs_release_entry(struct kobject 
> *kobj)
>  }
>  
>  /* kobj_type: ties together all properties required to register an entry */
> -static struct kobj_type fw_cfg_sysfs_entry_ktype = {
> +static const struct kobj_type fw_cfg_sysfs_entry_ktype = {

Reviewed-by: Gabriel L. Somlo 

Thanks,
--Gabriel

>   .default_groups = fw_cfg_sysfs_entry_groups,
>   .sysfs_ops = _cfg_sysfs_attr_ops,
>   .release = fw_cfg_sysfs_release_entry,
> 
> ---
> base-commit: 2fcd07b7ccd5fd10b2120d298363e4e6c53ccf9c
> change-id: 20230227-kobj_type-firmware-qemu-7746b6320db0
> 
> Best regards,
> -- 
> Thomas Weißschuh 
> 



Re: [PATCH] hw/misc: applesmc: use host osk as default on macs

2021-10-11 Thread Gabriel L. Somlo
On Mon, 11 Oct 2021 15:40:07 +0200, bala...@eik.bme.hu wrote:
> I guess a frequent use case for running macOS guests with keys from host 
> would be on hosts running macOS too so a solution that works both on macOS 
> and Linux might be better than a Linux specific one which then needs 
> another way to do the same on macOS. Looks like there's free code for that 
> too and you don't have to convince a maintainer either.

I mostly agree with you (hadn't given much thought to qemu on macOSX),
with the small caveat that (on Linux) you'll end up racing the kernel
applesmc driver for access to the physical hardware; not sure whether
you'd run into anything similar on host-side macOSX as well, never
actually used it much as a developer... :)

Cheers,
--Gabriel



Re: [PATCH] hw/misc: applesmc: use host osk as default on macs

2021-10-11 Thread Gabriel L. Somlo
FWIW, there's an applesmc driver in the Linux kernel, and it exposes
many of the keys and values stored on the chip under
/sys/devices/platform/applesmc.768 (or at least it *used* to back when
I last checked).

My idea at the time was to get this driver to also expose the value of
OSK0,1, so that userspace programs (like e.g. qemu) could read and use
the values hardcoded in hardware without needing to hardcode them
themselves in software.

It went nowhere at the time (the hwmon maintainer kept insisting that
"since it's a constant why don't you just hardcode it", and round and
round we went until I walked away:

https://lore.kernel.org/lkml/20121210222313.gf2...@hedwig.ini.cmu.edu/

Given *this* conversation, it might be worth someone's effort to try
that approach again. IMO it's really the most efficient: have an
already existing applesmc driver in the hypervisor's kernel expose the
desired key values (it's whole job is to expose key values to
userspace in the first place). Then have userspace read that and use
it for whatever purposes (including populating guest-facing emulated
smc devices). Nobody has to use anyone's copyrighted code or strings
or whatever. If only the hwmon folks could be convinced this time
around :)

HTH,
--Gabriel

On Sun, Oct 10, 2021 at 06:22:04PM -0300, Pedro Tôrres wrote:
> AFAIK there’s no public documentation from Apple on how to read values from
> SMC.
> 
> But Amit Singh wrote a book, Mac OS X Internals, and one of the processes
> described on it is how to read OSK directly from SMC: https://web.archive.org/
> web/20190630050544/http://osxbook.com/book/bonus/chapter7/tpmdrmmyth/
> 
> This is actually referenced on VirtualBox’s source code as the base for their
> implementation: 
> https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Devices/
> EFI/DevSmc.cpp#L520
> 
> Additionally, there is the smcFanControl project, licensed under GPLv2, that
> performs reads and writes on SMC and have all information necessary to
> implement this feature on QEMU: https://github.com/hholtmann/smcFanControl
> 
> This project was used as base for the SMC in-tree driver for Linux and it’s
> referenced there: https://github.com/torvalds/linux/blob/master/drivers/hwmon/
> applesmc.c#L14
> 
> I think we would be safe using these sources as the base for our
> implementation, given that other huge GPL projects like Linux and VirtualBox
> have been using them for years.
> 
> Best regards,
> Pedro Tôrres
> 
> 
> On Oct 10, 2021, at 4:25 PM, Paolo Bonzini  wrote:
> 
> 
> Can you instead provide documentation in English (pseudocode, tables of 
> the
> structs, etc.)? That's the safest bet.
> 
> Paolo
> 
> El sáb., 9 oct. 2021 7:32, Pedro Tôrres  escribió:
> 
> Hey Paolo and Phil,
> 
> I understand you concerns regarding the license that Apple open-source
> code is distributed.
> 
> If I restart from scratch and implement this feature based only on
> VirtualBox code, that is distributed under GPLv2, would it be fine?
> 
> Best regards,
> Pedro Tôrres
> 
> 
> On Oct 8, 2021, at 3:54 PM, Paolo Bonzini 
> wrote:
> 
> 
> On 08/10/21 14:03, Phil Dennis-Jordan wrote:
> 
> 1. Licensing
> 
> Given that the code it's heavily based on is copyright Apple
> Computer Inc., licensed under APSL, is it safe including it in
> qemu as is?
> 
> If the integrated code is going to be quite so "directly
> inspired" (down to the inconsistent struct definition style 
> and
> mixing unrelated constants in the same anonymous enum), 
> perhaps
> at minimum place it in its own isolated source file with
> appropriate notice?
> 
>
> Yeah, this should be reverted.
>
> Pedro, I understand that you stated it was "based on code from
> Apple" but you also said (by including Signed-off-by) that
>
> ---
> (a) The contribution was created in whole or in part by me and I
>have the right to submit it under the open source license
>indicated in the file; or
>
> (b) The contribution is based upon previous work that, to the best
>of my knowledge, is covered under an appropriate open source
>license and I have the right under that license to submit that
>work with modifications, whether created in whole or in part
>by me, under the same open source license (unless I am
>permitted to submit under a different license), as indicated
>in the file; or
> ---
>
> and this is not true.
>
> Thanks very much,
>
> Paolo
>
> 



Re: [Qemu-devel] [PATCH] firmware: Use PTR_ERR_OR_ZERO()

2017-11-29 Thread Gabriel L. Somlo
Acked-by: Gabriel Somlo 

On Tue, Nov 28, 2017 at 10:40:27PM +0100, Vasyl Gomonovych wrote:
> Fix ptr_ret.cocci warnings:
> drivers/firmware/efi/efi.c:610:8-14: WARNING: PTR_ERR_OR_ZERO can be used
> 
> Use PTR_ERR_OR_ZERO rather than if(IS_ERR(...)) + PTR_ERR
> 
> Generated by: scripts/coccinelle/api/ptr_ret.cocci
> 
> Signed-off-by: Vasyl Gomonovych 
> ---
>  drivers/firmware/qemu_fw_cfg.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> index 5cfe39f7a45f..18489b6a696d 100644
> --- a/drivers/firmware/qemu_fw_cfg.c
> +++ b/drivers/firmware/qemu_fw_cfg.c
> @@ -693,10 +693,8 @@ static int fw_cfg_cmdline_set(const char *arg, const 
> struct kernel_param *kp)
>*/
>   fw_cfg_cmdline_dev = platform_device_register_simple("fw_cfg",
>   PLATFORM_DEVID_NONE, res, processed);
> - if (IS_ERR(fw_cfg_cmdline_dev))
> - return PTR_ERR(fw_cfg_cmdline_dev);
>  
> - return 0;
> + return PTR_ERR_OR_ZERO(fw_cfg_cmdline_dev);
>  }
>  
>  static int fw_cfg_cmdline_get(char *buf, const struct kernel_param *kp)
> -- 
> 1.9.1
> 



Re: [Qemu-devel] [PATCH v4 3/5] fw_cfg: do DMA read operation

2017-11-12 Thread Gabriel L. Somlo
On Sun, Nov 12, 2017 at 09:36:33AM -0500, Marc-André Lureau wrote:
> 
> 
> - Original Message -
> > On Tue, Oct 31, 2017 at 04:19:36PM +0100, Marc-André Lureau wrote:
> > > Modify fw_cfg_read_blob() to use DMA if the device supports it.
> > > Return errors, because the operation may fail.
> > > 
> > > To avoid polling with unbound amount of time, the DMA operation is
> > > expected to complete within 200ms, or will return ETIME error.
> > > 
> > > We may want to switch all the *buf addresses to use only kmalloc'ed
> > > buffers (instead of using stack/image addresses with dma=false).
> > > 
> > > Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com>
> > 
> > A couple of silly questions, inline, below.
> > 
> > Thanks,
> > --G
> > 
> > > ---
> > >  drivers/firmware/qemu_fw_cfg.c | 154
> > >  -
> > >  1 file changed, 137 insertions(+), 17 deletions(-)
> > > 
> > > diff --git a/drivers/firmware/qemu_fw_cfg.c
> > > b/drivers/firmware/qemu_fw_cfg.c
> > > index 1f3e8545dab7..8ce5e49b7c62 100644
> > > --- a/drivers/firmware/qemu_fw_cfg.c
> > > +++ b/drivers/firmware/qemu_fw_cfg.c
> > > @@ -33,6 +33,8 @@
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > > +#include 
> > >  
> > >  MODULE_AUTHOR("Gabriel L. Somlo <so...@cmu.edu>");
> > >  MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
> > > @@ -43,12 +45,26 @@ MODULE_LICENSE("GPL");
> > >  #define FW_CFG_ID 0x01
> > >  #define FW_CFG_FILE_DIR   0x19
> > >  
> > > +#define FW_CFG_VERSION_DMA 0x02
> > > +#define FW_CFG_DMA_CTL_ERROR   0x01
> > > +#define FW_CFG_DMA_CTL_READ0x02
> > > +#define FW_CFG_DMA_CTL_SKIP0x04
> > > +#define FW_CFG_DMA_CTL_SELECT  0x08
> > > +#define FW_CFG_DMA_CTL_WRITE   0x10
> > > +#define FW_CFG_DMA_TIMEOUT 200 /* ms */
> > > +
> > >  /* size in bytes of fw_cfg signature */
> > >  #define FW_CFG_SIG_SIZE 4
> > >  
> > >  /* fw_cfg "file name" is up to 56 characters (including terminating nul)
> > >  */
> > >  #define FW_CFG_MAX_FILE_PATH 56
> > >  
> > > +/* platform device for dma mapping */
> > > +static struct device *dev;
> > > +
> > > +/* fw_cfg revision attribute, in /sys/firmware/qemu_fw_cfg top-level dir.
> > > */
> > > +static u32 fw_cfg_rev;
> > > +
> > >  /* fw_cfg file directory entry type */
> > >  struct fw_cfg_file {
> > >   u32 size;
> > > @@ -57,6 +73,12 @@ struct fw_cfg_file {
> > >   char name[FW_CFG_MAX_FILE_PATH];
> > >  };
> > >  
> > > +struct fw_cfg_dma {
> > > + u32 control;
> > > + u32 length;
> > > + u64 address;
> > > +} __packed;
> > > +
> > >  /* fw_cfg device i/o register addresses */
> > >  static bool fw_cfg_is_mmio;
> > >  static phys_addr_t fw_cfg_p_base;
> > > @@ -75,12 +97,93 @@ static inline u16 fw_cfg_sel_endianness(u16 key)
> > >   return fw_cfg_is_mmio ? cpu_to_be16(key) : cpu_to_le16(key);
> > >  }
> > >  
> > > +static inline bool fw_cfg_dma_enabled(void)
> > > +{
> > > + return fw_cfg_rev & FW_CFG_VERSION_DMA && fw_cfg_reg_dma;
> > > +}
> > > +
> > > +static bool fw_cfg_wait_for_control(struct fw_cfg_dma *d, unsigned long
> > > timeout)
> > > +{
> > > + ktime_t start;
> > > + ktime_t stop;
> > > +
> > > + start = ktime_get();
> > > + stop = ktime_add(start, ms_to_ktime(timeout));
> > > +
> > > + do {
> > > + if ((be32_to_cpu(d->control) & ~FW_CFG_DMA_CTL_ERROR) == 0)
> > > + return true;
> > > +
> > > + usleep_range(50, 100);
> > > + } while (ktime_before(ktime_get(), stop));
> > > +
> > > + return false;
> > > +}
> > > +
> > > +static ssize_t fw_cfg_dma_transfer(void *address, u32 length, u32 
> > > control)
> > > +{
> > > + dma_addr_t dma_addr = 0;
> > > + struct fw_cfg_dma *d;
> > > + dma_addr_t dma;
> > > + ssize_t ret = length;
> > > + enum dma_data_direction dir =
> > > + (control & FW_CFG_DMA_CTL_READ ? DMA_FROM_DEVICE : 0);
> > > +
> > > + if (add

Re: [Qemu-devel] [PATCH v4 5/5] fw_cfg: write vmcoreinfo details

2017-11-12 Thread Gabriel L. Somlo
On Tue, Oct 31, 2017 at 04:19:38PM +0100, Marc-André Lureau wrote:
> If the "etc/vmcoreinfo" fw_cfg file is present and we are not running
> the kdump kernel, write the addr/size of the vmcoreinfo ELF note.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com>

Same two questions as for 3/5 earlier :)

Thanks,
--G

> ---
>  drivers/firmware/qemu_fw_cfg.c | 87 
> +-
>  1 file changed, 86 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> index 8ce5e49b7c62..ebd9bb134900 100644
> --- a/drivers/firmware/qemu_fw_cfg.c
> +++ b/drivers/firmware/qemu_fw_cfg.c
> @@ -35,6 +35,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  
>  MODULE_AUTHOR("Gabriel L. Somlo <so...@cmu.edu>");
>  MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
> @@ -59,6 +61,8 @@ MODULE_LICENSE("GPL");
>  /* fw_cfg "file name" is up to 56 characters (including terminating nul) */
>  #define FW_CFG_MAX_FILE_PATH 56
>  
> +#define VMCOREINFO_FORMAT_ELF 0x1
> +
>  /* platform device for dma mapping */
>  static struct device *dev;
>  
> @@ -127,7 +131,8 @@ static ssize_t fw_cfg_dma_transfer(void *address, u32 
> length, u32 control)
>   dma_addr_t dma;
>   ssize_t ret = length;
>   enum dma_data_direction dir =
> - (control & FW_CFG_DMA_CTL_READ ? DMA_FROM_DEVICE : 0);
> + (control & FW_CFG_DMA_CTL_READ ? DMA_FROM_DEVICE : 0) |
> + (control & FW_CFG_DMA_CTL_WRITE ? DMA_TO_DEVICE : 0);
>  
>   if (address && length) {
>   dma_addr = dma_map_single(dev, address, length, dir);
> @@ -225,6 +230,48 @@ static ssize_t fw_cfg_read_blob(u16 key,
>   return ret;
>  }
>  
> +#ifdef CONFIG_CRASH_CORE
> +/* write chunk of given fw_cfg blob (caller responsible for sanity-check) */
> +static ssize_t fw_cfg_write_blob(u16 key,
> +  void *buf, loff_t pos, size_t count)
> +{
> + u32 glk = -1U;
> + acpi_status status;
> + ssize_t ret = count;
> +
> + /* If we have ACPI, ensure mutual exclusion against any potential
> +  * device access by the firmware, e.g. via AML methods:
> +  */
> + status = acpi_acquire_global_lock(ACPI_WAIT_FOREVER, );
> + if (ACPI_FAILURE(status) && status != AE_NOT_CONFIGURED) {
> + /* Should never get here */
> + WARN(1, "%s: Failed to lock ACPI!\n", __func__);
> + memset(buf, 0, count);
> + return -EBUSY;

Same question as before: why not e.g. EINVAL?

> + }
> +
> + mutex_lock(_cfg_dev_lock);
> + if (pos == 0) {
> + ret = fw_cfg_dma_transfer(buf, count, key << 16
> +   | FW_CFG_DMA_CTL_SELECT
> +   | FW_CFG_DMA_CTL_WRITE);
> + } else {
> + iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl);
> + ret = fw_cfg_dma_transfer(0, pos, FW_CFG_DMA_CTL_SKIP);

NULL?

> + if (ret < 0)
> + goto end;
> + ret = fw_cfg_dma_transfer(buf, count, FW_CFG_DMA_CTL_WRITE);
> + }
> +
> +end:
> + mutex_unlock(_cfg_dev_lock);
> +
> + acpi_release_global_lock(glk);
> +
> + return ret;
> +}
> +#endif /* CONFIG_CRASH_CORE */
> +
>  /* clean up fw_cfg device i/o */
>  static void fw_cfg_io_cleanup(void)
>  {
> @@ -343,6 +390,37 @@ struct fw_cfg_sysfs_entry {
>   struct list_head list;
>  };
>  
> +#ifdef CONFIG_CRASH_CORE
> +static ssize_t write_vmcoreinfo(const struct fw_cfg_file *f)
> +{
> + struct vmci {
> + __le16 host_format;
> + __le16 guest_format;
> + __le32 size;
> + __le64 paddr;
> + } __packed;
> + struct vmci *data;
> + ssize_t ret;
> +
> + data = kmalloc(sizeof(struct vmci), GFP_KERNEL | GFP_DMA);
> + if (!data)
> + return -ENOMEM;
> +
> + /* spare ourself reading host format support for now since we
> +  * don't know what else to format - host may ignore ours
> +  */
> + *data = (struct vmci) {
> + .guest_format = cpu_to_le16(VMCOREINFO_FORMAT_ELF),
> + .size = cpu_to_le32(VMCOREINFO_NOTE_SIZE),
> + .paddr = cpu_to_le64(paddr_vmcoreinfo_note())
> + };
> + ret = fw_cfg_write_blob(f->select, data, 0, sizeof(struct vmci));
> +
> + kfree(data);
> + return ret;
> +}
> +#endif /* CONFIG_CRASH_CORE */
> +
>  /*

Re: [Qemu-devel] [PATCH v4 4/5] crash: export paddr_vmcoreinfo_note()

2017-11-12 Thread Gabriel L. Somlo
On Tue, Oct 31, 2017 at 04:19:37PM +0100, Marc-André Lureau wrote:
> The following patch is going to use the symbol from the fw_cfg module.
> 
> Signed-off-by: Marc-André Lureau 

Acked-by: Gabriel Somlo 

> ---
>  kernel/crash_core.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 6db80fc0810b..47541c891810 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -375,6 +375,7 @@ phys_addr_t __weak paddr_vmcoreinfo_note(void)
>  {
>   return __pa(vmcoreinfo_note);
>  }
> +EXPORT_SYMBOL(paddr_vmcoreinfo_note);
>  
>  static int __init crash_save_vmcoreinfo_init(void)
>  {
> -- 
> 2.15.0.rc0.40.gaefcc5f6f
> 



Re: [Qemu-devel] [PATCH v4 3/5] fw_cfg: do DMA read operation

2017-11-12 Thread Gabriel L. Somlo
On Tue, Oct 31, 2017 at 04:19:36PM +0100, Marc-André Lureau wrote:
> Modify fw_cfg_read_blob() to use DMA if the device supports it.
> Return errors, because the operation may fail.
> 
> To avoid polling with unbound amount of time, the DMA operation is
> expected to complete within 200ms, or will return ETIME error.
> 
> We may want to switch all the *buf addresses to use only kmalloc'ed
> buffers (instead of using stack/image addresses with dma=false).
> 
> Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com>

A couple of silly questions, inline, below.

Thanks,
--G

> ---
>  drivers/firmware/qemu_fw_cfg.c | 154 
> -
>  1 file changed, 137 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> index 1f3e8545dab7..8ce5e49b7c62 100644
> --- a/drivers/firmware/qemu_fw_cfg.c
> +++ b/drivers/firmware/qemu_fw_cfg.c
> @@ -33,6 +33,8 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
>  
>  MODULE_AUTHOR("Gabriel L. Somlo <so...@cmu.edu>");
>  MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
> @@ -43,12 +45,26 @@ MODULE_LICENSE("GPL");
>  #define FW_CFG_ID 0x01
>  #define FW_CFG_FILE_DIR   0x19
>  
> +#define FW_CFG_VERSION_DMA 0x02
> +#define FW_CFG_DMA_CTL_ERROR   0x01
> +#define FW_CFG_DMA_CTL_READ0x02
> +#define FW_CFG_DMA_CTL_SKIP0x04
> +#define FW_CFG_DMA_CTL_SELECT  0x08
> +#define FW_CFG_DMA_CTL_WRITE   0x10
> +#define FW_CFG_DMA_TIMEOUT 200 /* ms */
> +
>  /* size in bytes of fw_cfg signature */
>  #define FW_CFG_SIG_SIZE 4
>  
>  /* fw_cfg "file name" is up to 56 characters (including terminating nul) */
>  #define FW_CFG_MAX_FILE_PATH 56
>  
> +/* platform device for dma mapping */
> +static struct device *dev;
> +
> +/* fw_cfg revision attribute, in /sys/firmware/qemu_fw_cfg top-level dir. */
> +static u32 fw_cfg_rev;
> +
>  /* fw_cfg file directory entry type */
>  struct fw_cfg_file {
>   u32 size;
> @@ -57,6 +73,12 @@ struct fw_cfg_file {
>   char name[FW_CFG_MAX_FILE_PATH];
>  };
>  
> +struct fw_cfg_dma {
> + u32 control;
> + u32 length;
> + u64 address;
> +} __packed;
> +
>  /* fw_cfg device i/o register addresses */
>  static bool fw_cfg_is_mmio;
>  static phys_addr_t fw_cfg_p_base;
> @@ -75,12 +97,93 @@ static inline u16 fw_cfg_sel_endianness(u16 key)
>   return fw_cfg_is_mmio ? cpu_to_be16(key) : cpu_to_le16(key);
>  }
>  
> +static inline bool fw_cfg_dma_enabled(void)
> +{
> + return fw_cfg_rev & FW_CFG_VERSION_DMA && fw_cfg_reg_dma;
> +}
> +
> +static bool fw_cfg_wait_for_control(struct fw_cfg_dma *d, unsigned long 
> timeout)
> +{
> + ktime_t start;
> + ktime_t stop;
> +
> + start = ktime_get();
> + stop = ktime_add(start, ms_to_ktime(timeout));
> +
> + do {
> + if ((be32_to_cpu(d->control) & ~FW_CFG_DMA_CTL_ERROR) == 0)
> + return true;
> +
> + usleep_range(50, 100);
> + } while (ktime_before(ktime_get(), stop));
> +
> + return false;
> +}
> +
> +static ssize_t fw_cfg_dma_transfer(void *address, u32 length, u32 control)
> +{
> + dma_addr_t dma_addr = 0;
> + struct fw_cfg_dma *d;
> + dma_addr_t dma;
> + ssize_t ret = length;
> + enum dma_data_direction dir =
> + (control & FW_CFG_DMA_CTL_READ ? DMA_FROM_DEVICE : 0);
> +
> + if (address && length) {
> + dma_addr = dma_map_single(dev, address, length, dir);
> + if (dma_mapping_error(NULL, dma_addr)) {
> + WARN(1, "%s: failed to map address\n", __func__);
> + return -EFAULT;
> + }
> + }
> +
> + d = kmalloc(sizeof(*d), GFP_KERNEL | GFP_DMA);
> + if (!d) {
> + ret = -ENOMEM;
> + goto end;
> + }
> +
> + dma = dma_map_single(dev, d, sizeof(*d), DMA_BIDIRECTIONAL);
> + if (dma_mapping_error(NULL, dma)) {
> + WARN(1, "%s: failed to map fw_cfg_dma\n", __func__);
> + ret = -EFAULT;
> + goto end;
> + }
> +
> + *d = (struct fw_cfg_dma) {
> + .address = cpu_to_be64(dma_addr),
> + .length = cpu_to_be32(length),
> + .control = cpu_to_be32(control)
> + };
> +
> + iowrite32be((u64)dma >> 32, fw_cfg_reg_dma);
> + iowrite32be(dma, fw_cfg_reg_dma + 4);
> +
> + if (!fw_cfg_wait_for_control(d, FW_CFG_DMA_TIMEOUT)) {
> +   

Re: [Qemu-devel] [PATCH v4 2/5] fw_cfg: add DMA register

2017-11-12 Thread Gabriel L. Somlo
On Tue, Oct 31, 2017 at 04:19:35PM +0100, Marc-André Lureau wrote:
> Add an optional  kernel module (or command line) parameter
> using the following syntax:
> 
>   [qemu_fw_cfg.]ioport=@[::[:]]
>  or
>   [qemu_fw_cfg.]mmio=@[::[:]]
> 
> and initializes the register address using given or default offset.
> 
> Signed-off-by: Marc-André Lureau 

Reviewed-by: Gabriel Somlo 

> ---
>  drivers/firmware/qemu_fw_cfg.c | 53 
> --
>  1 file changed, 41 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> index 5cfe39f7a45f..1f3e8545dab7 100644
> --- a/drivers/firmware/qemu_fw_cfg.c
> +++ b/drivers/firmware/qemu_fw_cfg.c
> @@ -10,20 +10,21 @@
>   * and select subsets of aarch64), a Device Tree node (on arm), or using
>   * a kernel module (or command line) parameter with the following syntax:
>   *
> - *  [qemu_fw_cfg.]ioport=@[::]
> + *  
> [qemu_fw_cfg.]ioport=@[::[:]]
>   * or
> - *  [qemu_fw_cfg.]mmio=@[::]
> + *  [qemu_fw_cfg.]mmio=@[::[:]]
>   *
>   * where:
>   *   := size of ioport or mmio range
>   *   := physical base address of ioport or mmio range
>   *   := (optional) offset of control register
>   *   := (optional) offset of data register
> + *   := (optional) offset of dma register
>   *
>   * e.g.:
> - *  qemu_fw_cfg.ioport=2@0x510:0:1   (the default on x86)
> + *  qemu_fw_cfg.ioport=12@0x510:0:1:4(the default on x86)
>   * or
> - *  qemu_fw_cfg.mmio=0xA@0x902:8:0   (the default on arm)
> + *  qemu_fw_cfg.mmio=16@0x902:8:0:16 (the default on arm)
>   */
>  
>  #include 
> @@ -63,6 +64,7 @@ static resource_size_t fw_cfg_p_size;
>  static void __iomem *fw_cfg_dev_base;
>  static void __iomem *fw_cfg_reg_ctrl;
>  static void __iomem *fw_cfg_reg_data;
> +static void __iomem *fw_cfg_reg_dma;
>  
>  /* atomic access to fw_cfg device (potentially slow i/o, so using mutex) */
>  static DEFINE_MUTEX(fw_cfg_dev_lock);
> @@ -118,12 +120,14 @@ static void fw_cfg_io_cleanup(void)
>  # if (defined(CONFIG_ARM) || defined(CONFIG_ARM64))
>  #  define FW_CFG_CTRL_OFF 0x08
>  #  define FW_CFG_DATA_OFF 0x00
> +#  define FW_CFG_DMA_OFF 0x10
>  # elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* 
> ppc/mac,sun4m */
>  #  define FW_CFG_CTRL_OFF 0x00
>  #  define FW_CFG_DATA_OFF 0x02
>  # elif (defined(CONFIG_X86) || defined(CONFIG_SPARC64)) /* x86, sun4u */
>  #  define FW_CFG_CTRL_OFF 0x00
>  #  define FW_CFG_DATA_OFF 0x01
> +#  define FW_CFG_DMA_OFF 0x04
>  # else
>  #  error "QEMU FW_CFG not available on this architecture!"
>  # endif
> @@ -133,7 +137,7 @@ static void fw_cfg_io_cleanup(void)
>  static int fw_cfg_do_platform_probe(struct platform_device *pdev)
>  {
>   char sig[FW_CFG_SIG_SIZE];
> - struct resource *range, *ctrl, *data;
> + struct resource *range, *ctrl, *data, *dma;
>  
>   /* acquire i/o range details */
>   fw_cfg_is_mmio = false;
> @@ -170,6 +174,7 @@ static int fw_cfg_do_platform_probe(struct 
> platform_device *pdev)
>   /* were custom register offsets provided (e.g. on the command line)? */
>   ctrl = platform_get_resource_byname(pdev, IORESOURCE_REG, "ctrl");
>   data = platform_get_resource_byname(pdev, IORESOURCE_REG, "data");
> + dma = platform_get_resource_byname(pdev, IORESOURCE_REG, "dma");
>   if (ctrl && data) {
>   fw_cfg_reg_ctrl = fw_cfg_dev_base + ctrl->start;
>   fw_cfg_reg_data = fw_cfg_dev_base + data->start;
> @@ -179,6 +184,13 @@ static int fw_cfg_do_platform_probe(struct 
> platform_device *pdev)
>   fw_cfg_reg_data = fw_cfg_dev_base + FW_CFG_DATA_OFF;
>   }
>  
> + if (dma)
> + fw_cfg_reg_dma = fw_cfg_dev_base + dma->start;
> +#ifdef FW_CFG_DMA_OFF
> + else
> + fw_cfg_reg_dma = fw_cfg_dev_base + FW_CFG_DMA_OFF;
> +#endif
> +
>   /* verify fw_cfg device signature */
>   fw_cfg_read_blob(FW_CFG_SIGNATURE, sig, 0, FW_CFG_SIG_SIZE);
>   if (memcmp(sig, "QEMU", FW_CFG_SIG_SIZE) != 0) {
> @@ -628,6 +640,7 @@ static struct platform_device *fw_cfg_cmdline_dev;
>  /* use special scanf/printf modifier for phys_addr_t, resource_size_t */
>  #define PH_ADDR_SCAN_FMT "@%" __PHYS_ADDR_PREFIX "i%n" \
>":%" __PHYS_ADDR_PREFIX "i" \
> +  ":%" __PHYS_ADDR_PREFIX "i%n" \
>":%" __PHYS_ADDR_PREFIX "i%n"
>  
>  #define PH_ADDR_PR_1_FMT "0x%" __PHYS_ADDR_PREFIX "x@" \
> @@ -637,12 +650,15 @@ static struct platform_device *fw_cfg_cmdline_dev;
>":%" __PHYS_ADDR_PREFIX "u" \
>":%" __PHYS_ADDR_PREFIX "u"
>  
> +#define PH_ADDR_PR_4_FMT PH_ADDR_PR_3_FMT \
> +  ":%" __PHYS_ADDR_PREFIX "u"
> +
>  static int fw_cfg_cmdline_set(const char *arg, const struct kernel_param *kp)
>  {
> - struct resource 

Re: [Qemu-devel] [PATCH v4 1/5] fw_cfg: fix the command line module name

2017-11-12 Thread Gabriel L. Somlo
On Tue, Oct 31, 2017 at 04:19:34PM +0100, Marc-André Lureau wrote:
> Signed-off-by: Marc-André Lureau 

Acked-by: Gabriel Somlo 

> ---
>  drivers/firmware/qemu_fw_cfg.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> index 0e2011636fbb..5cfe39f7a45f 100644
> --- a/drivers/firmware/qemu_fw_cfg.c
> +++ b/drivers/firmware/qemu_fw_cfg.c
> @@ -10,9 +10,9 @@
>   * and select subsets of aarch64), a Device Tree node (on arm), or using
>   * a kernel module (or command line) parameter with the following syntax:
>   *
> - *  [fw_cfg.]ioport=@[::]
> + *  [qemu_fw_cfg.]ioport=@[::]
>   * or
> - *  [fw_cfg.]mmio=@[::]
> + *  [qemu_fw_cfg.]mmio=@[::]
>   *
>   * where:
>   *   := size of ioport or mmio range
> @@ -21,9 +21,9 @@
>   *   := (optional) offset of data register
>   *
>   * e.g.:
> - *  fw_cfg.ioport=2@0x510:0:1(the default on x86)
> + *  qemu_fw_cfg.ioport=2@0x510:0:1   (the default on x86)
>   * or
> - *  fw_cfg.mmio=0xA@0x902:8:0(the default on arm)
> + *  qemu_fw_cfg.mmio=0xA@0x902:8:0   (the default on arm)
>   */
>  
>  #include 
> -- 
> 2.15.0.rc0.40.gaefcc5f6f
> 



Re: [Qemu-devel] [PATCH v4 0/5] fw_cfg: add DMA operations & etc/vmcoreinfo support

2017-11-12 Thread Gabriel L. Somlo
On Tue, Oct 31, 2017 at 04:19:33PM +0100, Marc-André Lureau wrote:
> Hi,
> 
> This series adds DMA operations support to the qemu fw_cfg kernel
> module and populates "etc/vmcoreinfo" with vmcoreinfo location
> details.
> 
> Note: the support for this entry handling has been merged for next
> qemu release (2.11)
> 
> v4:
> - export paddr_vmcoreinfo_note() to fix fw_cfg.ko build
> - fix build with !CONFIG_CRASH_CORE
> - replace the unbounded yield() loop with a usleep_range() loop and a
>   200ms timeout
> - do not write vmcoreinfo entry when running the kdump kernel (D. Hatayama)
> - drop the experimental sysfs write support patch from this series

Tested it on x86_64, appears to work fine.
I have a couple of silly questions re. 3/5 and 5/5. Lost the v5 emails
with the vmcore folks cc-ed, but my questions are unrelated to vmcore
anyway :)

Thanks,
--Gabriel

> 
> v3: (thanks kbuild)
> - add "fw_cfg: fix the command line module name" patch
> - fix build of "fw_cfg: add DMA register" with CONFIG_FW_CFG_SYSFS_CMDLINE=y
> - fix 'Wshift-count-overflow'
> 
> v2:
> - use platform device for dma mapping
> - add etc/vmcoreinfo patch
> - some code cleanups
> 
> Marc-André Lureau (5):
>   fw_cfg: fix the command line module name
>   fw_cfg: add DMA register
>   fw_cfg: do DMA read operation
>   crash: export paddr_vmcoreinfo_note()
>   fw_cfg: write vmcoreinfo details
> 
>  drivers/firmware/qemu_fw_cfg.c | 292 
> +
>  kernel/crash_core.c|   1 +
>  2 files changed, 264 insertions(+), 29 deletions(-)
> 
> -- 
> 2.15.0.rc0.40.gaefcc5f6f
> 



Re: [Qemu-devel] [PATCH 54/88] KVM: use g_new() family of functions

2017-10-09 Thread Gabriel L. Somlo
Reviewed-by: Gabriel Somlo 

On Fri, Oct 06, 2017 at 08:49:49PM -0300, Philippe Mathieu-Daudé wrote:
> From: Marc-André Lureau 
> 
> Signed-off-by: Marc-André Lureau 
> Signed-off-by: Philippe Mathieu-Daudé 
> [PMD: more changes]
> ---
>  accel/kvm/kvm-all.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index 90c88b517d..12568d703c 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -278,7 +278,7 @@ int kvm_destroy_vcpu(CPUState *cpu)
>  goto err;
>  }
>  
> -vcpu = g_malloc0(sizeof(*vcpu));
> +vcpu = g_new0(struct KVMParkedVcpu, 1);
>  vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
>  vcpu->kvm_fd = cpu->kvm_fd;
>  QLIST_INSERT_HEAD(_state->kvm_parked_vcpus, vcpu, node);
> @@ -865,7 +865,7 @@ void kvm_memory_listener_register(KVMState *s, 
> KVMMemoryListener *kml,
>  {
>  int i;
>  
> -kml->slots = g_malloc0(s->nr_slots * sizeof(KVMSlot));
> +kml->slots = g_new0(KVMSlot, s->nr_slots);
>  kml->as_id = as_id;
>  
>  for (i = 0; i < s->nr_slots; i++) {
> @@ -1129,7 +1129,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
>  return virq;
>  }
>  
> -route = g_malloc0(sizeof(KVMMSIRoute));
> +route = g_new0(KVMMSIRoute, 1);
>  route->kroute.gsi = virq;
>  route->kroute.type = KVM_IRQ_ROUTING_MSI;
>  route->kroute.flags = 0;
> @@ -2243,7 +2243,7 @@ int kvm_insert_breakpoint(CPUState *cpu, target_ulong 
> addr,
>  return 0;
>  }
>  
> -bp = g_malloc(sizeof(struct kvm_sw_breakpoint));
> +bp = g_new(struct kvm_sw_breakpoint, 1);
>  bp->pc = addr;
>  bp->use_count = 1;
>  err = kvm_arch_insert_sw_breakpoint(cpu, bp);
> -- 
> 2.14.2
> 



Re: [Qemu-devel] [PATCH 49/88] hw/misc: use g_new() family of functions

2017-10-09 Thread Gabriel L. Somlo
Reviewed-by: Gabriel Somlo 

On Fri, Oct 06, 2017 at 08:49:44PM -0300, Philippe Mathieu-Daudé wrote:
> From: Marc-André Lureau 
> 
> Signed-off-by: Marc-André Lureau 
> Signed-off-by: Philippe Mathieu-Daudé 
> [PMD: added hw/misc/pvpanic.c]
> ---
>  hw/misc/applesmc.c | 2 +-
>  hw/misc/pvpanic.c  | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
> index 7be8b5f13c..12e32b107e 100644
> --- a/hw/misc/applesmc.c
> +++ b/hw/misc/applesmc.c
> @@ -252,7 +252,7 @@ static void applesmc_add_key(AppleSMCState *s, const char 
> *key,
>  {
>  struct AppleSMCData *def;
>  
> -def = g_malloc0(sizeof(struct AppleSMCData));
> +def = g_new0(struct AppleSMCData, 1);
>  def->key = key;
>  def->len = len;
>  def->data = data;
> diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
> index 2b1e9a6450..dc51e4386c 100644
> --- a/hw/misc/pvpanic.c
> +++ b/hw/misc/pvpanic.c
> @@ -95,7 +95,7 @@ static void pvpanic_isa_realizefn(DeviceState *dev, Error 
> **errp)
>  return;
>  }
>  
> -pvpanic_port = g_malloc(sizeof(*pvpanic_port));
> +pvpanic_port = g_new(uint16_t, 1);
>  *pvpanic_port = cpu_to_le16(s->ioport);
>  fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
>  sizeof(*pvpanic_port));
> -- 
> 2.14.2
> 



Re: [Qemu-devel] [PATCHv7 0/6] fw_cfg: qdev-related tidy-ups

2017-06-29 Thread Gabriel L. Somlo
On Thu, Jun 29, 2017 at 03:07:14PM +0100, Mark Cave-Ayland wrote:
> As part of some ongoing sun4u work, I need to be able to wire the fw_cfg
> IO interface to a separate IO space by instantiating the qdev device instead
> of calling fw_cfg_init_io(). This patchset brings FW_CFG_IO in line with
> FW_CFG_MEM and tidies up the realize methods accordingly.

Tested-by: Gabriel Somlo 

Specifically, verified that passing blobs into the guest via
"-fw-cfg name=opt/foo,file=./bar" still shows up properly in
'/sys/firmware/qemu_fw_cfg/by_name/opt/foo/raw' on the guest.

Thanks much,
--Gabriel
 
> Signed-off-by: Mark Cave-Ayland 
> 
> v7:
> - Remove instance_init() function with assert()
> - Switch fw_cfg_find() over to use object_resolve_path_type() which removes 
> the
>   need for the fw_cfg device to exist at a fixed QOM path
> - Switch check for existence of another fw_cfg device over to use the new
>   fw_cfg_find()
> - Add check for fw_cfg parent at realize time
> 
> v6:
> - Revert move of FWCfgEntry from fw_cfg.c to fw_cfg.h from v5
> - Add Reviewed-by tag from Laszlo for patch 5
> - Add Tested-by tags from Laszlo for the series
> 
> v5:
> - Remove unused FWCfgIoState iobase and dma_iobase fields
> - Add Reviewed-By tags from Laszlo
> - Update commit message in patch 5 as suggested by Laszlo
> - Move FWCfgEntry typedef from fw_cfg.h to typedefs.h with the others
> 
> v4:
> - Undo accidental typedef change in patch 5 caught in v3 rework
> 
> v3:
> - Rework patch 1 to use sysbus_add_io() as suggested by Laszlo
> - Add Reviewed-By from Laszlo for patch 2
> - Fix assert() when instantiating > 1 fw_cfg device (new patch 3)
> - Rename fw_cfg_init1() to fw_cfg_common_realize() as part of patch 4
> 
> v2:
> - Fix the QOM bug in patch 1 as indicated by Laszlo
> - Minimise code churn compared to v1
> 
> 
> Mark Cave-Ayland (6):
>   fw_cfg: don't map the fw_cfg IO ports in fw_cfg_io_realize()
>   fw_cfg: move setting of FW_CFG_VERSION_DMA bit to fw_cfg_init1()
>   fw_cfg: switch fw_cfg_find() to locate the fw_cfg device by type
> rather than path
>   fw_cfg: add assert() to ensure the fw_cfg device has been added as a
> child property
>   fw_cfg: move qdev_init_nofail() from fw_cfg_init1() to callers
>   fw_cfg: move QOM type defines and fw_cfg types into fw_cfg.h
> 
>  hw/nvram/fw_cfg.c |  133 
> +++--
>  include/hw/nvram/fw_cfg.h |   50 +
>  include/qemu/typedefs.h   |1 +
>  3 files changed, 108 insertions(+), 76 deletions(-)
> 
> -- 
> 1.7.10.4
> 



Re: [Qemu-devel] Commit 77af8a2b9 breaks (mac)OS X 10.11.6

2017-06-19 Thread Gabriel L. Somlo
Zoltan, Phil:

On Sun, Jun 18, 2017 at 11:25:15PM +0200, BALATON Zoltan wrote:
> After 77af8a2b9 (hw/i386: Use Rev3 FADT (ACPI 2.0) instead of Rev1 to
> improve guest OS support.) OS X 10.11.6 hangs during boot near detecting
> IOAPIC. (Gabriel's latest v3 applesmc patch series does not fix this.) Maybe
> another register needs to be implemented somewhere?

I can (still) boot off my 10.11.0 installer iso image, and
successfully upgraded from 10.11.4 to 10.11.6, with the latter
continuing to boot without problems.

This is with qemu master (patched for applesmc with the latest v3
pending series that's also on the mailing list), and OVMF master
(patched for HFS+).

Zoltan: did reverting 77af8a2b9 actually help in your case ? Leaving
it in doesn't seem to be a problem for me...

Thanks,
--Gabriel



[Qemu-devel] [PATCH v3 2/3] applesmc: implement error status port

2017-06-16 Thread Gabriel L. Somlo
As of release 10.12.4, OS X (Sierra) refuses to boot unless the
AppleSMC supports an additional I/O port, expected to provide an
error status code.

Update the [cmd|data]_write() and data_read() methods to implement
the required state machine, and add I/O region & methods to handle
access to the error port.

Originally proposed by Eric Shelton  based in
part on FakeSMC (git://git.assembla.com/fakesmc.git).

Signed-off-by: Gabriel Somlo 
Reviewed-by: Alexander Graf 
Reviewed-by: Phil Dennis-Jordan 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/misc/applesmc.c | 141 +++--
 1 file changed, 115 insertions(+), 26 deletions(-)

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 6381197..0d882e8 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -43,6 +43,7 @@
 enum {
 APPLESMC_DATA_PORT   = 0x00,
 APPLESMC_CMD_PORT= 0x04,
+APPLESMC_ERR_PORT= 0x1e,
 APPLESMC_NUM_PORTS   = 0x20,
 };
 
@@ -53,6 +54,24 @@ enum {
 APPLESMC_GET_KEY_TYPE_CMD= 0x13,
 };
 
+enum {
+APPLESMC_ST_CMD_DONE = 0x00,
+APPLESMC_ST_DATA_READY   = 0x01,
+APPLESMC_ST_BUSY = 0x02,
+APPLESMC_ST_ACK  = 0x04,
+APPLESMC_ST_NEW_CMD  = 0x08,
+};
+
+enum {
+APPLESMC_ST_1E_CMD_INTRUPTED = 0x80,
+APPLESMC_ST_1E_STILL_BAD_CMD = 0x81,
+APPLESMC_ST_1E_BAD_CMD   = 0x82,
+APPLESMC_ST_1E_NOEXIST   = 0x84,
+APPLESMC_ST_1E_WRITEONLY = 0x85,
+APPLESMC_ST_1E_READONLY  = 0x86,
+APPLESMC_ST_1E_BAD_INDEX = 0xb8,
+};
+
 #ifdef DEBUG_SMC
 #define smc_debug(...) fprintf(stderr, "AppleSMC: " __VA_ARGS__)
 #else
@@ -77,9 +96,12 @@ struct AppleSMCState {
 
 MemoryRegion io_data;
 MemoryRegion io_cmd;
+MemoryRegion io_err;
 uint32_t iobase;
 uint8_t cmd;
 uint8_t status;
+uint8_t status_1e;
+uint8_t last_ret;
 char key[4];
 uint8_t read_pos;
 uint8_t data_len;
@@ -93,89 +115,138 @@ static void applesmc_io_cmd_write(void *opaque, hwaddr 
addr, uint64_t val,
   unsigned size)
 {
 AppleSMCState *s = opaque;
+uint8_t status = s->status & 0x0f;
 
-smc_debug("CMD Write B: %#x = %#x\n", addr, val);
+smc_debug("CMD received: 0x%02x\n", (uint8_t)val);
 switch (val) {
 case APPLESMC_READ_CMD:
-s->status = 0x0c;
+/* did last command run through OK? */
+if (status == APPLESMC_ST_CMD_DONE || status == APPLESMC_ST_NEW_CMD) {
+s->cmd = val;
+s->status = APPLESMC_ST_NEW_CMD | APPLESMC_ST_ACK;
+} else {
+smc_debug("ERROR: previous command interrupted!\n");
+s->status = APPLESMC_ST_NEW_CMD;
+s->status_1e = APPLESMC_ST_1E_CMD_INTRUPTED;
+}
 break;
+default:
+smc_debug("UNEXPECTED CMD 0x%02x\n", (uint8_t)val);
+s->status = APPLESMC_ST_NEW_CMD;
+s->status_1e = APPLESMC_ST_1E_BAD_CMD;
 }
-s->cmd = val;
 s->read_pos = 0;
 s->data_pos = 0;
 }
 
-static void applesmc_fill_data(AppleSMCState *s)
+static struct AppleSMCData *applesmc_find_key(AppleSMCState *s)
 {
 struct AppleSMCData *d;
 
 QLIST_FOREACH(d, >data_def, node) {
 if (!memcmp(d->key, s->key, 4)) {
-smc_debug("Key matched (%s Len=%d Data=%s)\n", d->key,
-  d->len, d->data);
-memcpy(s->data, d->data, d->len);
-return;
+return d;
 }
 }
+return NULL;
 }
 
 static void applesmc_io_data_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
 {
 AppleSMCState *s = opaque;
+struct AppleSMCData *d;
 
-smc_debug("DATA Write B: %#x = %#x\n", addr, val);
+smc_debug("DATA received: 0x%02x\n", (uint8_t)val);
 switch (s->cmd) {
 case APPLESMC_READ_CMD:
+if ((s->status & 0x0f) == APPLESMC_ST_CMD_DONE) {
+break;
+}
 if (s->read_pos < 4) {
 s->key[s->read_pos] = val;
-s->status = 0x04;
+s->status = APPLESMC_ST_ACK;
 } else if (s->read_pos == 4) {
-s->data_len = val;
-s->status = 0x05;
-s->data_pos = 0;
-smc_debug("Key = %c%c%c%c Len = %d\n", s->key[0],
-  s->key[1], s->key[2], s->key[3], val);
-applesmc_fill_data(s);
+d = applesmc_find_key(s);
+if (d != NULL) {
+memcpy(s->data, d->data, d->len);
+s->data_len = d->len;
+s->data_pos = 0;
+s->status = APPLESMC_ST_ACK | APPLESMC_ST_DATA_READY;
+s->status_1e = APPLESMC_ST_CMD_DONE;  /* clear on valid key */
+} else {
+

[Qemu-devel] [PATCH v3 1/3] applesmc: cosmetic whitespace and indentation cleanup

2017-06-16 Thread Gabriel L. Somlo
Signed-off-by: Gabriel Somlo 
Reviewed-by: Alexander Graf 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Phil Dennis-Jordan 
---
 hw/misc/applesmc.c | 98 --
 1 file changed, 50 insertions(+), 48 deletions(-)

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 77fab5b..6381197 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -39,21 +39,24 @@
 /* #define DEBUG_SMC */
 
 #define APPLESMC_DEFAULT_IOBASE0x300
-/* data port used by Apple SMC */
-#define APPLESMC_DATA_PORT 0x0
-/* command/status port used by Apple SMC */
-#define APPLESMC_CMD_PORT  0x4
-#define APPLESMC_NR_PORTS  32
 
-#define APPLESMC_READ_CMD  0x10
-#define APPLESMC_WRITE_CMD 0x11
-#define APPLESMC_GET_KEY_BY_INDEX_CMD  0x12
-#define APPLESMC_GET_KEY_TYPE_CMD  0x13
+enum {
+APPLESMC_DATA_PORT   = 0x00,
+APPLESMC_CMD_PORT= 0x04,
+APPLESMC_NUM_PORTS   = 0x20,
+};
+
+enum {
+APPLESMC_READ_CMD= 0x10,
+APPLESMC_WRITE_CMD   = 0x11,
+APPLESMC_GET_KEY_BY_INDEX_CMD= 0x12,
+APPLESMC_GET_KEY_TYPE_CMD= 0x13,
+};
 
 #ifdef DEBUG_SMC
 #define smc_debug(...) fprintf(stderr, "AppleSMC: " __VA_ARGS__)
 #else
-#define smc_debug(...) do { } while(0)
+#define smc_debug(...) do { } while (0)
 #endif
 
 static char default_osk[64] = "This is a dummy key. Enter the real key "
@@ -77,12 +80,11 @@ struct AppleSMCState {
 uint32_t iobase;
 uint8_t cmd;
 uint8_t status;
-uint8_t key[4];
+char key[4];
 uint8_t read_pos;
 uint8_t data_len;
 uint8_t data_pos;
 uint8_t data[255];
-uint8_t charactic[4];
 char *osk;
 QLIST_HEAD(, AppleSMCData) data_def;
 };
@@ -93,10 +95,10 @@ static void applesmc_io_cmd_write(void *opaque, hwaddr 
addr, uint64_t val,
 AppleSMCState *s = opaque;
 
 smc_debug("CMD Write B: %#x = %#x\n", addr, val);
-switch(val) {
-case APPLESMC_READ_CMD:
-s->status = 0x0c;
-break;
+switch (val) {
+case APPLESMC_READ_CMD:
+s->status = 0x0c;
+break;
 }
 s->cmd = val;
 s->read_pos = 0;
@@ -123,54 +125,54 @@ static void applesmc_io_data_write(void *opaque, hwaddr 
addr, uint64_t val,
 AppleSMCState *s = opaque;
 
 smc_debug("DATA Write B: %#x = %#x\n", addr, val);
-switch(s->cmd) {
-case APPLESMC_READ_CMD:
-if(s->read_pos < 4) {
-s->key[s->read_pos] = val;
-s->status = 0x04;
-} else if(s->read_pos == 4) {
-s->data_len = val;
-s->status = 0x05;
-s->data_pos = 0;
-smc_debug("Key = %c%c%c%c Len = %d\n", s->key[0],
-  s->key[1], s->key[2], s->key[3], val);
-applesmc_fill_data(s);
-}
-s->read_pos++;
-break;
+switch (s->cmd) {
+case APPLESMC_READ_CMD:
+if (s->read_pos < 4) {
+s->key[s->read_pos] = val;
+s->status = 0x04;
+} else if (s->read_pos == 4) {
+s->data_len = val;
+s->status = 0x05;
+s->data_pos = 0;
+smc_debug("Key = %c%c%c%c Len = %d\n", s->key[0],
+  s->key[1], s->key[2], s->key[3], val);
+applesmc_fill_data(s);
+}
+s->read_pos++;
+break;
 }
 }
 
-static uint64_t applesmc_io_data_read(void *opaque, hwaddr addr1,
-  unsigned size)
+static uint64_t applesmc_io_data_read(void *opaque, hwaddr addr, unsigned size)
 {
 AppleSMCState *s = opaque;
 uint8_t retval = 0;
 
-switch(s->cmd) {
-case APPLESMC_READ_CMD:
-if(s->data_pos < s->data_len) {
-retval = s->data[s->data_pos];
-smc_debug("READ_DATA[%d] = %#hhx\n", s->data_pos,
-  retval);
-s->data_pos++;
-if(s->data_pos == s->data_len) {
-s->status = 0x00;
-smc_debug("EOF\n");
-} else
-s->status = 0x05;
+switch (s->cmd) {
+case APPLESMC_READ_CMD:
+if (s->data_pos < s->data_len) {
+retval = s->data[s->data_pos];
+smc_debug("READ_DATA[%d] = %#hhx\n", s->data_pos,
+  retval);
+s->data_pos++;
+if (s->data_pos == s->data_len) {
+s->status = 0x00;
+smc_debug("EOF\n");
+} else {
+s->status = 0x05;
 }
+}
 }
-smc_debug("DATA Read b: %#x = %#x\n", addr1, retval);
+smc_debug("DATA Read b: %#x = %#x\n", addr, retval);
 
 return retval;
 }
 
-static uint64_t applesmc_io_cmd_read(void *opaque, hwaddr addr1, unsigned 

[Qemu-devel] [PATCH v3 3/3] applesmc: fix port i/o access width

2017-06-16 Thread Gabriel L. Somlo
Set access width of all AppleSMC i/o regions to 1 byte, since they
all represent 8-bit-wide ports.

Signed-off-by: Gabriel Somlo 
Reviewed-by: Alexander Graf 
---
 hw/misc/applesmc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 0d882e8..7896812 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -316,12 +316,12 @@ static void applesmc_isa_realize(DeviceState *dev, Error 
**errp)
 AppleSMCState *s = APPLE_SMC(dev);
 
 memory_region_init_io(>io_data, OBJECT(s), _data_io_ops, s,
-  "applesmc-data", 4);
+  "applesmc-data", 1);
 isa_register_ioport(>parent_obj, >io_data,
 s->iobase + APPLESMC_DATA_PORT);
 
 memory_region_init_io(>io_cmd, OBJECT(s), _cmd_io_ops, s,
-  "applesmc-cmd", 4);
+  "applesmc-cmd", 1);
 isa_register_ioport(>parent_obj, >io_cmd,
 s->iobase + APPLESMC_CMD_PORT);
 
-- 
2.7.4




[Qemu-devel] [PATCH v3 0/3] Update AppleSMC for OS X 10.12.4+ guests

2017-06-16 Thread Gabriel L. Somlo
As of 10.12.4, OS X refuses to boot unless the AppleSMC supports a
third I/O port, which provides the current error status when read.

New since v2:
- updated "reviewd-by" fields
- ping ?

>New since v1:
>
>- 1/3: don't touch the default OSK string, as it's unnecessary
>at this time
>
>- 2/3: don't consolidate I/O regions, leave as-is for data
>and cmd; This patch now implements the error-code state
>machine, AND adds an i/o region dedicaded to the error
>status port, complete with read/write access methods.
>
>- 3/3: set access width to 1-byte on data and cmd i/o regions.
>Tested on OS X versions 10.[6..12].
>
>> This series consists of three patches:
>>
>>   - 1/3: indentation/whitespace cleanup for applesmc.c to the point
>>   where it now passes scripts/checkpatc.pl, and allows
>>   subsequent changes to look nice in diff-patch format :)
>>
>>   - 2/3: consolidate Port I/O into a single region, and invoke
>>   appropriate read/write methods based on the offset being
>>   accessed
>>
>>   - 3/3: implement read-only error/status port, and update
>>   data and command read/write methods to correctly
>>   maintain the state machine for keeping the status_1e
>>   value up to date.


Gabriel L. Somlo (3):
  applesmc: cosmetic whitespace and indentation cleanup
  applesmc: implement error status port
  applesmc: fix port i/o access width

 hw/misc/applesmc.c | 219 +
 1 file changed, 155 insertions(+), 64 deletions(-)

-- 
2.7.4




Re: [Qemu-devel] [PATCH v6] kvm: better MWAIT emulation for guests

2017-04-11 Thread Gabriel L. Somlo
On Tue, Apr 11, 2017 at 08:41:11AM -0400, Gabriel L. Somlo wrote:
> On Tue, Apr 11, 2017 at 01:45:35PM +0200, Alexander Graf wrote:
> > From: "Michael S. Tsirkin" <m...@redhat.com>
> > 
> > Guests that are heavy on futexes end up IPI'ing each other a lot. That
> > can lead to significant slowdowns and latency increase for those guests
> > when running within KVM.
> > 
> > If only a single guest is needed on a host, we have a lot of spare host
> > CPU time we can throw at the problem. Modern CPUs implement a feature
> > called "MWAIT" which allows guests to wake up sleeping remote CPUs without
> > an IPI - thus without an exit - at the expense of never going out of guest
> > context.
> > 
> > The decision whether this is something sensible to use should be up to the
> > VM admin, so to user space. We can however allow MWAIT execution on systems
> > that support it properly hardware wise.
> > 
> > This patch adds a CAP to user space and a KVM cpuid leaf to indicate
> > availability of native MWAIT execution. With that enabled, the worst a
> > guest can do is waste as many cycles as a "jmp ." would do, so it's not
> > a privilege problem.
> 
> Did you mean "hlt" rather than "jmp" ?

Or, rather, "nop" ? (apologies, still waiting for the coffee to
cool down to a drinkable temperature... :)
 
> > We consciously do *not* expose the feature in our CPUID bitmap, as most
> > people will want to benefit from sleeping vCPUs to allow for over commit.
> > 
> > Reported-by: "Gabriel L. Somlo" <gso...@gmail.com>
> 
> That's maybe a bit inacurate, I didn't actually report anything *this*
> patch is trying to address (that was rather commit 87c00572ba05aa8c9d).
> 
> Maybe
> 
> Acked-by: Gabriel Somlo <gso...@gmail.com>
> 
> would be a more accurate statement instead?
> 
> Thanks much,
> --Gabriel
> 
> > Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
> > [agraf: fix amd, change commit message]
> > Signed-off-by: Alexander Graf <ag...@suse.de>
> > 
> > ---
> > 
> > v5 -> v6:
> > 
> >   - Fix AMD check, so that we're consistent between svm and vmx
> >   - Clarify commit message
> > ---
> >  Documentation/virtual/kvm/api.txt|  9 +
> >  Documentation/virtual/kvm/cpuid.txt  |  6 ++
> >  arch/x86/include/uapi/asm/kvm_para.h |  1 +
> >  arch/x86/kvm/cpuid.c |  3 +++
> >  arch/x86/kvm/svm.c   |  7 +--
> >  arch/x86/kvm/vmx.c   |  6 --
> >  arch/x86/kvm/x86.c   |  3 +++
> >  arch/x86/kvm/x86.h   | 36 
> > 
> >  include/uapi/linux/kvm.h |  1 +
> >  9 files changed, 68 insertions(+), 4 deletions(-)
> > 
> > diff --git a/Documentation/virtual/kvm/api.txt 
> > b/Documentation/virtual/kvm/api.txt
> > index 1a18484..dacc3d7 100644
> > --- a/Documentation/virtual/kvm/api.txt
> > +++ b/Documentation/virtual/kvm/api.txt
> > @@ -4094,3 +4094,12 @@ reserved.
> >   2: MIPS64 or microMIPS64 with access to all address segments.
> >  Both registers and addresses are 64-bits wide.
> >  It will be possible to run 64-bit or 32-bit guest code.
> > +
> > +8.8 KVM_CAP_X86_GUEST_MWAIT
> > +
> > +Architectures: x86
> > +
> > +This capability indicates that guest using memory monotoring instructions
> > +(MWAIT/MWAITX) to stop the virtual CPU will not cause a VM exit.  As such 
> > time
> > +spent while virtual CPU is halted in this way will then be accounted for as
> > +guest running time on the host (as opposed to e.g. HLT).
> > diff --git a/Documentation/virtual/kvm/cpuid.txt 
> > b/Documentation/virtual/kvm/cpuid.txt
> > index 3c65feb..04c201c 100644
> > --- a/Documentation/virtual/kvm/cpuid.txt
> > +++ b/Documentation/virtual/kvm/cpuid.txt
> > @@ -54,6 +54,12 @@ KVM_FEATURE_PV_UNHALT  || 7 || guest 
> > checks this feature bit
> > ||   || before enabling 
> > paravirtualized
> > ||   || spinlock support.
> >  
> > --
> > +KVM_FEATURE_MWAIT  || 8 || guest can use monitor/mwait
> > +   ||   || to halt the VCPU without 
> > exits,
> > +   ||   || time spent while halted in 
> > this
> &g

Re: [Qemu-devel] [PATCH v6] kvm: better MWAIT emulation for guests

2017-04-11 Thread Gabriel L. Somlo
On Tue, Apr 11, 2017 at 01:45:35PM +0200, Alexander Graf wrote:
> From: "Michael S. Tsirkin" <m...@redhat.com>
> 
> Guests that are heavy on futexes end up IPI'ing each other a lot. That
> can lead to significant slowdowns and latency increase for those guests
> when running within KVM.
> 
> If only a single guest is needed on a host, we have a lot of spare host
> CPU time we can throw at the problem. Modern CPUs implement a feature
> called "MWAIT" which allows guests to wake up sleeping remote CPUs without
> an IPI - thus without an exit - at the expense of never going out of guest
> context.
> 
> The decision whether this is something sensible to use should be up to the
> VM admin, so to user space. We can however allow MWAIT execution on systems
> that support it properly hardware wise.
> 
> This patch adds a CAP to user space and a KVM cpuid leaf to indicate
> availability of native MWAIT execution. With that enabled, the worst a
> guest can do is waste as many cycles as a "jmp ." would do, so it's not
> a privilege problem.

Did you mean "hlt" rather than "jmp" ?

> We consciously do *not* expose the feature in our CPUID bitmap, as most
> people will want to benefit from sleeping vCPUs to allow for over commit.
> 
> Reported-by: "Gabriel L. Somlo" <gso...@gmail.com>

That's maybe a bit inacurate, I didn't actually report anything *this*
patch is trying to address (that was rather commit 87c00572ba05aa8c9d).

Maybe

Acked-by: Gabriel Somlo <gso...@gmail.com>

would be a more accurate statement instead?

Thanks much,
--Gabriel

> Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
> [agraf: fix amd, change commit message]
> Signed-off-by: Alexander Graf <ag...@suse.de>
> 
> ---
> 
> v5 -> v6:
> 
>   - Fix AMD check, so that we're consistent between svm and vmx
>   - Clarify commit message
> ---
>  Documentation/virtual/kvm/api.txt|  9 +
>  Documentation/virtual/kvm/cpuid.txt  |  6 ++
>  arch/x86/include/uapi/asm/kvm_para.h |  1 +
>  arch/x86/kvm/cpuid.c |  3 +++
>  arch/x86/kvm/svm.c   |  7 +--
>  arch/x86/kvm/vmx.c   |  6 --
>  arch/x86/kvm/x86.c   |  3 +++
>  arch/x86/kvm/x86.h   | 36 
> 
>  include/uapi/linux/kvm.h |  1 +
>  9 files changed, 68 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt 
> b/Documentation/virtual/kvm/api.txt
> index 1a18484..dacc3d7 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -4094,3 +4094,12 @@ reserved.
>   2: MIPS64 or microMIPS64 with access to all address segments.
>  Both registers and addresses are 64-bits wide.
>  It will be possible to run 64-bit or 32-bit guest code.
> +
> +8.8 KVM_CAP_X86_GUEST_MWAIT
> +
> +Architectures: x86
> +
> +This capability indicates that guest using memory monotoring instructions
> +(MWAIT/MWAITX) to stop the virtual CPU will not cause a VM exit.  As such 
> time
> +spent while virtual CPU is halted in this way will then be accounted for as
> +guest running time on the host (as opposed to e.g. HLT).
> diff --git a/Documentation/virtual/kvm/cpuid.txt 
> b/Documentation/virtual/kvm/cpuid.txt
> index 3c65feb..04c201c 100644
> --- a/Documentation/virtual/kvm/cpuid.txt
> +++ b/Documentation/virtual/kvm/cpuid.txt
> @@ -54,6 +54,12 @@ KVM_FEATURE_PV_UNHALT  || 7 || guest 
> checks this feature bit
> ||   || before enabling 
> paravirtualized
> ||   || spinlock support.
>  
> --
> +KVM_FEATURE_MWAIT  || 8 || guest can use monitor/mwait
> +   ||   || to halt the VCPU without 
> exits,
> +   ||   || time spent while halted in 
> this
> +   ||   || way is accounted for on host 
> as
> +   ||   || VCPU run time.
> +--
>  KVM_FEATURE_CLOCKSOURCE_STABLE_BIT ||24 || host will warn if no 
> guest-side
> ||   || per-cpu warps are expected in
> ||   || kvmclock.
> diff --git a/arch/x86/include/uapi/asm/kvm_para.h 
> b/arch/x86/include/uapi/asm/kvm_para.h
> index cff0bb6..9cc77a7 100644
> --- a/arch/x86/include/uapi/asm/kvm_para.h
> +++ b/arch/x86/include/

Re: [Qemu-devel] [PATCH v2 0/3] Update AppleSMC for OS X Sierra 10.12.4 guests

2017-04-04 Thread Gabriel L. Somlo
On Tue, Apr 04, 2017 at 09:35:00PM +0200, Alexander Graf wrote:
> On 04/04/2017 07:01 PM, Gabriel L. Somlo wrote:
> > As of 10.12.4 (currently the latest Sierra update), OS X refuses to boot
> > unless the AppleSMC supports a third I/O port, which provides the current
> > error status when read.
> 
> Looks much nicer after this series :). Thanks a lot!
> 
> Reviewed-by: Alexander Graf <ag...@suse.de>

Thanks! Thinking about it, we should probably drop the last (3/3)
patch, once again to minimize useless churn -- Doing that part (or
not, as the case may turn out to be) should be part of a future
series implementing more accurate emulation, including key write
support...

Thanks,
--Gabriel



[Qemu-devel] [PATCH v2 2/3] applesmc: implement error status port

2017-04-04 Thread Gabriel L. Somlo
As of release 10.12.4, OS X (Sierra) refuses to boot unless the
AppleSMC supports an additional I/O port, expected to provide an
error status code.

Update the [cmd|data]_write() and data_read() methods to implement
the required state machine, and add I/O region & methods to handle
access to the error port.

Originally proposed by Eric Shelton 

Signed-off-by: Gabriel Somlo 
---
 hw/misc/applesmc.c | 141 +++--
 1 file changed, 115 insertions(+), 26 deletions(-)

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 6381197..0d882e8 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -43,6 +43,7 @@
 enum {
 APPLESMC_DATA_PORT   = 0x00,
 APPLESMC_CMD_PORT= 0x04,
+APPLESMC_ERR_PORT= 0x1e,
 APPLESMC_NUM_PORTS   = 0x20,
 };
 
@@ -53,6 +54,24 @@ enum {
 APPLESMC_GET_KEY_TYPE_CMD= 0x13,
 };
 
+enum {
+APPLESMC_ST_CMD_DONE = 0x00,
+APPLESMC_ST_DATA_READY   = 0x01,
+APPLESMC_ST_BUSY = 0x02,
+APPLESMC_ST_ACK  = 0x04,
+APPLESMC_ST_NEW_CMD  = 0x08,
+};
+
+enum {
+APPLESMC_ST_1E_CMD_INTRUPTED = 0x80,
+APPLESMC_ST_1E_STILL_BAD_CMD = 0x81,
+APPLESMC_ST_1E_BAD_CMD   = 0x82,
+APPLESMC_ST_1E_NOEXIST   = 0x84,
+APPLESMC_ST_1E_WRITEONLY = 0x85,
+APPLESMC_ST_1E_READONLY  = 0x86,
+APPLESMC_ST_1E_BAD_INDEX = 0xb8,
+};
+
 #ifdef DEBUG_SMC
 #define smc_debug(...) fprintf(stderr, "AppleSMC: " __VA_ARGS__)
 #else
@@ -77,9 +96,12 @@ struct AppleSMCState {
 
 MemoryRegion io_data;
 MemoryRegion io_cmd;
+MemoryRegion io_err;
 uint32_t iobase;
 uint8_t cmd;
 uint8_t status;
+uint8_t status_1e;
+uint8_t last_ret;
 char key[4];
 uint8_t read_pos;
 uint8_t data_len;
@@ -93,89 +115,138 @@ static void applesmc_io_cmd_write(void *opaque, hwaddr 
addr, uint64_t val,
   unsigned size)
 {
 AppleSMCState *s = opaque;
+uint8_t status = s->status & 0x0f;
 
-smc_debug("CMD Write B: %#x = %#x\n", addr, val);
+smc_debug("CMD received: 0x%02x\n", (uint8_t)val);
 switch (val) {
 case APPLESMC_READ_CMD:
-s->status = 0x0c;
+/* did last command run through OK? */
+if (status == APPLESMC_ST_CMD_DONE || status == APPLESMC_ST_NEW_CMD) {
+s->cmd = val;
+s->status = APPLESMC_ST_NEW_CMD | APPLESMC_ST_ACK;
+} else {
+smc_debug("ERROR: previous command interrupted!\n");
+s->status = APPLESMC_ST_NEW_CMD;
+s->status_1e = APPLESMC_ST_1E_CMD_INTRUPTED;
+}
 break;
+default:
+smc_debug("UNEXPECTED CMD 0x%02x\n", (uint8_t)val);
+s->status = APPLESMC_ST_NEW_CMD;
+s->status_1e = APPLESMC_ST_1E_BAD_CMD;
 }
-s->cmd = val;
 s->read_pos = 0;
 s->data_pos = 0;
 }
 
-static void applesmc_fill_data(AppleSMCState *s)
+static struct AppleSMCData *applesmc_find_key(AppleSMCState *s)
 {
 struct AppleSMCData *d;
 
 QLIST_FOREACH(d, >data_def, node) {
 if (!memcmp(d->key, s->key, 4)) {
-smc_debug("Key matched (%s Len=%d Data=%s)\n", d->key,
-  d->len, d->data);
-memcpy(s->data, d->data, d->len);
-return;
+return d;
 }
 }
+return NULL;
 }
 
 static void applesmc_io_data_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
 {
 AppleSMCState *s = opaque;
+struct AppleSMCData *d;
 
-smc_debug("DATA Write B: %#x = %#x\n", addr, val);
+smc_debug("DATA received: 0x%02x\n", (uint8_t)val);
 switch (s->cmd) {
 case APPLESMC_READ_CMD:
+if ((s->status & 0x0f) == APPLESMC_ST_CMD_DONE) {
+break;
+}
 if (s->read_pos < 4) {
 s->key[s->read_pos] = val;
-s->status = 0x04;
+s->status = APPLESMC_ST_ACK;
 } else if (s->read_pos == 4) {
-s->data_len = val;
-s->status = 0x05;
-s->data_pos = 0;
-smc_debug("Key = %c%c%c%c Len = %d\n", s->key[0],
-  s->key[1], s->key[2], s->key[3], val);
-applesmc_fill_data(s);
+d = applesmc_find_key(s);
+if (d != NULL) {
+memcpy(s->data, d->data, d->len);
+s->data_len = d->len;
+s->data_pos = 0;
+s->status = APPLESMC_ST_ACK | APPLESMC_ST_DATA_READY;
+s->status_1e = APPLESMC_ST_CMD_DONE;  /* clear on valid key */
+} else {
+smc_debug("READ_CMD: key '%c%c%c%c' not found!\n",
+  s->key[0], s->key[1], s->key[2], s->key[3]);
+s->status = APPLESMC_ST_CMD_DONE;
+s->status_1e = 

[Qemu-devel] [PATCH v2 1/3] applesmc: cosmetic whitespace and indentation cleanup

2017-04-04 Thread Gabriel L. Somlo
Signed-off-by: Gabriel Somlo 
Reviewed-by: Alexander Graf 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/misc/applesmc.c | 98 --
 1 file changed, 50 insertions(+), 48 deletions(-)

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 77fab5b..6381197 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -39,21 +39,24 @@
 /* #define DEBUG_SMC */
 
 #define APPLESMC_DEFAULT_IOBASE0x300
-/* data port used by Apple SMC */
-#define APPLESMC_DATA_PORT 0x0
-/* command/status port used by Apple SMC */
-#define APPLESMC_CMD_PORT  0x4
-#define APPLESMC_NR_PORTS  32
 
-#define APPLESMC_READ_CMD  0x10
-#define APPLESMC_WRITE_CMD 0x11
-#define APPLESMC_GET_KEY_BY_INDEX_CMD  0x12
-#define APPLESMC_GET_KEY_TYPE_CMD  0x13
+enum {
+APPLESMC_DATA_PORT   = 0x00,
+APPLESMC_CMD_PORT= 0x04,
+APPLESMC_NUM_PORTS   = 0x20,
+};
+
+enum {
+APPLESMC_READ_CMD= 0x10,
+APPLESMC_WRITE_CMD   = 0x11,
+APPLESMC_GET_KEY_BY_INDEX_CMD= 0x12,
+APPLESMC_GET_KEY_TYPE_CMD= 0x13,
+};
 
 #ifdef DEBUG_SMC
 #define smc_debug(...) fprintf(stderr, "AppleSMC: " __VA_ARGS__)
 #else
-#define smc_debug(...) do { } while(0)
+#define smc_debug(...) do { } while (0)
 #endif
 
 static char default_osk[64] = "This is a dummy key. Enter the real key "
@@ -77,12 +80,11 @@ struct AppleSMCState {
 uint32_t iobase;
 uint8_t cmd;
 uint8_t status;
-uint8_t key[4];
+char key[4];
 uint8_t read_pos;
 uint8_t data_len;
 uint8_t data_pos;
 uint8_t data[255];
-uint8_t charactic[4];
 char *osk;
 QLIST_HEAD(, AppleSMCData) data_def;
 };
@@ -93,10 +95,10 @@ static void applesmc_io_cmd_write(void *opaque, hwaddr 
addr, uint64_t val,
 AppleSMCState *s = opaque;
 
 smc_debug("CMD Write B: %#x = %#x\n", addr, val);
-switch(val) {
-case APPLESMC_READ_CMD:
-s->status = 0x0c;
-break;
+switch (val) {
+case APPLESMC_READ_CMD:
+s->status = 0x0c;
+break;
 }
 s->cmd = val;
 s->read_pos = 0;
@@ -123,54 +125,54 @@ static void applesmc_io_data_write(void *opaque, hwaddr 
addr, uint64_t val,
 AppleSMCState *s = opaque;
 
 smc_debug("DATA Write B: %#x = %#x\n", addr, val);
-switch(s->cmd) {
-case APPLESMC_READ_CMD:
-if(s->read_pos < 4) {
-s->key[s->read_pos] = val;
-s->status = 0x04;
-} else if(s->read_pos == 4) {
-s->data_len = val;
-s->status = 0x05;
-s->data_pos = 0;
-smc_debug("Key = %c%c%c%c Len = %d\n", s->key[0],
-  s->key[1], s->key[2], s->key[3], val);
-applesmc_fill_data(s);
-}
-s->read_pos++;
-break;
+switch (s->cmd) {
+case APPLESMC_READ_CMD:
+if (s->read_pos < 4) {
+s->key[s->read_pos] = val;
+s->status = 0x04;
+} else if (s->read_pos == 4) {
+s->data_len = val;
+s->status = 0x05;
+s->data_pos = 0;
+smc_debug("Key = %c%c%c%c Len = %d\n", s->key[0],
+  s->key[1], s->key[2], s->key[3], val);
+applesmc_fill_data(s);
+}
+s->read_pos++;
+break;
 }
 }
 
-static uint64_t applesmc_io_data_read(void *opaque, hwaddr addr1,
-  unsigned size)
+static uint64_t applesmc_io_data_read(void *opaque, hwaddr addr, unsigned size)
 {
 AppleSMCState *s = opaque;
 uint8_t retval = 0;
 
-switch(s->cmd) {
-case APPLESMC_READ_CMD:
-if(s->data_pos < s->data_len) {
-retval = s->data[s->data_pos];
-smc_debug("READ_DATA[%d] = %#hhx\n", s->data_pos,
-  retval);
-s->data_pos++;
-if(s->data_pos == s->data_len) {
-s->status = 0x00;
-smc_debug("EOF\n");
-} else
-s->status = 0x05;
+switch (s->cmd) {
+case APPLESMC_READ_CMD:
+if (s->data_pos < s->data_len) {
+retval = s->data[s->data_pos];
+smc_debug("READ_DATA[%d] = %#hhx\n", s->data_pos,
+  retval);
+s->data_pos++;
+if (s->data_pos == s->data_len) {
+s->status = 0x00;
+smc_debug("EOF\n");
+} else {
+s->status = 0x05;
 }
+}
 }
-smc_debug("DATA Read b: %#x = %#x\n", addr1, retval);
+smc_debug("DATA Read b: %#x = %#x\n", addr, retval);
 
 return retval;
 }
 
-static uint64_t applesmc_io_cmd_read(void *opaque, hwaddr addr1, unsigned size)
+static uint64_t applesmc_io_cmd_read(void 

[Qemu-devel] [PATCH v2 0/3] Update AppleSMC for OS X Sierra 10.12.4 guests

2017-04-04 Thread Gabriel L. Somlo
As of 10.12.4 (currently the latest Sierra update), OS X refuses to boot
unless the AppleSMC supports a third I/O port, which provides the current
error status when read.

New since v1:

- 1/3: don't touch the default OSK string, as it's unnecessary
at this time

- 2/3: don't consolidate I/O regions, leave as-is for data
and cmd; This patch now implements the error-code state
machine, AND adds an i/o region dedicaded to the error
status port, complete with read/write access methods.

- 3/3: optional patch setting access width to 1-byte on data and
cmd i/o regions. Tested on OS X versions 10.[6..12].

> This series consists of three patches:
>
>   - 1/3: indentation/whitespace cleanup for applesmc.c to the point
>   where it now passes scripts/checkpatc.pl, and allows
>   subsequent changes to look nice in diff-patch format :)
>
>   - 2/3: consolidate Port I/O into a single region, and invoke
>   appropriate read/write methods based on the offset being
>   accessed
>
>   - 3/3: implement read-only error/status port, and update
>   data and command read/write methods to correctly
>   maintain the state machine for keeping the status_1e
>       value up to date.

Gabriel L. Somlo (3):
  applesmc: cosmetic whitespace and indentation cleanup
  applesmc: implement error status port
  applesmc: fix port i/o access width

 hw/misc/applesmc.c | 219 +
 1 file changed, 155 insertions(+), 64 deletions(-)

-- 
2.7.4




[Qemu-devel] [PATCH v2 3/3] applesmc: fix port i/o access width

2017-04-04 Thread Gabriel L. Somlo
Set width of the two i/o regions dedicated to the AppleSMC's 8-bit
data and command ports to 1 byte.

Signed-off-by: Gabriel Somlo 
---

Setting these to 1-byte width works fine on any OS X version I could find
to test on: 10.(6-12), inclusive.

On linux, the applesmc kernel module tries *hard* to avoid loading on
anything that's not a Mac, by checking DMI board vendor and product
strings. If I force it using:

   -smbios type=1,manufacturer='Apple Inc.',product='iMac2',family='iMac' \
   -smbios type=2,manufacturer='Apple Inc.',version='iMac' \
   -device isa-applesmc

the module fails both before and after this whole series, suggesting it's
not (just) the access width but rather the overall incomplete emulation
that's the issue.

If we decide to go for implementing a more complete emulation, beyond
simply the minimum necessary to satisfy OS X, we should definitely ensure
that Linux is also happily able to initialize its applesmc driver...

 hw/misc/applesmc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 0d882e8..7896812 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -316,12 +316,12 @@ static void applesmc_isa_realize(DeviceState *dev, Error 
**errp)
 AppleSMCState *s = APPLE_SMC(dev);
 
 memory_region_init_io(>io_data, OBJECT(s), _data_io_ops, s,
-  "applesmc-data", 4);
+  "applesmc-data", 1);
 isa_register_ioport(>parent_obj, >io_data,
 s->iobase + APPLESMC_DATA_PORT);
 
 memory_region_init_io(>io_cmd, OBJECT(s), _cmd_io_ops, s,
-  "applesmc-cmd", 4);
+  "applesmc-cmd", 1);
 isa_register_ioport(>parent_obj, >io_cmd,
 s->iobase + APPLESMC_CMD_PORT);
 
-- 
2.7.4




Re: [Qemu-devel] [PATCH v1 2/3] applesmc: consolidate port i/o into single contiguous region

2017-04-04 Thread Gabriel L. Somlo
On Tue, Apr 04, 2017 at 11:44:29AM +0200, Alexander Graf wrote:
> On 04/04/2017 02:04 AM, Gabriel L. Somlo wrote:
> > On Mon, Apr 03, 2017 at 12:27:15PM +0200, Paolo Bonzini wrote:
> > > 
> > > On 03/04/2017 11:32, Alexander Graf wrote:
> > > > > Newer AppleSMC revisions support an error status (read) port
> > > > > in addition to the data and command ports currently supported.
> > > > > 
> > > > > Register the full 32-bit region at once, and handle individual
> > > > > ports at various offsets within the region from the top-level
> > > > > applesmc_io_[write|read]() methods (ctual support for reading
> > > > > the error status port to be added by a subsequent patch).
> > > > > 
> > > > > Originally proposed by Eric Shelton <eshel...@pobox.com>
> > > > > 
> > > > > Signed-off-by: Gabriel Somlo <gso...@gmail.com>
> > > > I would prefer if we could leave the multiplexing to the layer that
> > > > knows how to do that the best: Memory Regions.
> > > > 
> > > > Why don't you just define a big region that ecompasses all of the IO
> > > > space (with fallback I/O handlers for warnings) and then just sprinkle
> > > > the ones we handle on top with higher prio?
> > > You don't need priority at all, "contained" regions always win over the
> > > container (docs/memory.txt just before "Region names").
> > > 
> > > Both what you propose and what Gabriel did makes sense.  In general QEMU
> > > does things more like in this patch, but there are exceptions (e.g. ACPI).
> > So, option 1 would be:
> > 
> > Leave the region covering the entire AppleSMC port range 
> > (APPLESMC_NUM_PORTS)
> > as-is:
> > 
> > static const MemoryRegionOps applesmc_io_ops = {
> >  .write = applesmc_io_write,
> >  .read = applesmc_io_read,
> >  .endianness = DEVICE_NATIVE_ENDIAN,
> >  .impl = {
> >  .min_access_size = 1,
> >  .max_access_size = 1,
> >  },
> > };
> > 
> > but modify applesmc_io_write() and applesmc_io_read() to do nothing or
> > return 0xff, respectively. Then, add three separate regions covering 1
> > byte, for each of the three ports, with their own methods pointing at
> > the existing port-specific read/write methods.
> 
> Basically, yes. I think it would reduce the code churn quite a bit, as 99%
> of it stays the same. You only add the fall-through layer.
> 
> > Option 2 would be to leave everything as-is, per Paolo's suggestion
> > that it's the more common way of doing things. I personally find this
> > one easier to follow, but really don't mind doing either.
> > 
> > 
> > If I end up going with #1, I'd probably be bringing back
> > applesmc_data_io_ops and applesmc_cmd_io_ops, in which case I'd like
> > to know why the access size was set to 4 bytes to begin with:
> > 
> > -memory_region_init_io(>io_data, OBJECT(s), _data_io_ops, s,
> > -  "applesmc-data", 4);
> > -isa_register_ioport(>parent_obj, >io_data,
> > -s->iobase + APPLESMC_DATA_PORT);
> > -
> > -memory_region_init_io(>io_cmd, OBJECT(s), _cmd_io_ops, s,
> > -  "applesmc-cmd", 4);
> > -isa_register_ioport(>parent_obj, >io_cmd,
> > -s->iobase + APPLESMC_CMD_PORT);
> > 
> > Each port is 8-bits wide only, so why 4 and not 1, above ?
> 
> I don't fully remember, but I suppose Mac OS X or Linux were accessing it
> using 32bit read/write operations, so we had to encompass the full size. I
> don't think you need to do that if you have the fall-through.
> 
> > I guess that doesn't matter if we stick with option #2... :)
> > 
> > Any further advice on which way to go much appreciated!
> 
> I was mostly curious on why you would change so much code without any
> obvious gain. I'm perfectly fine with moving to a switch based approach for
> the memory region, but I didn't really understand *why* it was done in the
> first place :). It just felt like a lot of patch for no reason.

At first glance, I found the idea of having a single pair of
read/write access methods for the whole 32-byte region, with
supported/unsupported ports handled internally to be aesthetically
appealing. Now I'm not so sure anymore... :)

What about if I leave everything alone, and just add a third region to
represent the error port only, with no fallback?

Also, I'll probably be able to reverse engineer this by staring at the
code long enough, but if something doesn't support e.g. a write method,
is it better to not provide a .write method to the respective region at
all, or to provide one that does nothing and returns immediately ?
(same question for the fallback/container region, if it turns out to
be reauired: provide empty read/write methods, or don't set .read and
.write at all ?)

Thanks,
--Gabriel



Re: [Qemu-devel] [PATCH v1 2/3] applesmc: consolidate port i/o into single contiguous region

2017-04-03 Thread Gabriel L. Somlo
On Mon, Apr 03, 2017 at 12:27:15PM +0200, Paolo Bonzini wrote:
> 
> 
> On 03/04/2017 11:32, Alexander Graf wrote:
> > 
> >> Newer AppleSMC revisions support an error status (read) port
> >> in addition to the data and command ports currently supported.
> >>
> >> Register the full 32-bit region at once, and handle individual
> >> ports at various offsets within the region from the top-level
> >> applesmc_io_[write|read]() methods (ctual support for reading
> >> the error status port to be added by a subsequent patch).
> >>
> >> Originally proposed by Eric Shelton 
> >>
> >> Signed-off-by: Gabriel Somlo 
> > 
> > I would prefer if we could leave the multiplexing to the layer that
> > knows how to do that the best: Memory Regions.
> > 
> > Why don't you just define a big region that ecompasses all of the IO
> > space (with fallback I/O handlers for warnings) and then just sprinkle
> > the ones we handle on top with higher prio?
> 
> You don't need priority at all, "contained" regions always win over the
> container (docs/memory.txt just before "Region names").
> 
> Both what you propose and what Gabriel did makes sense.  In general QEMU
> does things more like in this patch, but there are exceptions (e.g. ACPI).

So, option 1 would be:

Leave the region covering the entire AppleSMC port range (APPLESMC_NUM_PORTS)
as-is:

static const MemoryRegionOps applesmc_io_ops = {
.write = applesmc_io_write,
.read = applesmc_io_read,
.endianness = DEVICE_NATIVE_ENDIAN,
.impl = {
.min_access_size = 1,
.max_access_size = 1,
},
};

but modify applesmc_io_write() and applesmc_io_read() to do nothing or
return 0xff, respectively. Then, add three separate regions covering 1
byte, for each of the three ports, with their own methods pointing at
the existing port-specific read/write methods.


Option 2 would be to leave everything as-is, per Paolo's suggestion
that it's the more common way of doing things. I personally find this
one easier to follow, but really don't mind doing either.


If I end up going with #1, I'd probably be bringing back
applesmc_data_io_ops and applesmc_cmd_io_ops, in which case I'd like
to know why the access size was set to 4 bytes to begin with:

-memory_region_init_io(>io_data, OBJECT(s), _data_io_ops, s,
-  "applesmc-data", 4);
-isa_register_ioport(>parent_obj, >io_data,
-s->iobase + APPLESMC_DATA_PORT);
-
-memory_region_init_io(>io_cmd, OBJECT(s), _cmd_io_ops, s,
-  "applesmc-cmd", 4);
-isa_register_ioport(>parent_obj, >io_cmd,
-s->iobase + APPLESMC_CMD_PORT);

Each port is 8-bits wide only, so why 4 and not 1, above ?

I guess that doesn't matter if we stick with option #2... :)

Any further advice on which way to go much appreciated!

Thanks,
--Gabriel



Re: [Qemu-devel] [PATCH v1 1/3] applesmc: cosmetic whitespace and indentation cleanup

2017-04-03 Thread Gabriel L. Somlo
On Mon, Apr 03, 2017 at 10:34:09AM -0300, Philippe Mathieu-Daudé wrote:
> Hi Gabriel,
> 
> On 03/31/2017 01:48 PM, Gabriel L. Somlo wrote:
> > Signed-off-by: Gabriel Somlo <gso...@gmail.com>
> > ---
> >  hw/misc/applesmc.c | 100 
> > +++--
> >  1 file changed, 51 insertions(+), 49 deletions(-)
> > 
> > diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
> > index 77fab5b..986f2ac 100644
> > --- a/hw/misc/applesmc.c
> > +++ b/hw/misc/applesmc.c
> > @@ -39,24 +39,27 @@
> >  /* #define DEBUG_SMC */
> > 
> >  #define APPLESMC_DEFAULT_IOBASE0x300
> > -/* data port used by Apple SMC */
> > -#define APPLESMC_DATA_PORT 0x0
> > -/* command/status port used by Apple SMC */
> > -#define APPLESMC_CMD_PORT  0x4
> > -#define APPLESMC_NR_PORTS  32
> > 
> > -#define APPLESMC_READ_CMD  0x10
> > -#define APPLESMC_WRITE_CMD 0x11
> > -#define APPLESMC_GET_KEY_BY_INDEX_CMD  0x12
> > -#define APPLESMC_GET_KEY_TYPE_CMD  0x13
> > +enum {
> > +APPLESMC_DATA_PORT   = 0x00,
> > +APPLESMC_CMD_PORT= 0x04,
> > +APPLESMC_NUM_PORTS   = 0x20,
> > +};
> > +
> > +enum {
> > +APPLESMC_READ_CMD= 0x10,
> > +APPLESMC_WRITE_CMD   = 0x11,
> > +APPLESMC_GET_KEY_BY_INDEX_CMD= 0x12,
> > +APPLESMC_GET_KEY_TYPE_CMD= 0x13,
> > +};
> > 
> >  #ifdef DEBUG_SMC
> >  #define smc_debug(...) fprintf(stderr, "AppleSMC: " __VA_ARGS__)
> >  #else
> > -#define smc_debug(...) do { } while(0)
> > +#define smc_debug(...) do { } while (0)
> >  #endif
> > 
> > -static char default_osk[64] = "This is a dummy key. Enter the real key "
> > +static char default_osk[65] = "This is a dummy key. Enter the real key "
> 
> Here is more than a cosmetic change.

You're right, that was my mistake (should have left it 64.
> 
> Since this array is initialized you can declare it without specify the size:
> static char default_osk[] = ...

It's initialized to something that's not necessarily 64 characters, so
(I assume) the size specification is there to reserve the appropriate
amount of space, which is precisely 64 bytes.

> OSK0 + OSK1 is 64, why need an extra byte?

Right, I undid that part of the patch, will resubmit everything minus
that hunk as part of v2.

> Can yoy add some self-explanatory #define and use them later in this file:
> 
> applesmc_add_key(s, "OSK0", 32, s->osk);
> applesmc_add_key(s, "OSK1", 32, s->osk + 32);
> 
> and
> 
> if (!s->osk || (strlen(s->osk) != 64)) {
> fprintf(stderr, "WARNING: Using AppleSMC with invalid key\n");

Do I have to, now that I'm staying away from touching that bit in the
first place ? :)

The original patch Eric Shelton proposed (inspired by FakeSMC)
completely reworks how keys are initialized, adds write support (and
access permissions) for select keys, and generally implements a much
more complete emulation of the AppleSMC. Since this is just about
getting OS X to keep working, I figured I'd keep changes to a minimum.

Reworking key initialization, adding write support, etc. could
(should?) be part of a separate series, if we decide we want a more
realistically emulated AppleSMC. In that case, minimizing churn and
leaving things as-is in this particular case would be preferable.

Let me know what you think.

Thanks,
--Gabriel
 
> 
> >"using the -osk parameter";
> > 
> >  struct AppleSMCData {
> > @@ -77,12 +80,11 @@ struct AppleSMCState {
> >  uint32_t iobase;
> >  uint8_t cmd;
> >  uint8_t status;
> > -uint8_t key[4];
> > +char key[4];
> >  uint8_t read_pos;
> >  uint8_t data_len;
> >  uint8_t data_pos;
> >  uint8_t data[255];
> > -uint8_t charactic[4];
> >  char *osk;
> >  QLIST_HEAD(, AppleSMCData) data_def;
> >  };
> > @@ -93,10 +95,10 @@ static void applesmc_io_cmd_write(void *opaque, hwaddr 
> > addr, uint64_t val,
> >  AppleSMCState *s = opaque;
> > 
> >  smc_debug("CMD Write B: %#x = %#x\n", addr, val);
> > -switch(val) {
> > -case APPLESMC_READ_CMD:
> > -s->status = 0x0c;
> > -break;
> > +switch (val) {
> > +case APPLESMC_READ_CMD:
> > +s->status = 0x0c;
> > +break;
> >  }
> >  s->cmd = val;
> >  s

[Qemu-devel] [PATCH v1 1/3] applesmc: cosmetic whitespace and indentation cleanup

2017-03-31 Thread Gabriel L. Somlo
Signed-off-by: Gabriel Somlo 
---
 hw/misc/applesmc.c | 100 +++--
 1 file changed, 51 insertions(+), 49 deletions(-)

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 77fab5b..986f2ac 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -39,24 +39,27 @@
 /* #define DEBUG_SMC */
 
 #define APPLESMC_DEFAULT_IOBASE0x300
-/* data port used by Apple SMC */
-#define APPLESMC_DATA_PORT 0x0
-/* command/status port used by Apple SMC */
-#define APPLESMC_CMD_PORT  0x4
-#define APPLESMC_NR_PORTS  32
 
-#define APPLESMC_READ_CMD  0x10
-#define APPLESMC_WRITE_CMD 0x11
-#define APPLESMC_GET_KEY_BY_INDEX_CMD  0x12
-#define APPLESMC_GET_KEY_TYPE_CMD  0x13
+enum {
+APPLESMC_DATA_PORT   = 0x00,
+APPLESMC_CMD_PORT= 0x04,
+APPLESMC_NUM_PORTS   = 0x20,
+};
+
+enum {
+APPLESMC_READ_CMD= 0x10,
+APPLESMC_WRITE_CMD   = 0x11,
+APPLESMC_GET_KEY_BY_INDEX_CMD= 0x12,
+APPLESMC_GET_KEY_TYPE_CMD= 0x13,
+};
 
 #ifdef DEBUG_SMC
 #define smc_debug(...) fprintf(stderr, "AppleSMC: " __VA_ARGS__)
 #else
-#define smc_debug(...) do { } while(0)
+#define smc_debug(...) do { } while (0)
 #endif
 
-static char default_osk[64] = "This is a dummy key. Enter the real key "
+static char default_osk[65] = "This is a dummy key. Enter the real key "
   "using the -osk parameter";
 
 struct AppleSMCData {
@@ -77,12 +80,11 @@ struct AppleSMCState {
 uint32_t iobase;
 uint8_t cmd;
 uint8_t status;
-uint8_t key[4];
+char key[4];
 uint8_t read_pos;
 uint8_t data_len;
 uint8_t data_pos;
 uint8_t data[255];
-uint8_t charactic[4];
 char *osk;
 QLIST_HEAD(, AppleSMCData) data_def;
 };
@@ -93,10 +95,10 @@ static void applesmc_io_cmd_write(void *opaque, hwaddr 
addr, uint64_t val,
 AppleSMCState *s = opaque;
 
 smc_debug("CMD Write B: %#x = %#x\n", addr, val);
-switch(val) {
-case APPLESMC_READ_CMD:
-s->status = 0x0c;
-break;
+switch (val) {
+case APPLESMC_READ_CMD:
+s->status = 0x0c;
+break;
 }
 s->cmd = val;
 s->read_pos = 0;
@@ -123,54 +125,54 @@ static void applesmc_io_data_write(void *opaque, hwaddr 
addr, uint64_t val,
 AppleSMCState *s = opaque;
 
 smc_debug("DATA Write B: %#x = %#x\n", addr, val);
-switch(s->cmd) {
-case APPLESMC_READ_CMD:
-if(s->read_pos < 4) {
-s->key[s->read_pos] = val;
-s->status = 0x04;
-} else if(s->read_pos == 4) {
-s->data_len = val;
-s->status = 0x05;
-s->data_pos = 0;
-smc_debug("Key = %c%c%c%c Len = %d\n", s->key[0],
-  s->key[1], s->key[2], s->key[3], val);
-applesmc_fill_data(s);
-}
-s->read_pos++;
-break;
+switch (s->cmd) {
+case APPLESMC_READ_CMD:
+if (s->read_pos < 4) {
+s->key[s->read_pos] = val;
+s->status = 0x04;
+} else if (s->read_pos == 4) {
+s->data_len = val;
+s->status = 0x05;
+s->data_pos = 0;
+smc_debug("Key = %c%c%c%c Len = %d\n", s->key[0],
+  s->key[1], s->key[2], s->key[3], val);
+applesmc_fill_data(s);
+}
+s->read_pos++;
+break;
 }
 }
 
-static uint64_t applesmc_io_data_read(void *opaque, hwaddr addr1,
-  unsigned size)
+static uint64_t applesmc_io_data_read(void *opaque, hwaddr addr, unsigned size)
 {
 AppleSMCState *s = opaque;
 uint8_t retval = 0;
 
-switch(s->cmd) {
-case APPLESMC_READ_CMD:
-if(s->data_pos < s->data_len) {
-retval = s->data[s->data_pos];
-smc_debug("READ_DATA[%d] = %#hhx\n", s->data_pos,
-  retval);
-s->data_pos++;
-if(s->data_pos == s->data_len) {
-s->status = 0x00;
-smc_debug("EOF\n");
-} else
-s->status = 0x05;
+switch (s->cmd) {
+case APPLESMC_READ_CMD:
+if (s->data_pos < s->data_len) {
+retval = s->data[s->data_pos];
+smc_debug("READ_DATA[%d] = %#hhx\n", s->data_pos,
+  retval);
+s->data_pos++;
+if (s->data_pos == s->data_len) {
+s->status = 0x00;
+smc_debug("EOF\n");
+} else {
+s->status = 0x05;
 }
+}
 }
-smc_debug("DATA Read b: %#x = %#x\n", addr1, retval);
+smc_debug("DATA Read b: %#x = %#x\n", addr, retval);
 
 return retval;
 }
 
-static uint64_t applesmc_io_cmd_read(void *opaque, hwaddr addr1, 

[Qemu-devel] [PATCH v1 2/3] applesmc: consolidate port i/o into single contiguous region

2017-03-31 Thread Gabriel L. Somlo
Newer AppleSMC revisions support an error status (read) port
in addition to the data and command ports currently supported.

Register the full 32-bit region at once, and handle individual
ports at various offsets within the region from the top-level
applesmc_io_[write|read]() methods (ctual support for reading
the error status port to be added by a subsequent patch).

Originally proposed by Eric Shelton 

Signed-off-by: Gabriel Somlo 
---
 hw/misc/applesmc.c | 56 --
 1 file changed, 33 insertions(+), 23 deletions(-)

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index 986f2ac..e581e02 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -75,8 +75,7 @@ typedef struct AppleSMCState AppleSMCState;
 struct AppleSMCState {
 ISADevice parent_obj;
 
-MemoryRegion io_data;
-MemoryRegion io_cmd;
+MemoryRegion io_reg;
 uint32_t iobase;
 uint8_t cmd;
 uint8_t status;
@@ -207,19 +206,36 @@ static void qdev_applesmc_isa_reset(DeviceState *dev)
 applesmc_add_key(s, "MSSD", 1, "\0x3");
 }
 
-static const MemoryRegionOps applesmc_data_io_ops = {
-.write = applesmc_io_data_write,
-.read = applesmc_io_data_read,
-.endianness = DEVICE_NATIVE_ENDIAN,
-.impl = {
-.min_access_size = 1,
-.max_access_size = 1,
-},
-};
+static void applesmc_io_write(void *opaque, hwaddr addr, uint64_t val,
+  unsigned size)
+{
+switch (addr) {
+case APPLESMC_DATA_PORT:
+applesmc_io_data_write(opaque, addr, val, size);
+break;
+case APPLESMC_CMD_PORT:
+applesmc_io_cmd_write(opaque, addr, val, size);
+break;
+default:
+break;
+}
+}
 
-static const MemoryRegionOps applesmc_cmd_io_ops = {
-.write = applesmc_io_cmd_write,
-.read = applesmc_io_cmd_read,
+static uint64_t applesmc_io_read(void *opaque, hwaddr addr, unsigned size)
+{
+switch (addr) {
+case APPLESMC_DATA_PORT:
+return applesmc_io_data_read(opaque, addr, size);
+case APPLESMC_CMD_PORT:
+return applesmc_io_cmd_read(opaque, addr, size);
+default:
+return 0xff;
+}
+}
+
+static const MemoryRegionOps applesmc_io_ops = {
+.write = applesmc_io_write,
+.read = applesmc_io_read,
 .endianness = DEVICE_NATIVE_ENDIAN,
 .impl = {
 .min_access_size = 1,
@@ -231,15 +247,9 @@ static void applesmc_isa_realize(DeviceState *dev, Error 
**errp)
 {
 AppleSMCState *s = APPLE_SMC(dev);
 
-memory_region_init_io(>io_data, OBJECT(s), _data_io_ops, s,
-  "applesmc-data", 4);
-isa_register_ioport(>parent_obj, >io_data,
-s->iobase + APPLESMC_DATA_PORT);
-
-memory_region_init_io(>io_cmd, OBJECT(s), _cmd_io_ops, s,
-  "applesmc-cmd", 4);
-isa_register_ioport(>parent_obj, >io_cmd,
-s->iobase + APPLESMC_CMD_PORT);
+memory_region_init_io(>io_reg, OBJECT(s), _io_ops, s,
+  "applesmc", APPLESMC_NUM_PORTS);
+isa_register_ioport(>parent_obj, >io_reg, s->iobase);
 
 if (!s->osk || (strlen(s->osk) != 64)) {
 fprintf(stderr, "WARNING: Using AppleSMC with invalid key\n");
-- 
2.7.4




[Qemu-devel] [PATCH v1 0/3] Update AppleSMC for OS X Sierra 10.12.4 guests

2017-03-31 Thread Gabriel L. Somlo
As of 10.12.4 (currently the latest Sierra update), OS X refuses to boot
unless the AppleSMC supports a third I/O port, which provides the current
error status when read.

This series consists of three patches:

- 1/3: indentation/whitespace cleanup for applesmc.c to the point
where it now passes scripts/checkpatc.pl, and allows
subsequent changes to look nice in diff-patch format :)

- 2/3: consolidate Port I/O into a single region, and invoke
appropriate read/write methods based on the offset being
accessed

- 3/3: implement read-only error/status port, and update
data and command read/write methods to correctly
maintain the state machine for keeping the status_1e
value up to date.

Thanks,
  --Gabriel

Gabriel L. Somlo (3):
  applesmc: cosmetic whitespace and indentation cleanup
  applesmc: consolidate port i/o into single contiguous region
  applesmc: implement error status port

 hw/misc/applesmc.c | 254 +++--
 1 file changed, 167 insertions(+), 87 deletions(-)

-- 
2.7.4




[Qemu-devel] [PATCH v1 3/3] applesmc: implement error status port

2017-03-31 Thread Gabriel L. Somlo
As of release 10.12.4, OS X (Sierra) refuses to boot unless the
AppleSMC supports an additional I/O port, expected to provide an
error status code.

Update the [cmd|data]_write() and data_read() methods to implement
the required state machine, and add an err_read() method to provide
the error status code to the guest.

Originally proposed by Eric Shelton 

Signed-off-by: Gabriel Somlo 
---
 hw/misc/applesmc.c | 120 +
 1 file changed, 94 insertions(+), 26 deletions(-)

diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c
index e581e02..eac0659 100644
--- a/hw/misc/applesmc.c
+++ b/hw/misc/applesmc.c
@@ -43,6 +43,7 @@
 enum {
 APPLESMC_DATA_PORT   = 0x00,
 APPLESMC_CMD_PORT= 0x04,
+APPLESMC_ERR_PORT= 0x1e,
 APPLESMC_NUM_PORTS   = 0x20,
 };
 
@@ -53,6 +54,24 @@ enum {
 APPLESMC_GET_KEY_TYPE_CMD= 0x13,
 };
 
+enum {
+APPLESMC_ST_CMD_DONE = 0x00,
+APPLESMC_ST_DATA_READY   = 0x01,
+APPLESMC_ST_BUSY = 0x02,
+APPLESMC_ST_ACK  = 0x04,
+APPLESMC_ST_NEW_CMD  = 0x08,
+};
+
+enum {
+APPLESMC_ST_1E_CMD_INTRUPTED = 0x80,
+APPLESMC_ST_1E_STILL_BAD_CMD = 0x81,
+APPLESMC_ST_1E_BAD_CMD   = 0x82,
+APPLESMC_ST_1E_NOEXIST   = 0x84,
+APPLESMC_ST_1E_WRITEONLY = 0x85,
+APPLESMC_ST_1E_READONLY  = 0x86,
+APPLESMC_ST_1E_BAD_INDEX = 0xb8,
+};
+
 #ifdef DEBUG_SMC
 #define smc_debug(...) fprintf(stderr, "AppleSMC: " __VA_ARGS__)
 #else
@@ -79,6 +98,8 @@ struct AppleSMCState {
 uint32_t iobase;
 uint8_t cmd;
 uint8_t status;
+uint8_t status_1e;
+uint8_t last_ret;
 char key[4];
 uint8_t read_pos;
 uint8_t data_len;
@@ -92,79 +113,112 @@ static void applesmc_io_cmd_write(void *opaque, hwaddr 
addr, uint64_t val,
   unsigned size)
 {
 AppleSMCState *s = opaque;
+uint8_t status = s->status & 0x0f;
 
-smc_debug("CMD Write B: %#x = %#x\n", addr, val);
+smc_debug("CMD received: 0x%02x\n", (uint8_t)val);
 switch (val) {
 case APPLESMC_READ_CMD:
-s->status = 0x0c;
+/* did last command run through OK? */
+if (status == APPLESMC_ST_CMD_DONE || status == APPLESMC_ST_NEW_CMD) {
+s->cmd = val;
+s->status = APPLESMC_ST_NEW_CMD | APPLESMC_ST_ACK;
+} else {
+smc_debug("ERROR: previous command interrupted!\n");
+s->status = APPLESMC_ST_NEW_CMD;
+s->status_1e = APPLESMC_ST_1E_CMD_INTRUPTED;
+}
 break;
+default:
+smc_debug("UNEXPECTED CMD 0x%02x\n", (uint8_t)val);
+s->status = APPLESMC_ST_NEW_CMD;
+s->status_1e = APPLESMC_ST_1E_BAD_CMD;
 }
-s->cmd = val;
 s->read_pos = 0;
 s->data_pos = 0;
 }
 
-static void applesmc_fill_data(AppleSMCState *s)
+static struct AppleSMCData *applesmc_find_key(AppleSMCState *s, const char 
*key)
 {
 struct AppleSMCData *d;
 
 QLIST_FOREACH(d, >data_def, node) {
-if (!memcmp(d->key, s->key, 4)) {
-smc_debug("Key matched (%s Len=%d Data=%s)\n", d->key,
-  d->len, d->data);
-memcpy(s->data, d->data, d->len);
-return;
+if (!memcmp(d->key, key, 4)) {
+return d;
 }
 }
+return NULL;
 }
 
 static void applesmc_io_data_write(void *opaque, hwaddr addr, uint64_t val,
unsigned size)
 {
 AppleSMCState *s = opaque;
+struct AppleSMCData *d;
 
-smc_debug("DATA Write B: %#x = %#x\n", addr, val);
+smc_debug("DATA received: 0x%02x\n", (uint8_t)val);
 switch (s->cmd) {
 case APPLESMC_READ_CMD:
+if ((s->status & 0x0f) == APPLESMC_ST_CMD_DONE) {
+break;
+}
 if (s->read_pos < 4) {
 s->key[s->read_pos] = val;
-s->status = 0x04;
+s->status = APPLESMC_ST_ACK;
 } else if (s->read_pos == 4) {
-s->data_len = val;
-s->status = 0x05;
-s->data_pos = 0;
-smc_debug("Key = %c%c%c%c Len = %d\n", s->key[0],
-  s->key[1], s->key[2], s->key[3], val);
-applesmc_fill_data(s);
+d = applesmc_find_key(s, s->key);
+if (d != NULL) {
+memcpy(s->data, d->data, d->len);
+s->data_len = d->len;
+s->data_pos = 0;
+s->status = APPLESMC_ST_ACK | APPLESMC_ST_DATA_READY;
+s->status_1e = APPLESMC_ST_CMD_DONE;  /* clear on valid key */
+} else {
+smc_debug("READ_CMD: key '%c%c%c%c' not found!\n",
+  s->key[0], s->key[1], s->key[2], s->key[3]);
+s->status = APPLESMC_ST_CMD_DONE;
+s->status_1e = 

Re: [Qemu-devel] [PATCH v2 0/2] hw/usb/dev-hid: Make usb-tablet work with OS X/macOS guests

2017-01-20 Thread Gabriel L. Somlo
On Fri, Jan 20, 2017 at 13:30:15 +0100, p...@philjordan.eu wrote:
> This series makes the Qemu usb-tablet work correctly with OS X/macOS guests 
> without the need for a special guest driver.
> 
>  * The usb-tablet should not have a boot protocol of 2. Other OSes seem to 
> ignore this, but the IOHIDFamily driver stack chokes on it for anything but 
> conventional (relative motion) mice.
>  * A "mac_compat" boolean option is added to the usb-tablet, which changes 
> its report descriptor to specify a usage of 0x02 (mouse) instead of 0x01 
> (pointer). This is required for correct operation in the Mac HID driver stack.

works like a charm on Sierra (10.12.1). Also tried it with
Fedora-Workstation-Live-x86_64-25-1.3.iso, where it behaves
identically with or without the mac_compat option. All tests
used qemu in SDL/X11-client mode.

Tested-by: Gabriel Somlo 

Thanks,
--Gabriel

> 
> Changelog
> =
> 
> v1 -> v2:
>  * v1 Thread was "[PATCH] hw/usb/dev-hid: add a Mac guest compatibility 
> option to usb-tablet"
>  * Always apply the boot protocol (bInterfaceProtocol) change to usb-tablet, 
> not just when the Mac compatibility option is active. The original value of 
> 0x02 was determined to be incorrect according to the spec anyway.
>  * As the boot protocol change is permanent, separate interface and device 
> descriptor constants for the Mac/non-Mac variants of the tablet are no longer 
> required, and have been removed.
> 
> Phil Dennis-Jordan (2):
>   hw/usb/dev-hid: set bInterfaceProtocol to 0x00 for usb-tablet
>   hw/usb/dev-hid: add a usb-tablet Mac guest compatibility option
> 
>  hw/usb/dev-hid.c | 9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)



Re: [Qemu-devel] [PATCH v5 wave 1 0/4] fw-cfg: support writeable blobs and more files

2017-01-11 Thread Gabriel L. Somlo
On Wed, Jan 11, 2017 at 06:34:53PM +0100, Laszlo Ersek wrote:
> This is the first (fw_cfg) half of the v5 iteration of the series posted
> here:
> <http://lists.nongnu.org/archive/html/qemu-devel/2016-12/msg00129.html>.
> 
> In this version, the fw_cfg patches have been separated into a
> standalone "wave", for helping review / maintenance, and also for
> enabling independent features on top of writeable blobs. More
> importantly, I've addressed Igor's v4 feedback. See the individual
> patches for the details.
> 
> Patch #3 is included verbatim from Eduardo's pending series (see the
> patch notes for the archive URL), as a dependency for patch #4. If
> Eduardo's series is merged first, patch #3 can be dropped (in fact
> git-rebase should do it automatically).
> 
> Please excuse the surprisingly long list of CC's, it's due to the fact
> that fw_cfg is quite widely used (see patch #4).
> 
> Cc: "Gabriel L. Somlo" <so...@cmu.edu>

Whole series:

Acked-by: Gabriel Somlo <so...@cmu.edu>

Data passed in via the "-fw_cfg" qemu command still shows up fine in
/sys/firmware/qemu-fw-cfg on the guest, so also:

Tested-by: Gabriel Somlo <so...@cmu.edu>

Thanks,
--Gabriel

> Cc: "Michael S. Tsirkin" <m...@redhat.com>
> Cc: Alexander Graf <ag...@suse.de>
> Cc: Anthony Perard <anthony.per...@citrix.com>
> Cc: Artyom Tarasenko <atar4q...@gmail.com>
> Cc: David Gibson <da...@gibson.dropbear.id.au>
> Cc: Eduardo Habkost <ehabk...@redhat.com>
> Cc: Gerd Hoffmann <kra...@redhat.com>
> Cc: Igor Mammedov <imamm...@redhat.com>
> Cc: Laszlo Ersek <ler...@redhat.com>
> Cc: Mark Cave-Ayland <mark.cave-ayl...@ilande.co.uk>
> Cc: Michael Walle <mich...@walle.cc>
> Cc: Paolo Bonzini <pbonz...@redhat.com>
> Cc: Peter Maydell <peter.mayd...@linaro.org>
> Cc: Shannon Zhao <zhaoshengl...@huawei.com>
> Cc: Stefano Stabellini <sstabell...@kernel.org>
> Cc: qemu-...@nongnu.org
> 
> Thanks
> Laszlo
> 
> 
> Eduardo Habkost (1):
>   pc: Add 2.9 machine-types
> 
> Laszlo Ersek (2):
>   fw-cfg: turn FW_CFG_FILE_SLOTS into a device property
>   fw-cfg: bump "file_slots" to 0x20 for 2.9+ machine types
> 
> Michael S. Tsirkin (1):
>   fw-cfg: support writeable blobs
> 
>  docs/specs/fw_cfg.txt  |  36 ++
>  hw/lm32/lm32_hwsetup.h |   2 +-
>  include/hw/compat.h|  10 +++-
>  include/hw/i386/pc.h   |   2 +
>  include/hw/loader.h|   7 +--
>  include/hw/nvram/fw_cfg.h  |   3 +-
>  include/hw/nvram/fw_cfg_keys.h |   3 +-
>  hw/arm/virt-acpi-build.c   |   2 +-
>  hw/core/loader.c   |  18 ---
>  hw/i386/acpi-build.c   |   4 +-
>  hw/i386/pc_piix.c  |  15 --
>  hw/i386/pc_q35.c   |  13 -
>  hw/nvram/fw_cfg.c  | 110 
> +++--
>  13 files changed, 177 insertions(+), 48 deletions(-)
> 
> -- 
> 2.9.3
> 



Re: [Qemu-devel] [PATCH 0/6] firmware-qemu_fw_cfg: Fine-tuning for four function implementations

2016-09-20 Thread Gabriel L. Somlo
On Sun, Sep 18, 2016 at 02:48:30PM +0200, SF Markus Elfring wrote:
> From: Markus Elfring 
> Date: Sun, 18 Sep 2016 14:43:21 +0200
> 
> Some update suggestions were taken into account
> from static source code analysis.
> 
> Markus Elfring (6):
>   Use kmalloc_array() in fw_cfg_register_dir_entries()
>   Improve a size determination in fw_cfg_register_file()
>   Rename jump labels in fw_cfg_register_file()
>   Improve a size determination in fw_cfg_build_symlink()
>   Rename jump labels in fw_cfg_sysfs_probe()
>   Move a variable assignment in fw_cfg_sysfs_probe()

Acked-by: Gabriel Somlo 

>  drivers/firmware/qemu_fw_cfg.c | 53 
> +-
>  1 file changed, 27 insertions(+), 26 deletions(-)
> 
> -- 
> 2.10.0
> 



Re: [Qemu-devel] [PATCH for-2.6] fw_cfg: Adopt /opt/RFQDN convention

2016-04-19 Thread Gabriel L. Somlo
On Tue, Apr 19, 2016 at 09:48:40AM +0200, Markus Armbruster wrote:
> "Michael S. Tsirkin" <m...@redhat.com> writes:
> 
> > On Mon, Apr 18, 2016 at 06:42:09PM +0200, Markus Armbruster wrote:
> >> FW CFG's primary user is QEMU, which uses it to expose configuration
> >> information (in the widest sense) to Firmware.  Thus the name FW CFG.
> >> 
> >> FW CFG can also be used by others for their own purposes.  QEMU is
> >> merely acting as transport then.  Names starting with opt/ are reseved
> >> for such uses.  There is no provision, however, to guide safe sharing
> >> among different such users.
> >> 
> >> Fix that, losely following QMP precedence: names should start with
> >> opt/RFQDN/, where RFQDN is a reverse fully qualified domain name you
> >> control.
> >> 
> >> Based on a more ambitious patch from Michael Tsirkin.
> >> 
> >> Cc: Gerd Hoffmann <kra...@redhat.com>
> >> Cc: Gabriel L. Somlo <so...@cmu.edu>
> >> Cc: Laszlo Ersek <ler...@redhat.com>
> >> Cc: Michael S. Tsirkin <m...@redhat.com>
> >> Signed-off-by: Markus Armbruster <arm...@redhat.com>
> >
> > Reviewed-by: Michael S. Tsirkin <m...@redhat.com>
> > Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
> >
> > I don't think there's any rush to get this into 2.6, though.
> > If no one beats me to it, I'll apply this after 2.6 is out.
> 
> The patch touches only documentation and help text, i.e. it's as safe as
> it gets.  I'd like to have it in 2.6.
> 
> Since both of the two patched files have no maintainer, I intend to post
> a pull request myself, assuming nobody objects.

Acked-by: Gabriel Somlo <so...@cmu.edu>

Thanks much!
--Gabriel



Re: [Qemu-devel] [patch] firmware: qemu_fw_cfg.c: potential unintialized variable

2016-04-14 Thread Gabriel L. Somlo
On Thu, Apr 14, 2016 at 12:33:37PM +0300, Dan Carpenter wrote:
> It acpi_acquire_global_lock() return AE_NOT_CONFIGURED then "glk" isn't
> initialized, which, if you got very unlucky, could cause a bug.
> 
> Signed-off-by: Dan Carpenter 
> 
> diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> index d999fe3..0e20116 100644
> --- a/drivers/firmware/qemu_fw_cfg.c
> +++ b/drivers/firmware/qemu_fw_cfg.c
> @@ -77,7 +77,7 @@ static inline u16 fw_cfg_sel_endianness(u16 key)
>  static inline void fw_cfg_read_blob(u16 key,
>   void *buf, loff_t pos, size_t count)
>  {
> - u32 glk;
> + u32 glk = -1U;

After digging through the acpi_[acquire|release]_global_lock() code in
drivers/acpi/acpica/evxface.c, the -1 value actually makes sense, as
glk is set to the value of acpi_gbl_global_lock_handle, which
internally is a 16-bit value which can wrap around, but will never be
equal to 32-bit "-1". As such, the unlock function would fail with
AE_NOT_ACQUIRED if its "for-real" version ever ended up being called.

So, with the typos in the commit blurb fixed (s/It/If/ and
s/return/returns/), and on general "belt-and-suspenders" principle,

Reviewed-by: Gabriel Somlo 

I just wanted to make sure my understanding of "this can't happen with
the way the ACPI macros are currently defined" is still correct :)

Thanks,
--Gabe

>   acpi_status status;
>  
>   /* If we have ACPI, ensure mutual exclusion against any potential



Re: [Qemu-devel] [patch] firmware: qemu_fw_cfg.c: potential unintialized variable

2016-04-14 Thread Gabriel L. Somlo
On Thu, Apr 14, 2016 at 10:12:53PM +0300, Dan Carpenter wrote:
> On Thu, Apr 14, 2016 at 02:40:06PM -0400, Gabriel L. Somlo wrote:
> > On Thu, Apr 14, 2016 at 12:33:37PM +0300, Dan Carpenter wrote:
> > > It acpi_acquire_global_lock() return AE_NOT_CONFIGURED then "glk" isn't
> >   ^   ^
> >   Ifreturns
> > 
> > > initialized, which, if you got very unlucky, could cause a bug.
> > 
> > 
> > In principle I'm OK with being cautious and initializing local
> > variables just in case, but I'm curious:
> > 
> > acpi_acquire_global_lock() (and its friend, acpi_release_global_lock())
> > are both wrapped inside the same macro -- ACPI_HW_DEPENDENT_RETURN_STATUS
> > -- which either makes them both do something useful, or makes them both
> > no-ops returning a hardcoded AE_NOT_CONFIGURED.
> > 
> > So what else do you think could be a way to get very unlucky ?
> 
> If "glk" happened to to equal acpi_gbl_global_lock_handle by chance
> then we would release it without acquiring it first.  Actually I could
> initialize it to zero and that would be better, no?

No, because acpi_release_global_lock() would also be a hard-coded
"return AE_NOT_CONFIGURED" by the same macro which also hard-coded
acpi_acquire_global_lock() to be "return AE_NOT_CONFIGURED" in the
first place. See include/acpi/acpixf.h, search for the two occurrences
of

"#define ACPI_HW_DEPENDENT_RETURN_STATUS"

and then for:

"global_lock"

further down in the file.

Whether both (or neither) of lock/unlock are for real or just
hardcoded to return AE_NOT_CONFIGURED depends on ACPI_REDUCED_HARDWARE,
which I assume is also set when there's *no* ACPI hardware at all.

But I don't believe it's possible for "unlock" to do anything at all
if "lock" was hardcoded to simply return AE_NOT_CONFIGURED.

Then again, it's possible I'm still missing something :)

Thanks,
--Gabe



Re: [Qemu-devel] [patch] firmware: qemu_fw_cfg.c: potential unintialized variable

2016-04-14 Thread Gabriel L. Somlo
On Thu, Apr 14, 2016 at 12:33:37PM +0300, Dan Carpenter wrote:
> It acpi_acquire_global_lock() return AE_NOT_CONFIGURED then "glk" isn't
  ^   ^
  Ifreturns

> initialized, which, if you got very unlucky, could cause a bug.


In principle I'm OK with being cautious and initializing local
variables just in case, but I'm curious:

acpi_acquire_global_lock() (and its friend, acpi_release_global_lock())
are both wrapped inside the same macro -- ACPI_HW_DEPENDENT_RETURN_STATUS
-- which either makes them both do something useful, or makes them both
no-ops returning a hardcoded AE_NOT_CONFIGURED.

So what else do you think could be a way to get very unlucky ?

Otherwise, sure: Just 'cause we're paranoid doesn't mean someone's not
out to get us! :)

Thanks,
--Gabriel

> Signed-off-by: Dan Carpenter 
> 
> diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> index d999fe3..0e20116 100644
> --- a/drivers/firmware/qemu_fw_cfg.c
> +++ b/drivers/firmware/qemu_fw_cfg.c
> @@ -77,7 +77,7 @@ static inline u16 fw_cfg_sel_endianness(u16 key)
>  static inline void fw_cfg_read_blob(u16 key,
>   void *buf, loff_t pos, size_t count)
>  {
> - u32 glk;
> + u32 glk = -1U;
>   acpi_status status;
>  
>   /* If we have ACPI, ensure mutual exclusion against any potential



Re: [Qemu-devel] [PATCH v2] firmware: qemu_fw_cfg.c: hold ACPI global lock during device access

2016-04-11 Thread Gabriel L. Somlo
On Tue, Apr 05, 2016 at 11:54:19AM +0300, Michael S. Tsirkin wrote:
> On Thu, Mar 17, 2016 at 09:33:40AM -0400, Gabriel L. Somlo wrote:
> > On Wed, Mar 16, 2016 at 06:57:01PM +0200, Michael S. Tsirkin wrote:
> > > On Tue, Mar 08, 2016 at 01:30:50PM -0500, Gabriel Somlo wrote:
> > > > Allowing for the future possibility of implementing AML-based
> > > > (i.e., firmware-triggered) access to the QEMU fw_cfg device,
> > > > acquire the global ACPI lock when accessing the device on behalf
> > > > of the guest-side sysfs driver, to prevent any potential race
> > > > conditions.
> > > > 
> > > > Suggested-by: Michael S. Tsirkin <m...@redhat.com>
> > > > Signed-off-by: Gabriel Somlo <so...@cmu.edu>
> > > 
> > > So this patch makes sense of course.
> > > 
> > > 
> > > Given the recent discussion on QEMU mailing list,
> > > I think there is an additional patch that we need:
> > > filter the files exposed to userspace by "opt/" prefix.
> > > 
> > > This will ensure that we can change all other fw cfg files
> > > at will without breaking guest scripts.
> > > 
> > > Gabriel, could you code this up? Or do you see a
> > > pressing need to expose internal QEMU registers to
> > > userspace?
> > 
> > I'd be happy to update the docs to (better) emphasisze that:
> 
> Well my experience shows people do not read the docs.
> And really, good interfaces should be self-documenting.
> 
> > 1 the only way to guarantee any particular item shows up in
> >   guest-side fw_cfg sysfs is manually putting it there via the
> >   host-side command line
> > 
> > - and BTW, unless you prefixed it with "opt/..." you
> >   are off the reservation, and it might collide with
> >   qemu->firmware communications.
> > 
> > 2 anything one didn't place there themselves via the qemu
> >   command line is informational only, might change or go away
> >   at any time, and developing expectations about it based on
> >   past observation is done at the observer's own risk.
> > 
> > While I don't *personally* care about items outside of "opt/", I'm a bit
> > uncomfortable actively *hiding* them from userspace -- I could easily
> > imagine the ability to see (read-only) fw_cfg content from userspace
> > being a handy debugging/troubleshooting tool. It's back to separating
> > between mechanism and policy: hiding things from userspace would IMHO
> > fall into the policy enforcement side of things, and I'm still unclear
> > about the failure scenario we'd be trying to prevent, and its likelihood.
> > 
> > Thanks,
> > --Gabriel
> 
> Mostly, we can change internal qemu/firmware interfaces
> as long as we verify that firmware that ships with QEMU
> does not rely on them.
> 
> I'm fine with exposing stuff for debugging purposes
> but I would like a cleaner separation between the two,
> and self-documenting interfaces.
> How about:
>   - place everything that is under "opt/" in e.g. "supported"
> directory, or at root
>   - place everything that is not under "opt/" in e.g. "unsupported"
> directory
> 
> Abstracting hardware is what OS is all about, this is not policy.

I'm not sure I agree with this last point:

Arguably, fw_cfg could be viewed as a glorified out-of-band USB stick
with special files prepared by QEMU for the guest VM.

The sysfs driver is a mechanism to list/access these files, and is
IMHO the only thing one can reasonably construe as "kernel interface".

What you're suggesting boils down to adding a translation layer between
what QEMU names the files when preparing this magic USB stick, and what
we tell users the names are (by adding additional folders named e.g.
"supported" and "unsupported").

That to me looks like injecting policy ("look *here*, NOT there!") by
doing this, instead of sticking with mechanism only ("here's what qemu
wrote to fw_cfg, look at it if you want, or don't...").

While I understand your concerns, I'm not sure we should have to go
through this level of convolution to protect people from their own
mistakes (such as assuming certain content on the magic USB stick will
always be there, and writing some sort of script which would break if
said content mysteriously disappears, then reasonably complain about
either the sysfs kernel driver or qemu itself). Presence or absence of
some file on a magic USB stick does NOT (again, IM

Re: [Qemu-devel] [PATCH v2] fw_cfg: RFQDN rules, documentation

2016-04-07 Thread Gabriel L. Somlo
On Thu, Apr 07, 2016 at 07:40:12PM +0300, Michael S. Tsirkin wrote:
> On Thu, Apr 07, 2016 at 06:23:24PM +0200, Laszlo Ersek wrote:
> > On 04/07/16 17:38, Michael S. Tsirkin wrote:
> > > This requires that all -fw_cfg command line users use names of the form
> > > opt/RFQDN/: such names are compatible with QEMU 2.4 and 2.5 as well as
> > > future QEMU versions.
> > > 
> > > As ability to insert fw_cfg entries in QEMU root is useful for
> > > firmware development, add a special prefix: unsupported/root/ that
> > > allows that, while making sure users are aware it's unsupported.
> > > 
> > > Cc: Gerd Hoffmann <kra...@redhat.com>
> > > Cc: Gabriel L. Somlo <so...@cmu.edu>
> > > Cc: Laszlo Ersek <ler...@redhat.com>
> > > Cc: Markus Armbruster <arm...@redhat.com>
> > > Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
> > > ---
> > > 
> > > changes from v1:
> > > address comments by Laszlo Ersek.
> > > 
> > > There are still things worrying me
> > > 
> > > 1. there is apparently no way to tell linux guests whether it should 
> > > expose
> > >a specific file to userspace.
> > >
> > > 2. Should we have opt/fw/ or opt/hidden/ for firmware use?
> > >Alternatively, agree to hide files and/or directories
> > >starting with e.g. "."?
> > 
> > Hm, is #2 an idea for addressing #1?
> > 
> > For interpreting #2, I again have to reach back to the three groups of
> > people you identified -- QEMU developers, QEMU firmware developers, and
> > users.
> > 
> > Since you say "for firmware use", I guess the point would be to enable
> > QEMU firmware developers to create such settings, either for
> > (a) population by QEMU, or for
> > (b) population by firmware end-users,
> > that the guest kernel would be prevented from seeing.
> > 
> > Furthermore, since your examples both start with opt/, *and* we have
> > language saying
> > 
> >   QEMU developers MUST NOT use item names prefixed with "opt/" when
> >   inserting items programmatically
> > 
> > I determine that option (a) must not be your intent. Therefore, the
> > question is, I think:
> > 
> >   Should we allow QEMU firmware developers to create special settings,
> >   to be populated manually by their end-users, that the guest kernel
> >   would be prevented from seeing?
> 
> Exactly.
> 
> > I don't think so. Namely, in practice, new firmware settings (that are
> > to be populated manually by users) will go under "opt/org.seabios/" and
> > "opt/org.tianocore.edk2.ovmf/". I couldn't care less if a guest kernel
> > user looks at such files. After all, the names *explicitly carry* the
> > RFQDN of the intended consumer. If a user violates it, that's his
> > problem. (It may become the problem of his downstream users too, but
> > that's the same thing.)
> > 
> > So, as long as I understood your question right, I don't think it's
> > necessary.
> 
> It's not a question we need to ask ourselves as hardware/qemu designers.
> It's a question for the guest kernel - once that exposes
> interfaces to applications, it has to maintain them forever.

And that's why IMHO it's cleaner for that interface to be:

/sys/firmware/qemu-fw-cfg/by-name//[key|name|raw|size]

I really don't think any particular instance of  could
reasonably be called an "interface" (and therefore create expectations
of its continued presence forever), or can it ?

Thanks,
--Gabriel

> This is unlike firmware interfaces - if these are updated
> together with firmware, you do not need to maintain
> old ones.
> 
> > I have one other comment below:
> > 
> > >  vl.c  | 44 
> > >  docs/specs/fw_cfg.txt | 34 +-
> > >  qemu-options.hx   | 38 +-
> > >  3 files changed, 90 insertions(+), 26 deletions(-)
> > > 
> > > diff --git a/vl.c b/vl.c
> > > index 2200e62..aec8a94 100644
> > > --- a/vl.c
> > > +++ b/vl.c
> > > @@ -2296,8 +2296,11 @@ static int parse_fw_cfg(void *opaque, QemuOpts 
> > > *opts, Error **errp)
> > >  {
> > >  gchar *buf;
> > >  size_t size;
> > > -const char *name, *file, *str;
> > > +const char *name, *file, *str, *slash, *dot;
> > >  FWCfgState *fw_cfg = (FWCfgState *) opaque;
> >

[Qemu-devel] commit 084a85e breaks build

2016-03-19 Thread Gabriel L. Somlo
Hi Daniel,

I get the error below when I try to build QEMU, and bisect claims it
started with commit 084a85e (crypto: add support for the cast5-128
cipher algorithm).

Sorry if this is already a known issue. Let me know if there's
anything you'd like me to test.

My command line is:
~/KVM-OSX/SCRATCH/qemu/configure --prefix=/home/somlo/KVM-OSX/SCRATCH 
--audio-drv-list=pa 
--target-list=x86_64-softmmu,i386-softmmu,aarch64-softmmu,arm-softmmu; make 
install

Thanks,
--Gabriel

...
  CCcrypto/cipher.o
In file included from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher.c:153:0:
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c: In function
‘qcrypto_cipher_new’:
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c:229:13: error:
implicit declaration of function ‘cast5_set_key’
[-Werror=implicit-function-declaration]
 cast5_set_key(ctx->ctx, nkey, key);
 ^
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c:229:13: error:
nested extern declaration of ‘cast5_set_key’ [-Werror=nested-externs]
In file included from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher.c:153:0:
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c: In function
‘qcrypto_cipher_encrypt’:
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c:344:21: error:
passing argument 3 of ‘xts_encrypt’ from incompatible pointer type
[-Werror=incompatible-pointer-types]
 ctx->alg_encrypt, ctx->alg_encrypt,
 ^
In file included from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c:22:0,
 from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher.c:153:
/home/somlo/KVM-OSX/SCRATCH/qemu/include/crypto/xts.h:76:6: note:
expected ‘void (*)(const void *, size_t,  uint8_t *, const uint8_t *)
{aka void (*)(const void *, long unsigned int,  unsigned char *, const
unsigned char *)}’ but argument is of type ‘void (*)(void *, unsigned
int,  uint8_t *, const uint8_t *) {aka void (*)(void *, unsigned int,
unsigned char *, const unsigned char *)}’
 void xts_encrypt(const void *datactx,
  ^
In file included from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher.c:153:0:
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c:344:39: error:
passing argument 4 of ‘xts_encrypt’ from incompatible pointer type
[-Werror=incompatible-pointer-types]
 ctx->alg_encrypt, ctx->alg_encrypt,
   ^
In file included from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c:22:0,
 from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher.c:153:
/home/somlo/KVM-OSX/SCRATCH/qemu/include/crypto/xts.h:76:6: note:
expected ‘void (*)(const void *, size_t,  uint8_t *, const uint8_t *)
{aka void (*)(const void *, long unsigned int,  unsigned char *, const
unsigned char *)}’ but argument is of type ‘void (*)(void *, unsigned
int,  uint8_t *, const uint8_t *) {aka void (*)(void *, unsigned int,
unsigned char *, const unsigned char *)}’
 void xts_encrypt(const void *datactx,
  ^
In file included from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher.c:153:0:
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c: In function
‘qcrypto_cipher_decrypt’:
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c:389:21: error:
passing argument 3 of ‘xts_decrypt’ from incompatible pointer type
[-Werror=incompatible-pointer-types]
 ctx->alg_encrypt, ctx->alg_decrypt,
 ^
In file included from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c:22:0,
 from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher.c:153:
/home/somlo/KVM-OSX/SCRATCH/qemu/include/crypto/xts.h:54:6: note:
expected ‘void (*)(const void *, size_t,  uint8_t *, const uint8_t *)
{aka void (*)(const void *, long unsigned int,  unsigned char *, const
unsigned char *)}’ but argument is of type ‘void (*)(void *, unsigned
int,  uint8_t *, const uint8_t *) {aka void (*)(void *, unsigned int,
unsigned char *, const unsigned char *)}’
 void xts_decrypt(const void *datactx,
  ^
In file included from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher.c:153:0:
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c:389:39: error:
passing argument 4 of ‘xts_decrypt’ from incompatible pointer type
[-Werror=incompatible-pointer-types]
 ctx->alg_encrypt, ctx->alg_decrypt,
   ^
In file included from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher-nettle.c:22:0,
 from
/home/somlo/KVM-OSX/SCRATCH/qemu/crypto/cipher.c:153:
/home/somlo/KVM-OSX/SCRATCH/qemu/include/crypto/xts.h:54:6: note:
expected ‘void (*)(const void *, size_t,  uint8_t *, const uint8_t *)
{aka void (*)(const void *, long unsigned int,  unsigned char *, const
unsigned char *)}’ but argument is of type ‘void (*)(void *, unsigned
int,  uint8_t *, const uint8_t *) {aka void (*)(void *, unsigned int,
unsigned char *, const unsigned char *)}’
 void xts_decrypt(const void *datactx,
  ^
cc1: all 

Re: [Qemu-devel] [PATCH v1 0/2] Fix build problems with nettle < 3.0.0

2016-03-19 Thread Gabriel L. Somlo
On Fri, Mar 18, 2016 at 01:21:54PM +, Daniel P. Berrange wrote:
> This series fixes two build problems identified by people using
> 2.x series of nettle
> 
>   https://lists.gnu.org/archive/html/qemu-devel/2016-03/msg04420.html

Builds and works fine now on F22 with nettle 2.7.1. Thanks again for
the quick response!

Tested-by: Gabriel Somlo 

> 
> 
> Daniel P. Berrange (2):
>   crypto: add compat cast5_set_key with  nettle < 3.0.0
>   crypto: fix cipher function signature mismatch with nettle & xts
> 
>  crypto/cipher-nettle.c | 143 
> +
>  1 file changed, 109 insertions(+), 34 deletions(-)
> 
> -- 
> 2.5.0
> 



Re: [Qemu-devel] [PATCH v2] vl.c: disallow command line fw cfg without opt/

2016-03-19 Thread Gabriel L. Somlo
On Wed, 16 Mar 2016 at 18:50:57 +0200, Michael S. Tsirkin wrote:
> On Wed, Mar 16, 2016 at 05:29:45PM +0100, Markus Armbruster wrote:
> > "Michael S. Tsirkin"  writes:
> > 
> > > Allowing arbitary file names on command line is setting us up for
> > > failure: future guests will look for a specific QEMU-specified name and
> > > will get confused finding a user file there.
> > >
> > > We do warn but people are conditioned to ignore warnings by now,
> > > so at best that will help users debug problem, not avoid it.
> > >
> > > Disable this by default, so distros don't get to deal with it,
> > > but leave an option for developers to configure this in,
> > > with scary warnings so people only do it if they know
> > > what they are doing.
> > >
> > > Signed-off-by: Michael S. Tsirkin 
> > 
> > I'm having a hard time to see the point.
> 
> Frankly, I am having a hard time to see the point of exposing fw cfg to
> users at all.  It was designed as an internal interface between QEMU PC
> hardware and firmware.  As a PC maintainer, I do not like it that users
> get to poke at PC internals.
> 
> So it is yet another way to pass binaries to Linux guests.  Don't we
> have enough of these?  But Gerd likes it for some reason, and merged it.
> OK.

As the author of the feature, I feel I should jump back in and clarify:

It's a way to pass arbitrary blobs to any type of guest, with two
important properties: 1. asynchronous, and 2. out-of-band. When I
started looking, all existing methods involved either having the host
start polling for the guest to bring up qga and be ready to accept an
out-of-band connection (i.e., *not* asynchronous), or have the guest
mount some special cdrom or floppy image prepared by the host (i.e.,
*not* out of band).

fw_cfg is both asynchronous and out-of-band, so it appeared to be the
perfect choice.

> But please find a way to make sure it does not conflict with its current
> usage in PC.  Asking that all files have an "opt/" prefix is one way
> but only if it is enforced.

Enforcing the "opt/" prefix was clearly on the table when I submitted
the feature (and totally acceptable for my own needs). At the time, however,
most of the advice I received on the list was to leave it as a warning
only (i.e., "mechanism, not policy"), especially since other respondents
expressed interest in passing in non-"/opt" blobs for easier development
and debugging of alternative firmware (such as OVMF, iirc).

Having a mis-use of this feature become "institutionalized" over time was
seen as a low/negligible risk at the time. Do we have any new reasons
to worry about it ?

Thanks much,
--Gabriel



Re: [Qemu-devel] [PATCH v2] firmware: qemu_fw_cfg.c: hold ACPI global lock during device access

2016-03-18 Thread Gabriel L. Somlo
On Wed, Mar 16, 2016 at 06:57:01PM +0200, Michael S. Tsirkin wrote:
> On Tue, Mar 08, 2016 at 01:30:50PM -0500, Gabriel Somlo wrote:
> > Allowing for the future possibility of implementing AML-based
> > (i.e., firmware-triggered) access to the QEMU fw_cfg device,
> > acquire the global ACPI lock when accessing the device on behalf
> > of the guest-side sysfs driver, to prevent any potential race
> > conditions.
> > 
> > Suggested-by: Michael S. Tsirkin 
> > Signed-off-by: Gabriel Somlo 
> 
> So this patch makes sense of course.
> 
> 
> Given the recent discussion on QEMU mailing list,
> I think there is an additional patch that we need:
> filter the files exposed to userspace by "opt/" prefix.
> 
> This will ensure that we can change all other fw cfg files
> at will without breaking guest scripts.
> 
> Gabriel, could you code this up? Or do you see a
> pressing need to expose internal QEMU registers to
> userspace?

I'd be happy to update the docs to (better) emphasisze that:

1 the only way to guarantee any particular item shows up in
  guest-side fw_cfg sysfs is manually putting it there via the
  host-side command line

- and BTW, unless you prefixed it with "opt/..." you
  are off the reservation, and it might collide with
  qemu->firmware communications.

2 anything one didn't place there themselves via the qemu
  command line is informational only, might change or go away
  at any time, and developing expectations about it based on
  past observation is done at the observer's own risk.

While I don't *personally* care about items outside of "opt/", I'm a bit
uncomfortable actively *hiding* them from userspace -- I could easily
imagine the ability to see (read-only) fw_cfg content from userspace
being a handy debugging/troubleshooting tool. It's back to separating
between mechanism and policy: hiding things from userspace would IMHO
fall into the policy enforcement side of things, and I'm still unclear
about the failure scenario we'd be trying to prevent, and its likelihood.

Thanks,
--Gabriel
 
> > ---
> > 
> > Changes since v1:
> > - no more "#ifdef CONFIG_ACPI"; instead we proceed if
> >   acpi_acquire_global_lock() returns either OK or NOT_CONFIGURED,
> >   and only throw a warning/error message otherwise.
> > 
> > - didn't get any *negative* feedback from the QEMU crowd, so
> >   this is now a bona-fide "please apply this", rather than just
> >   an RFC :)
> > 
> > - tested on ACPI-enabled x86_64, and acpi_less ARM (32 and 64 bit)
> >   QEMU VMs (I don't have handy access to an ACPI-enabled ARM VM)
> > 
> > Thanks much,
> >   --Gabriel
> > 
> >  drivers/firmware/qemu_fw_cfg.c | 16 
> >  1 file changed, 16 insertions(+)
> > 
> > diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
> > index 7bba76c..a44dc32 100644
> > --- a/drivers/firmware/qemu_fw_cfg.c
> > +++ b/drivers/firmware/qemu_fw_cfg.c
> > @@ -77,12 +77,28 @@ static inline u16 fw_cfg_sel_endianness(u16 key)
> >  static inline void fw_cfg_read_blob(u16 key,
> > void *buf, loff_t pos, size_t count)
> >  {
> > +   u32 glk;
> > +   acpi_status status;
> > +
> > +   /* If we have ACPI, ensure mutual exclusion against any potential
> > +* device access by the firmware, e.g. via AML methods:
> > +*/
> > +   status = acpi_acquire_global_lock(ACPI_WAIT_FOREVER, );
> > +   if (ACPI_FAILURE(status) && status != AE_NOT_CONFIGURED) {
> > +   /* Should never get here */
> > +   WARN(1, "fw_cfg_read_blob: Failed to lock ACPI!\n");
> > +   memset(buf, 0, count);
> > +   return;
> > +   }
> > +
> > mutex_lock(_cfg_dev_lock);
> > iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl);
> > while (pos-- > 0)
> > ioread8(fw_cfg_reg_data);
> > ioread8_rep(fw_cfg_reg_data, buf, count);
> > mutex_unlock(_cfg_dev_lock);
> > +
> > +   acpi_release_global_lock(glk);
> >  }
> >  
> >  /* clean up fw_cfg device i/o */
> > -- 
> > 2.4.3



Re: [Qemu-devel] [PATCH v8 1/4] firmware: introduce sysfs driver for QEMU's fw_cfg device

2016-02-23 Thread Gabriel L. Somlo
On Tue, Feb 23, 2016 at 04:14:46PM +0200, Michael S. Tsirkin wrote:
> On Tue, Feb 23, 2016 at 08:47:00AM -0500, Gabriel L. Somlo wrote:
> > On Tue, Feb 23, 2016 at 07:07:36AM +0200, Michael S. Tsirkin wrote:
> > > On Mon, Feb 22, 2016 at 03:26:23PM -0500, Gabriel L. Somlo wrote:
> > > > On Mon, Feb 22, 2016 at 10:14:50PM +0200, Michael S. Tsirkin wrote:
> > > > > On Sun, Feb 21, 2016 at 08:06:17AM -0500, Gabriel L. Somlo wrote:
> > > > > > > > +static void fw_cfg_io_cleanup(void)
> > > > > > > > +{
> > > > > > > > +   if (fw_cfg_is_mmio) {
> > > > > > > > +   iounmap(fw_cfg_dev_base);
> > > > > > > > +   release_mem_region(fw_cfg_p_base, 
> > > > > > > > fw_cfg_p_size);
> > > > > > > > +   } else {
> > > > > > > > +   ioport_unmap(fw_cfg_dev_base);
> > > > > > > > +   release_region(fw_cfg_p_base, fw_cfg_p_size);
> > > > > > > > +   }
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +/* arch-specific ctrl & data register offsets are not 
> > > > > > > > available in ACPI, DT */
> > > > > > > 
> > > > > > > So for all arches which support ACPI, I think this driver
> > > > > > > should just rely on ACPI.
> > > > > > 
> > > > > > There was a discussion about that a few versions ago, and IIRC the
> > > > > > conclusion was not to expect the firmware to contend for fw_cfg 
> > > > > > access
> > > > > > after the guest kernel boots:
> > > > > > 
> > > > > > https://lkml.org/lkml/2015/10/5/283
> > > > > > 
> > > > > 
> > > > > So it looks like NVDIMM at least wants to pass label data to guest -
> > > > > for which fw cfg might be a reasonable choice.
> > > > > 
> > > > > I suspect things changed - fw cfg used to be very slow but we now have
> > > > > DMA interface which makes it useful for a range of applications.
> > > 
> > > Comment on this? I'm really worried we'll release linux
> > > without a way to access fw cfg from aml.
> > > How about taking acpi lock around all accesses?
> > 
> > You mean something like this (haven't tried compiling it yet, so it
> > might be a bit more complicated, but just for the purpose of this
> > conversation):
> > 
> > diff --git a/drivers/firmware/qemu_fw_cfg.c
> > b/drivers/firmware/qemu_fw_cfg.c
> > index fedbff5..3462a2c 100644
> > --- a/drivers/firmware/qemu_fw_cfg.c
> > +++ b/drivers/firmware/qemu_fw_cfg.c
> > @@ -77,12 +77,18 @@ static inline u16 fw_cfg_sel_endianness(u16 key)
> >  static inline void fw_cfg_read_blob(u16 key,
> > void *buf, loff_t pos, size_t
> > count)
> >  {
> > +#ifdef CONFIG_ACPI
> > +   acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
> > +#endif
> > mutex_lock(_cfg_dev_lock);
> > iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl);
> > while (pos-- > 0)
> > ioread8(fw_cfg_reg_data);
> > ioread8_rep(fw_cfg_reg_data, buf, count);
> > mutex_unlock(_cfg_dev_lock);
> > +#ifdef CONFIG_ACPI
> > +   acpi_os_release_mutex(acpi_gbl_osi_mutex);
> > +#endif
> >  }
> >  
> >  /* clean up fw_cfg device i/o */
> 
> Fundamentally yes.
> 
> > I wouldn't particularly *mind* doing that, but I'd still like to hear
> > from other QEMU devs on whether it's really necessary.
> 
> It seems like a prudent thing to do IMHO, before this
> goes out to users.
> 
> [...]
> 
> On balance, I think locking ACPI solves most problems so
> if we just do that, I think what you did here is fine.

Only trouble is, acpi_gbl_osi_mutex seems to be "private" to the acpi
subsystem, and I'm not sure how well a patch to allow some random
module to lock/unlock ACPI at its convenience would be received...

So unless I'm missing something obvious (wouldn't be the first time),
I think we're back to where *if* we *have* to do this [*], providing an
AML blob-reader method in ACPI and punting to it from the guest-side
kernel module (via #ifdef CONFIG_ACPI) would be the less painful
alternative.

[*] that is, mutual exclusion between kernel and firmware regarding
fw_cfg is (back) on the table, for real this time...

It would be good to know that it's the new consensus among QEMU
folks, since I have a strong feeling I'd no longer be "Keeping It Simple"
by moving in this direction.

Thanks,
--Gabriel




Re: [Qemu-devel] [PATCH v8 1/4] firmware: introduce sysfs driver for QEMU's fw_cfg device

2016-02-23 Thread Gabriel L. Somlo
On Tue, Feb 23, 2016 at 07:07:36AM +0200, Michael S. Tsirkin wrote:
> On Mon, Feb 22, 2016 at 03:26:23PM -0500, Gabriel L. Somlo wrote:
> > On Mon, Feb 22, 2016 at 10:14:50PM +0200, Michael S. Tsirkin wrote:
> > > On Sun, Feb 21, 2016 at 08:06:17AM -0500, Gabriel L. Somlo wrote:
> > > > > > +static void fw_cfg_io_cleanup(void)
> > > > > > +{
> > > > > > +   if (fw_cfg_is_mmio) {
> > > > > > +   iounmap(fw_cfg_dev_base);
> > > > > > +   release_mem_region(fw_cfg_p_base, fw_cfg_p_size);
> > > > > > +   } else {
> > > > > > +   ioport_unmap(fw_cfg_dev_base);
> > > > > > +   release_region(fw_cfg_p_base, fw_cfg_p_size);
> > > > > > +   }
> > > > > > +}
> > > > > > +
> > > > > > +/* arch-specific ctrl & data register offsets are not available in 
> > > > > > ACPI, DT */
> > > > > 
> > > > > So for all arches which support ACPI, I think this driver
> > > > > should just rely on ACPI.
> > > > 
> > > > There was a discussion about that a few versions ago, and IIRC the
> > > > conclusion was not to expect the firmware to contend for fw_cfg access
> > > > after the guest kernel boots:
> > > > 
> > > > https://lkml.org/lkml/2015/10/5/283
> > > > 
> > > 
> > > So it looks like NVDIMM at least wants to pass label data to guest -
> > > for which fw cfg might be a reasonable choice.
> > > 
> > > I suspect things changed - fw cfg used to be very slow but we now have
> > > DMA interface which makes it useful for a range of applications.
> 
> Comment on this? I'm really worried we'll release linux
> without a way to access fw cfg from aml.
> How about taking acpi lock around all accesses?

You mean something like this (haven't tried compiling it yet, so it
might be a bit more complicated, but just for the purpose of this
conversation):

diff --git a/drivers/firmware/qemu_fw_cfg.c
b/drivers/firmware/qemu_fw_cfg.c
index fedbff5..3462a2c 100644
--- a/drivers/firmware/qemu_fw_cfg.c
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -77,12 +77,18 @@ static inline u16 fw_cfg_sel_endianness(u16 key)
 static inline void fw_cfg_read_blob(u16 key,
void *buf, loff_t pos, size_t
count)
 {
+#ifdef CONFIG_ACPI
+   acpi_os_acquire_mutex(acpi_gbl_osi_mutex, ACPI_WAIT_FOREVER);
+#endif
mutex_lock(_cfg_dev_lock);
iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl);
while (pos-- > 0)
ioread8(fw_cfg_reg_data);
ioread8_rep(fw_cfg_reg_data, buf, count);
mutex_unlock(_cfg_dev_lock);
+#ifdef CONFIG_ACPI
+   acpi_os_release_mutex(acpi_gbl_osi_mutex);
+#endif
 }
 
 /* clean up fw_cfg device i/o */

I wouldn't particularly *mind* doing that, but I'd still like to hear
from other QEMU devs on whether it's really necessary.

> > > > (I even had a prototype version doing what you suggested, but per the 
> > > > above
> > > > reference decided to drop it -- which IMHO is for the better, since 
> > > > otherwise
> > > > I'd have had to ifdef between ACPI and non-ACPI versions of the driver 
> > > > --
> > > > see https://lkml.org/lkml/2015/11/4/534 )
> > > 
> > > I'm not sure why you have these ifdefs - they are on the host, are they
> > > not?
> > 
> > Think of those as "pseudocode" ifdefs, they're there to distinguish
> > between AML that would be generated on MMIO vs. IOPORT systems
> > (specifically, arm vs. x86, respectively)
> > 
> > Some of the AML is the same, but obviously the _CRS, and
> > OperationRegion + Field are different, and I wanted to point that out
> > somehow :)
> > 
> > Cheers,
> > --Gabriel
> 
> You can do ifs as well.

Yeah, but the AML is generated from arch-specific locations in QEMU,
so we'd be doing MMIO-only from e.g. hw/arm/virt-acpi-build.c, and
IOPORT-only from hw/i386/acpi-build.c, etc. I wouldnt need to write a
generic AML blob with 'if' statements and insert it the same way on
all architectures, or would I ? Not sure what the best practice would
be for that :)

Speaking of AML, if we were to implement a "RDBL" (read-blob) method
for fw_cfg in AML, and call it from the guest-side kernel module,
we'll never be able to make it use DMA on ACPI systems. The way
fw_cfg_read_blob is written now, we could patch that in at some later
point. So that's an argument in favor of *at most* wrapping
acpi_os_acquire_mutex() around the current fw_cfg_read_blob, rather
than including an acpi-specific version implemented on top of an
AML call.

Thanks,
--Gabriel



Re: [Qemu-devel] [PATCH v8 1/4] firmware: introduce sysfs driver for QEMU's fw_cfg device

2016-02-22 Thread Gabriel L. Somlo
On Mon, Feb 22, 2016 at 10:14:50PM +0200, Michael S. Tsirkin wrote:
> On Sun, Feb 21, 2016 at 08:06:17AM -0500, Gabriel L. Somlo wrote:
> > > > +static void fw_cfg_io_cleanup(void)
> > > > +{
> > > > +   if (fw_cfg_is_mmio) {
> > > > +   iounmap(fw_cfg_dev_base);
> > > > +   release_mem_region(fw_cfg_p_base, fw_cfg_p_size);
> > > > +   } else {
> > > > +   ioport_unmap(fw_cfg_dev_base);
> > > > +   release_region(fw_cfg_p_base, fw_cfg_p_size);
> > > > +   }
> > > > +}
> > > > +
> > > > +/* arch-specific ctrl & data register offsets are not available in 
> > > > ACPI, DT */
> > > 
> > > So for all arches which support ACPI, I think this driver
> > > should just rely on ACPI.
> > 
> > There was a discussion about that a few versions ago, and IIRC the
> > conclusion was not to expect the firmware to contend for fw_cfg access
> > after the guest kernel boots:
> > 
> > https://lkml.org/lkml/2015/10/5/283
> > 
> 
> So it looks like NVDIMM at least wants to pass label data to guest -
> for which fw cfg might be a reasonable choice.
> 
> I suspect things changed - fw cfg used to be very slow but we now have
> DMA interface which makes it useful for a range of applications.
> 
> > (I even had a prototype version doing what you suggested, but per the above
> > reference decided to drop it -- which IMHO is for the better, since 
> > otherwise
> > I'd have had to ifdef between ACPI and non-ACPI versions of the driver --
> > see https://lkml.org/lkml/2015/11/4/534 )
> 
> I'm not sure why you have these ifdefs - they are on the host, are they
> not?

Think of those as "pseudocode" ifdefs, they're there to distinguish
between AML that would be generated on MMIO vs. IOPORT systems
(specifically, arm vs. x86, respectively)

Some of the AML is the same, but obviously the _CRS, and
OperationRegion + Field are different, and I wanted to point that out
somehow :)

Cheers,
--Gabriel



Re: [Qemu-devel] [PATCH v8 1/4] firmware: introduce sysfs driver for QEMU's fw_cfg device

2016-02-21 Thread Gabriel L. Somlo
On Sun, Feb 21, 2016 at 03:10:30PM +0200, Michael S. Tsirkin wrote:
> On Sun, Feb 21, 2016 at 08:06:17AM -0500, Gabriel L. Somlo wrote:
> > 
> > > 
> > > > +#if !(defined(FW_CFG_CTRL_OFF) && defined(FW_CTRL_DATA_OFF))
> > > > +# if (defined(CONFIG_ARM) || defined(CONFIG_ARM64))
> > > > +#  define FW_CFG_CTRL_OFF 0x08
> > > > +#  define FW_CFG_DATA_OFF 0x00
> > > > +# elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* 
> > > > ppc/mac,sun4m */
> > > > +#  define FW_CFG_CTRL_OFF 0x00
> > > > +#  define FW_CFG_DATA_OFF 0x02
> > > > +# elif (defined(CONFIG_X86) || defined(CONFIG_SPARC64)) /* x86, sun4u 
> > > > */
> > > > +#  define FW_CFG_CTRL_OFF 0x00
> > > > +#  define FW_CFG_DATA_OFF 0x01
> > > > +# else
> > > > +#  warning "QEMU FW_CFG may not be available on this architecture!"
> > > > +#  define FW_CFG_CTRL_OFF 0x00
> > > > +#  define FW_CFG_DATA_OFF 0x01
> > > 
> > > Better not try hacks like this, they are hard
> > > to support down the road. Please only list what is tested and
> > > actually exposed by QEMU.
> > 
> > I was looking for a standard way to advertise register offsets within
> > the ioport or mmio region assigned to fw_cfg, but right now the answer
> > is "there isn't one", and "register offsets are an arch specific
> > detail". As such, the only reasonable way I saw was to copy the same
> > values used in the QEMU source.
> > 
> > See also:
> > https://lists.gnu.org/archive/html/qemu-devel/2015-11/msg05037.html
> >  
> > Thanks much,
> > --Gabriel
> 
> My point is you don't know what will qemu do on these
> other arches which do not at the moment have fw cfg.
> So don't try to guess!

Oh, you mean for the "else". I originally wanted to be able to compile
this on any architecture and wanted some dummy defaults I could
override on the command line. But now we're already restricting this
to known architectures only, so I'll send a patch turning the warning
into an error, and removing the #defines for the "else" branch above.

Sorry I misunderstood you the first time around :)

Thanks,
--Gabriel



Re: [Qemu-devel] [PATCH v8 1/4] firmware: introduce sysfs driver for QEMU's fw_cfg device

2016-02-21 Thread Gabriel L. Somlo
On Sun, Feb 21, 2016 at 10:30:26AM +0200, Michael S. Tsirkin wrote:
> On Thu, Jan 28, 2016 at 09:23:11AM -0500, Gabriel L. Somlo wrote:
> > From: Gabriel Somlo <so...@cmu.edu>
> > 
> > Make fw_cfg entries of type "file" available via sysfs. Entries
> > are listed under /sys/firmware/qemu_fw_cfg/by_key, in folders
> > named after each entry's selector key. Filename, selector value,
> > and size read-only attributes are included for each entry. Also,
> > a "raw" attribute allows retrieval of the full binary content of
> > each entry.
> > 
> > The fw_cfg device can be instantiated automatically from ACPI or
> > the Device Tree, or manually by using a kernel module (or command
> > line) parameter, with a syntax outlined in the documentation file.
> > 
> > Signed-off-by: Gabriel Somlo <so...@cmu.edu>
> > ---
> >  .../ABI/testing/sysfs-firmware-qemu_fw_cfg |  58 ++
> >  drivers/firmware/Kconfig   |  19 +
> >  drivers/firmware/Makefile  |   1 +
> >  drivers/firmware/qemu_fw_cfg.c | 648 
> > +
> >  4 files changed, 726 insertions(+)
> >  create mode 100644 Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
> >  create mode 100644 drivers/firmware/qemu_fw_cfg.c
> > 
> > diff --git a/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg 
> > b/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
> > new file mode 100644
> > index 000..e9e58d4
> > --- /dev/null
> > +++ b/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
> > @@ -0,0 +1,58 @@
> > +What:  /sys/firmware/qemu_fw_cfg/
> > +Date:  August 2015
> > +Contact:   Gabriel Somlo <so...@cmu.edu>
> > +Description:
> > +   Several different architectures supported by QEMU (x86, arm,
> > +   sun4*, ppc/mac) are provisioned with a firmware configuration
> > +   (fw_cfg) device, originally intended as a way for the host to
> > +   provide configuration data to the guest firmware. Starting
> > +   with QEMU v2.4, arbitrary fw_cfg file entries may be specified
> > +   by the user on the command line, which makes fw_cfg additionally
> > +   useful as an out-of-band, asynchronous mechanism for providing
> > +   configuration data to the guest userspace.
> > +
> > +   The authoritative guest-side hardware interface documentation
> > +   to the fw_cfg device can be found in "docs/specs/fw_cfg.txt"
> > +   in the QEMU source tree.
> > +
> > +   === SysFS fw_cfg Interface ===
> > +
> > +   The fw_cfg sysfs interface described in this document is only
> > +   intended to display discoverable blobs (i.e., those registered
> > +   with the file directory), as there is no way to determine the
> > +   presence or size of "legacy" blobs (with selector keys between
> > +   0x0002 and 0x0018) programmatically.
> > +
> > +   All fw_cfg information is shown under:
> > +
> > +   /sys/firmware/qemu_fw_cfg/
> > +
> > +   The only legacy blob displayed is the fw_cfg device revision:
> > +
> > +   /sys/firmware/qemu_fw_cfg/rev
> > +
> > +   --- Discoverable fw_cfg blobs by selector key ---
> > +
> > +   All discoverable blobs listed in the fw_cfg file directory are
> > +   displayed as entries named after their unique selector key
> > +   value, e.g.:
> > +
> > +   /sys/firmware/qemu_fw_cfg/by_key/32
> > +   /sys/firmware/qemu_fw_cfg/by_key/33
> > +   /sys/firmware/qemu_fw_cfg/by_key/34
> > +   ...
> > +
> > +   Each such fw_cfg sysfs entry has the following values exported
> > +   as attributes:
> > +
> > +   name: The 56-byte nul-terminated ASCII string used as the
> > + blob's 'file name' in the fw_cfg directory.
> > +   size: The length of the blob, as given in the fw_cfg
> > + directory.
> > +   key : The value of the blob's selector key as given in the
> > + fw_cfg directory. This value is the same as used in
> > + the parent directory name.
> > +   raw : The raw bytes of the blob, obtained by selecting the
> > + entry via the control register, and 

[Qemu-devel] [PATCH v9 0/5] add ACPI node for fw_cfg on pc and arm

2016-02-19 Thread Gabriel L. Somlo
Generate an ACPI DSDT node for fw_cfg on pc and arm guests.

New since v8:

- patch 3/5: on pc/x86, place FWCF node in scope \_SB.PCI0
  (instead of directly under \_SB), to prevent any possible
  resource conflict as might be observed by Windows
  (thanks again to Igor Mammedov for the suggestion!)

Thanks,
  --Gabriel

>New since v7:
>
>   - edited commit blurb on 3/5 to match updated content, i.e. that
> the ACPI node is now inserted into the DSDT (no longer the SSDT).
> (Thanks to Igor Mammedov for catching that!)
>
>>New since v6:
>>  - rebased to fit on top of fb306ff and f264d36, which moved things
>>around in pc's acpi-build.c (only patch 3/5 affected);
>>  - kernel-side fw_cfg sysfs driver accepted into upstream linux
>>
>>>New since v5:
>>>
>>> - rebased on top of latest QEMU git master
>>>
>>>>New since v4:
>>>>
>>>>- rebased on top of Marc's DMA series
>>>>- drop machine compat dependency for insertion into x86/ssdt
>>>>  (patch 3/5), following agreement between Igor and Eduardo
>>>>- [mm]io register range now covers DMA register as well, if
>>>>  available.
>>>>- s/bios/firmware in doc file updates
>>>>
>>>>>New since v3:
>>>>>
>>>>>   - rebased to work on top of 87e896ab (introducing pc-*-25 classes),
>>>>> inserting fw_cfg acpi node only for machines >= 2.5.
>>>>>
>>>>>   - reintroduce _STA with value 0x0B (bit 2 for u/i visibility turned
>>>>> off to avoid Windows complaining -- thanks Igor for catching that!)
>>>>>
>>>>>If there's any other feedback besides questions regarding the
>>>>>appropriateness of "QEMU0002" as the value of _HID, please don't hesitate!
>>>>>
>>>>>>New since v2:
>>>>>>
>>>>>>  - pc/i386 node in ssdt only on machine types *newer* than 2.4
>>>>>>(as suggested by Eduardo)
>>>>>>
>>>>>>I appreciate any further comments and reviews. Hopefully we can make
>>>>>>this palatable for upstream, modulo the lingering concerns about whether
>>>>>>"QEMU0002" is ok to use as the value of _HID, which I'll hopefully get
>>>>>>sorted out with the kernel crew...
>>>>>>
>>>>>>>New since v1:
>>>>>>>
>>>>>>> - expose control register size (suggested by Marc Marí)
>>>>>>>
>>>>>>> - leaving out _UID and _STA fields (thanks Shannon & Igor)
>>>>>>>
>>>>>>> - using "QEMU0002" as the value of _HID (thanks Michael)
>>>>>>>
>>>>>>> - added documentation blurb to docs/specs/fw_cfg.txt
>>>>>>>   (mainly to record usage of the "QEMU0002" string with fw_cfg).
>>>>>>>
>>>>>>>> This series adds a fw_cfg device node to the SSDT (on pc), or to the
>>>>>>>> DSDT (on arm).
>>>>>>>>
>>>>>>>>- Patch 1/3 moves (and renames) the BIOS_CFG_IOPORT (0x510)
>>>>>>>>  define from pc.c to pc.h, so that it could be used from
>>>>>>>>  acpi-build.c in patch 2/3.
>>>>>>>> 
>>>>>>>>- Patch 2/3 adds a fw_cfg node to the pc SSDT.
>>>>>>>> 
>>>>>>>>- Patch 3/3 adds a fw_cfg node to the arm DSDT.
>>>>>>>>
>>>>>>>> I made up some names - "FWCF" for the node name, and "FWCF0001"
>>>>>>>> for _HID; no idea whether that's appropriate, or how else I should
>>>>>>>> figure out what to use instead...
>>>>>>>>
>>>>>>>> Also, using scope "\\_SB", based on where fw_cfg shows up in the
>>>>>>>> output of "info qtree". Again, if that's wrong, please point me in
>>>>>>>> the right direction.
>>>>>>>>
>>>>>>>> Re. 3/3 (also mentioned after the commit blurb in the patch itself),
>>>>>>>> I noticed none of the other DSDT entries contain a _STA field, 
>>>>>>>> wondering
>>>>>>>> why it would (not) make sense to include that, same as on the PC.

Gabriel L. Somlo (5):
  fw_cfg: expose control register size in fw_cfg.h
  pc: fw_cfg: move ioport base constant to pc.h
  acpi: pc: add fw_cfg device node to dsdt
  acpi: arm: add fw_cfg device node to dsdt
  fw_cfg: document ACPI device node information

 docs/specs/fw_cfg.txt |  9 +
 hw/arm/virt-acpi-build.c  | 15 +++
 hw/i386/acpi-build.c  | 29 +
 hw/i386/pc.c  |  5 ++---
 hw/nvram/fw_cfg.c |  4 +++-
 include/hw/i386/pc.h  |  2 ++
 include/hw/nvram/fw_cfg.h |  3 +++
 7 files changed, 63 insertions(+), 4 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v9 3/5] acpi: pc: add fw_cfg device node to dsdt

2016-02-19 Thread Gabriel L. Somlo
Add a fw_cfg device node to the ACPI DSDT. While the guest-side
firmware can't utilize this information (since it has to access
the hard-coded fw_cfg device to extract ACPI tables to begin with),
having fw_cfg listed in ACPI will help the guest kernel keep a more
accurate inventory of in-use IO port regions.

Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/i386/acpi-build.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4554eb8..915fddd 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2190,6 +2190,35 @@ build_dsdt(GArray *table_data, GArray *linker,
 aml_append(scope, aml_name_decl("_S5", pkg));
 aml_append(dsdt, scope);
 
+/* create fw_cfg node, unconditionally */
+{
+/* when using port i/o, the 8-bit data register *always* overlaps
+ * with half of the 16-bit control register. Hence, the total size
+ * of the i/o region used is FW_CFG_CTL_SIZE; when using DMA, the
+ * DMA control register is located at FW_CFG_DMA_IO_BASE + 4 */
+uint8_t io_size = object_property_get_bool(OBJECT(pcms->fw_cfg),
+   "dma_enabled", NULL) ?
+  ROUND_UP(FW_CFG_CTL_SIZE, 4) + sizeof(dma_addr_t) :
+  FW_CFG_CTL_SIZE;
+
+scope = aml_scope("\\_SB.PCI0");
+dev = aml_device("FWCF");
+
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+
+/* device present, functioning, decoding, not shown in UI */
+aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+
+crs = aml_resource_template();
+aml_append(crs,
+aml_io(AML_DECODE16, FW_CFG_IO_BASE, FW_CFG_IO_BASE, 0x01, io_size)
+);
+aml_append(dev, aml_name_decl("_CRS", crs));
+
+aml_append(scope, dev);
+aml_append(dsdt, scope);
+}
+
 if (misc->applesmc_io_base) {
 scope = aml_scope("\\_SB.PCI0.ISA");
 dev = aml_device("SMC");
-- 
2.4.3




[Qemu-devel] [PATCH v9 2/5] pc: fw_cfg: move ioport base constant to pc.h

2016-02-19 Thread Gabriel L. Somlo
Move BIOS_CFG_IOPORT define from pc.c to pc.h, and rename
it to FW_CFG_IO_BASE.

Cc: Marc Marí 
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/i386/pc.c | 5 ++---
 include/hw/i386/pc.h | 2 ++
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 0aeefd2..56ec6cd 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -78,7 +78,6 @@
 #define DPRINTF(fmt, ...)
 #endif
 
-#define BIOS_CFG_IOPORT 0x510
 #define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
 #define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
 #define FW_CFG_IRQ0_OVERRIDE (FW_CFG_ARCH_LOCAL + 2)
@@ -756,7 +755,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as)
 int i, j;
 unsigned int apic_id_limit = pc_apic_id_limit(max_cpus);
 
-fw_cfg = fw_cfg_init_io_dma(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 4, as);
+fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4, as);
 
 /* FW_CFG_MAX_CPUS is a bit confusing/problematic on x86:
  *
@@ -1258,7 +1257,7 @@ void xen_load_linux(PCMachineState *pcms)
 
 assert(MACHINE(pcms)->kernel_filename != NULL);
 
-fw_cfg = fw_cfg_init_io(BIOS_CFG_IOPORT);
+fw_cfg = fw_cfg_init_io(FW_CFG_IO_BASE);
 rom_set_fw(fw_cfg);
 
 load_linux(pcms, fw_cfg);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 8b3546e..79ffe5b 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -266,6 +266,8 @@ void ioapic_init_gsi(GSIState *gsi_state, const char 
*parent_name);
 
 ISADevice *pc_find_fdc0(void);
 
+#define FW_CFG_IO_BASE 0x510
+
 /* acpi_piix.c */
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
-- 
2.4.3




[Qemu-devel] [PATCH v9 1/5] fw_cfg: expose control register size in fw_cfg.h

2016-02-19 Thread Gabriel L. Somlo
Expose the size of the control register (FW_CFG_CTL_SIZE) in fw_cfg.h.
Add comment to fw_cfg_io_realize() pointing out that since the
8-bit data register is always subsumed by the 16-bit control
register in the port I/O case, we use the control register width
as the *total* width of the (classic, non-DMA) port I/O region reserved
for the device.

Cc: Marc Marí 
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/nvram/fw_cfg.c | 4 +++-
 include/hw/nvram/fw_cfg.h | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 79c5742..ef2a219 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -32,7 +32,6 @@
 #include "qemu/error-report.h"
 #include "qemu/config-file.h"
 
-#define FW_CFG_CTL_SIZE 2
 #define FW_CFG_NAME "fw_cfg"
 #define FW_CFG_PATH "/machine/" FW_CFG_NAME
 
@@ -882,6 +881,9 @@ static void fw_cfg_io_realize(DeviceState *dev, Error 
**errp)
 FWCfgIoState *s = FW_CFG_IO(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
+/* when using port i/o, the 8-bit data register ALWAYS overlaps
+ * with half of the 16-bit control register. Hence, the total size
+ * of the i/o region used is FW_CFG_CTL_SIZE */
 memory_region_init_io(>comb_iomem, OBJECT(s), _cfg_comb_mem_ops,
   FW_CFG(s), "fwcfg", FW_CFG_CTL_SIZE);
 sysbus_add_io(sbd, s->iobase, >comb_iomem);
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index 664eaf6..2667ca9 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -46,6 +46,9 @@
 
 #define FW_CFG_INVALID  0x
 
+/* width in bytes of fw_cfg control register */
+#define FW_CFG_CTL_SIZE 0x02
+
 #define FW_CFG_MAX_FILE_PATH56
 
 #ifndef NO_QEMU_PROTOS
-- 
2.4.3




[Qemu-devel] [PATCH v9 5/5] fw_cfg: document ACPI device node information

2016-02-19 Thread Gabriel L. Somlo
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 docs/specs/fw_cfg.txt | 9 +
 1 file changed, 9 insertions(+)

diff --git a/docs/specs/fw_cfg.txt b/docs/specs/fw_cfg.txt
index 2099ad9..5414140 100644
--- a/docs/specs/fw_cfg.txt
+++ b/docs/specs/fw_cfg.txt
@@ -84,6 +84,15 @@ Selector Register address: Base + 8 (2 bytes)
 Data Register address: Base + 0 (8 bytes)
 DMA Address address:   Base + 16 (8 bytes)
 
+== ACPI Interface ==
+
+The fw_cfg device is defined with ACPI ID "QEMU0002". Since we expect
+ACPI tables to be passed into the guest through the fw_cfg device itself,
+the guest-side firmware can not use ACPI to find fw_cfg. However, once the
+firmware is finished setting up ACPI tables and hands control over to the
+guest kernel, the latter can use the fw_cfg ACPI node for a more accurate
+inventory of in-use IOport or MMIO regions.
+
 == Firmware Configuration Items ==
 
 === Signature (Key 0x, FW_CFG_SIGNATURE) ===
-- 
2.4.3




[Qemu-devel] [PATCH v9 4/5] acpi: arm: add fw_cfg device node to dsdt

2016-02-19 Thread Gabriel L. Somlo
Add a fw_cfg device node to the ACPI DSDT. This is mostly
informational, as the authoritative fw_cfg MMIO region(s)
are listed in the Device Tree. However, since we are building
ACPI tables, we might as well be thorough while at it...

Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Tested-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/arm/virt-acpi-build.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 8cf9a21..7d7998b 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -81,6 +81,20 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry 
*uart_memmap,
 aml_append(scope, dev);
 }
 
+static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
+{
+Aml *dev = aml_device("FWCF");
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+/* device present, functioning, decoding, not shown in UI */
+aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base,
+   fw_cfg_memmap->size, AML_READ_WRITE));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
 static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
 {
 Aml *dev, *crs;
@@ -548,6 +562,7 @@ build_dsdt(GArray *table_data, GArray *linker, 
VirtGuestInfo *guest_info)
 acpi_dsdt_add_uart(scope, [VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, [VIRT_FLASH]);
+acpi_dsdt_add_fw_cfg(scope, [VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, [VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
 acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
-- 
2.4.3




Re: [Qemu-devel] [PATCH v8 3/5] acpi: pc: add fw_cfg device node to dsdt

2016-02-19 Thread Gabriel L. Somlo
On Fri, Feb 19, 2016 at 02:49:53PM +0100, Igor Mammedov wrote:
> On Thu, 11 Feb 2016 17:06:03 -0500
> "Gabriel L. Somlo" <so...@cmu.edu> wrote:
> 
> > Add a fw_cfg device node to the ACPI DSDT. While the guest-side
> > firmware can't utilize this information (since it has to access
> > the hard-coded fw_cfg device to extract ACPI tables to begin with),
> > having fw_cfg listed in ACPI will help the guest kernel keep a more
> > accurate inventory of in-use IO port regions.
> > 
> > Signed-off-by: Gabriel Somlo <so...@cmu.edu>
> > Reviewed-by: Laszlo Ersek <ler...@redhat.com>
> > Reviewed-by: Marc Marí <mar...@redhat.com>
> > ---
> >  hw/i386/acpi-build.c | 29 +
> >  1 file changed, 29 insertions(+)
> > 
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index 4554eb8..4762fd2 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -2190,6 +2190,35 @@ build_dsdt(GArray *table_data, GArray *linker,
> >  aml_append(scope, aml_name_decl("_S5", pkg));
> >  aml_append(dsdt, scope);
> >  
> > +/* create fw_cfg node, unconditionally */
> > +{
> > +/* when using port i/o, the 8-bit data register *always* overlaps
> > + * with half of the 16-bit control register. Hence, the total size
> > + * of the i/o region used is FW_CFG_CTL_SIZE; when using DMA, the
> > + * DMA control register is located at FW_CFG_DMA_IO_BASE + 4 */
> > +uint8_t io_size = object_property_get_bool(OBJECT(pcms->fw_cfg),
> > +   "dma_enabled", NULL) ?
> > +  ROUND_UP(FW_CFG_CTL_SIZE, 4) + 
> > sizeof(dma_addr_t) :
> > +  FW_CFG_CTL_SIZE;
> > +
> > +scope = aml_scope("\\_SB");
> > +dev = aml_device("FWCF");
> > +
> > +aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
> From my tests with different Windows versions, it doesn't prevent
> WS2003 and WS2008 from showing a prompt for unknown device that asks for a 
> driver.

I installed windows 2008 server r2 64bit, on both pc and q35 machines,
and still only saw the "unknown device" in the Device Manager after
forcing _STA to 0xF (instead of 0xB).

> One however could shut it up by allowing OS look for a driver
> which is not found and then tell  not to ask for it anymore.

It's entirely possible that "after a while" something would pop up and
ask for a driver anyway. I did try to "humor it" by allowing it to
search for a driver, and it failed, and the device was still showing
up as unknown (remember, this is with _STA set to 0xF, which I did
only to force it to show up :)

I never waited around long enough for it to prompt me, so that may be
the difference between our tests...

> 
> So existing users will have to perform this action once
> they have migrated to newer QEMU regardless of machine version.
> 
> > +
> > +/* device present, functioning, decoding, not shown in UI */
> > +aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
> > +
> > +crs = aml_resource_template();
> > +aml_append(crs,
> > +aml_io(AML_DECODE16, FW_CFG_IO_BASE, FW_CFG_IO_BASE, 0x01, 
> > io_size)
> > +);
> that creates \_SB.FWCF._CRS 
> +Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource 
> Settings
> +{
> +IO (Decode16,
> +0x0510, // Range Minimum
> +0x0510, // Range Maximum
> +0x01,   // Alignment
> +0x0C,   // Length
> +)
> +})
> 
> which collides with \_SB.PCI0._CRS
> WordIO (ResourceProducer, MinFixed, MaxFixed, PosDecode, 
> EntireRange,
> 0x, // Granularity
> 0x, // Range Minimum
> 0x0CF7, // Range Maximum
> 0x, // Translation Offset
> 0x0CF8,
> 
> that shouldn't happen, and solution for this is to put
> FWCF device descriptor in \_SB.PCI0 scope so FWCF would consume
> from PCI0 IO range.
> 
> That won't help Windows to notice a conflict, if there is any,
> as there aren't any drivers for QEMU0002 device but at least
> when Windows gets a driver it won't crash due above conflict.

OK, so the difference between "\_

Re: [Qemu-devel] [PATCH v8 0/5] add ACPI node for fw_cfg on pc and arm

2016-02-16 Thread Gabriel L. Somlo
On Thu, Feb 11, 2016 at 05:06:00PM -0500, Gabriel L. Somlo wrote:
> Generate an ACPI DSDT node for fw_cfg on pc and arm guests.
> 
> New since v7:
> 
>   - edited commit blurb on 3/5 to match updated content, i.e. that
> the ACPI node is now inserted into the DSDT (no longer the SSDT).
> (Thanks to Igor Mammedov for catching that!)

BTW, regarding Igor's question about Windows starting to search for a
driver: Just for grins, I installed Windows 10 (with qemu git master
*before* this series was applied). Then, after applying the series,
DeviceManager was happy and had no unknown hardware listed.

Only after setting the fw_cfg _STA to 0x0F did I get an unknown device
like so: http://imagebin.ca/v/2XDUfONVF3bY

So, on XP, Windows 7, and Windows 10, the fw_cfg device showing up in
ACPI with a _STA set to 0x0B will *NOT* prompt the device manager to 
start making trouble :)

Thanks,
--Gabriel

> >New since v6:
> > - rebased to fit on top of fb306ff and f264d36, which moved things
> >   around in pc's acpi-build.c (only patch 3/5 affected);
> > - kernel-side fw_cfg sysfs driver accepted into upstream linux
> >
> >>New since v5:
> >>
> >>- rebased on top of latest QEMU git master
> >>
> >>>New since v4:
> >>>
> >>>   - rebased on top of Marc's DMA series
> >>>   - drop machine compat dependency for insertion into x86/ssdt
> >>> (patch 3/5), following agreement between Igor and Eduardo
> >>>   - [mm]io register range now covers DMA register as well, if
> >>> available.
> >>>   - s/bios/firmware in doc file updates
> >>>
> >>>>New since v3:
> >>>>
> >>>>  - rebased to work on top of 87e896ab (introducing pc-*-25 classes),
> >>>>inserting fw_cfg acpi node only for machines >= 2.5.
> >>>>
> >>>>  - reintroduce _STA with value 0x0B (bit 2 for u/i visibility turned
> >>>>off to avoid Windows complaining -- thanks Igor for catching that!)
> >>>>
> >>>>If there's any other feedback besides questions regarding the
> >>>>appropriateness of "QEMU0002" as the value of _HID, please don't hesitate!
> >>>>
> >>>>>New since v2:
> >>>>>
> >>>>> - pc/i386 node in ssdt only on machine types *newer* than 2.4
> >>>>>   (as suggested by Eduardo)
> >>>>>
> >>>>>I appreciate any further comments and reviews. Hopefully we can make
> >>>>>this palatable for upstream, modulo the lingering concerns about whether
> >>>>>"QEMU0002" is ok to use as the value of _HID, which I'll hopefully get
> >>>>>sorted out with the kernel crew...
> >>>>>
> >>>>>>New since v1:
> >>>>>>
> >>>>>>- expose control register size (suggested by Marc Marí)
> >>>>>>
> >>>>>>- leaving out _UID and _STA fields (thanks Shannon & Igor)
> >>>>>>
> >>>>>>- using "QEMU0002" as the value of _HID (thanks Michael)
> >>>>>>
> >>>>>>- added documentation blurb to docs/specs/fw_cfg.txt
> >>>>>>  (mainly to record usage of the "QEMU0002" string with fw_cfg).
> >>>>>>
> >>>>>>> This series adds a fw_cfg device node to the SSDT (on pc), or to the
> >>>>>>> DSDT (on arm).
> >>>>>>>
> >>>>>>>   - Patch 1/3 moves (and renames) the BIOS_CFG_IOPORT (0x510)
> >>>>>>> define from pc.c to pc.h, so that it could be used from
> >>>>>>> acpi-build.c in patch 2/3.
> >>>>>>> 
> >>>>>>>   - Patch 2/3 adds a fw_cfg node to the pc SSDT.
> >>>>>>> 
> >>>>>>>   - Patch 3/3 adds a fw_cfg node to the arm DSDT.
> >>>>>>>
> >>>>>>> I made up some names - "FWCF" for the node name, and "FWCF0001"
> >>>>>>> for _HID; no idea whether that's appropriate, or how else I should
> >>>>>>> figure out what to use instead...
> >>>>>>>
> >>>>>>> Also, using scope "\\_SB", based on where fw_cfg shows up in the
> >>>>>>> output of "info qtree". Again, if that's wrong, please point me in
> >>>>>>> the right direction.
> >>>>>>>
> >>>>>>> Re. 3/3 (also mentioned after the commit blurb in the patch itself),
> >>>>>>> I noticed none of the other DSDT entries contain a _STA field, 
> >>>>>>> wondering
> >>>>>>> why it would (not) make sense to include that, same as on the PC.
> 
> Gabriel L. Somlo (5):
>   fw_cfg: expose control register size in fw_cfg.h
>   pc: fw_cfg: move ioport base constant to pc.h
>   acpi: pc: add fw_cfg device node to dsdt
>   acpi: arm: add fw_cfg device node to dsdt
>   fw_cfg: document ACPI device node information
> 
>  docs/specs/fw_cfg.txt |  9 +
>  hw/arm/virt-acpi-build.c  | 15 +++
>  hw/i386/acpi-build.c  | 29 +
>  hw/i386/pc.c  |  5 ++---
>  hw/nvram/fw_cfg.c |  4 +++-
>  include/hw/i386/pc.h  |  2 ++
>  include/hw/nvram/fw_cfg.h |  3 +++
>  7 files changed, 63 insertions(+), 4 deletions(-)
> 
> -- 
> 2.4.3
> 



Re: [Qemu-devel] [PATCH v7 3/5] acpi: pc: add fw_cfg device node to ssdt

2016-02-11 Thread Gabriel L. Somlo
On Thu, Feb 11, 2016 at 04:19:59PM +0100, Igor Mammedov wrote:
> On Wed, 10 Feb 2016 15:41:38 -0500
> "Gabriel L. Somlo" <so...@cmu.edu> wrote:
> 
> > Add a fw_cfg device node to the ACPI SSDT. While the guest-side
> > firmware can't utilize this information (since it has to access
> > the hard-coded fw_cfg device to extract ACPI tables to begin with),
> > having fw_cfg listed in ACPI will help the guest kernel keep a more
> > accurate inventory of in-use IO port regions.
> subj and commit msg:
> s/SSDT/DSDT/

Thanks for catching that, got it lined up for v8 :)

> > 
> > Signed-off-by: Gabriel Somlo <so...@cmu.edu>
> > Reviewed-by: Laszlo Ersek <ler...@redhat.com>
> > Reviewed-by: Marc Marí <mar...@redhat.com>
> > ---
> >  hw/i386/acpi-build.c | 29 +
> >  1 file changed, 29 insertions(+)
> > 
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index 4554eb8..4762fd2 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -2190,6 +2190,35 @@ build_dsdt(GArray *table_data, GArray *linker,
> >  aml_append(scope, aml_name_decl("_S5", pkg));
> >  aml_append(dsdt, scope);
> >  
> > +/* create fw_cfg node, unconditionally */
> Will that unconditionally make all Windows guests ask for driver for unknown 
> device?

That didn't happen in my tests. With _STA set to 0xB, we have the
bit representing "device shown in the UI" set to "off", and so Windows
(XP and Win7 in my tests) completely ignore it.

Originally I was asked (by Eduardo, IIRC) to make insertion of the
fw_cfg acpi node conditional on the machine version, but then later we
collectively agreed to no longer require that, so there wasn't an if (...)
condition to put in front of the { ... } block anymore. I replaced the
condition with the comment that says "add unconditionally"; I can change
the wording on that if it's confusing, but I'd like to keep the extra
curly braces to match the way all other surrounding ACPI nodes are added.

Thanks,
--Gabriel

> > +{
> > +/* when using port i/o, the 8-bit data register *always* overlaps
> > + * with half of the 16-bit control register. Hence, the total size
> > + * of the i/o region used is FW_CFG_CTL_SIZE; when using DMA, the
> > + * DMA control register is located at FW_CFG_DMA_IO_BASE + 4 */
> > +uint8_t io_size = object_property_get_bool(OBJECT(pcms->fw_cfg),
> > +   "dma_enabled", NULL) ?
> > +  ROUND_UP(FW_CFG_CTL_SIZE, 4) + 
> > sizeof(dma_addr_t) :
> > +  FW_CFG_CTL_SIZE;
> > +
> > +scope = aml_scope("\\_SB");
> > +dev = aml_device("FWCF");
> > +
> > +aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
> > +
> > +/* device present, functioning, decoding, not shown in UI */
> > +aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
> > +
> > +crs = aml_resource_template();
> > +aml_append(crs,
> > +aml_io(AML_DECODE16, FW_CFG_IO_BASE, FW_CFG_IO_BASE, 0x01, 
> > io_size)
> > +);
> > +aml_append(dev, aml_name_decl("_CRS", crs));
> > +
> > +aml_append(scope, dev);
> > +aml_append(dsdt, scope);
> > +}
> > +
> >  if (misc->applesmc_io_base) {
> >  scope = aml_scope("\\_SB.PCI0.ISA");
> >  dev = aml_device("SMC");
> 



[Qemu-devel] [PATCH v8 0/5] add ACPI node for fw_cfg on pc and arm

2016-02-11 Thread Gabriel L. Somlo
Generate an ACPI DSDT node for fw_cfg on pc and arm guests.

New since v7:

- edited commit blurb on 3/5 to match updated content, i.e. that
  the ACPI node is now inserted into the DSDT (no longer the SSDT).
  (Thanks to Igor Mammedov for catching that!)

Thanks,
  --Gabriel

>New since v6:
>   - rebased to fit on top of fb306ff and f264d36, which moved things
> around in pc's acpi-build.c (only patch 3/5 affected);
>   - kernel-side fw_cfg sysfs driver accepted into upstream linux
>
>>New since v5:
>>
>>  - rebased on top of latest QEMU git master
>>
>>>New since v4:
>>>
>>> - rebased on top of Marc's DMA series
>>> - drop machine compat dependency for insertion into x86/ssdt
>>>   (patch 3/5), following agreement between Igor and Eduardo
>>> - [mm]io register range now covers DMA register as well, if
>>>   available.
>>> - s/bios/firmware in doc file updates
>>>
>>>>New since v3:
>>>>
>>>>- rebased to work on top of 87e896ab (introducing pc-*-25 classes),
>>>>  inserting fw_cfg acpi node only for machines >= 2.5.
>>>>
>>>>- reintroduce _STA with value 0x0B (bit 2 for u/i visibility turned
>>>>  off to avoid Windows complaining -- thanks Igor for catching that!)
>>>>
>>>>If there's any other feedback besides questions regarding the
>>>>appropriateness of "QEMU0002" as the value of _HID, please don't hesitate!
>>>>
>>>>>New since v2:
>>>>>
>>>>>   - pc/i386 node in ssdt only on machine types *newer* than 2.4
>>>>> (as suggested by Eduardo)
>>>>>
>>>>>I appreciate any further comments and reviews. Hopefully we can make
>>>>>this palatable for upstream, modulo the lingering concerns about whether
>>>>>"QEMU0002" is ok to use as the value of _HID, which I'll hopefully get
>>>>>sorted out with the kernel crew...
>>>>>
>>>>>>New since v1:
>>>>>>
>>>>>>  - expose control register size (suggested by Marc Marí)
>>>>>>
>>>>>>  - leaving out _UID and _STA fields (thanks Shannon & Igor)
>>>>>>
>>>>>>  - using "QEMU0002" as the value of _HID (thanks Michael)
>>>>>>
>>>>>>  - added documentation blurb to docs/specs/fw_cfg.txt
>>>>>>(mainly to record usage of the "QEMU0002" string with fw_cfg).
>>>>>>
>>>>>>> This series adds a fw_cfg device node to the SSDT (on pc), or to the
>>>>>>> DSDT (on arm).
>>>>>>>
>>>>>>> - Patch 1/3 moves (and renames) the BIOS_CFG_IOPORT (0x510)
>>>>>>>   define from pc.c to pc.h, so that it could be used from
>>>>>>>   acpi-build.c in patch 2/3.
>>>>>>> 
>>>>>>> - Patch 2/3 adds a fw_cfg node to the pc SSDT.
>>>>>>> 
>>>>>>> - Patch 3/3 adds a fw_cfg node to the arm DSDT.
>>>>>>>
>>>>>>> I made up some names - "FWCF" for the node name, and "FWCF0001"
>>>>>>> for _HID; no idea whether that's appropriate, or how else I should
>>>>>>> figure out what to use instead...
>>>>>>>
>>>>>>> Also, using scope "\\_SB", based on where fw_cfg shows up in the
>>>>>>> output of "info qtree". Again, if that's wrong, please point me in
>>>>>>> the right direction.
>>>>>>>
>>>>>>> Re. 3/3 (also mentioned after the commit blurb in the patch itself),
>>>>>>> I noticed none of the other DSDT entries contain a _STA field, wondering
>>>>>>> why it would (not) make sense to include that, same as on the PC.

Gabriel L. Somlo (5):
  fw_cfg: expose control register size in fw_cfg.h
  pc: fw_cfg: move ioport base constant to pc.h
  acpi: pc: add fw_cfg device node to dsdt
  acpi: arm: add fw_cfg device node to dsdt
  fw_cfg: document ACPI device node information

 docs/specs/fw_cfg.txt |  9 +
 hw/arm/virt-acpi-build.c  | 15 +++
 hw/i386/acpi-build.c  | 29 +
 hw/i386/pc.c  |  5 ++---
 hw/nvram/fw_cfg.c |  4 +++-
 include/hw/i386/pc.h  |  2 ++
 include/hw/nvram/fw_cfg.h |  3 +++
 7 files changed, 63 insertions(+), 4 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v8 1/5] fw_cfg: expose control register size in fw_cfg.h

2016-02-11 Thread Gabriel L. Somlo
Expose the size of the control register (FW_CFG_CTL_SIZE) in fw_cfg.h.
Add comment to fw_cfg_io_realize() pointing out that since the
8-bit data register is always subsumed by the 16-bit control
register in the port I/O case, we use the control register width
as the *total* width of the (classic, non-DMA) port I/O region reserved
for the device.

Cc: Marc Marí 
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/nvram/fw_cfg.c | 4 +++-
 include/hw/nvram/fw_cfg.h | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 79c5742..ef2a219 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -32,7 +32,6 @@
 #include "qemu/error-report.h"
 #include "qemu/config-file.h"
 
-#define FW_CFG_CTL_SIZE 2
 #define FW_CFG_NAME "fw_cfg"
 #define FW_CFG_PATH "/machine/" FW_CFG_NAME
 
@@ -882,6 +881,9 @@ static void fw_cfg_io_realize(DeviceState *dev, Error 
**errp)
 FWCfgIoState *s = FW_CFG_IO(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
+/* when using port i/o, the 8-bit data register ALWAYS overlaps
+ * with half of the 16-bit control register. Hence, the total size
+ * of the i/o region used is FW_CFG_CTL_SIZE */
 memory_region_init_io(>comb_iomem, OBJECT(s), _cfg_comb_mem_ops,
   FW_CFG(s), "fwcfg", FW_CFG_CTL_SIZE);
 sysbus_add_io(sbd, s->iobase, >comb_iomem);
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index 664eaf6..2667ca9 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -46,6 +46,9 @@
 
 #define FW_CFG_INVALID  0x
 
+/* width in bytes of fw_cfg control register */
+#define FW_CFG_CTL_SIZE 0x02
+
 #define FW_CFG_MAX_FILE_PATH56
 
 #ifndef NO_QEMU_PROTOS
-- 
2.4.3




[Qemu-devel] [PATCH v8 3/5] acpi: pc: add fw_cfg device node to dsdt

2016-02-11 Thread Gabriel L. Somlo
Add a fw_cfg device node to the ACPI DSDT. While the guest-side
firmware can't utilize this information (since it has to access
the hard-coded fw_cfg device to extract ACPI tables to begin with),
having fw_cfg listed in ACPI will help the guest kernel keep a more
accurate inventory of in-use IO port regions.

Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/i386/acpi-build.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4554eb8..4762fd2 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2190,6 +2190,35 @@ build_dsdt(GArray *table_data, GArray *linker,
 aml_append(scope, aml_name_decl("_S5", pkg));
 aml_append(dsdt, scope);
 
+/* create fw_cfg node, unconditionally */
+{
+/* when using port i/o, the 8-bit data register *always* overlaps
+ * with half of the 16-bit control register. Hence, the total size
+ * of the i/o region used is FW_CFG_CTL_SIZE; when using DMA, the
+ * DMA control register is located at FW_CFG_DMA_IO_BASE + 4 */
+uint8_t io_size = object_property_get_bool(OBJECT(pcms->fw_cfg),
+   "dma_enabled", NULL) ?
+  ROUND_UP(FW_CFG_CTL_SIZE, 4) + sizeof(dma_addr_t) :
+  FW_CFG_CTL_SIZE;
+
+scope = aml_scope("\\_SB");
+dev = aml_device("FWCF");
+
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+
+/* device present, functioning, decoding, not shown in UI */
+aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+
+crs = aml_resource_template();
+aml_append(crs,
+aml_io(AML_DECODE16, FW_CFG_IO_BASE, FW_CFG_IO_BASE, 0x01, io_size)
+);
+aml_append(dev, aml_name_decl("_CRS", crs));
+
+aml_append(scope, dev);
+aml_append(dsdt, scope);
+}
+
 if (misc->applesmc_io_base) {
 scope = aml_scope("\\_SB.PCI0.ISA");
 dev = aml_device("SMC");
-- 
2.4.3




[Qemu-devel] [PATCH v8 2/5] pc: fw_cfg: move ioport base constant to pc.h

2016-02-11 Thread Gabriel L. Somlo
Move BIOS_CFG_IOPORT define from pc.c to pc.h, and rename
it to FW_CFG_IO_BASE.

Cc: Marc Marí 
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/i386/pc.c | 5 ++---
 include/hw/i386/pc.h | 2 ++
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 0aeefd2..56ec6cd 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -78,7 +78,6 @@
 #define DPRINTF(fmt, ...)
 #endif
 
-#define BIOS_CFG_IOPORT 0x510
 #define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
 #define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
 #define FW_CFG_IRQ0_OVERRIDE (FW_CFG_ARCH_LOCAL + 2)
@@ -756,7 +755,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as)
 int i, j;
 unsigned int apic_id_limit = pc_apic_id_limit(max_cpus);
 
-fw_cfg = fw_cfg_init_io_dma(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 4, as);
+fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4, as);
 
 /* FW_CFG_MAX_CPUS is a bit confusing/problematic on x86:
  *
@@ -1258,7 +1257,7 @@ void xen_load_linux(PCMachineState *pcms)
 
 assert(MACHINE(pcms)->kernel_filename != NULL);
 
-fw_cfg = fw_cfg_init_io(BIOS_CFG_IOPORT);
+fw_cfg = fw_cfg_init_io(FW_CFG_IO_BASE);
 rom_set_fw(fw_cfg);
 
 load_linux(pcms, fw_cfg);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 8b3546e..79ffe5b 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -266,6 +266,8 @@ void ioapic_init_gsi(GSIState *gsi_state, const char 
*parent_name);
 
 ISADevice *pc_find_fdc0(void);
 
+#define FW_CFG_IO_BASE 0x510
+
 /* acpi_piix.c */
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
-- 
2.4.3




[Qemu-devel] [PATCH v8 5/5] fw_cfg: document ACPI device node information

2016-02-11 Thread Gabriel L. Somlo
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 docs/specs/fw_cfg.txt | 9 +
 1 file changed, 9 insertions(+)

diff --git a/docs/specs/fw_cfg.txt b/docs/specs/fw_cfg.txt
index 2099ad9..5414140 100644
--- a/docs/specs/fw_cfg.txt
+++ b/docs/specs/fw_cfg.txt
@@ -84,6 +84,15 @@ Selector Register address: Base + 8 (2 bytes)
 Data Register address: Base + 0 (8 bytes)
 DMA Address address:   Base + 16 (8 bytes)
 
+== ACPI Interface ==
+
+The fw_cfg device is defined with ACPI ID "QEMU0002". Since we expect
+ACPI tables to be passed into the guest through the fw_cfg device itself,
+the guest-side firmware can not use ACPI to find fw_cfg. However, once the
+firmware is finished setting up ACPI tables and hands control over to the
+guest kernel, the latter can use the fw_cfg ACPI node for a more accurate
+inventory of in-use IOport or MMIO regions.
+
 == Firmware Configuration Items ==
 
 === Signature (Key 0x, FW_CFG_SIGNATURE) ===
-- 
2.4.3




[Qemu-devel] [PATCH v8 4/5] acpi: arm: add fw_cfg device node to dsdt

2016-02-11 Thread Gabriel L. Somlo
Add a fw_cfg device node to the ACPI DSDT. This is mostly
informational, as the authoritative fw_cfg MMIO region(s)
are listed in the Device Tree. However, since we are building
ACPI tables, we might as well be thorough while at it...

Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Tested-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/arm/virt-acpi-build.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 8cf9a21..7d7998b 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -81,6 +81,20 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry 
*uart_memmap,
 aml_append(scope, dev);
 }
 
+static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
+{
+Aml *dev = aml_device("FWCF");
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+/* device present, functioning, decoding, not shown in UI */
+aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base,
+   fw_cfg_memmap->size, AML_READ_WRITE));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
 static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
 {
 Aml *dev, *crs;
@@ -548,6 +562,7 @@ build_dsdt(GArray *table_data, GArray *linker, 
VirtGuestInfo *guest_info)
 acpi_dsdt_add_uart(scope, [VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, [VIRT_FLASH]);
+acpi_dsdt_add_fw_cfg(scope, [VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, [VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
 acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
-- 
2.4.3




Re: [Qemu-devel] [PATCH v6 0/5] add ACPI node for fw_cfg on pc and arm

2016-02-10 Thread Gabriel L. Somlo
Ping.

Now that the kernel side seems to have been accepted (Thanks again
Laszlo and Matt for all the help and advice!!!), is there anything
left to clean up before this series could be applied to QEMU ?

gmane.org quick links:
1/5: http://article.gmane.org/gmane.comp.emulators.qemu/389896/raw
2/5: http://article.gmane.org/gmane.comp.emulators.qemu/389894/raw
3/5: http://article.gmane.org/gmane.comp.emulators.qemu/389895/raw
4/5: http://article.gmane.org/gmane.comp.emulators.qemu/389900/raw
5/5: http://article.gmane.org/gmane.comp.emulators.qemu/389898/raw

Thanks much,
--Gabriel


On Wed, Jan 27, 2016 at 10:00:52PM -0500, Gabriel L. Somlo wrote:
> New since v5:
> 
>   - rebased on top of latest QEMU git master
> 
> Thanks,
>   --Gabriel
> 
> >New since v4:
> >
> > - rebased on top of Marc's DMA series
> > - drop machine compat dependency for insertion into x86/ssdt
> >   (patch 3/5), following agreement between Igor and Eduardo
> > - [mm]io register range now covers DMA register as well, if
> >   available.
> > - s/bios/firmware in doc file updates
> >
> >>New since v3:
> >>
> >>- rebased to work on top of 87e896ab (introducing pc-*-25 classes),
> >>  inserting fw_cfg acpi node only for machines >= 2.5.
> >>
> >>- reintroduce _STA with value 0x0B (bit 2 for u/i visibility turned
> >>  off to avoid Windows complaining -- thanks Igor for catching that!)
> >>
> >>If there's any other feedback besides questions regarding the
> >>appropriateness of "QEMU0002" as the value of _HID, please don't hesitate!
> >>
> >>>New since v2:
> >>>
> >>>   - pc/i386 node in ssdt only on machine types *newer* than 2.4
> >>> (as suggested by Eduardo)
> >>>
> >>>I appreciate any further comments and reviews. Hopefully we can make
> >>>this palatable for upstream, modulo the lingering concerns about whether
> >>>"QEMU0002" is ok to use as the value of _HID, which I'll hopefully get
> >>>sorted out with the kernel crew...
> >>>
> >>>>New since v1:
> >>>>
> >>>>  - expose control register size (suggested by Marc Marí)
> >>>>
> >>>>  - leaving out _UID and _STA fields (thanks Shannon & Igor)
> >>>>
> >>>>  - using "QEMU0002" as the value of _HID (thanks Michael)
> >>>>
> >>>>  - added documentation blurb to docs/specs/fw_cfg.txt
> >>>>(mainly to record usage of the "QEMU0002" string with fw_cfg).
> >>>>
> >>>>> This series adds a fw_cfg device node to the SSDT (on pc), or to the
> >>>>> DSDT (on arm).
> >>>>>
> >>>>> - Patch 1/3 moves (and renames) the BIOS_CFG_IOPORT (0x510)
> >>>>>   define from pc.c to pc.h, so that it could be used from
> >>>>>   acpi-build.c in patch 2/3.
> >>>>> 
> >>>>> - Patch 2/3 adds a fw_cfg node to the pc SSDT.
> >>>>> 
> >>>>>     - Patch 3/3 adds a fw_cfg node to the arm DSDT.
> >>>>>
> >>>>> I made up some names - "FWCF" for the node name, and "FWCF0001"
> >>>>> for _HID; no idea whether that's appropriate, or how else I should
> >>>>> figure out what to use instead...
> >>>>>
> >>>>> Also, using scope "\\_SB", based on where fw_cfg shows up in the
> >>>>> output of "info qtree". Again, if that's wrong, please point me in
> >>>>> the right direction.
> >>>>>
> >>>>> Re. 3/3 (also mentioned after the commit blurb in the patch itself),
> >>>>> I noticed none of the other DSDT entries contain a _STA field, wondering
> >>>>> why it would (not) make sense to include that, same as on the PC.
> 
> Gabriel L. Somlo (5):
>   fw_cfg: expose control register size in fw_cfg.h
>   pc: fw_cfg: move ioport base constant to pc.h
>   acpi: pc: add fw_cfg device node to ssdt
>   acpi: arm: add fw_cfg device node to dsdt
>   fw_cfg: document ACPI device node information
> 
>  docs/specs/fw_cfg.txt |  9 +
>  hw/arm/virt-acpi-build.c  | 15 +++
>  hw/i386/acpi-build.c  | 29 +
>  hw/i386/pc.c  |  5 ++---
>  hw/nvram/fw_cfg.c |  4 +++-
>  include/hw/i386/pc.h  |  2 ++
>  include/hw/nvram/fw_cfg.h |  3 +++
>  7 files changed, 63 insertions(+), 4 deletions(-)
> 
> -- 
> 2.4.3
> 



[Qemu-devel] commit 5b82b70 boot problems

2016-02-10 Thread Gabriel L. Somlo
Hi Stefan,

After pulling from upstream this morning, my guest VMs were no longer
able to boot. For instance, running something like

bin/qemu-system-x86_64 -machine q35,accel=kvm -m 2048 -monitor stdio \
  -device ide-drive,bus=ide.2,drive=CD \
  -drive id=CD,if=none,snapshot=on,file=Fedora-Live-Workstation-x86_64-22-3.iso

Would just hang with a black screen, or sometimes partially display
the GRUB boot menu, and never make it any further than that.

After a bisect, I narrowed it down to 5b82b70 ("memory: RCU
ram_list.dirty_memory[] for safe RAM hotplug"); reverting that
commit got me back to where my VMs were working fine, but the
actual content of the changes isn't immediately obvious.

Apologies for the noise in case you're already aware of the problem.
Otherwise, I'd be happy to test and send you debug output.

Please advise.

Thanks much,
--Gabriel



[Qemu-devel] [PATCH v7 2/5] pc: fw_cfg: move ioport base constant to pc.h

2016-02-10 Thread Gabriel L. Somlo
Move BIOS_CFG_IOPORT define from pc.c to pc.h, and rename
it to FW_CFG_IO_BASE.

Cc: Marc Marí 
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/i386/pc.c | 5 ++---
 include/hw/i386/pc.h | 2 ++
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 0aeefd2..56ec6cd 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -78,7 +78,6 @@
 #define DPRINTF(fmt, ...)
 #endif
 
-#define BIOS_CFG_IOPORT 0x510
 #define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
 #define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
 #define FW_CFG_IRQ0_OVERRIDE (FW_CFG_ARCH_LOCAL + 2)
@@ -756,7 +755,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as)
 int i, j;
 unsigned int apic_id_limit = pc_apic_id_limit(max_cpus);
 
-fw_cfg = fw_cfg_init_io_dma(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 4, as);
+fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4, as);
 
 /* FW_CFG_MAX_CPUS is a bit confusing/problematic on x86:
  *
@@ -1258,7 +1257,7 @@ void xen_load_linux(PCMachineState *pcms)
 
 assert(MACHINE(pcms)->kernel_filename != NULL);
 
-fw_cfg = fw_cfg_init_io(BIOS_CFG_IOPORT);
+fw_cfg = fw_cfg_init_io(FW_CFG_IO_BASE);
 rom_set_fw(fw_cfg);
 
 load_linux(pcms, fw_cfg);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 8b3546e..79ffe5b 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -266,6 +266,8 @@ void ioapic_init_gsi(GSIState *gsi_state, const char 
*parent_name);
 
 ISADevice *pc_find_fdc0(void);
 
+#define FW_CFG_IO_BASE 0x510
+
 /* acpi_piix.c */
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
-- 
2.4.3




[Qemu-devel] [PATCH v7 3/5] acpi: pc: add fw_cfg device node to ssdt

2016-02-10 Thread Gabriel L. Somlo
Add a fw_cfg device node to the ACPI SSDT. While the guest-side
firmware can't utilize this information (since it has to access
the hard-coded fw_cfg device to extract ACPI tables to begin with),
having fw_cfg listed in ACPI will help the guest kernel keep a more
accurate inventory of in-use IO port regions.

Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/i386/acpi-build.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 4554eb8..4762fd2 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2190,6 +2190,35 @@ build_dsdt(GArray *table_data, GArray *linker,
 aml_append(scope, aml_name_decl("_S5", pkg));
 aml_append(dsdt, scope);
 
+/* create fw_cfg node, unconditionally */
+{
+/* when using port i/o, the 8-bit data register *always* overlaps
+ * with half of the 16-bit control register. Hence, the total size
+ * of the i/o region used is FW_CFG_CTL_SIZE; when using DMA, the
+ * DMA control register is located at FW_CFG_DMA_IO_BASE + 4 */
+uint8_t io_size = object_property_get_bool(OBJECT(pcms->fw_cfg),
+   "dma_enabled", NULL) ?
+  ROUND_UP(FW_CFG_CTL_SIZE, 4) + sizeof(dma_addr_t) :
+  FW_CFG_CTL_SIZE;
+
+scope = aml_scope("\\_SB");
+dev = aml_device("FWCF");
+
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+
+/* device present, functioning, decoding, not shown in UI */
+aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+
+crs = aml_resource_template();
+aml_append(crs,
+aml_io(AML_DECODE16, FW_CFG_IO_BASE, FW_CFG_IO_BASE, 0x01, io_size)
+);
+aml_append(dev, aml_name_decl("_CRS", crs));
+
+aml_append(scope, dev);
+aml_append(dsdt, scope);
+}
+
 if (misc->applesmc_io_base) {
 scope = aml_scope("\\_SB.PCI0.ISA");
 dev = aml_device("SMC");
-- 
2.4.3




[Qemu-devel] [PATCH v7 0/5] add ACPI node for fw_cfg on pc and arm

2016-02-10 Thread Gabriel L. Somlo
Generate an ACPI DSDT node for fw_cfg on pc and arm guests.

New since v6:
- rebased to fit on top of fb306ff and f264d36, which moved things
  around in pc's acpi-build.c (only patch 3/5 affected);
- kernel-side fw_cfg sysfs driver accepted into upstream linux

Thanks,
 --Gabriel

>New since v5:
>
>   - rebased on top of latest QEMU git master
>
>>New since v4:
>>
>>  - rebased on top of Marc's DMA series
>>  - drop machine compat dependency for insertion into x86/ssdt
>>(patch 3/5), following agreement between Igor and Eduardo
>>  - [mm]io register range now covers DMA register as well, if
>>available.
>>  - s/bios/firmware in doc file updates
>>
>>>New since v3:
>>>
>>> - rebased to work on top of 87e896ab (introducing pc-*-25 classes),
>>>   inserting fw_cfg acpi node only for machines >= 2.5.
>>>
>>> - reintroduce _STA with value 0x0B (bit 2 for u/i visibility turned
>>>   off to avoid Windows complaining -- thanks Igor for catching that!)
>>>
>>>If there's any other feedback besides questions regarding the
>>>appropriateness of "QEMU0002" as the value of _HID, please don't hesitate!
>>>
>>>>New since v2:
>>>>
>>>>- pc/i386 node in ssdt only on machine types *newer* than 2.4
>>>>  (as suggested by Eduardo)
>>>>
>>>>I appreciate any further comments and reviews. Hopefully we can make
>>>>this palatable for upstream, modulo the lingering concerns about whether
>>>>"QEMU0002" is ok to use as the value of _HID, which I'll hopefully get
>>>>sorted out with the kernel crew...
>>>>
>>>>>New since v1:
>>>>>
>>>>>   - expose control register size (suggested by Marc Marí)
>>>>>
>>>>>   - leaving out _UID and _STA fields (thanks Shannon & Igor)
>>>>>
>>>>>   - using "QEMU0002" as the value of _HID (thanks Michael)
>>>>>
>>>>>   - added documentation blurb to docs/specs/fw_cfg.txt
>>>>> (mainly to record usage of the "QEMU0002" string with fw_cfg).
>>>>>
>>>>>> This series adds a fw_cfg device node to the SSDT (on pc), or to the
>>>>>> DSDT (on arm).
>>>>>>
>>>>>>  - Patch 1/3 moves (and renames) the BIOS_CFG_IOPORT (0x510)
>>>>>>define from pc.c to pc.h, so that it could be used from
>>>>>>acpi-build.c in patch 2/3.
>>>>>> 
>>>>>>  - Patch 2/3 adds a fw_cfg node to the pc SSDT.
>>>>>> 
>>>>>>  - Patch 3/3 adds a fw_cfg node to the arm DSDT.
>>>>>>
>>>>>> I made up some names - "FWCF" for the node name, and "FWCF0001"
>>>>>> for _HID; no idea whether that's appropriate, or how else I should
>>>>>> figure out what to use instead...
>>>>>>
>>>>>> Also, using scope "\\_SB", based on where fw_cfg shows up in the
>>>>>> output of "info qtree". Again, if that's wrong, please point me in
>>>>>> the right direction.
>>>>>>
>>>>>> Re. 3/3 (also mentioned after the commit blurb in the patch itself),
>>>>>> I noticed none of the other DSDT entries contain a _STA field, wondering
>>>>>> why it would (not) make sense to include that, same as on the PC.

Gabriel L. Somlo (5):
  fw_cfg: expose control register size in fw_cfg.h
  pc: fw_cfg: move ioport base constant to pc.h
  acpi: pc: add fw_cfg device node to ssdt
  acpi: arm: add fw_cfg device node to dsdt
  fw_cfg: document ACPI device node information

 docs/specs/fw_cfg.txt |  9 +
 hw/arm/virt-acpi-build.c  | 15 +++
 hw/i386/acpi-build.c  | 29 +
 hw/i386/pc.c  |  5 ++---
 hw/nvram/fw_cfg.c |  4 +++-
 include/hw/i386/pc.h  |  2 ++
 include/hw/nvram/fw_cfg.h |  3 +++
 7 files changed, 63 insertions(+), 4 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v7 5/5] fw_cfg: document ACPI device node information

2016-02-10 Thread Gabriel L. Somlo
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 docs/specs/fw_cfg.txt | 9 +
 1 file changed, 9 insertions(+)

diff --git a/docs/specs/fw_cfg.txt b/docs/specs/fw_cfg.txt
index 2099ad9..5414140 100644
--- a/docs/specs/fw_cfg.txt
+++ b/docs/specs/fw_cfg.txt
@@ -84,6 +84,15 @@ Selector Register address: Base + 8 (2 bytes)
 Data Register address: Base + 0 (8 bytes)
 DMA Address address:   Base + 16 (8 bytes)
 
+== ACPI Interface ==
+
+The fw_cfg device is defined with ACPI ID "QEMU0002". Since we expect
+ACPI tables to be passed into the guest through the fw_cfg device itself,
+the guest-side firmware can not use ACPI to find fw_cfg. However, once the
+firmware is finished setting up ACPI tables and hands control over to the
+guest kernel, the latter can use the fw_cfg ACPI node for a more accurate
+inventory of in-use IOport or MMIO regions.
+
 == Firmware Configuration Items ==
 
 === Signature (Key 0x, FW_CFG_SIGNATURE) ===
-- 
2.4.3




[Qemu-devel] [PATCH v7 1/5] fw_cfg: expose control register size in fw_cfg.h

2016-02-10 Thread Gabriel L. Somlo
Expose the size of the control register (FW_CFG_CTL_SIZE) in fw_cfg.h.
Add comment to fw_cfg_io_realize() pointing out that since the
8-bit data register is always subsumed by the 16-bit control
register in the port I/O case, we use the control register width
as the *total* width of the (classic, non-DMA) port I/O region reserved
for the device.

Cc: Marc Marí 
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/nvram/fw_cfg.c | 4 +++-
 include/hw/nvram/fw_cfg.h | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 79c5742..ef2a219 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -32,7 +32,6 @@
 #include "qemu/error-report.h"
 #include "qemu/config-file.h"
 
-#define FW_CFG_CTL_SIZE 2
 #define FW_CFG_NAME "fw_cfg"
 #define FW_CFG_PATH "/machine/" FW_CFG_NAME
 
@@ -882,6 +881,9 @@ static void fw_cfg_io_realize(DeviceState *dev, Error 
**errp)
 FWCfgIoState *s = FW_CFG_IO(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
+/* when using port i/o, the 8-bit data register ALWAYS overlaps
+ * with half of the 16-bit control register. Hence, the total size
+ * of the i/o region used is FW_CFG_CTL_SIZE */
 memory_region_init_io(>comb_iomem, OBJECT(s), _cfg_comb_mem_ops,
   FW_CFG(s), "fwcfg", FW_CFG_CTL_SIZE);
 sysbus_add_io(sbd, s->iobase, >comb_iomem);
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index 664eaf6..2667ca9 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -46,6 +46,9 @@
 
 #define FW_CFG_INVALID  0x
 
+/* width in bytes of fw_cfg control register */
+#define FW_CFG_CTL_SIZE 0x02
+
 #define FW_CFG_MAX_FILE_PATH56
 
 #ifndef NO_QEMU_PROTOS
-- 
2.4.3




[Qemu-devel] [PATCH v7 4/5] acpi: arm: add fw_cfg device node to dsdt

2016-02-10 Thread Gabriel L. Somlo
Add a fw_cfg device node to the ACPI DSDT. This is mostly
informational, as the authoritative fw_cfg MMIO region(s)
are listed in the Device Tree. However, since we are building
ACPI tables, we might as well be thorough while at it...

Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Tested-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/arm/virt-acpi-build.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 8cf9a21..7d7998b 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -81,6 +81,20 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry 
*uart_memmap,
 aml_append(scope, dev);
 }
 
+static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
+{
+Aml *dev = aml_device("FWCF");
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+/* device present, functioning, decoding, not shown in UI */
+aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base,
+   fw_cfg_memmap->size, AML_READ_WRITE));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
 static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
 {
 Aml *dev, *crs;
@@ -548,6 +562,7 @@ build_dsdt(GArray *table_data, GArray *linker, 
VirtGuestInfo *guest_info)
 acpi_dsdt_add_uart(scope, [VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, [VIRT_FLASH]);
+acpi_dsdt_add_fw_cfg(scope, [VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, [VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
 acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
-- 
2.4.3




Re: [Qemu-devel] [PATCH v6 0/5] add ACPI node for fw_cfg on pc and arm

2016-02-10 Thread Gabriel L. Somlo
On Wed, Feb 10, 2016 at 11:16:57AM -0500, Gabriel L. Somlo wrote:
> Ping.
> 
> Now that the kernel side seems to have been accepted (Thanks again
> Laszlo and Matt for all the help and advice!!!), is there anything
> left to clean up before this series could be applied to QEMU ?

Actually, I take that back. I need to rebase the i386 patch (3/5) to
handle PcGuestInfo changes (commits fb306ff and f264d36); but right
now I'm bisecting, trying to figure out why after a giant git pull my
video suddenly stopped working ...

I'll be back soon with v7, stay tuned.

Thanks,
--Gabriel

> 
> gmane.org quick links:
> 1/5: http://article.gmane.org/gmane.comp.emulators.qemu/389896/raw
> 2/5: http://article.gmane.org/gmane.comp.emulators.qemu/389894/raw
> 3/5: http://article.gmane.org/gmane.comp.emulators.qemu/389895/raw
> 4/5: http://article.gmane.org/gmane.comp.emulators.qemu/389900/raw
> 5/5: http://article.gmane.org/gmane.comp.emulators.qemu/389898/raw
> 
> On Wed, Jan 27, 2016 at 10:00:52PM -0500, Gabriel L. Somlo wrote:
> > New since v5:
> > 
> > - rebased on top of latest QEMU git master
> > 
> > Thanks,
> >   --Gabriel
> > 
> > >New since v4:
> > >
> > >   - rebased on top of Marc's DMA series
> > >   - drop machine compat dependency for insertion into x86/ssdt
> > > (patch 3/5), following agreement between Igor and Eduardo
> > >   - [mm]io register range now covers DMA register as well, if
> > > available.
> > >   - s/bios/firmware in doc file updates
> > >
> > >>New since v3:
> > >>
> > >>  - rebased to work on top of 87e896ab (introducing pc-*-25 classes),
> > >>inserting fw_cfg acpi node only for machines >= 2.5.
> > >>
> > >>  - reintroduce _STA with value 0x0B (bit 2 for u/i visibility turned
> > >>off to avoid Windows complaining -- thanks Igor for catching that!)
> > >>
> > >>If there's any other feedback besides questions regarding the
> > >>appropriateness of "QEMU0002" as the value of _HID, please don't hesitate!
> > >>
> > >>>New since v2:
> > >>>
> > >>> - pc/i386 node in ssdt only on machine types *newer* than 2.4
> > >>>   (as suggested by Eduardo)
> > >>>
> > >>>I appreciate any further comments and reviews. Hopefully we can make
> > >>>this palatable for upstream, modulo the lingering concerns about whether
> > >>>"QEMU0002" is ok to use as the value of _HID, which I'll hopefully get
> > >>>sorted out with the kernel crew...
> > >>>
> > >>>>New since v1:
> > >>>>
> > >>>>- expose control register size (suggested by Marc Marí)
> > >>>>
> > >>>>- leaving out _UID and _STA fields (thanks Shannon & Igor)
> > >>>>
> > >>>>- using "QEMU0002" as the value of _HID (thanks Michael)
> > >>>>
> > >>>>- added documentation blurb to docs/specs/fw_cfg.txt
> > >>>>  (mainly to record usage of the "QEMU0002" string with fw_cfg).
> > >>>>
> > >>>>> This series adds a fw_cfg device node to the SSDT (on pc), or to the
> > >>>>> DSDT (on arm).
> > >>>>>
> > >>>>>   - Patch 1/3 moves (and renames) the BIOS_CFG_IOPORT (0x510)
> > >>>>> define from pc.c to pc.h, so that it could be used from
> > >>>>> acpi-build.c in patch 2/3.
> > >>>>> 
> > >>>>>   - Patch 2/3 adds a fw_cfg node to the pc SSDT.
> > >>>>> 
> > >>>>>   - Patch 3/3 adds a fw_cfg node to the arm DSDT.
> > >>>>>
> > >>>>> I made up some names - "FWCF" for the node name, and "FWCF0001"
> > >>>>> for _HID; no idea whether that's appropriate, or how else I should
> > >>>>> figure out what to use instead...
> > >>>>>
> > >>>>> Also, using scope "\\_SB", based on where fw_cfg shows up in the
> > >>>>> output of "info qtree". Again, if that's wrong, please point me in
> > >>>>> the right direction.
> > >>>>>
> > >>>>> Re. 3/3 (also mentioned after the commit blurb in the patch itself),
> > >>>>> I noticed none of the other DSDT entries contain a _STA field, 
> > >>>>> wondering
> > >>>>> why it would (not) make sense to include that, same as on the PC.
> > 
> > Gabriel L. Somlo (5):
> >   fw_cfg: expose control register size in fw_cfg.h
> >   pc: fw_cfg: move ioport base constant to pc.h
> >   acpi: pc: add fw_cfg device node to ssdt
> >   acpi: arm: add fw_cfg device node to dsdt
> >   fw_cfg: document ACPI device node information
> > 
> >  docs/specs/fw_cfg.txt |  9 +
> >  hw/arm/virt-acpi-build.c  | 15 +++
> >  hw/i386/acpi-build.c  | 29 +
> >  hw/i386/pc.c  |  5 ++---
> >  hw/nvram/fw_cfg.c |  4 +++-
> >  include/hw/i386/pc.h  |  2 ++
> >  include/hw/nvram/fw_cfg.h |  3 +++
> >  7 files changed, 63 insertions(+), 4 deletions(-)
> > 
> > -- 
> > 2.4.3
> > 



Re: [Qemu-devel] [PATCH v8 2/4] kobject: export kset_find_obj() for module use

2016-02-07 Thread Gabriel L. Somlo
On Sat, Feb 06, 2016 at 11:24:23PM -0800, Greg KH wrote:
> On Thu, Jan 28, 2016 at 09:23:12AM -0500, Gabriel L. Somlo wrote:
> > From: Gabriel Somlo <so...@cmu.edu>
> > 
> > Signed-off-by: Gabriel Somlo <so...@cmu.edu>
> > ---
> >  lib/kobject.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/lib/kobject.c b/lib/kobject.c
> > index 7cbccd2..90d1be6 100644
> > --- a/lib/kobject.c
> > +++ b/lib/kobject.c
> > @@ -861,6 +861,7 @@ struct kobject *kset_find_obj(struct kset *kset, const 
> > char *name)
> > spin_unlock(>list_lock);
> > return ret;
> >  }
> > +EXPORT_SYMBOL(kset_find_obj);
> 
> EXPORT_SYMBOL_GPL() please here.  I'll edit it by hand if you don't want
> to resend the series.

If you don't mind editing, that'd be much appreciated!

I'll make sure and remember to use EXPORT_SYMBOL_GPL() for the next
chance I get... :)

Thanks much,
--Gabriel

> 
> thanks.
> 
> greg k-h



[Qemu-devel] [PATCH v8 2/4] kobject: export kset_find_obj() for module use

2016-01-28 Thread Gabriel L. Somlo
From: Gabriel Somlo 

Signed-off-by: Gabriel Somlo 
---
 lib/kobject.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/kobject.c b/lib/kobject.c
index 7cbccd2..90d1be6 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -861,6 +861,7 @@ struct kobject *kset_find_obj(struct kset *kset, const char 
*name)
spin_unlock(>list_lock);
return ret;
 }
+EXPORT_SYMBOL(kset_find_obj);
 
 static void kset_release(struct kobject *kobj)
 {
-- 
2.4.3




[Qemu-devel] [PATCH v8 3/4] firmware: create directory hierarchy for sysfs fw_cfg entries

2016-01-28 Thread Gabriel L. Somlo
From: Gabriel Somlo 

Each fw_cfg entry of type "file" has an associated 56-char,
nul-terminated ASCII string which represents its name. While
the fw_cfg device doesn't itself impose any specific naming
convention, QEMU developers have traditionally used path name
semantics (i.e. "etc/acpi/rsdp") to descriptively name the
various fw_cfg "blobs" passed into the guest.

This patch attempts, on a best effort basis, to create a
directory hierarchy representing the content of fw_cfg file
names, under /sys/firmware/qemu_fw_cfg/by_name.

Upon successful creation of all directories representing the
"dirname" portion of a fw_cfg file, a symlink will be created
to represent the "basename", pointing at the appropriate
/sys/firmware/qemu_fw_cfg/by_key entry. If a file name is not
suitable for this procedure (e.g., if its basename or dirname
components collide with an already existing dirname component
or basename, respectively) the corresponding fw_cfg blob is
skipped and will remain available in sysfs only by its selector
key value.

Signed-off-by: Gabriel Somlo 
Cc: Andy Lutomirski 
---
 .../ABI/testing/sysfs-firmware-qemu_fw_cfg |  42 
 drivers/firmware/qemu_fw_cfg.c | 109 -
 2 files changed, 148 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg 
b/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
index e9e58d4..011dda4 100644
--- a/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
+++ b/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
@@ -56,3 +56,45 @@ Description:
  entry via the control register, and reading a number
  of bytes equal to the blob size from the data
  register.
+
+   --- Listing fw_cfg blobs by file name ---
+
+   While the fw_cfg device does not impose any specific naming
+   convention on the blobs registered in the file directory,
+   QEMU developers have traditionally used path name semantics
+   to give each blob a descriptive name. For example:
+
+   "bootorder"
+   "genroms/kvmvapic.bin"
+   "etc/e820"
+   "etc/boot-fail-wait"
+   "etc/system-states"
+   "etc/table-loader"
+   "etc/acpi/rsdp"
+   "etc/acpi/tables"
+   "etc/smbios/smbios-tables"
+   "etc/smbios/smbios-anchor"
+   ...
+
+   In addition to the listing by unique selector key described
+   above, the fw_cfg sysfs driver also attempts to build a tree
+   of directories matching the path name components of fw_cfg
+   blob names, ending in symlinks to the by_key entry for each
+   "basename", as illustrated below (assume current directory is
+   /sys/firmware):
+
+   qemu_fw_cfg/by_name/bootorder -> ../by_key/38
+   qemu_fw_cfg/by_name/etc/e820 -> ../../by_key/35
+   qemu_fw_cfg/by_name/etc/acpi/rsdp -> ../../../by_key/41
+   ...
+
+   Construction of the directory tree and symlinks is done on a
+   "best-effort" basis, as there is no guarantee that components
+   of fw_cfg blob names are always "well behaved". I.e., there is
+   the possibility that a symlink (basename) will conflict with
+   a dirname component of another fw_cfg blob, in which case the
+   creation of the offending /sys/firmware/qemu_fw_cfg/by_name
+   entry will be skipped.
+
+   The authoritative list of entries will continue to be found
+   under the /sys/firmware/qemu_fw_cfg/by_key directory.
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
index 83e8a5c..19f6851 100644
--- a/drivers/firmware/qemu_fw_cfg.c
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -334,9 +334,103 @@ static struct bin_attribute fw_cfg_sysfs_attr_raw = {
.read = fw_cfg_sysfs_read_raw,
 };
 
-/* kobjects representing top-level and by_key folders */
+/*
+ * Create a kset subdirectory matching each '/' delimited dirname token
+ * in 'name', starting with sysfs kset/folder 'dir'; At the end, create
+ * a symlink directed at the given 'target'.
+ * NOTE: We do this on a best-effort basis, since 'name' is not guaranteed
+ * to be a well-behaved path name. Whenever a symlink vs. kset directory
+ * name collision occurs, the kernel will issue big scary warnings while
+ * refusing to add the offending link or directory. We follow up with our
+ * own, slightly less scary error messages explaining the situation :)
+ */
+static int fw_cfg_build_symlink(struct kset *dir,
+   struct kobject *target, 

[Qemu-devel] [PATCH v8 1/4] firmware: introduce sysfs driver for QEMU's fw_cfg device

2016-01-28 Thread Gabriel L. Somlo
 and loaded.
+
+config FW_CFG_SYSFS_CMDLINE
+   bool "QEMU fw_cfg device parameter parsing"
+   depends on FW_CFG_SYSFS
+   help
+ Allow the qemu_fw_cfg device to be initialized via the kernel
+ command line or using a module parameter.
+ WARNING: Using incorrect parameters (base address in particular)
+ may crash your system.
+
 config QCOM_SCM
bool
depends on ARM || ARM64
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 48dd417..474bada 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)   += iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)  += memmap.o
 obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
+obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
 obj-$(CONFIG_QCOM_SCM) += qcom_scm.o
 obj-$(CONFIG_QCOM_SCM_64)  += qcom_scm-64.o
 obj-$(CONFIG_QCOM_SCM_32)  += qcom_scm-32.o
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
new file mode 100644
index 000..83e8a5c
--- /dev/null
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -0,0 +1,648 @@
+/*
+ * drivers/firmware/qemu_fw_cfg.c
+ *
+ * Copyright 2015 Carnegie Mellon University
+ *
+ * Expose entries from QEMU's firmware configuration (fw_cfg) device in
+ * sysfs (read-only, under "/sys/firmware/qemu_fw_cfg/...").
+ *
+ * The fw_cfg device may be instantiated via either an ACPI node (on x86
+ * and select subsets of aarch64), a Device Tree node (on arm), or using
+ * a kernel module (or command line) parameter with the following syntax:
+ *
+ *  [fw_cfg.]ioport=@[::]
+ * or
+ *  [fw_cfg.]mmio=@[::]
+ *
+ * where:
+ *   := size of ioport or mmio range
+ *   := physical base address of ioport or mmio range
+ *   := (optional) offset of control register
+ *   := (optional) offset of data register
+ *
+ * e.g.:
+ *  fw_cfg.ioport=2@0x510:0:1  (the default on x86)
+ * or
+ *  fw_cfg.mmio=0xA@0x902:8:0  (the default on arm)
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+MODULE_AUTHOR("Gabriel L. Somlo <so...@cmu.edu>");
+MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
+MODULE_LICENSE("GPL");
+
+/* selector key values for "well-known" fw_cfg entries */
+#define FW_CFG_SIGNATURE  0x00
+#define FW_CFG_ID 0x01
+#define FW_CFG_FILE_DIR   0x19
+
+/* size in bytes of fw_cfg signature */
+#define FW_CFG_SIG_SIZE 4
+
+/* fw_cfg "file name" is up to 56 characters (including terminating nul) */
+#define FW_CFG_MAX_FILE_PATH 56
+
+/* fw_cfg file directory entry type */
+struct fw_cfg_file {
+   u32 size;
+   u16 select;
+   u16 reserved;
+   char name[FW_CFG_MAX_FILE_PATH];
+};
+
+/* fw_cfg device i/o register addresses */
+static bool fw_cfg_is_mmio;
+static phys_addr_t fw_cfg_p_base;
+static resource_size_t fw_cfg_p_size;
+static void __iomem *fw_cfg_dev_base;
+static void __iomem *fw_cfg_reg_ctrl;
+static void __iomem *fw_cfg_reg_data;
+
+/* atomic access to fw_cfg device (potentially slow i/o, so using mutex) */
+static DEFINE_MUTEX(fw_cfg_dev_lock);
+
+/* pick appropriate endianness for selector key */
+static inline u16 fw_cfg_sel_endianness(u16 key)
+{
+   return fw_cfg_is_mmio ? cpu_to_be16(key) : cpu_to_le16(key);
+}
+
+/* read chunk of given fw_cfg blob (caller responsible for sanity-check) */
+static inline void fw_cfg_read_blob(u16 key,
+   void *buf, loff_t pos, size_t count)
+{
+   mutex_lock(_cfg_dev_lock);
+   iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl);
+   while (pos-- > 0)
+   ioread8(fw_cfg_reg_data);
+   ioread8_rep(fw_cfg_reg_data, buf, count);
+   mutex_unlock(_cfg_dev_lock);
+}
+
+/* clean up fw_cfg device i/o */
+static void fw_cfg_io_cleanup(void)
+{
+   if (fw_cfg_is_mmio) {
+   iounmap(fw_cfg_dev_base);
+   release_mem_region(fw_cfg_p_base, fw_cfg_p_size);
+   } else {
+   ioport_unmap(fw_cfg_dev_base);
+   release_region(fw_cfg_p_base, fw_cfg_p_size);
+   }
+}
+
+/* arch-specific ctrl & data register offsets are not available in ACPI, DT */
+#if !(defined(FW_CFG_CTRL_OFF) && defined(FW_CTRL_DATA_OFF))
+# if (defined(CONFIG_ARM) || defined(CONFIG_ARM64))
+#  define FW_CFG_CTRL_OFF 0x08
+#  define FW_CFG_DATA_OFF 0x00
+# elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* ppc/mac,sun4m 
*/
+#  define FW_CFG_CTRL_OFF 0x00
+#  define FW_CFG_DATA_OFF 0x02
+# elif (defined(CONFIG_X86) || defined(CONFIG_SPARC64)) /* x86, sun4u */
+#  define FW_CFG_CTRL_OFF 0x00
+#  define FW_CFG_DATA_OFF 0x01
+# else
+#  warning "QEMU FW_CFG may not be available on this architecture!"
+#  define FW_CFG_CTRL_OFF 0x00
+#  define FW_CFG_DATA_OFF 0x01
+# endif
+#endif
+
+/* in

[Qemu-devel] [PATCH v8 0/4] SysFS driver for QEMU fw_cfg device

2016-01-28 Thread Gabriel L. Somlo
From: "Gabriel Somlo" 

Allow access to QEMU firmware blobs, passed into the guest VM via
the fw_cfg device, through SysFS entries. Blob meta-data (e.g. name,
size, and fw_cfg key), as well as the raw binary blob data may be
accessed.

The SysFS access location is /sys/firmware/qemu_fw_cfg/... and was
selected based on overall similarity to the type of information
exposed under /sys/firmware/dmi/entries/...

This functionality is primarily intended to serve as a host->guest
configuration data transfer mechanism that is both:

- asynchronous: the host doesn't need to wait for the guest
to be ready to accept data (e.g., by starting
an agent daemon)

- out-of-band:  there is no need to commandeer a guest element
normally visible and available to the guest user
(e.g., kernel cmdline, mounting floppy/cdrom, etc.)

QEMU now allows arbitrary fw_cfg blobs to be added via the command line,
so it would be nice to make them easy to retrieve from within the guest
OS, and the niceset and easiest way I can think of is

cat /sys/firmware/qemu-fw-cfg/...//raw

New since v7:

- kbuild testbot complained about a warning on ia64, so limit
  the availability of fw_cfg in Kconfig to only architectures
  on which QEMU makes it available, which include:

(ARM || ARM64 || PPC_PMAC || SPARC || X86)

Thanks,
  --Gabriel

>New since v6:
>
>   - added architecture-specific default values for fw_cfg register
> offsets: DT and/or ACPI will only give us the base address and
> total size of the fw_cfg register set, but not individual register
> offsets *within* this total extent. The specific offsets are
> different across architectures, and this version adds #defines
> so that reasonable defaults can be used on each supported platform.
>
>>New since v5:
>>
>>  - fixed typos in documentation files (Patches 1/4 and 4/4
>>
>>  - printf/scanf type modifier for phys_addr_t now matches
>>arch-specific width (u32 vs. u64), avoiding compiler warnings.
>>(tested on i386 with and without PAE, and on armv7hl with and
>> without lpae -- the latter pair took quite a while on an
>> emulated QEMU guest :) )
>>
>>>New since v4:
>>>
>>> Documentation (Patches 1/4 and 4/4) now points to the authoritative
>>> file in the QEMU source tree for any details related to the "hardware
>>> interface" of the fw_cfg device; Only details specific to sysfs (1/4) 
>>> and DT (4/4) should stay in the kernel docs.
>>>
New (since v3):

Patch 1/4: Device probing now works with either ACPI, DT, or
   optionally by manually specifying a base, size, and
   register offsets on the command line. This way, all
   architectures offering fw_cfg can be supported, although
   x86 and ARM get *automatic* support via ACPI and/or DT.

   HUGE thanks to Laszlo Ersek  for
   pointing out drivers/virtio/virtio_mmio.c, as an example
   on how to pull this off !!!

   Stefan: I saw Marc's DMA patches to fw_cfg. Since only
   x86 and ARM will support it starting with QEMU 2.5, and
   since I expect to get lots of otherwise interesting (but
   otherwise orthogonal) feedback on this series, I'd like
   to stick with ioread8() across the board for now. We can
   always patch in DMA support in a backward compatible way
   later, once this series gets (hopefully) accepted :)

Patch 2/4: (was 3/4 in v3): unchanged. Exports kset_find_obj() so
   modules can call it.

Patch 3/4: (was 4/4 in v3): rebased, but otherwise the same.
   Essentially, creates a "human readable" directory
   hierarchy from "path-like" tokens making up fw_cfg
   blob names. I'm not really sure there's a way to make
   this happen via udev rules, but I have at least one
   potential use case for doing it *before* udev becomes
   available (cc: Andy Lutomirski ),
   so I'd be happy to leave this functionality in the
   kernel module. See further below for an illustration
   of this.

Patch 4/4: Updates the existing ARM DT documentation for fw_cfg,
   mainly by pointing at the more comprehensive document
   introduced with Patch 1/4 for details on the fw_cfg
   device interface, leaving only the specific ARM/DT
   address/size node information in place.

>  In addition to the "by_key" blob listing, e.g.:
>  

[Qemu-devel] [PATCH v8 4/4] devicetree: update documentation for fw_cfg ARM bindings

2016-01-28 Thread Gabriel L. Somlo
From: Gabriel Somlo 

Remove fw_cfg hardware interface details from
Documentation/devicetree/bindings/arm/fw-cfg.txt,
and replace them with a pointer to the authoritative
documentation in the QEMU source tree.

Signed-off-by: Gabriel Somlo 
Cc: Laszlo Ersek 
Acked-by: Rob Herring 
Reviewed-by: Laszlo Ersek 
---
 Documentation/devicetree/bindings/arm/fw-cfg.txt | 38 ++--
 1 file changed, 2 insertions(+), 36 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/fw-cfg.txt 
b/Documentation/devicetree/bindings/arm/fw-cfg.txt
index 953fb64..fd54e1d 100644
--- a/Documentation/devicetree/bindings/arm/fw-cfg.txt
+++ b/Documentation/devicetree/bindings/arm/fw-cfg.txt
@@ -11,43 +11,9 @@ QEMU exposes the control and data register to ARM guests as 
memory mapped
 registers; their location is communicated to the guest's UEFI firmware in the
 DTB that QEMU places at the bottom of the guest's DRAM.
 
-The guest writes a selector value (a key) to the selector register, and then
-can read the corresponding data (produced by QEMU) via the data register. If
-the selected entry is writable, the guest can rewrite it through the data
-register.
+The authoritative guest-side hardware interface documentation to the fw_cfg
+device can be found in "docs/specs/fw_cfg.txt" in the QEMU source tree.
 
-The selector register takes keys in big endian byte order.
-
-The data register allows accesses with 8, 16, 32 and 64-bit width (only at
-offset 0 of the register). Accesses larger than a byte are interpreted as
-arrays, bundled together only for better performance. The bytes constituting
-such a word, in increasing address order, correspond to the bytes that would
-have been transferred by byte-wide accesses in chronological order.
-
-The interface allows guest firmware to download various parameters and blobs
-that affect how the firmware works and what tables it installs for the guest
-OS. For example, boot order of devices, ACPI tables, SMBIOS tables, kernel and
-initrd images for direct kernel booting, virtual machine UUID, SMP information,
-virtual NUMA topology, and so on.
-
-The authoritative registry of the valid selector values and their meanings is
-the QEMU source code; the structure of the data blobs corresponding to the
-individual key values is also defined in the QEMU source code.
-
-The presence of the registers can be verified by selecting the "signature" blob
-with key 0x, and reading four bytes from the data register. The returned
-signature is "QEMU".
-
-The outermost protocol (involving the write / read sequences of the control and
-data registers) is expected to be versioned, and/or described by feature bits.
-The interface revision / feature bitmap can be retrieved with key 0x0001. The
-blob to be read from the data register has size 4, and it is to be interpreted
-as a uint32_t value in little endian byte order. The current value
-(corresponding to the above outer protocol) is zero.
-
-The guest kernel is not expected to use these registers (although it is
-certainly allowed to); the device tree bindings are documented here because
-this is where device tree bindings reside in general.
 
 Required properties:
 
-- 
2.4.3




[Qemu-devel] [PATCH v6 4/5] acpi: arm: add fw_cfg device node to dsdt

2016-01-27 Thread Gabriel L. Somlo
Add a fw_cfg device node to the ACPI DSDT. This is mostly
informational, as the authoritative fw_cfg MMIO region(s)
are listed in the Device Tree. However, since we are building
ACPI tables, we might as well be thorough while at it...

Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Tested-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/arm/virt-acpi-build.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 87fbe7c..20bbdf2 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -95,6 +95,20 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry 
*uart_memmap,
 aml_append(scope, dev);
 }
 
+static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
+{
+Aml *dev = aml_device("FWCF");
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+/* device present, functioning, decoding, not shown in UI */
+aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+
+Aml *crs = aml_resource_template();
+aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base,
+   fw_cfg_memmap->size, AML_READ_WRITE));
+aml_append(dev, aml_name_decl("_CRS", crs));
+aml_append(scope, dev);
+}
+
 static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
 {
 Aml *dev, *crs;
@@ -565,6 +579,7 @@ build_dsdt(GArray *table_data, GArray *linker, 
VirtGuestInfo *guest_info)
 acpi_dsdt_add_uart(scope, [VIRT_UART],
(irqmap[VIRT_UART] + ARM_SPI_BASE));
 acpi_dsdt_add_flash(scope, [VIRT_FLASH]);
+acpi_dsdt_add_fw_cfg(scope, [VIRT_FW_CFG]);
 acpi_dsdt_add_virtio(scope, [VIRT_MMIO],
 (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
 acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
-- 
2.4.3




[Qemu-devel] [PATCH v6 5/5] fw_cfg: document ACPI device node information

2016-01-27 Thread Gabriel L. Somlo
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 docs/specs/fw_cfg.txt | 9 +
 1 file changed, 9 insertions(+)

diff --git a/docs/specs/fw_cfg.txt b/docs/specs/fw_cfg.txt
index 2099ad9..5414140 100644
--- a/docs/specs/fw_cfg.txt
+++ b/docs/specs/fw_cfg.txt
@@ -84,6 +84,15 @@ Selector Register address: Base + 8 (2 bytes)
 Data Register address: Base + 0 (8 bytes)
 DMA Address address:   Base + 16 (8 bytes)
 
+== ACPI Interface ==
+
+The fw_cfg device is defined with ACPI ID "QEMU0002". Since we expect
+ACPI tables to be passed into the guest through the fw_cfg device itself,
+the guest-side firmware can not use ACPI to find fw_cfg. However, once the
+firmware is finished setting up ACPI tables and hands control over to the
+guest kernel, the latter can use the fw_cfg ACPI node for a more accurate
+inventory of in-use IOport or MMIO regions.
+
 == Firmware Configuration Items ==
 
 === Signature (Key 0x, FW_CFG_SIGNATURE) ===
-- 
2.4.3




[Qemu-devel] [PATCH v6 0/5] add ACPI node for fw_cfg on pc and arm

2016-01-27 Thread Gabriel L. Somlo
New since v5:

- rebased on top of latest QEMU git master

Thanks,
  --Gabriel

>New since v4:
>
>   - rebased on top of Marc's DMA series
>   - drop machine compat dependency for insertion into x86/ssdt
> (patch 3/5), following agreement between Igor and Eduardo
>   - [mm]io register range now covers DMA register as well, if
> available.
>   - s/bios/firmware in doc file updates
>
>>New since v3:
>>
>>  - rebased to work on top of 87e896ab (introducing pc-*-25 classes),
>>inserting fw_cfg acpi node only for machines >= 2.5.
>>
>>  - reintroduce _STA with value 0x0B (bit 2 for u/i visibility turned
>>off to avoid Windows complaining -- thanks Igor for catching that!)
>>
>>If there's any other feedback besides questions regarding the
>>appropriateness of "QEMU0002" as the value of _HID, please don't hesitate!
>>
>>>New since v2:
>>>
>>> - pc/i386 node in ssdt only on machine types *newer* than 2.4
>>>   (as suggested by Eduardo)
>>>
>>>I appreciate any further comments and reviews. Hopefully we can make
>>>this palatable for upstream, modulo the lingering concerns about whether
>>>"QEMU0002" is ok to use as the value of _HID, which I'll hopefully get
>>>sorted out with the kernel crew...
>>>
>>>>New since v1:
>>>>
>>>>- expose control register size (suggested by Marc Marí)
>>>>
>>>>- leaving out _UID and _STA fields (thanks Shannon & Igor)
>>>>
>>>>- using "QEMU0002" as the value of _HID (thanks Michael)
>>>>
>>>>- added documentation blurb to docs/specs/fw_cfg.txt
>>>>  (mainly to record usage of the "QEMU0002" string with fw_cfg).
>>>>
>>>>> This series adds a fw_cfg device node to the SSDT (on pc), or to the
>>>>> DSDT (on arm).
>>>>>
>>>>>   - Patch 1/3 moves (and renames) the BIOS_CFG_IOPORT (0x510)
>>>>> define from pc.c to pc.h, so that it could be used from
>>>>> acpi-build.c in patch 2/3.
>>>>> 
>>>>>   - Patch 2/3 adds a fw_cfg node to the pc SSDT.
>>>>> 
>>>>>   - Patch 3/3 adds a fw_cfg node to the arm DSDT.
>>>>>
>>>>> I made up some names - "FWCF" for the node name, and "FWCF0001"
>>>>> for _HID; no idea whether that's appropriate, or how else I should
>>>>> figure out what to use instead...
>>>>>
>>>>> Also, using scope "\\_SB", based on where fw_cfg shows up in the
>>>>> output of "info qtree". Again, if that's wrong, please point me in
>>>>> the right direction.
>>>>>
>>>>> Re. 3/3 (also mentioned after the commit blurb in the patch itself),
>>>>> I noticed none of the other DSDT entries contain a _STA field, wondering
>>>>> why it would (not) make sense to include that, same as on the PC.

Gabriel L. Somlo (5):
  fw_cfg: expose control register size in fw_cfg.h
  pc: fw_cfg: move ioport base constant to pc.h
  acpi: pc: add fw_cfg device node to ssdt
  acpi: arm: add fw_cfg device node to dsdt
  fw_cfg: document ACPI device node information

 docs/specs/fw_cfg.txt |  9 +
 hw/arm/virt-acpi-build.c  | 15 +++
 hw/i386/acpi-build.c  | 29 +
 hw/i386/pc.c  |  5 ++---
 hw/nvram/fw_cfg.c |  4 +++-
 include/hw/i386/pc.h  |  2 ++
 include/hw/nvram/fw_cfg.h |  3 +++
 7 files changed, 63 insertions(+), 4 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v6 1/5] fw_cfg: expose control register size in fw_cfg.h

2016-01-27 Thread Gabriel L. Somlo
Expose the size of the control register (FW_CFG_CTL_SIZE) in fw_cfg.h.
Add comment to fw_cfg_io_realize() pointing out that since the
8-bit data register is always subsumed by the 16-bit control
register in the port I/O case, we use the control register width
as the *total* width of the (classic, non-DMA) port I/O region reserved
for the device.

Cc: Marc Marí 
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/nvram/fw_cfg.c | 4 +++-
 include/hw/nvram/fw_cfg.h | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index a1d650d..06a4ff0 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -31,7 +31,6 @@
 #include "qemu/error-report.h"
 #include "qemu/config-file.h"
 
-#define FW_CFG_CTL_SIZE 2
 #define FW_CFG_NAME "fw_cfg"
 #define FW_CFG_PATH "/machine/" FW_CFG_NAME
 
@@ -881,6 +880,9 @@ static void fw_cfg_io_realize(DeviceState *dev, Error 
**errp)
 FWCfgIoState *s = FW_CFG_IO(dev);
 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
 
+/* when using port i/o, the 8-bit data register ALWAYS overlaps
+ * with half of the 16-bit control register. Hence, the total size
+ * of the i/o region used is FW_CFG_CTL_SIZE */
 memory_region_init_io(>comb_iomem, OBJECT(s), _cfg_comb_mem_ops,
   FW_CFG(s), "fwcfg", FW_CFG_CTL_SIZE);
 sysbus_add_io(sbd, s->iobase, >comb_iomem);
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index 664eaf6..2667ca9 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -46,6 +46,9 @@
 
 #define FW_CFG_INVALID  0x
 
+/* width in bytes of fw_cfg control register */
+#define FW_CFG_CTL_SIZE 0x02
+
 #define FW_CFG_MAX_FILE_PATH56
 
 #ifndef NO_QEMU_PROTOS
-- 
2.4.3




[Qemu-devel] [PATCH v6 0/5] add ACPI node for fw_cfg on pc and arm

2016-01-27 Thread Gabriel L. Somlo
New since v5:

- rebased on top of latest QEMU git master

Thanks,
  --Gabriel

>New since v4:
>
>   - rebased on top of Marc's DMA series
>   - drop machine compat dependency for insertion into x86/ssdt
> (patch 3/5), following agreement between Igor and Eduardo
>   - [mm]io register range now covers DMA register as well, if
> available.
>   - s/bios/firmware in doc file updates
>
>>New since v3:
>>
>>  - rebased to work on top of 87e896ab (introducing pc-*-25 classes),
>>inserting fw_cfg acpi node only for machines >= 2.5.
>>
>>  - reintroduce _STA with value 0x0B (bit 2 for u/i visibility turned
>>off to avoid Windows complaining -- thanks Igor for catching that!)
>>
>>If there's any other feedback besides questions regarding the
>>appropriateness of "QEMU0002" as the value of _HID, please don't hesitate!
>>
>>>New since v2:
>>>
>>> - pc/i386 node in ssdt only on machine types *newer* than 2.4
>>>   (as suggested by Eduardo)
>>>
>>>I appreciate any further comments and reviews. Hopefully we can make
>>>this palatable for upstream, modulo the lingering concerns about whether
>>>"QEMU0002" is ok to use as the value of _HID, which I'll hopefully get
>>>sorted out with the kernel crew...
>>>
>>>>New since v1:
>>>>
>>>>- expose control register size (suggested by Marc Marí)
>>>>
>>>>- leaving out _UID and _STA fields (thanks Shannon & Igor)
>>>>
>>>>- using "QEMU0002" as the value of _HID (thanks Michael)
>>>>
>>>>- added documentation blurb to docs/specs/fw_cfg.txt
>>>>  (mainly to record usage of the "QEMU0002" string with fw_cfg).
>>>>
>>>>> This series adds a fw_cfg device node to the SSDT (on pc), or to the
>>>>> DSDT (on arm).
>>>>>
>>>>>   - Patch 1/3 moves (and renames) the BIOS_CFG_IOPORT (0x510)
>>>>> define from pc.c to pc.h, so that it could be used from
>>>>> acpi-build.c in patch 2/3.
>>>>> 
>>>>>   - Patch 2/3 adds a fw_cfg node to the pc SSDT.
>>>>> 
>>>>>   - Patch 3/3 adds a fw_cfg node to the arm DSDT.
>>>>>
>>>>> I made up some names - "FWCF" for the node name, and "FWCF0001"
>>>>> for _HID; no idea whether that's appropriate, or how else I should
>>>>> figure out what to use instead...
>>>>>
>>>>> Also, using scope "\\_SB", based on where fw_cfg shows up in the
>>>>> output of "info qtree". Again, if that's wrong, please point me in
>>>>> the right direction.
>>>>>
>>>>> Re. 3/3 (also mentioned after the commit blurb in the patch itself),
>>>>> I noticed none of the other DSDT entries contain a _STA field, wondering
>>>>> why it would (not) make sense to include that, same as on the PC.

Gabriel L. Somlo (5):
  fw_cfg: expose control register size in fw_cfg.h
  pc: fw_cfg: move ioport base constant to pc.h
  acpi: pc: add fw_cfg device node to ssdt
  acpi: arm: add fw_cfg device node to dsdt
  fw_cfg: document ACPI device node information

 docs/specs/fw_cfg.txt |  9 +
 hw/arm/virt-acpi-build.c  | 15 +++
 hw/i386/acpi-build.c  | 29 +
 hw/i386/pc.c  |  5 ++---
 hw/nvram/fw_cfg.c |  4 +++-
 include/hw/i386/pc.h  |  2 ++
 include/hw/nvram/fw_cfg.h |  3 +++
 7 files changed, 63 insertions(+), 4 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH v6 3/5] acpi: pc: add fw_cfg device node to ssdt

2016-01-27 Thread Gabriel L. Somlo
Add a fw_cfg device node to the ACPI SSDT. While the guest-side
firmware can't utilize this information (since it has to access
the hard-coded fw_cfg device to extract ACPI tables to begin with),
having fw_cfg listed in ACPI will help the guest kernel keep a more
accurate inventory of in-use IO port regions.

Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/i386/acpi-build.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 78758e2..8a9ae9d 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -2100,6 +2100,35 @@ build_ssdt(GArray *table_data, GArray *linker,
 aml_append(scope, aml_name_decl("_S5", pkg));
 aml_append(ssdt, scope);
 
+/* create fw_cfg node, unconditionally */
+{
+/* when using port i/o, the 8-bit data register *always* overlaps
+ * with half of the 16-bit control register. Hence, the total size
+ * of the i/o region used is FW_CFG_CTL_SIZE; when using DMA, the
+ * DMA control register is located at FW_CFG_DMA_IO_BASE + 4 */
+uint8_t io_size = object_property_get_bool(OBJECT(guest_info->fw_cfg),
+   "dma_enabled", NULL) ?
+  ROUND_UP(FW_CFG_CTL_SIZE, 4) + sizeof(dma_addr_t) :
+  FW_CFG_CTL_SIZE;
+
+scope = aml_scope("\\_SB");
+dev = aml_device("FWCF");
+
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
+
+/* device present, functioning, decoding, not shown in UI */
+aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
+
+crs = aml_resource_template();
+aml_append(crs,
+aml_io(AML_DECODE16, FW_CFG_IO_BASE, FW_CFG_IO_BASE, 0x01, io_size)
+);
+aml_append(dev, aml_name_decl("_CRS", crs));
+
+aml_append(scope, dev);
+aml_append(ssdt, scope);
+}
+
 if (misc->applesmc_io_base) {
 scope = aml_scope("\\_SB.PCI0.ISA");
 dev = aml_device("SMC");
-- 
2.4.3




[Qemu-devel] [PATCH v6 2/5] pc: fw_cfg: move ioport base constant to pc.h

2016-01-27 Thread Gabriel L. Somlo
Move BIOS_CFG_IOPORT define from pc.c to pc.h, and rename
it to FW_CFG_IO_BASE.

Cc: Marc Marí 
Signed-off-by: Gabriel Somlo 
Reviewed-by: Laszlo Ersek 
Reviewed-by: Marc Marí 
---
 hw/i386/pc.c | 5 ++---
 include/hw/i386/pc.h | 2 ++
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 78cf8fa..aa79dd1 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -77,7 +77,6 @@
 #define DPRINTF(fmt, ...)
 #endif
 
-#define BIOS_CFG_IOPORT 0x510
 #define FW_CFG_ACPI_TABLES (FW_CFG_ARCH_LOCAL + 0)
 #define FW_CFG_SMBIOS_ENTRIES (FW_CFG_ARCH_LOCAL + 1)
 #define FW_CFG_IRQ0_OVERRIDE (FW_CFG_ARCH_LOCAL + 2)
@@ -755,7 +754,7 @@ static FWCfgState *bochs_bios_init(AddressSpace *as)
 int i, j;
 unsigned int apic_id_limit = pc_apic_id_limit(max_cpus);
 
-fw_cfg = fw_cfg_init_io_dma(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 4, as);
+fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4, as);
 
 /* FW_CFG_MAX_CPUS is a bit confusing/problematic on x86:
  *
@@ -1269,7 +1268,7 @@ FWCfgState *xen_load_linux(PCMachineState *pcms,
 
 assert(MACHINE(pcms)->kernel_filename != NULL);
 
-fw_cfg = fw_cfg_init_io(BIOS_CFG_IOPORT);
+fw_cfg = fw_cfg_init_io(FW_CFG_IO_BASE);
 rom_set_fw(fw_cfg);
 
 load_linux(pcms, fw_cfg);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 65e8f24..0a4e0da 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -272,6 +272,8 @@ void ioapic_init_gsi(GSIState *gsi_state, const char 
*parent_name);
 
 ISADevice *pc_find_fdc0(void);
 
+#define FW_CFG_IO_BASE 0x510
+
 /* acpi_piix.c */
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
-- 
2.4.3




[Qemu-devel] [PATCH v7 3/4] firmware: create directory hierarchy for sysfs fw_cfg entries

2016-01-27 Thread Gabriel L. Somlo
From: Gabriel Somlo 

Each fw_cfg entry of type "file" has an associated 56-char,
nul-terminated ASCII string which represents its name. While
the fw_cfg device doesn't itself impose any specific naming
convention, QEMU developers have traditionally used path name
semantics (i.e. "etc/acpi/rsdp") to descriptively name the
various fw_cfg "blobs" passed into the guest.

This patch attempts, on a best effort basis, to create a
directory hierarchy representing the content of fw_cfg file
names, under /sys/firmware/qemu_fw_cfg/by_name.

Upon successful creation of all directories representing the
"dirname" portion of a fw_cfg file, a symlink will be created
to represent the "basename", pointing at the appropriate
/sys/firmware/qemu_fw_cfg/by_key entry. If a file name is not
suitable for this procedure (e.g., if its basename or dirname
components collide with an already existing dirname component
or basename, respectively) the corresponding fw_cfg blob is
skipped and will remain available in sysfs only by its selector
key value.

Signed-off-by: Gabriel Somlo 
Cc: Andy Lutomirski 
---
 .../ABI/testing/sysfs-firmware-qemu_fw_cfg |  42 
 drivers/firmware/qemu_fw_cfg.c | 109 -
 2 files changed, 148 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg 
b/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
index e9e58d4..011dda4 100644
--- a/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
+++ b/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
@@ -56,3 +56,45 @@ Description:
  entry via the control register, and reading a number
  of bytes equal to the blob size from the data
  register.
+
+   --- Listing fw_cfg blobs by file name ---
+
+   While the fw_cfg device does not impose any specific naming
+   convention on the blobs registered in the file directory,
+   QEMU developers have traditionally used path name semantics
+   to give each blob a descriptive name. For example:
+
+   "bootorder"
+   "genroms/kvmvapic.bin"
+   "etc/e820"
+   "etc/boot-fail-wait"
+   "etc/system-states"
+   "etc/table-loader"
+   "etc/acpi/rsdp"
+   "etc/acpi/tables"
+   "etc/smbios/smbios-tables"
+   "etc/smbios/smbios-anchor"
+   ...
+
+   In addition to the listing by unique selector key described
+   above, the fw_cfg sysfs driver also attempts to build a tree
+   of directories matching the path name components of fw_cfg
+   blob names, ending in symlinks to the by_key entry for each
+   "basename", as illustrated below (assume current directory is
+   /sys/firmware):
+
+   qemu_fw_cfg/by_name/bootorder -> ../by_key/38
+   qemu_fw_cfg/by_name/etc/e820 -> ../../by_key/35
+   qemu_fw_cfg/by_name/etc/acpi/rsdp -> ../../../by_key/41
+   ...
+
+   Construction of the directory tree and symlinks is done on a
+   "best-effort" basis, as there is no guarantee that components
+   of fw_cfg blob names are always "well behaved". I.e., there is
+   the possibility that a symlink (basename) will conflict with
+   a dirname component of another fw_cfg blob, in which case the
+   creation of the offending /sys/firmware/qemu_fw_cfg/by_name
+   entry will be skipped.
+
+   The authoritative list of entries will continue to be found
+   under the /sys/firmware/qemu_fw_cfg/by_key directory.
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
index 83e8a5c..19f6851 100644
--- a/drivers/firmware/qemu_fw_cfg.c
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -334,9 +334,103 @@ static struct bin_attribute fw_cfg_sysfs_attr_raw = {
.read = fw_cfg_sysfs_read_raw,
 };
 
-/* kobjects representing top-level and by_key folders */
+/*
+ * Create a kset subdirectory matching each '/' delimited dirname token
+ * in 'name', starting with sysfs kset/folder 'dir'; At the end, create
+ * a symlink directed at the given 'target'.
+ * NOTE: We do this on a best-effort basis, since 'name' is not guaranteed
+ * to be a well-behaved path name. Whenever a symlink vs. kset directory
+ * name collision occurs, the kernel will issue big scary warnings while
+ * refusing to add the offending link or directory. We follow up with our
+ * own, slightly less scary error messages explaining the situation :)
+ */
+static int fw_cfg_build_symlink(struct kset *dir,
+   struct kobject *target, 

[Qemu-devel] [PATCH v7 0/4] SysFS driver for QEMU fw_cfg device

2016-01-27 Thread Gabriel L. Somlo
From: "Gabriel Somlo" 

Allow access to QEMU firmware blobs, passed into the guest VM via
the fw_cfg device, through SysFS entries. Blob meta-data (e.g. name,
size, and fw_cfg key), as well as the raw binary blob data may be
accessed.

The SysFS access location is /sys/firmware/qemu_fw_cfg/... and was
selected based on overall similarity to the type of information
exposed under /sys/firmware/dmi/entries/...

This functionality is primarily intended to serve as a host->guest
configuration data transfer mechanism that is both:

- asynchronous: the host doesn't need to wait for the guest
to be ready to accept data (e.g., by starting
an agent daemon)

- out-of-band:  there is no need to commandeer a guest element
normally visible and available to the guest user
(e.g., kernel cmdline, mounting floppy/cdrom, etc.)

QEMU now allows arbitrary fw_cfg blobs to be added via the command line,
so it would be nice to make them easy to retrieve from within the guest
OS, and the niceset and easiest way I can think of is

cat /sys/firmware/qemu-fw-cfg/...//raw

New since v6:

- added architecture-specific default values for fw_cfg register
  offsets: DT and/or ACPI will only give us the base address and
  total size of the fw_cfg register set, but not individual register
  offsets *within* this total extent. The specific offsets are
  different across architectures, and this version adds #defines
  so that reasonable defaults can be used on each supported platform.

Thanks,
  --Gabriel

>New since v5:
>
>   - fixed typos in documentation files (Patches 1/4 and 4/4
>
>   - printf/scanf type modifier for phys_addr_t now matches
> arch-specific width (u32 vs. u64), avoiding compiler warnings.
> (tested on i386 with and without PAE, and on armv7hl with and
>  without lpae -- the latter pair took quite a while on an
>  emulated QEMU guest :) )
>
>>New since v4:
>>
>>  Documentation (Patches 1/4 and 4/4) now points to the authoritative
>>  file in the QEMU source tree for any details related to the "hardware
>>  interface" of the fw_cfg device; Only details specific to sysfs (1/4) 
>>  and DT (4/4) should stay in the kernel docs.
>>
>>>New (since v3):
>>>
>>> Patch 1/4: Device probing now works with either ACPI, DT, or
>>>optionally by manually specifying a base, size, and
>>>register offsets on the command line. This way, all
>>>architectures offering fw_cfg can be supported, although
>>>x86 and ARM get *automatic* support via ACPI and/or DT.
>>>
>>>HUGE thanks to Laszlo Ersek  for
>>>pointing out drivers/virtio/virtio_mmio.c, as an example
>>>on how to pull this off !!!
>>>
>>>Stefan: I saw Marc's DMA patches to fw_cfg. Since only
>>>x86 and ARM will support it starting with QEMU 2.5, and
>>>since I expect to get lots of otherwise interesting (but
>>>otherwise orthogonal) feedback on this series, I'd like
>>>to stick with ioread8() across the board for now. We can
>>>always patch in DMA support in a backward compatible way
>>>later, once this series gets (hopefully) accepted :)
>>>
>>> Patch 2/4: (was 3/4 in v3): unchanged. Exports kset_find_obj() so
>>>modules can call it.
>>>
>>> Patch 3/4: (was 4/4 in v3): rebased, but otherwise the same.
>>>Essentially, creates a "human readable" directory
>>>hierarchy from "path-like" tokens making up fw_cfg
>>>blob names. I'm not really sure there's a way to make
>>>this happen via udev rules, but I have at least one
>>>potential use case for doing it *before* udev becomes
>>>available (cc: Andy Lutomirski ),
>>>so I'd be happy to leave this functionality in the
>>>kernel module. See further below for an illustration
>>>of this.
>>>
>>> Patch 4/4: Updates the existing ARM DT documentation for fw_cfg,
>>>mainly by pointing at the more comprehensive document
>>>introduced with Patch 1/4 for details on the fw_cfg
>>>device interface, leaving only the specific ARM/DT
>>>address/size node information in place.
>>>
  In addition to the "by_key" blob listing, e.g.:
  
  $ tree /sys/firmware/qemu_fw_cfg/
  /sys/firmware/qemu_fw_cfg/
  |-- by_key
  |   |-- 32
  |   |   |-- key
  |   |   |-- name("etc/boot-fail-wait")
  |   |   |-- raw
  |   |   `-- size
  |   |-- 33
  |   |   |-- key
  |   |  

[Qemu-devel] [PATCH v7 4/4] devicetree: update documentation for fw_cfg ARM bindings

2016-01-27 Thread Gabriel L. Somlo
From: Gabriel Somlo 

Remove fw_cfg hardware interface details from
Documentation/devicetree/bindings/arm/fw-cfg.txt,
and replace them with a pointer to the authoritative
documentation in the QEMU source tree.

Signed-off-by: Gabriel Somlo 
Cc: Laszlo Ersek 
Acked-by: Rob Herring 
Reviewed-by: Laszlo Ersek 
---
 Documentation/devicetree/bindings/arm/fw-cfg.txt | 38 ++--
 1 file changed, 2 insertions(+), 36 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/fw-cfg.txt 
b/Documentation/devicetree/bindings/arm/fw-cfg.txt
index 953fb64..fd54e1d 100644
--- a/Documentation/devicetree/bindings/arm/fw-cfg.txt
+++ b/Documentation/devicetree/bindings/arm/fw-cfg.txt
@@ -11,43 +11,9 @@ QEMU exposes the control and data register to ARM guests as 
memory mapped
 registers; their location is communicated to the guest's UEFI firmware in the
 DTB that QEMU places at the bottom of the guest's DRAM.
 
-The guest writes a selector value (a key) to the selector register, and then
-can read the corresponding data (produced by QEMU) via the data register. If
-the selected entry is writable, the guest can rewrite it through the data
-register.
+The authoritative guest-side hardware interface documentation to the fw_cfg
+device can be found in "docs/specs/fw_cfg.txt" in the QEMU source tree.
 
-The selector register takes keys in big endian byte order.
-
-The data register allows accesses with 8, 16, 32 and 64-bit width (only at
-offset 0 of the register). Accesses larger than a byte are interpreted as
-arrays, bundled together only for better performance. The bytes constituting
-such a word, in increasing address order, correspond to the bytes that would
-have been transferred by byte-wide accesses in chronological order.
-
-The interface allows guest firmware to download various parameters and blobs
-that affect how the firmware works and what tables it installs for the guest
-OS. For example, boot order of devices, ACPI tables, SMBIOS tables, kernel and
-initrd images for direct kernel booting, virtual machine UUID, SMP information,
-virtual NUMA topology, and so on.
-
-The authoritative registry of the valid selector values and their meanings is
-the QEMU source code; the structure of the data blobs corresponding to the
-individual key values is also defined in the QEMU source code.
-
-The presence of the registers can be verified by selecting the "signature" blob
-with key 0x, and reading four bytes from the data register. The returned
-signature is "QEMU".
-
-The outermost protocol (involving the write / read sequences of the control and
-data registers) is expected to be versioned, and/or described by feature bits.
-The interface revision / feature bitmap can be retrieved with key 0x0001. The
-blob to be read from the data register has size 4, and it is to be interpreted
-as a uint32_t value in little endian byte order. The current value
-(corresponding to the above outer protocol) is zero.
-
-The guest kernel is not expected to use these registers (although it is
-certainly allowed to); the device tree bindings are documented here because
-this is where device tree bindings reside in general.
 
 Required properties:
 
-- 
2.4.3




[Qemu-devel] [PATCH v7 1/4] firmware: introduce sysfs driver for QEMU's fw_cfg device

2016-01-27 Thread Gabriel L. Somlo
+   bool "QEMU fw_cfg device parameter parsing"
+   depends on FW_CFG_SYSFS
+   help
+ Allow the qemu_fw_cfg device to be initialized via the kernel
+ command line or using a module parameter.
+ WARNING: Using incorrect parameters (base address in particular)
+ may crash your system.
+
 config QCOM_SCM
bool
depends on ARM || ARM64
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 48dd417..474bada 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)   += iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)  += memmap.o
 obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
+obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
 obj-$(CONFIG_QCOM_SCM) += qcom_scm.o
 obj-$(CONFIG_QCOM_SCM_64)  += qcom_scm-64.o
 obj-$(CONFIG_QCOM_SCM_32)  += qcom_scm-32.o
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
new file mode 100644
index 000..83e8a5c
--- /dev/null
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -0,0 +1,648 @@
+/*
+ * drivers/firmware/qemu_fw_cfg.c
+ *
+ * Copyright 2015 Carnegie Mellon University
+ *
+ * Expose entries from QEMU's firmware configuration (fw_cfg) device in
+ * sysfs (read-only, under "/sys/firmware/qemu_fw_cfg/...").
+ *
+ * The fw_cfg device may be instantiated via either an ACPI node (on x86
+ * and select subsets of aarch64), a Device Tree node (on arm), or using
+ * a kernel module (or command line) parameter with the following syntax:
+ *
+ *  [fw_cfg.]ioport=@[::]
+ * or
+ *  [fw_cfg.]mmio=@[::]
+ *
+ * where:
+ *   := size of ioport or mmio range
+ *   := physical base address of ioport or mmio range
+ *   := (optional) offset of control register
+ *   := (optional) offset of data register
+ *
+ * e.g.:
+ *  fw_cfg.ioport=2@0x510:0:1  (the default on x86)
+ * or
+ *  fw_cfg.mmio=0xA@0x902:8:0  (the default on arm)
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+MODULE_AUTHOR("Gabriel L. Somlo <so...@cmu.edu>");
+MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
+MODULE_LICENSE("GPL");
+
+/* selector key values for "well-known" fw_cfg entries */
+#define FW_CFG_SIGNATURE  0x00
+#define FW_CFG_ID 0x01
+#define FW_CFG_FILE_DIR   0x19
+
+/* size in bytes of fw_cfg signature */
+#define FW_CFG_SIG_SIZE 4
+
+/* fw_cfg "file name" is up to 56 characters (including terminating nul) */
+#define FW_CFG_MAX_FILE_PATH 56
+
+/* fw_cfg file directory entry type */
+struct fw_cfg_file {
+   u32 size;
+   u16 select;
+   u16 reserved;
+   char name[FW_CFG_MAX_FILE_PATH];
+};
+
+/* fw_cfg device i/o register addresses */
+static bool fw_cfg_is_mmio;
+static phys_addr_t fw_cfg_p_base;
+static resource_size_t fw_cfg_p_size;
+static void __iomem *fw_cfg_dev_base;
+static void __iomem *fw_cfg_reg_ctrl;
+static void __iomem *fw_cfg_reg_data;
+
+/* atomic access to fw_cfg device (potentially slow i/o, so using mutex) */
+static DEFINE_MUTEX(fw_cfg_dev_lock);
+
+/* pick appropriate endianness for selector key */
+static inline u16 fw_cfg_sel_endianness(u16 key)
+{
+   return fw_cfg_is_mmio ? cpu_to_be16(key) : cpu_to_le16(key);
+}
+
+/* read chunk of given fw_cfg blob (caller responsible for sanity-check) */
+static inline void fw_cfg_read_blob(u16 key,
+   void *buf, loff_t pos, size_t count)
+{
+   mutex_lock(_cfg_dev_lock);
+   iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl);
+   while (pos-- > 0)
+   ioread8(fw_cfg_reg_data);
+   ioread8_rep(fw_cfg_reg_data, buf, count);
+   mutex_unlock(_cfg_dev_lock);
+}
+
+/* clean up fw_cfg device i/o */
+static void fw_cfg_io_cleanup(void)
+{
+   if (fw_cfg_is_mmio) {
+   iounmap(fw_cfg_dev_base);
+   release_mem_region(fw_cfg_p_base, fw_cfg_p_size);
+   } else {
+   ioport_unmap(fw_cfg_dev_base);
+   release_region(fw_cfg_p_base, fw_cfg_p_size);
+   }
+}
+
+/* arch-specific ctrl & data register offsets are not available in ACPI, DT */
+#if !(defined(FW_CFG_CTRL_OFF) && defined(FW_CTRL_DATA_OFF))
+# if (defined(CONFIG_ARM) || defined(CONFIG_ARM64))
+#  define FW_CFG_CTRL_OFF 0x08
+#  define FW_CFG_DATA_OFF 0x00
+# elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* ppc/mac,sun4m 
*/
+#  define FW_CFG_CTRL_OFF 0x00
+#  define FW_CFG_DATA_OFF 0x02
+# elif (defined(CONFIG_X86) || defined(CONFIG_SPARC64)) /* x86, sun4u */
+#  define FW_CFG_CTRL_OFF 0x00
+#  define FW_CFG_DATA_OFF 0x01
+# else
+#  warning "QEMU FW_CFG may not be available on this architecture!"
+#  define FW_CFG_CTRL_OFF 0x00
+#  define FW_CFG_DATA_OFF 0x01
+# endif
+#endif
+
+/* initialize fw_cfg device i/o from platform data */
+stati

[Qemu-devel] [PATCH v7 2/4] kobject: export kset_find_obj() for module use

2016-01-27 Thread Gabriel L. Somlo
From: Gabriel Somlo 

Signed-off-by: Gabriel Somlo 
---
 lib/kobject.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/kobject.c b/lib/kobject.c
index 7cbccd2..90d1be6 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -861,6 +861,7 @@ struct kobject *kset_find_obj(struct kset *kset, const char 
*name)
spin_unlock(>list_lock);
return ret;
 }
+EXPORT_SYMBOL(kset_find_obj);
 
 static void kset_release(struct kobject *kobj)
 {
-- 
2.4.3




Re: [Qemu-devel] [PATCH v6 0/4] SysFS driver for QEMU fw_cfg device

2015-12-19 Thread Gabriel L. Somlo
Hi Pavel,

On Sat, Dec 19, 2015 at 10:12:28AM +0100, Pavel Machek wrote:
> On Thu 2015-12-17 11:09:23, Gabriel L. Somlo wrote:
> > ping ?
> > 
> > Also, for the corresponding patch set on the QEMU end of things,
> > ping on http://thread.gmane.org/gmane.comp.emulators.qemu/376321
> 
> I guess missing information is why such access is a good
> idea. Debugging?

Debugging did come up in earlier threads as well. However, personally,
I am interested in a mechanism for the host to pass information to the
guest in a way that's both

- asynchronous: i.e., host doesn't need to wait for guest to
  be ready to accept data (e.g. by first starting an agent)

- out-of-band: don't commandeer guest elements normally visible
  and available to guest *users* (e.g. kernel command line,
  mount a floppy/cdrom image, etc).

QEMU now allows arbitrary fw_cfg blobs to be added via the command
line, so it would be nice to make it easy to access them from the
guest OS -- and what's nicer and easier than:

cat /sys/firmware/qemu-fw-cfg/.../some-blob-name/raw

Thanks,
--Gabriel

> > On Fri, Dec 04, 2015 at 10:29:02AM -0500, Gabriel L. Somlo wrote:
> > > Allow access to QEMU firmware blobs, passed into the guest VM via
> > > the fw_cfg device, through SysFS entries. Blob meta-data (e.g. name,
> > > size, and fw_cfg key), as well as the raw binary blob data may be
> > > accessed.
> > > 
> > > The SysFS access location is /sys/firmware/qemu_fw_cfg/... and was
> > > selected based on overall similarity to the type of information
> > > exposed under /sys/firmware/dmi/entries/...
> 
> -- 
> (english) http://www.livejournal.com/~pavelmachek
> (cesky, pictures) 
> http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html



Re: [Qemu-devel] [PATCH v6 0/4] SysFS driver for QEMU fw_cfg device

2015-12-17 Thread Gabriel L. Somlo
ping ?

Also, for the corresponding patch set on the QEMU end of things,
ping on http://thread.gmane.org/gmane.comp.emulators.qemu/376321

Thanks,
--Gabriel

On Fri, Dec 04, 2015 at 10:29:02AM -0500, Gabriel L. Somlo wrote:
> Allow access to QEMU firmware blobs, passed into the guest VM via
> the fw_cfg device, through SysFS entries. Blob meta-data (e.g. name,
> size, and fw_cfg key), as well as the raw binary blob data may be
> accessed.
> 
> The SysFS access location is /sys/firmware/qemu_fw_cfg/... and was
> selected based on overall similarity to the type of information
> exposed under /sys/firmware/dmi/entries/...
> 
> New since v5:
> 
>   - fixed typos in documentation files (Patches 1/4 and 4/4
> 
>   - printf/scanf type modifier for phys_addr_t now matches
> arch-specific width (u32 vs. u64), avoiding compiler warnings.
> (tested on i386 with and without PAE, and on armv7hl with and
>  without lpae -- the latter pair took quite a while on an
>  emulated QEMU guest :) )
> 
> Thanks,
>   --Gabriel
> 
> >New since v4:
> >
> > Documentation (Patches 1/4 and 4/4) now points to the authoritative
> > file in the QEMU source tree for any details related to the "hardware
> > interface" of the fw_cfg device; Only details specific to sysfs (1/4) 
> > and DT (4/4) should stay in the kernel docs.
> >
> >>New (since v3):
> >>
> >>Patch 1/4: Device probing now works with either ACPI, DT, or
> >>   optionally by manually specifying a base, size, and
> >>   register offsets on the command line. This way, all
> >>   architectures offering fw_cfg can be supported, although
> >>   x86 and ARM get *automatic* support via ACPI and/or DT.
> >>
> >>   HUGE thanks to Laszlo Ersek <ler...@redhat.com> for
> >>   pointing out drivers/virtio/virtio_mmio.c, as an example
> >>   on how to pull this off !!!
> >>
> >>   Stefan: I saw Marc's DMA patches to fw_cfg. Since only
> >>   x86 and ARM will support it starting with QEMU 2.5, and
> >>   since I expect to get lots of otherwise interesting (but
> >>   otherwise orthogonal) feedback on this series, I'd like
> >>   to stick with ioread8() across the board for now. We can
> >>   always patch in DMA support in a backward compatible way
> >>   later, once this series gets (hopefully) accepted :)
> >>
> >>Patch 2/4: (was 3/4 in v3): unchanged. Exports kset_find_obj() so
> >>   modules can call it.
> >>
> >>Patch 3/4: (was 4/4 in v3): rebased, but otherwise the same.
> >>   Essentially, creates a "human readable" directory
> >>   hierarchy from "path-like" tokens making up fw_cfg
> >>   blob names. I'm not really sure there's a way to make
> >>   this happen via udev rules, but I have at least one
> >>   potential use case for doing it *before* udev becomes
> >>   available (cc: Andy Lutomirski <l...@amacapital.net>),
> >>   so I'd be happy to leave this functionality in the
> >>   kernel module. See further below for an illustration
> >>   of this.
> >>
> >>Patch 4/4: Updates the existing ARM DT documentation for fw_cfg,
> >>   mainly by pointing at the more comprehensive document
> >>   introduced with Patch 1/4 for details on the fw_cfg
> >>   device interface, leaving only the specific ARM/DT
> >>   address/size node information in place.
> >>
> >>>  In addition to the "by_key" blob listing, e.g.:
> >>>  
> >>>  $ tree /sys/firmware/qemu_fw_cfg/
> >>>  /sys/firmware/qemu_fw_cfg/
> >>>  |-- by_key
> >>>  |   |-- 32
> >>>  |   |   |-- key
> >>>  |   |   |-- name("etc/boot-fail-wait")
> >>>  |   |   |-- raw
> >>>  |   |   `-- size
> >>>  |   |-- 33
> >>>  |   |   |-- key
> >>>  |   |   |-- name("etc/smbios/smbios-tables")
> >>>  |   |   |-- raw
> >>>  |   |   `-- size
> >>>  |   |-- 34
> >>>  |   |   |-- key
> >>>  |   |   |-- name("etc/smbios/smbios-anchor")

[Qemu-devel] [PATCH v6 2/4] kobject: export kset_find_obj() for module use

2015-12-04 Thread Gabriel L. Somlo
From: Gabriel Somlo 

Signed-off-by: Gabriel Somlo 
---
 lib/kobject.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/kobject.c b/lib/kobject.c
index 7cbccd2..90d1be6 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -861,6 +861,7 @@ struct kobject *kset_find_obj(struct kset *kset, const char 
*name)
spin_unlock(>list_lock);
return ret;
 }
+EXPORT_SYMBOL(kset_find_obj);
 
 static void kset_release(struct kobject *kobj)
 {
-- 
2.4.3




[Qemu-devel] [PATCH v6 0/4] SysFS driver for QEMU fw_cfg device

2015-12-04 Thread Gabriel L. Somlo
Allow access to QEMU firmware blobs, passed into the guest VM via
the fw_cfg device, through SysFS entries. Blob meta-data (e.g. name,
size, and fw_cfg key), as well as the raw binary blob data may be
accessed.

The SysFS access location is /sys/firmware/qemu_fw_cfg/... and was
selected based on overall similarity to the type of information
exposed under /sys/firmware/dmi/entries/...

New since v5:

- fixed typos in documentation files (Patches 1/4 and 4/4

- printf/scanf type modifier for phys_addr_t now matches
  arch-specific width (u32 vs. u64), avoiding compiler warnings.
  (tested on i386 with and without PAE, and on armv7hl with and
   without lpae -- the latter pair took quite a while on an
   emulated QEMU guest :) )

Thanks,
  --Gabriel

>New since v4:
>
>   Documentation (Patches 1/4 and 4/4) now points to the authoritative
>   file in the QEMU source tree for any details related to the "hardware
>   interface" of the fw_cfg device; Only details specific to sysfs (1/4) 
>   and DT (4/4) should stay in the kernel docs.
>
>>New (since v3):
>>
>>  Patch 1/4: Device probing now works with either ACPI, DT, or
>> optionally by manually specifying a base, size, and
>> register offsets on the command line. This way, all
>> architectures offering fw_cfg can be supported, although
>> x86 and ARM get *automatic* support via ACPI and/or DT.
>>
>> HUGE thanks to Laszlo Ersek  for
>> pointing out drivers/virtio/virtio_mmio.c, as an example
>> on how to pull this off !!!
>>
>> Stefan: I saw Marc's DMA patches to fw_cfg. Since only
>> x86 and ARM will support it starting with QEMU 2.5, and
>> since I expect to get lots of otherwise interesting (but
>> otherwise orthogonal) feedback on this series, I'd like
>> to stick with ioread8() across the board for now. We can
>> always patch in DMA support in a backward compatible way
>> later, once this series gets (hopefully) accepted :)
>>
>>  Patch 2/4: (was 3/4 in v3): unchanged. Exports kset_find_obj() so
>> modules can call it.
>>
>>  Patch 3/4: (was 4/4 in v3): rebased, but otherwise the same.
>> Essentially, creates a "human readable" directory
>> hierarchy from "path-like" tokens making up fw_cfg
>> blob names. I'm not really sure there's a way to make
>> this happen via udev rules, but I have at least one
>> potential use case for doing it *before* udev becomes
>> available (cc: Andy Lutomirski ),
>> so I'd be happy to leave this functionality in the
>> kernel module. See further below for an illustration
>> of this.
>>
>>  Patch 4/4: Updates the existing ARM DT documentation for fw_cfg,
>> mainly by pointing at the more comprehensive document
>> introduced with Patch 1/4 for details on the fw_cfg
>> device interface, leaving only the specific ARM/DT
>> address/size node information in place.
>>
>>>  In addition to the "by_key" blob listing, e.g.:
>>>  
>>>  $ tree /sys/firmware/qemu_fw_cfg/
>>>  /sys/firmware/qemu_fw_cfg/
>>>  |-- by_key
>>>  |   |-- 32
>>>  |   |   |-- key
>>>  |   |   |-- name("etc/boot-fail-wait")
>>>  |   |   |-- raw
>>>  |   |   `-- size
>>>  |   |-- 33
>>>  |   |   |-- key
>>>  |   |   |-- name("etc/smbios/smbios-tables")
>>>  |   |   |-- raw
>>>  |   |   `-- size
>>>  |   |-- 34
>>>  |   |   |-- key
>>>  |   |   |-- name("etc/smbios/smbios-anchor")
>>>  |   |   |-- raw
>>>  |   |   `-- size
>>>  |   |-- 35
>>>  |   |   |-- key
>>>  |   |   |-- name("etc/e820")
>>>  |   |   |-- raw
>>>  |   |   `-- size
>>>  |   |-- 36
>>>  |   |   |-- key
>>>  |   |   |-- name("genroms/kvmvapic.bin")
>>>  |   |   |-- raw
>>>  |   |   `-- size
>>>  |   |-- 37
>>>  |   |   |-- key
>>>  |   |   |-- name("etc/system-states")
>>>  |   |   |-- raw
>>>  |   |   `-- size
>>>  |   |-- 38
>>>  |   |   |-- key
>>>  |   |   |-- name("etc/acpi/tables")
>>>  |   |   |-- raw
>>>  |   |   `-- size
>>>  |   |-- 39
>>>  |   |   |-- key
>>>  |   |   |-- name("etc/table-loader")
>>>  |   |   |-- raw
>>>  |   |   `-- size
>>>  |   |-- 40
>>>  |   |   |-- key
>>>  |   |   |-- name("etc/tpm/log")
>>>  |   |   |-- raw
>>>  |   |   `-- size
>>>  |   |-- 41
>>>  |   |   |-- key
>>>  |   |   |-- name("etc/acpi/rsdp")
>>>  |   |   |-- raw
>>>  |   |   `-- size
>>>  |   `-- 42
>>>  |  

[Qemu-devel] [PATCH v6 4/4] devicetree: update documentation for fw_cfg ARM bindings

2015-12-04 Thread Gabriel L. Somlo
From: Gabriel Somlo 

Remove fw_cfg hardware interface details from
Documentation/devicetree/bindings/arm/fw-cfg.txt,
and replace them with a pointer to the authoritative
documentation in the QEMU source tree.

Signed-off-by: Gabriel Somlo 
Cc: Laszlo Ersek 
Acked-by: Rob Herring 
Reviewed-by: Laszlo Ersek 
---
 Documentation/devicetree/bindings/arm/fw-cfg.txt | 38 ++--
 1 file changed, 2 insertions(+), 36 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/fw-cfg.txt 
b/Documentation/devicetree/bindings/arm/fw-cfg.txt
index 953fb64..fd54e1d 100644
--- a/Documentation/devicetree/bindings/arm/fw-cfg.txt
+++ b/Documentation/devicetree/bindings/arm/fw-cfg.txt
@@ -11,43 +11,9 @@ QEMU exposes the control and data register to ARM guests as 
memory mapped
 registers; their location is communicated to the guest's UEFI firmware in the
 DTB that QEMU places at the bottom of the guest's DRAM.
 
-The guest writes a selector value (a key) to the selector register, and then
-can read the corresponding data (produced by QEMU) via the data register. If
-the selected entry is writable, the guest can rewrite it through the data
-register.
+The authoritative guest-side hardware interface documentation to the fw_cfg
+device can be found in "docs/specs/fw_cfg.txt" in the QEMU source tree.
 
-The selector register takes keys in big endian byte order.
-
-The data register allows accesses with 8, 16, 32 and 64-bit width (only at
-offset 0 of the register). Accesses larger than a byte are interpreted as
-arrays, bundled together only for better performance. The bytes constituting
-such a word, in increasing address order, correspond to the bytes that would
-have been transferred by byte-wide accesses in chronological order.
-
-The interface allows guest firmware to download various parameters and blobs
-that affect how the firmware works and what tables it installs for the guest
-OS. For example, boot order of devices, ACPI tables, SMBIOS tables, kernel and
-initrd images for direct kernel booting, virtual machine UUID, SMP information,
-virtual NUMA topology, and so on.
-
-The authoritative registry of the valid selector values and their meanings is
-the QEMU source code; the structure of the data blobs corresponding to the
-individual key values is also defined in the QEMU source code.
-
-The presence of the registers can be verified by selecting the "signature" blob
-with key 0x, and reading four bytes from the data register. The returned
-signature is "QEMU".
-
-The outermost protocol (involving the write / read sequences of the control and
-data registers) is expected to be versioned, and/or described by feature bits.
-The interface revision / feature bitmap can be retrieved with key 0x0001. The
-blob to be read from the data register has size 4, and it is to be interpreted
-as a uint32_t value in little endian byte order. The current value
-(corresponding to the above outer protocol) is zero.
-
-The guest kernel is not expected to use these registers (although it is
-certainly allowed to); the device tree bindings are documented here because
-this is where device tree bindings reside in general.
 
 Required properties:
 
-- 
2.4.3




[Qemu-devel] [PATCH v6 3/4] firmware: create directory hierarchy for sysfs fw_cfg entries

2015-12-04 Thread Gabriel L. Somlo
From: Gabriel Somlo 

Each fw_cfg entry of type "file" has an associated 56-char,
nul-terminated ASCII string which represents its name. While
the fw_cfg device doesn't itself impose any specific naming
convention, QEMU developers have traditionally used path name
semantics (i.e. "etc/acpi/rsdp") to descriptively name the
various fw_cfg "blobs" passed into the guest.

This patch attempts, on a best effort basis, to create a
directory hierarchy representing the content of fw_cfg file
names, under /sys/firmware/qemu_fw_cfg/by_name.

Upon successful creation of all directories representing the
"dirname" portion of a fw_cfg file, a symlink will be created
to represent the "basename", pointing at the appropriate
/sys/firmware/qemu_fw_cfg/by_key entry. If a file name is not
suitable for this procedure (e.g., if its basename or dirname
components collide with an already existing dirname component
or basename, respectively) the corresponding fw_cfg blob is
skipped and will remain available in sysfs only by its selector
key value.

Signed-off-by: Gabriel Somlo 
Cc: Andy Lutomirski 
---
 .../ABI/testing/sysfs-firmware-qemu_fw_cfg |  42 
 drivers/firmware/qemu_fw_cfg.c | 109 -
 2 files changed, 148 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg 
b/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
index e9e58d4..011dda4 100644
--- a/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
+++ b/Documentation/ABI/testing/sysfs-firmware-qemu_fw_cfg
@@ -56,3 +56,45 @@ Description:
  entry via the control register, and reading a number
  of bytes equal to the blob size from the data
  register.
+
+   --- Listing fw_cfg blobs by file name ---
+
+   While the fw_cfg device does not impose any specific naming
+   convention on the blobs registered in the file directory,
+   QEMU developers have traditionally used path name semantics
+   to give each blob a descriptive name. For example:
+
+   "bootorder"
+   "genroms/kvmvapic.bin"
+   "etc/e820"
+   "etc/boot-fail-wait"
+   "etc/system-states"
+   "etc/table-loader"
+   "etc/acpi/rsdp"
+   "etc/acpi/tables"
+   "etc/smbios/smbios-tables"
+   "etc/smbios/smbios-anchor"
+   ...
+
+   In addition to the listing by unique selector key described
+   above, the fw_cfg sysfs driver also attempts to build a tree
+   of directories matching the path name components of fw_cfg
+   blob names, ending in symlinks to the by_key entry for each
+   "basename", as illustrated below (assume current directory is
+   /sys/firmware):
+
+   qemu_fw_cfg/by_name/bootorder -> ../by_key/38
+   qemu_fw_cfg/by_name/etc/e820 -> ../../by_key/35
+   qemu_fw_cfg/by_name/etc/acpi/rsdp -> ../../../by_key/41
+   ...
+
+   Construction of the directory tree and symlinks is done on a
+   "best-effort" basis, as there is no guarantee that components
+   of fw_cfg blob names are always "well behaved". I.e., there is
+   the possibility that a symlink (basename) will conflict with
+   a dirname component of another fw_cfg blob, in which case the
+   creation of the offending /sys/firmware/qemu_fw_cfg/by_name
+   entry will be skipped.
+
+   The authoritative list of entries will continue to be found
+   under the /sys/firmware/qemu_fw_cfg/by_key directory.
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
index 5b00d97..85f532a 100644
--- a/drivers/firmware/qemu_fw_cfg.c
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -318,9 +318,103 @@ static struct bin_attribute fw_cfg_sysfs_attr_raw = {
.read = fw_cfg_sysfs_read_raw,
 };
 
-/* kobjects representing top-level and by_key folders */
+/*
+ * Create a kset subdirectory matching each '/' delimited dirname token
+ * in 'name', starting with sysfs kset/folder 'dir'; At the end, create
+ * a symlink directed at the given 'target'.
+ * NOTE: We do this on a best-effort basis, since 'name' is not guaranteed
+ * to be a well-behaved path name. Whenever a symlink vs. kset directory
+ * name collision occurs, the kernel will issue big scary warnings while
+ * refusing to add the offending link or directory. We follow up with our
+ * own, slightly less scary error messages explaining the situation :)
+ */
+static int fw_cfg_build_symlink(struct kset *dir,
+   struct kobject *target, 

[Qemu-devel] [PATCH v6 1/4] firmware: introduce sysfs driver for QEMU's fw_cfg device

2015-12-04 Thread Gabriel L. Somlo
+   bool "QEMU fw_cfg device parameter parsing"
+   depends on FW_CFG_SYSFS
+   help
+ Allow the qemu_fw_cfg device to be initialized via the kernel
+ command line or using a module parameter.
+ WARNING: Using incorrect parameters (base address in particular)
+ may crash your system.
+
 config QCOM_SCM
bool
depends on ARM || ARM64
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 48dd417..474bada 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_ISCSI_IBFT_FIND) += iscsi_ibft_find.o
 obj-$(CONFIG_ISCSI_IBFT)   += iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)  += memmap.o
 obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
+obj-$(CONFIG_FW_CFG_SYSFS) += qemu_fw_cfg.o
 obj-$(CONFIG_QCOM_SCM) += qcom_scm.o
 obj-$(CONFIG_QCOM_SCM_64)  += qcom_scm-64.o
 obj-$(CONFIG_QCOM_SCM_32)  += qcom_scm-32.o
diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c
new file mode 100644
index 000..5b00d97
--- /dev/null
+++ b/drivers/firmware/qemu_fw_cfg.c
@@ -0,0 +1,632 @@
+/*
+ * drivers/firmware/qemu_fw_cfg.c
+ *
+ * Copyright 2015 Carnegie Mellon University
+ *
+ * Expose entries from QEMU's firmware configuration (fw_cfg) device in
+ * sysfs (read-only, under "/sys/firmware/qemu_fw_cfg/...").
+ *
+ * The fw_cfg device may be instantiated via either an ACPI node (on x86
+ * and select subsets of aarch64), a Device Tree node (on arm), or using
+ * a kernel module (or command line) parameter with the following syntax:
+ *
+ *  [fw_cfg.]ioport=@[::]
+ * or
+ *  [fw_cfg.]mmio=@[::]
+ *
+ * where:
+ *   := size of ioport or mmio range
+ *   := physical base address of ioport or mmio range
+ *   := (optional) offset of control register
+ *   := (optional) offset of data register
+ *
+ * e.g.:
+ *  fw_cfg.ioport=2@0x510:0:1  (the default on x86)
+ * or
+ *  fw_cfg.mmio=0xA@0x902:8:0  (the default on arm)
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+MODULE_AUTHOR("Gabriel L. Somlo <so...@cmu.edu>");
+MODULE_DESCRIPTION("QEMU fw_cfg sysfs support");
+MODULE_LICENSE("GPL");
+
+/* selector key values for "well-known" fw_cfg entries */
+#define FW_CFG_SIGNATURE  0x00
+#define FW_CFG_ID 0x01
+#define FW_CFG_FILE_DIR   0x19
+
+/* size in bytes of fw_cfg signature */
+#define FW_CFG_SIG_SIZE 4
+
+/* fw_cfg "file name" is up to 56 characters (including terminating nul) */
+#define FW_CFG_MAX_FILE_PATH 56
+
+/* fw_cfg file directory entry type */
+struct fw_cfg_file {
+   u32 size;
+   u16 select;
+   u16 reserved;
+   char name[FW_CFG_MAX_FILE_PATH];
+};
+
+/* fw_cfg device i/o register addresses */
+static bool fw_cfg_is_mmio;
+static phys_addr_t fw_cfg_p_base;
+static resource_size_t fw_cfg_p_size;
+static void __iomem *fw_cfg_dev_base;
+static void __iomem *fw_cfg_reg_ctrl;
+static void __iomem *fw_cfg_reg_data;
+
+/* atomic access to fw_cfg device (potentially slow i/o, so using mutex) */
+static DEFINE_MUTEX(fw_cfg_dev_lock);
+
+/* pick appropriate endianness for selector key */
+static inline u16 fw_cfg_sel_endianness(u16 key)
+{
+   return fw_cfg_is_mmio ? cpu_to_be16(key) : cpu_to_le16(key);
+}
+
+/* read chunk of given fw_cfg blob (caller responsible for sanity-check) */
+static inline void fw_cfg_read_blob(u16 key,
+   void *buf, loff_t pos, size_t count)
+{
+   mutex_lock(_cfg_dev_lock);
+   iowrite16(fw_cfg_sel_endianness(key), fw_cfg_reg_ctrl);
+   while (pos-- > 0)
+   ioread8(fw_cfg_reg_data);
+   ioread8_rep(fw_cfg_reg_data, buf, count);
+   mutex_unlock(_cfg_dev_lock);
+}
+
+/* clean up fw_cfg device i/o */
+static void fw_cfg_io_cleanup(void)
+{
+   if (fw_cfg_is_mmio) {
+   iounmap(fw_cfg_dev_base);
+   release_mem_region(fw_cfg_p_base, fw_cfg_p_size);
+   } else {
+   ioport_unmap(fw_cfg_dev_base);
+   release_region(fw_cfg_p_base, fw_cfg_p_size);
+   }
+}
+
+/* initialize fw_cfg device i/o from platform data */
+static int fw_cfg_do_platform_probe(struct platform_device *pdev)
+{
+   char sig[FW_CFG_SIG_SIZE];
+   struct resource *range, *ctrl, *data;
+
+   /* acquire i/o range details */
+   fw_cfg_is_mmio = false;
+   range = platform_get_resource(pdev, IORESOURCE_IO, 0);
+   if (!range) {
+   fw_cfg_is_mmio = true;
+   range = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (!range)
+   return -EINVAL;
+   }
+   fw_cfg_p_base = range->start;
+   fw_cfg_p_size = resource_size(range);
+
+   if (fw_cfg_is_mmio) {
+   if (!request_mem_region(fw_cfg_p_base,
+

  1   2   3   4   5   6   7   8   >