All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Auger <eric.auger@linaro.org>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: "Baptiste Reynal" <b.reynal@virtualopensystems.com>,
	"Thomas Huth" <thuth@redhat.com>,
	eric.auger@st.com, "Patch Tracking" <patches@linaro.org>,
	"Peter Crosthwaite" <crosthwaitepeter@gmail.com>,
	"QEMU Developers" <qemu-devel@nongnu.org>,
	"Alex Williamson" <alex.williamson@redhat.com>,
	"Suravee Suthikulpanit" <suravee.suthikulpanit@amd.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	thomas.lendacky@amd.com, "Alex Bennée" <alex.bennee@linaro.org>,
	"Christoffer Dall" <christoffer.dall@linaro.org>,
	"David Gibson" <david@gibson.dropbear.id.au>
Subject: Re: [Qemu-devel] [PATCH 2/6] device_tree: introduce load_device_tree_from_sysfs
Date: Mon, 4 Jan 2016 18:37:52 +0100	[thread overview]
Message-ID: <568AADF0.2060605@linaro.org> (raw)
In-Reply-To: <CAFEAcA-r3XCgHP5GHztJAx1D=sVZW=aFCuATEAnc_WBMPn9EnA@mail.gmail.com>

Hi Peter,
On 12/18/2015 03:10 PM, Peter Maydell wrote:
> On 17 December 2015 at 12:29, Eric Auger <eric.auger@linaro.org> wrote:
>> This function returns the host device tree blob from sysfs
>> (/sys/firmware/devicetree/base). It uses a recursive function
>> inspired from dtc read_fstree.
>>
>> Signed-off-by: Eric Auger <eric.auger@linaro.org>
>>
>> ---
>>
>> RFC -> v1:
>> - remove runtime dependency on dtc binary and introduce read_fstree
>> ---
>>  device_tree.c                | 102 +++++++++++++++++++++++++++++++++++++++++++
>>  include/sysemu/device_tree.h |   1 +
>>  2 files changed, 103 insertions(+)
>>
>> diff --git a/device_tree.c b/device_tree.c
>> index a9f5f8e..e556a99 100644
>> --- a/device_tree.c
>> +++ b/device_tree.c
>> @@ -17,6 +17,7 @@
>>  #include <fcntl.h>
>>  #include <unistd.h>
>>  #include <stdlib.h>
>> +#include <dirent.h>
> 
> Does this code compile on non-Linux hosts? (You've put it in a file
> which is built everywhere, but it's definitely semantically Linux
> specific.)

