bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v3 1/1] acpi: Convert translator to an emulated mach device


From: Samuel Thibault
Subject: Re: [PATCH v3 1/1] acpi: Convert translator to an emulated mach device
Date: Tue, 20 Sep 2022 23:39:39 +0200
User-agent: NeoMutt/20170609 (1.8.3)

Damien Zammit, le mar. 20 sept. 2022 03:01:18 +0000, a ecrit:
> This makes acpi usable as a bootstrap translator.

Applied, thanks!

> ---
>  acpi/Makefile  |   6 +-
>  acpi/acpifs.c  |  37 ++++++++----
>  acpi/acpifs.h  |   6 +-
>  acpi/main.c    | 155 +++++++++++++++++++++++++++++++++++++++++++++----
>  acpi/options.c |  20 +++++++
>  acpi/options.h |   8 +++
>  6 files changed, 207 insertions(+), 25 deletions(-)
> 
> diff --git a/acpi/Makefile b/acpi/Makefile
> index 76f27aef..ceccb351 100644
> --- a/acpi/Makefile
> +++ b/acpi/Makefile
> @@ -22,15 +22,15 @@ PORTDIR = $(srcdir)/port
> 
>  SRCS           = main.c netfs_impl.c acpi.c \
>                   acpifs.c ncache.c options.c func_files.c acpi-ops.c \
> -                 acpiServer.c
> +                 acpiServer.c startup_notifyServer.c
> 
>  MIGSRCS        =
>  OBJS           = $(patsubst %.S,%.o,$(patsubst %.c,%.o, $(SRCS) $(MIGSRCS)))
> 
> -HURDLIBS= fshelp ports shouldbeinlibc netfs iohelp ihash
> +HURDLIBS= fshelp ports shouldbeinlibc netfs iohelp ihash machdev trivfs
>  LDLIBS = -lpthread $(libacpica_LIBS)
> 
> -target = acpi
> +target = acpi acpi.static
> 
>  include ../Makeconf
> 
> diff --git a/acpi/acpifs.c b/acpi/acpifs.c
> index 2b5fbc00..1b9fbcf2 100644
> --- a/acpi/acpifs.c
> +++ b/acpi/acpifs.c
> @@ -81,16 +81,19 @@ alloc_file_system (struct acpifs **fs)
>  }
> 
>  error_t
> -init_file_system (file_t underlying_node, struct acpifs *fs)
> +init_root_node (file_t underlying_node)
>  {
>    error_t err;
>    struct node *np;
> -  io_statbuf_t underlying_node_stat;
> +  io_statbuf_t underlying_node_stat = { 0 };
> 
> -  /* Initialize status from underlying node.  */
> -  err = io_stat (underlying_node, &underlying_node_stat);
> -  if (err)
> -    return err;
> +  if (underlying_node != MACH_PORT_NULL)
> +    {
> +      /* Initialize status from underlying node.  */
> +      err = io_stat (underlying_node, &underlying_node_stat);
> +      if (err)
> +     return err;
> +    }
> 
>    np = netfs_make_node_alloc (sizeof (struct netnode));
>    if (!np)
> @@ -106,18 +109,30 @@ init_file_system (file_t underlying_node, struct acpifs 
> *fs)
>    fshelp_touch (&np->nn_stat, TOUCH_ATIME | TOUCH_MTIME | TOUCH_CTIME,
>                 acpifs_maptime);
> 
> +  netfs_root_node = np;
> +  return 0;
> +}
> +
> +error_t
> +init_file_system (struct acpifs *fs)
> +{
> +  error_t err;
> +  struct node *np = netfs_root_node;
> +
>    fs->entries = calloc (1, sizeof (struct acpifs_dirent));
>    if (!fs->entries)
> -    {
> -      free (fs->entries);
> -      return ENOMEM;
> -    }
> +    return ENOMEM;
> 
>    /* Create the root entry */
>    err = create_dir_entry ("", 0, 0, np->nn_stat, np, fs->entries);
> +  if (err)
> +    {
> +      free(fs->entries);
> +      return err;
> +    }
> 
>    fs->num_entries = 1;
> -  fs->root = netfs_root_node = np;
> +  fs->root = np;
>    fs->root->nn->ln = fs->entries;
>    pthread_mutex_init (&fs->node_cache_lock, 0);
> 
> diff --git a/acpi/acpifs.h b/acpi/acpifs.h
> index 4597e1b0..e4ab0d95 100644
> --- a/acpi/acpifs.h
> +++ b/acpi/acpifs.h
> @@ -97,6 +97,9 @@ struct acpifs
>    size_t node_cache_max;
>    pthread_mutex_t node_cache_lock;
> 
> +  /* Next bootstrap task */
> +  mach_port_t next_task;
> +
>    struct acpifs_perm perm;
> 
>    struct acpifs_dirent *entries;
> @@ -138,7 +141,8 @@ extern volatile struct mapped_time_value *acpifs_maptime;
> 
>  /* FS manipulation functions */
>  error_t alloc_file_system (struct acpifs **fs);
> -error_t init_file_system (file_t underlying_node, struct acpifs *fs);
> +error_t init_file_system (struct acpifs *fs);
> +error_t init_root_node (file_t underlying_node);
>  error_t create_fs_tree (struct acpifs *fs);
>  error_t fs_set_permissions (struct acpifs *fs);
>  error_t entry_check_perms (struct iouser *user, struct acpifs_dirent *e,
> diff --git a/acpi/main.c b/acpi/main.c
> index fc46f4f2..aa153bdb 100644
> --- a/acpi/main.c
> +++ b/acpi/main.c
> @@ -25,14 +25,19 @@
>  #include <version.h>
>  #include <argp.h>
>  #include <hurd/netfs.h>
> +#include <hurd/fsys.h>
> 
>  #include "acpi_S.h"
> +#include "startup_notify_S.h"
>  #include "libnetfs/io_S.h"
>  #include "libnetfs/fs_S.h"
>  #include "libports/notify_S.h"
>  #include "libnetfs/fsys_S.h"
>  #include "libports/interrupt_S.h"
>  #include "libnetfs/ifsock_S.h"
> +#include "libmachdev/machdev.h"
> +#include <device/device.h>
> +#include <pthread.h>
>  #include <acpi/acpi_init.h>
>  #include <acpifs.h>
> 
> @@ -45,6 +50,8 @@ volatile struct mapped_time_value *acpifs_maptime;
> 
>  struct acpifs *fs;
> 
> +static mach_port_t acpi_control_port;
> +
>  int
>  netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * outp)
>  {
> @@ -56,7 +63,8 @@ netfs_demuxer (mach_msg_header_t * inp, mach_msg_header_t * 
> outp)
>        (routine = netfs_fsys_server_routine (inp)) ||
>        (routine = ports_interrupt_server_routine (inp)) ||
>        (routine = netfs_ifsock_server_routine (inp)) ||
> -      (routine = acpi_server_routine (inp)))
> +      (routine = acpi_server_routine (inp)) ||
> +      (routine = startup_notify_server_routine (inp)))
>      {
>        (*routine) (inp, outp);
>        return TRUE;
> @@ -65,23 +73,126 @@ netfs_demuxer (mach_msg_header_t * inp, 
> mach_msg_header_t * outp)
>      return FALSE;
>  }
> 
> +static io_return_t
> +acpi_device_open (mach_port_t reply_port, mach_msg_type_name_t 
> reply_port_type,
> +               dev_mode_t mode, const char *name, device_t * devp,
> +               mach_msg_type_name_t * devicePoly)
> +{
> +  io_return_t err = D_SUCCESS;
> +  mach_port_t dev_master, root;
> +  string_t retry_name;
> +  retry_type retry;
> +  uid_t idlist[] = {0, 0, 0};
> +
> +  if (strncmp(name, "acpi", 3))
> +    err = D_NO_SUCH_DEVICE;
> +
> +  /* Fall back to opening kernel device master */
> +  if (err)
> +    {
> +      err = get_privileged_ports(NULL, &dev_master);
> +      if (err)
> +        return err;
> +      if (dev_master == MACH_PORT_NULL)
> +        return D_NO_SUCH_DEVICE;
> +      err = device_open (dev_master, mode, name, devp);
> +      if (err)
> +        return err;
> +      *devicePoly = MACH_MSG_TYPE_MOVE_SEND;
> +      return D_SUCCESS;
> +    }
> +
> +  err = fsys_getroot(acpi_control_port, MACH_PORT_NULL, 
> MACH_MSG_TYPE_COPY_SEND,
> +                     idlist, 3, idlist, 3, 0,
> +                     &retry, retry_name, &root);
> +  if (err)
> +    return err;
> +
> +  *devp = root;
> +  *devicePoly = MACH_MSG_TYPE_COPY_SEND;
> +  return D_SUCCESS;
> +}
> +
> +static struct machdev_device_emulation_ops acpi_emulation_ops = {
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  acpi_device_open,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +  NULL,
> +};
> +
> +static mach_port_t
> +acpifs_startup(mach_port_t bootstrap, int flags)
> +{
> +  error_t err;
> +  mach_port_t realnode;
> +  struct port_info *newpi;
> +
> +  err = ports_create_port (netfs_control_class, netfs_port_bucket,
> +                          sizeof (struct port_info), &newpi);
> +  if (err)
> +    error (11, err, "Translator startup failure: acpifs_startup");
> +
> +  acpi_control_port = ports_get_send_right (newpi);
> +
> +  if (bootstrap != MACH_PORT_NULL)
> +    {
> +      err = fsys_startup (bootstrap, flags, acpi_control_port, 
> MACH_MSG_TYPE_COPY_SEND,
> +                          &realnode);
> +      assert_perror_backtrace (err);
> +    }
> +
> +  return realnode;
> +}
> +
>  int
>  main (int argc, char **argv)
>  {
>    error_t err;
>    mach_port_t bootstrap;
> +  mach_port_t next_task;
> +  pthread_t t, mt;
> +  file_t underlying_node = MACH_PORT_NULL;
> 
>    /* Parse options */
>    alloc_file_system (&fs);
>    argp_parse (netfs_runtime_argp, argc, argv, 0, 0, 0);
> +  next_task = fs->next_task;
> 
> -  task_get_bootstrap_port (mach_task_self (), &bootstrap);
> -  if (bootstrap == MACH_PORT_NULL)
> -    error (1, 0, "must be started as a translator");
> -
> -  /* Initialize ACPI */
> -  acpi_init();
> -
> +  if (next_task != MACH_PORT_NULL)
> +    {
> +      /* We are a bootstrap process */
> +
> +      machdev_register (&acpi_emulation_ops);
> +      /* TODO: make libmachdev allow us to also run netfs on the translated 
> path,
> +       * so that we don't need a second acpi to serve /servers/acpi  */
> +      machdev_trivfs_init (argc, argv, next_task, "acpi", NULL /* _SERVERS 
> "acpi" */, &bootstrap);
> +
> +      machdev_device_init ();
> +      err = pthread_create (&t, NULL, machdev_server, NULL);
> +      if (err)
> +        error (1, err, "creating machdev thread");
> +      pthread_detach (t);
> +    }
> +  else
> +    {
> +      task_get_bootstrap_port (mach_task_self (), &bootstrap);
> +      if (bootstrap == MACH_PORT_NULL)
> +        error (1, 0, "must be started as a translator");
> +    }
>    /* Initialize netfs and start the translator. */
>    netfs_init ();
> 
> @@ -91,8 +202,24 @@ main (int argc, char **argv)
>    if (err)
>      error (1, err, "mapping time");
> 
> -  /* Create the ACPI filesystem */
> -  err = init_file_system (netfs_startup (bootstrap, O_READ), fs);
> +  /* Enable ACPI mode of machine */
> +  acpi_init ();
> +
> +  if (next_task != MACH_PORT_NULL)
> +    machdev_trivfs_server_startup (bootstrap);
> +
> +  if (next_task == MACH_PORT_NULL)
> +    underlying_node = netfs_startup (bootstrap, O_READ);
> +
> +  /* Create the root node first */
> +  err = init_root_node (underlying_node);
> +  if (err)
> +    error (1, err, "creating the root node");
> +
> +  if (next_task != MACH_PORT_NULL)
> +    acpifs_startup (bootstrap, O_READ);
> +
> +  err = init_file_system (fs);
>    if (err)
>      error (1, err, "creating the ACPI filesystem");
> 
> @@ -106,6 +233,14 @@ main (int argc, char **argv)
>    if (err)
>      error (1, err, "setting permissions");
> 
> +  if (next_task != MACH_PORT_NULL)
> +    {
> +      err = pthread_create (&mt, NULL, machdev_trivfs_server_loop, NULL);
> +      if (err)
> +        error(1, err, "creating machdev_trivfs_server_loop thread");
> +      pthread_detach (mt);
> +    }
> +
>    netfs_server_loop (); /* Never returns.  */
> 
>    return 0;
> diff --git a/acpi/options.c b/acpi/options.c
> index 8dbcd263..fb348679 100644
> --- a/acpi/options.c
> +++ b/acpi/options.c
> @@ -64,6 +64,15 @@ parse_opt (int opt, char *arg, struct argp_state *state)
>      case 'G':
>        h->perm.gid = atoi (arg);
>        break;
> +    case 'N':
> +      h->next_task = atoi (arg);
> +      break;
> +    case 'H':
> +      h->host_priv_port = atoi (arg);
> +      break;
> +    case 'P':
> +      h->dev_master_port = atoi (arg);
> +      break;
> 
>      case ARGP_KEY_INIT:
>        /* Initialize our parsing state.  */
> @@ -74,6 +83,9 @@ parse_opt (int opt, char *arg, struct argp_state *state)
>        h->ncache_len = NODE_CACHE_MAX;
>        h->perm.uid = 0;
>        h->perm.gid = 0;
> +      h->next_task = MACH_PORT_NULL;
> +      h->host_priv_port = MACH_PORT_NULL;
> +      h->dev_master_port = MACH_PORT_NULL;
>        state->hook = h;
>        break;
> 
> @@ -84,6 +96,11 @@ parse_opt (int opt, char *arg, struct argp_state *state)
>        /* Set cache len */
>        fs->node_cache_max = h->ncache_len;
> 
> +      /* Set bootstrap ports */
> +      fs->next_task = h->next_task;
> +      _hurd_host_priv = h->host_priv_port;
> +      _hurd_device_master = h->dev_master_port;
> +
>        if (fs->root)
>         {
>           /*
> @@ -140,6 +157,9 @@ netfs_append_args (char **argz, size_t * argz_len)
>    if (p->gid >= 0)
>      ADD_OPT ("--gid=%u", p->gid);
> 
> +  if (fs->next_task != MACH_PORT_NULL)
> +    ADD_OPT ("--next-task=%u", fs->next_task);
> +
>  #undef ADD_OPT
>    return err;
>  }
> diff --git a/acpi/options.h b/acpi/options.h
> index 36ccc48b..53c98ab1 100644
> --- a/acpi/options.h
> +++ b/acpi/options.h
> @@ -36,6 +36,11 @@ struct parse_hook
>  {
>    struct acpifs_perm perm;
>    size_t ncache_len;
> +
> +  /* Mach ports */
> +  mach_port_t next_task;
> +  mach_port_t host_priv_port;
> +  mach_port_t dev_master_port;
>  };
> 
>  /* ACPI translator options.  Used for both startup and runtime.  */
> @@ -43,6 +48,9 @@ static const struct argp_option options[] = {
>    {0, 0, 0, 0, "These apply to the whole acpi tree:", 1},
>    {"uid", 'U', "UID", 0, "User ID to give permissions to"},
>    {"gid", 'G', "GID", 0, "Group ID to give permissions to"},
> +  {"next-task", 'N', "TASK", 0, "Next bootstrap task"},
> +  {"host-priv-port", 'H', "PORT", 0, "Port for bootstrapping host"},
> +  {"device-master-port", 'P', "PORT", 0, "Port for bootstrapping device 
> master"},
>    {0}
>  };
> 
> --
> 2.34.1
> 
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]