I struggled quite a lot while cross-compiling all dependencies for W32
(~ http://wiki.qemu.org/Hosts/W32).

Eventually device_tree.c compiles but there is a link issue since lstat
does not seem to be available with MinGW

But there is definitively a problem with hw/arm/sysbus-fdt.c which is
not compiling due to the inclusion of #include <linux/vfio.h>

So thanks for raising the concern.

With respect to read_fstree, what is your sugestion: shall I keep it in
device_tree.c while protecting it with a CONFIG_LINUX or is it better to
move it, for instance in hw/arm/sysbus-fdt.c?

> 
>>  #include "qemu-common.h"
>>  #include "qemu/error-report.h"
>> @@ -117,6 +118,107 @@ fail:
>>      return NULL;
>>  }
>>
>> +/**
>> + * read_fstree: this function is inspired from dtc read_fstree
>> + * @fdt: preallocated fdt blob buffer, to be populated
>> + * @dirname: directory to scan under /sys/firmware/devicetree/base
>> + * the search is recursive and the tree is search down to the
>> + * leafs (property files).
>> + *
>> + * the function self-asserts in case of error
>> + */
>> +static void read_fstree(void *fdt, const char *dirname)
>> +{
>> +        DIR *d;
>> +        struct dirent *de;
> 
> Indent here doesn't match QEMU coding style, which is four-space.
OK
> 
>> +        struct stat st;
>> +        const char *root_dir = "/sys/firmware/devicetree/base";
> 
> You use this string twice and its length once so it would be nice
> to have it in a #define.
OK
> 
>> +        char *parent_node;
>> +
>> +        if (strstr(dirname, root_dir) != dirname) {
>> +            error_report("%s: %s must be searched within %s",
>> +                         __func__, dirname, root_dir);
>> +            exit(1);
>> +        }
>> +        parent_node = (char *)&dirname[29];
> 
> I think 29 here should be strlen(SYSFS_DT_BASEDIR) or whatever
> you want to call it.
OK
> 
>> +
>> +        d = opendir(dirname);
>> +        if (!d) {
>> +                error_report("%s cannot open %s", __func__, dirname);
>> +                exit(1);
>> +        }
>> +
>> +        while ((de = readdir(d)) != NULL) {
>> +                char *tmpnam;
>> +
>> +                if (!g_strcmp0(de->d_name, ".")
>> +                    || !g_strcmp0(de->d_name, "..")) {
>> +                        continue;
>> +                }
> 
> If you used glib g_dir_open/g_dir_read_name/g_dir_close it would
> automatically skip '.' and '..' for you, but I'm not sure the
> benefit is enough to bother redoing this code now.
OK thanks for the hint
> 
>> +
>> +                tmpnam = g_strjoin("/", dirname, de->d_name, NULL);
>> +
>> +                if (lstat(tmpnam, &st) < 0) {
>> +                        error_report("%s cannot lstat %s", __func__, tmpnam);
>> +                        exit(1);
>> +                }
>> +
>> +                if (S_ISREG(st.st_mode)) {
>> +                    int ret, size = st.st_size;
>> +                    void *val = g_malloc0(size);
>> +                    FILE *pfile;
>> +
>> +                    pfile = fopen(tmpnam, "r");
>> +                    if (!pfile) {
>> +                        error_report("%s cannot open %s", __func__, tmpnam);
>> +                        exit(1);
>> +                    }
>> +                    ret = fread(val, 1, size, pfile);
>> +                    if (ferror(pfile) || ret < size) {
>> +                        error_report("%s fail reading %s", __func__, tmpnam);
>> +                        exit(1);
>> +                    }
>> +                    fclose(pfile);
> 
> This looks like it's reimplementing g_file_get_contents().
OK
> 
>> +
>> +                    if (strlen(parent_node) > 0) {
>> +                        qemu_fdt_setprop(fdt, parent_node,
>> +                                         de->d_name, val, size);
>> +                    } else {
>> +                        qemu_fdt_setprop(fdt, "/", de->d_name, val, size);
>> +                    }
>> +                    g_free(val);
>> +                } else if (S_ISDIR(st.st_mode)) {
>> +                        char *node_name;
>> +
>> +                        node_name = g_strdup_printf("%s/%s",
>> +                                                    parent_node, de->d_name);
>> +                        qemu_fdt_add_subnode(fdt, node_name);
>> +                        g_free(node_name);
>> +                        read_fstree(fdt, tmpnam);
>> +                }
>> +
>> +                g_free(tmpnam);
>> +        }
>> +
>> +        closedir(d);
>> +}
>> +
>> +/* load_device_tree_from_sysfs: extract the dt blob from host sysfs */
>> +void *load_device_tree_from_sysfs(void)
>> +{
>> +    void *host_fdt;
>> +    int host_fdt_size;
>> +
>> +    host_fdt = create_device_tree(&host_fdt_size);
>> +    read_fstree(host_fdt, "/sys/firmware/devicetree/base");
>> +    if (fdt_check_header(host_fdt)) {
>> +        error_report("%s host device tree extracted into memory is invalid",
>> +                     __func__);
>> +        g_free(host_fdt);
> 
> Why do we exit-on-error for the errors inside read_fstree() but
> plough on (returning a pointer to freed memory!) in this case?
Yes I can do that. I was doing something similar as in load_device_tree

Best Regards

Eric
> 
>> +    }
>> +    return host_fdt;
>> +}
>> +
>>  static int findnode_nofail(void *fdt, const char *node_path)
>>  {
>>      int offset;
>> diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
>> index 359e143..307e53d 100644
>> --- a/include/sysemu/device_tree.h
>> +++ b/include/sysemu/device_tree.h
>> @@ -16,6 +16,7 @@
>>
>>  void *create_device_tree(int *sizep);
>>  void *load_device_tree(const char *filename_path, int *sizep);
>> +void *load_device_tree_from_sysfs(void);
>>
>>  int qemu_fdt_setprop(void *fdt, const char *node_path,
>>                       const char *property, const void *val, int size);
>> --
>> 1.9.1
> 
> thanks
> -- PMM
> 

  reply	other threads:[~2016-01-04 17:38 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-17 12:29 [Qemu-devel] [PATCH 0/6] AMD XGBE KVM platform passthrough Eric Auger
2015-12-17 12:29 ` [Qemu-devel] [PATCH 1/6] hw/vfio/platform: amd-xgbe device Eric Auger
2015-12-18 13:53   ` Peter Maydell
2015-12-17 12:29 ` [Qemu-devel] [PATCH 2/6] device_tree: introduce load_device_tree_from_sysfs Eric Auger
2015-12-18 14:10   ` Peter Maydell
2016-01-04 17:37     ` Eric Auger [this message]
2016-01-04 21:33       ` Peter Maydell
2015-12-17 12:29 ` [Qemu-devel] [PATCH 3/6] device_tree: introduce qemu_fdt_node_path Eric Auger
2015-12-18 14:23   ` Peter Maydell
2016-01-05 16:20     ` Eric Auger
2016-01-05 17:55       ` Peter Maydell
2016-01-06  8:43         ` Eric Auger
2015-12-17 12:29 ` [Qemu-devel] [PATCH 4/6] device_tree: qemu_fdt_getprop converted to use the error API Eric Auger
2015-12-18 14:36   ` Peter Maydell
2016-01-05 16:20     ` Eric Auger
2016-01-05 17:54       ` Peter Maydell
2015-12-17 12:29 ` [Qemu-devel] [PATCH 5/6] hw/arm/sysbus-fdt: helpers for clock node generation Eric Auger
2015-12-18 14:54   ` Peter Maydell
2016-01-05 17:04     ` Eric Auger
2015-12-17 12:29 ` [Qemu-devel] [PATCH 6/6] hw/arm/sysbus-fdt: enable amd-xgbe dynamic instantiation Eric Auger
2015-12-18 15:05   ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=568AADF0.2060605@linaro.org \
    --to=eric.auger@linaro.org \
    --cc=alex.bennee@linaro.org \
    --cc=alex.williamson@redhat.com \
    --cc=b.reynal@virtualopensystems.com \
    --cc=christoffer.dall@linaro.org \
    --cc=crosthwaitepeter@gmail.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=eric.auger@st.com \
    --cc=patches@linaro.org \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=suravee.suthikulpanit@amd.com \
    --cc=thomas.lendacky@amd.com \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.