This pull request contains the following changes for UML:
- Devicetree support (for testing) - Various cleanups and fixes: UBD, port_user, uml_mconsole - Maintainer update -----BEGIN PGP SIGNATURE----- iQJKBAABCAA0FiEEdgfidid8lnn52cLTZvlZhesYu8EFAmJFwUMWHHJpY2hhcmRA c2lnbWEtc3Rhci5hdAAKCRBm+VmF6xi7wQqBD/9gLyeiVp2eu1YFVir64IASgVjK lNdlAfUwfebtEsw65JcfY8K64910ahw6TvkjTT2A+QGeJIYaVwmw69bLXJUvQq31 C7ZDsMHptuNiZrHDL9SoA0DfwqRdJx3tgGzDnSkhX+2T7Zs5n1nLRMBmn/NJV9Qy CmxG9fLH1VsU0p6RI76WST3GPLOqWa3jCeHK1vMGZNXI+eo5prHc59lkOcT7lEy7 M4vJRaAV6pCDDYMQdDOYr1PDEeG7/h49EqdKylkOhonDyYB649rL6Lc9nRBvSts3 NXX/qYy1Sj1AlOSR5IOon6QCyk1hap9kr85QoCtz3VMabD/yLlBovZzLOLaF+0S6 dQWgKg806g8QYQGxN03Ph0Pb5cA6hAjr8nVmAuICJDWgmY6Oo74pEvhI8toofFzk NJzwa6G99xNhfggeTcGdG0ddQDT8N3enKspDPkzpN127GzU5cgvI1Z8wnZXB7JDM zLMCxzwehocCSrFlh9aQDFK1XJfEWuP66xEPl5cX46//IMKqsrXEOjNlCTRUmA5F OhU4qqb01OW3K4HPaAkBcGPZ0HhFn6JREUFyNW07dg6s73IWzf0CaNKeYJS7abln tdvfPg3OPNXCjHd3aCW22EzuB9R/K8BNMkva3QQZxtUa+tOjBdBd9JBJ+vHGA1MN 7/k60wl1dt8/N9yHFg== =YsK8 -----END PGP SIGNATURE----- Merge tag 'for-linus-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml Pull UML updates from Richard Weinberger: - Devicetree support (for testing) - Various cleanups and fixes: UBD, port_user, uml_mconsole - Maintainer update * tag 'for-linus-5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml: um: run_helper: Write error message to kernel log on exec failure on host um: port_user: Improve error handling when port-helper is not found um: port_user: Allow setting path to port-helper using UML_PORT_HELPER envvar um: port_user: Search for in.telnetd in PATH um: clang: Strip out -mno-global-merge from USER_CFLAGS docs: UML: Mention telnetd for port channel um: Remove unused timeval_to_ns() function um: Fix uml_mconsole stop/go um: Cleanup syscall_handler_t definition/cast, fix warning uml: net: vector: fix const issue um: Fix WRITE_ZEROES in the UBD Driver um: Migrate vector drivers to NAPI um: Fix order of dtb unflatten/early init um: fix and optimize xor select template for CONFIG64 and timetravel mode um: Document dtb command line option lib/logic_iomem: correct fallback config references um: Remove duplicated include in syscalls_64.c MAINTAINERS: Update UserModeLinux entry
This commit is contained in:
Коммит
e8b767f5e0
|
@ -1193,6 +1193,26 @@ E.g. ``os_close_file()`` is just a wrapper around ``close()``
|
|||
which ensures that the userspace function close does not clash
|
||||
with similarly named function(s) in the kernel part.
|
||||
|
||||
Using UML as a Test Platform
|
||||
============================
|
||||
|
||||
UML is an excellent test platform for device driver development. As
|
||||
with most things UML, "some user assembly may be required". It is
|
||||
up to the user to build their emulation environment. UML at present
|
||||
provides only the kernel infrastructure.
|
||||
|
||||
Part of this infrastructure is the ability to load and parse fdt
|
||||
device tree blobs as used in Arm or Open Firmware platforms. These
|
||||
are supplied as an optional extra argument to the kernel command
|
||||
line::
|
||||
|
||||
dtb=filename
|
||||
|
||||
The device tree is loaded and parsed at boottime and is accessible by
|
||||
drivers which query it. At this moment in time this facility is
|
||||
intended solely for development purposes. UML's own devices do not
|
||||
query the device tree.
|
||||
|
||||
Security Considerations
|
||||
-----------------------
|
||||
|
||||
|
|
|
@ -20539,14 +20539,15 @@ F: Documentation/admin-guide/media/zr364xx*
|
|||
F: drivers/media/usb/zr364xx/
|
||||
|
||||
USER-MODE LINUX (UML)
|
||||
M: Jeff Dike <jdike@addtoit.com>
|
||||
M: Richard Weinberger <richard@nod.at>
|
||||
M: Anton Ivanov <anton.ivanov@cambridgegreys.com>
|
||||
M: Johannes Berg <johannes@sipsolutions.net>
|
||||
L: linux-um@lists.infradead.org
|
||||
S: Maintained
|
||||
W: http://user-mode-linux.sourceforge.net
|
||||
Q: https://patchwork.ozlabs.org/project/linux-um/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux.git next
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/uml/linux.git fixes
|
||||
F: Documentation/virt/uml/
|
||||
F: arch/um/
|
||||
F: arch/x86/um/
|
||||
|
|
|
@ -75,6 +75,10 @@ USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \
|
|||
-D_FILE_OFFSET_BITS=64 -idirafter $(srctree)/include \
|
||||
-idirafter $(objtree)/include -D__KERNEL__ -D__UM_HOST__
|
||||
|
||||
ifdef CONFIG_CC_IS_CLANG
|
||||
USER_CFLAGS := $(patsubst -mno-global-merge,,$(USER_CFLAGS))
|
||||
endif
|
||||
|
||||
#This will adjust *FLAGS accordingly to the platform.
|
||||
include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ void mconsole_go(struct mc_request *req)
|
|||
|
||||
void mconsole_stop(struct mc_request *req)
|
||||
{
|
||||
deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
|
||||
block_signals();
|
||||
os_set_fd_block(req->originating_fd, 1);
|
||||
mconsole_reply(req, "stopped", 0, 0);
|
||||
for (;;) {
|
||||
|
@ -247,6 +247,7 @@ void mconsole_stop(struct mc_request *req)
|
|||
}
|
||||
os_set_fd_block(req->originating_fd, 0);
|
||||
mconsole_reply(req, "", 0, 0);
|
||||
unblock_signals();
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(mc_devices_lock);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
@ -167,14 +168,29 @@ static void port_pre_exec(void *arg)
|
|||
int port_connection(int fd, int *socket, int *pid_out)
|
||||
{
|
||||
int new, err;
|
||||
char *argv[] = { "/usr/sbin/in.telnetd", "-L",
|
||||
char *env;
|
||||
char *argv[] = { "in.telnetd", "-L",
|
||||
OS_LIB_PATH "/uml/port-helper", NULL };
|
||||
struct port_pre_exec_data data;
|
||||
|
||||
if ((env = getenv("UML_PORT_HELPER")))
|
||||
argv[2] = env;
|
||||
|
||||
new = accept(fd, NULL, 0);
|
||||
if (new < 0)
|
||||
return -errno;
|
||||
|
||||
err = os_access(argv[2], X_OK);
|
||||
if (err < 0) {
|
||||
printk(UM_KERN_ERR "port_connection : error accessing port-helper "
|
||||
"executable at %s: %s\n", argv[2], strerror(-err));
|
||||
if (env == NULL)
|
||||
printk(UM_KERN_ERR "Set UML_PORT_HELPER environment "
|
||||
"variable to path to uml-utilities port-helper "
|
||||
"binary\n");
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
err = os_pipe(socket, 0, 0);
|
||||
if (err < 0)
|
||||
goto out_close;
|
||||
|
|
|
@ -1526,13 +1526,19 @@ static void do_io(struct io_thread_req *req, struct io_desc *desc)
|
|||
}
|
||||
break;
|
||||
case REQ_OP_DISCARD:
|
||||
case REQ_OP_WRITE_ZEROES:
|
||||
n = os_falloc_punch(req->fds[bit], off, len);
|
||||
if (n) {
|
||||
req->error = map_error(-n);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case REQ_OP_WRITE_ZEROES:
|
||||
n = os_falloc_zeroes(req->fds[bit], off, len);
|
||||
if (n) {
|
||||
req->error = map_error(-n);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
req->error = BLK_STS_NOTSUPP;
|
||||
|
|
|
@ -67,6 +67,7 @@ static LIST_HEAD(vector_devices);
|
|||
static int driver_registered;
|
||||
|
||||
static void vector_eth_configure(int n, struct arglist *def);
|
||||
static int vector_mmsg_rx(struct vector_private *vp, int budget);
|
||||
|
||||
/* Argument accessors to set variables (and/or set default values)
|
||||
* mtu, buffer sizing, default headroom, etc
|
||||
|
@ -77,7 +78,6 @@ static void vector_eth_configure(int n, struct arglist *def);
|
|||
#define DEFAULT_VECTOR_SIZE 64
|
||||
#define TX_SMALL_PACKET 128
|
||||
#define MAX_IOV_SIZE (MAX_SKB_FRAGS + 1)
|
||||
#define MAX_ITERATIONS 64
|
||||
|
||||
static const struct {
|
||||
const char string[ETH_GSTRING_LEN];
|
||||
|
@ -458,7 +458,6 @@ static int vector_send(struct vector_queue *qi)
|
|||
vp->estats.tx_queue_running_average =
|
||||
(vp->estats.tx_queue_running_average + result) >> 1;
|
||||
}
|
||||
netif_trans_update(qi->dev);
|
||||
netif_wake_queue(qi->dev);
|
||||
/* if TX is busy, break out of the send loop,
|
||||
* poll write IRQ will reschedule xmit for us
|
||||
|
@ -470,8 +469,6 @@ static int vector_send(struct vector_queue *qi)
|
|||
}
|
||||
}
|
||||
spin_unlock(&qi->head_lock);
|
||||
} else {
|
||||
tasklet_schedule(&vp->tx_poll);
|
||||
}
|
||||
return queue_depth;
|
||||
}
|
||||
|
@ -608,7 +605,7 @@ out_fail:
|
|||
|
||||
/*
|
||||
* We do not use the RX queue as a proper wraparound queue for now
|
||||
* This is not necessary because the consumption via netif_rx()
|
||||
* This is not necessary because the consumption via napi_gro_receive()
|
||||
* happens in-line. While we can try using the return code of
|
||||
* netif_rx() for flow control there are no drivers doing this today.
|
||||
* For this RX specific use we ignore the tail/head locks and
|
||||
|
@ -896,7 +893,7 @@ static int vector_legacy_rx(struct vector_private *vp)
|
|||
skb->protocol = eth_type_trans(skb, skb->dev);
|
||||
vp->dev->stats.rx_bytes += skb->len;
|
||||
vp->dev->stats.rx_packets++;
|
||||
netif_rx(skb);
|
||||
napi_gro_receive(&vp->napi, skb);
|
||||
} else {
|
||||
dev_kfree_skb_irq(skb);
|
||||
}
|
||||
|
@ -955,7 +952,7 @@ drop:
|
|||
* mmsg vector matched to an skb vector which we prepared earlier.
|
||||
*/
|
||||
|
||||
static int vector_mmsg_rx(struct vector_private *vp)
|
||||
static int vector_mmsg_rx(struct vector_private *vp, int budget)
|
||||
{
|
||||
int packet_count, i;
|
||||
struct vector_queue *qi = vp->rx_queue;
|
||||
|
@ -972,6 +969,9 @@ static int vector_mmsg_rx(struct vector_private *vp)
|
|||
|
||||
/* Fire the Lazy Gun - get as many packets as we can in one go. */
|
||||
|
||||
if (budget > qi->max_depth)
|
||||
budget = qi->max_depth;
|
||||
|
||||
packet_count = uml_vector_recvmmsg(
|
||||
vp->fds->rx_fd, qi->mmsg_vector, qi->max_depth, 0);
|
||||
|
||||
|
@ -1021,7 +1021,7 @@ static int vector_mmsg_rx(struct vector_private *vp)
|
|||
*/
|
||||
vp->dev->stats.rx_bytes += skb->len;
|
||||
vp->dev->stats.rx_packets++;
|
||||
netif_rx(skb);
|
||||
napi_gro_receive(&vp->napi, skb);
|
||||
} else {
|
||||
/* Overlay header too short to do anything - discard.
|
||||
* We can actually keep this skb and reuse it,
|
||||
|
@ -1044,23 +1044,6 @@ static int vector_mmsg_rx(struct vector_private *vp)
|
|||
return packet_count;
|
||||
}
|
||||
|
||||
static void vector_rx(struct vector_private *vp)
|
||||
{
|
||||
int err;
|
||||
int iter = 0;
|
||||
|
||||
if ((vp->options & VECTOR_RX) > 0)
|
||||
while (((err = vector_mmsg_rx(vp)) > 0) && (iter < MAX_ITERATIONS))
|
||||
iter++;
|
||||
else
|
||||
while (((err = vector_legacy_rx(vp)) > 0) && (iter < MAX_ITERATIONS))
|
||||
iter++;
|
||||
if ((err != 0) && net_ratelimit())
|
||||
netdev_err(vp->dev, "vector_rx: error(%d)\n", err);
|
||||
if (iter == MAX_ITERATIONS)
|
||||
netdev_err(vp->dev, "vector_rx: device stuck, remote end may have closed the connection\n");
|
||||
}
|
||||
|
||||
static int vector_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct vector_private *vp = netdev_priv(dev);
|
||||
|
@ -1085,25 +1068,15 @@ static int vector_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
netdev_sent_queue(vp->dev, skb->len);
|
||||
queue_depth = vector_enqueue(vp->tx_queue, skb);
|
||||
|
||||
/* if the device queue is full, stop the upper layers and
|
||||
* flush it.
|
||||
*/
|
||||
|
||||
if (queue_depth >= vp->tx_queue->max_depth - 1) {
|
||||
vp->estats.tx_kicks++;
|
||||
netif_stop_queue(dev);
|
||||
vector_send(vp->tx_queue);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
if (netdev_xmit_more()) {
|
||||
if (queue_depth < vp->tx_queue->max_depth && netdev_xmit_more()) {
|
||||
mod_timer(&vp->tl, vp->coalesce);
|
||||
return NETDEV_TX_OK;
|
||||
} else {
|
||||
queue_depth = vector_send(vp->tx_queue);
|
||||
if (queue_depth > 0)
|
||||
napi_schedule(&vp->napi);
|
||||
}
|
||||
if (skb->len < TX_SMALL_PACKET) {
|
||||
vp->estats.tx_kicks++;
|
||||
vector_send(vp->tx_queue);
|
||||
} else
|
||||
tasklet_schedule(&vp->tx_poll);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
|
@ -1114,7 +1087,7 @@ static irqreturn_t vector_rx_interrupt(int irq, void *dev_id)
|
|||
|
||||
if (!netif_running(dev))
|
||||
return IRQ_NONE;
|
||||
vector_rx(vp);
|
||||
napi_schedule(&vp->napi);
|
||||
return IRQ_HANDLED;
|
||||
|
||||
}
|
||||
|
@ -1133,8 +1106,7 @@ static irqreturn_t vector_tx_interrupt(int irq, void *dev_id)
|
|||
* tweaking the IRQ mask less costly
|
||||
*/
|
||||
|
||||
if (vp->in_write_poll)
|
||||
tasklet_schedule(&vp->tx_poll);
|
||||
napi_schedule(&vp->napi);
|
||||
return IRQ_HANDLED;
|
||||
|
||||
}
|
||||
|
@ -1161,7 +1133,8 @@ static int vector_net_close(struct net_device *dev)
|
|||
um_free_irq(vp->tx_irq, dev);
|
||||
vp->tx_irq = 0;
|
||||
}
|
||||
tasklet_kill(&vp->tx_poll);
|
||||
napi_disable(&vp->napi);
|
||||
netif_napi_del(&vp->napi);
|
||||
if (vp->fds->rx_fd > 0) {
|
||||
if (vp->bpf)
|
||||
uml_vector_detach_bpf(vp->fds->rx_fd, vp->bpf);
|
||||
|
@ -1193,15 +1166,32 @@ static int vector_net_close(struct net_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* TX tasklet */
|
||||
|
||||
static void vector_tx_poll(struct tasklet_struct *t)
|
||||
static int vector_poll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct vector_private *vp = from_tasklet(vp, t, tx_poll);
|
||||
struct vector_private *vp = container_of(napi, struct vector_private, napi);
|
||||
int work_done = 0;
|
||||
int err;
|
||||
bool tx_enqueued = false;
|
||||
|
||||
vp->estats.tx_kicks++;
|
||||
vector_send(vp->tx_queue);
|
||||
if ((vp->options & VECTOR_TX) != 0)
|
||||
tx_enqueued = (vector_send(vp->tx_queue) > 0);
|
||||
if ((vp->options & VECTOR_RX) > 0)
|
||||
err = vector_mmsg_rx(vp, budget);
|
||||
else {
|
||||
err = vector_legacy_rx(vp);
|
||||
if (err > 0)
|
||||
err = 1;
|
||||
}
|
||||
if (err > 0)
|
||||
work_done += err;
|
||||
|
||||
if (tx_enqueued || err > 0)
|
||||
napi_schedule(napi);
|
||||
if (work_done < budget)
|
||||
napi_complete_done(napi, work_done);
|
||||
return work_done;
|
||||
}
|
||||
|
||||
static void vector_reset_tx(struct work_struct *work)
|
||||
{
|
||||
struct vector_private *vp =
|
||||
|
@ -1265,6 +1255,9 @@ static int vector_net_open(struct net_device *dev)
|
|||
goto out_close;
|
||||
}
|
||||
|
||||
netif_napi_add(vp->dev, &vp->napi, vector_poll, get_depth(vp->parsed));
|
||||
napi_enable(&vp->napi);
|
||||
|
||||
/* READ IRQ */
|
||||
err = um_request_irq(
|
||||
irq_rr + VECTOR_BASE_IRQ, vp->fds->rx_fd,
|
||||
|
@ -1306,15 +1299,15 @@ static int vector_net_open(struct net_device *dev)
|
|||
uml_vector_attach_bpf(vp->fds->rx_fd, vp->bpf);
|
||||
|
||||
netif_start_queue(dev);
|
||||
vector_reset_stats(vp);
|
||||
|
||||
/* clear buffer - it can happen that the host side of the interface
|
||||
* is full when we get here. In this case, new data is never queued,
|
||||
* SIGIOs never arrive, and the net never works.
|
||||
*/
|
||||
|
||||
vector_rx(vp);
|
||||
napi_schedule(&vp->napi);
|
||||
|
||||
vector_reset_stats(vp);
|
||||
vdevice = find_device(vp->unit);
|
||||
vdevice->opened = 1;
|
||||
|
||||
|
@ -1543,15 +1536,16 @@ static const struct net_device_ops vector_netdev_ops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
|
||||
static void vector_timer_expire(struct timer_list *t)
|
||||
{
|
||||
struct vector_private *vp = from_timer(vp, t, tl);
|
||||
|
||||
vp->estats.tx_kicks++;
|
||||
vector_send(vp->tx_queue);
|
||||
napi_schedule(&vp->napi);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void vector_eth_configure(
|
||||
int n,
|
||||
struct arglist *def
|
||||
|
@ -1634,7 +1628,6 @@ static void vector_eth_configure(
|
|||
});
|
||||
|
||||
dev->features = dev->hw_features = (NETIF_F_SG | NETIF_F_FRAGLIST);
|
||||
tasklet_setup(&vp->tx_poll, vector_tx_poll);
|
||||
INIT_WORK(&vp->reset_tx, vector_reset_tx);
|
||||
|
||||
timer_setup(&vp->tl, vector_timer_expire, 0);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/ctype.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "vector_user.h"
|
||||
|
||||
/* Queue structure specially adapted for multiple enqueue/dequeue
|
||||
|
@ -72,6 +73,7 @@ struct vector_private {
|
|||
struct list_head list;
|
||||
spinlock_t lock;
|
||||
struct net_device *dev;
|
||||
struct napi_struct napi ____cacheline_aligned;
|
||||
|
||||
int unit;
|
||||
|
||||
|
@ -115,7 +117,6 @@ struct vector_private {
|
|||
|
||||
spinlock_t stats_lock;
|
||||
|
||||
struct tasklet_struct tx_poll;
|
||||
bool rexmit_scheduled;
|
||||
bool opened;
|
||||
bool in_write_poll;
|
||||
|
|
|
@ -771,7 +771,7 @@ int uml_vector_detach_bpf(int fd, void *bpf)
|
|||
printk(KERN_ERR BPF_DETACH_FAIL, prog->len, prog->filter, fd, -errno);
|
||||
return err;
|
||||
}
|
||||
void *uml_vector_default_bpf(void *mac)
|
||||
void *uml_vector_default_bpf(const void *mac)
|
||||
{
|
||||
struct sock_filter *bpf;
|
||||
uint32_t *mac1 = (uint32_t *)(mac + 2);
|
||||
|
|
|
@ -97,7 +97,7 @@ extern int uml_vector_recvmmsg(
|
|||
unsigned int vlen,
|
||||
unsigned int flags
|
||||
);
|
||||
extern void *uml_vector_default_bpf(void *mac);
|
||||
extern void *uml_vector_default_bpf(const void *mac);
|
||||
extern void *uml_vector_user_bpf(char *filename);
|
||||
extern int uml_vector_attach_bpf(int fd, void *bpf);
|
||||
extern int uml_vector_detach_bpf(int fd, void *bpf);
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
|
||||
#ifdef CONFIG_64BIT
|
||||
#undef CONFIG_X86_32
|
||||
#define TT_CPU_INF_XOR_DEFAULT (AVX_SELECT(&xor_block_sse_pf64))
|
||||
#else
|
||||
#define CONFIG_X86_32 1
|
||||
#define TT_CPU_INF_XOR_DEFAULT (AVX_SELECT(&xor_block_8regs))
|
||||
#endif
|
||||
|
||||
#include <asm/cpufeature.h>
|
||||
|
@ -16,7 +18,7 @@
|
|||
#undef XOR_SELECT_TEMPLATE
|
||||
/* pick an arbitrary one - measuring isn't possible with inf-cpu */
|
||||
#define XOR_SELECT_TEMPLATE(x) \
|
||||
(time_travel_mode == TT_MODE_INFCPU ? &xor_block_8regs : NULL)
|
||||
(time_travel_mode == TT_MODE_INFCPU ? TT_CPU_INF_XOR_DEFAULT : x))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -168,6 +168,7 @@ extern unsigned os_major(unsigned long long dev);
|
|||
extern unsigned os_minor(unsigned long long dev);
|
||||
extern unsigned long long os_makedev(unsigned major, unsigned minor);
|
||||
extern int os_falloc_punch(int fd, unsigned long long offset, int count);
|
||||
extern int os_falloc_zeroes(int fd, unsigned long long offset, int count);
|
||||
extern int os_eventfd(unsigned int initval, int flags);
|
||||
extern int os_sendmsg_fds(int fd, const void *buf, unsigned int len,
|
||||
const int *fds, unsigned int fds_num);
|
||||
|
|
|
@ -25,8 +25,8 @@ void uml_dtb_init(void)
|
|||
return;
|
||||
}
|
||||
|
||||
unflatten_device_tree();
|
||||
early_init_fdt_scan_reserved_mem();
|
||||
unflatten_device_tree();
|
||||
}
|
||||
|
||||
static int __init uml_dtb_setup(char *line, int *add)
|
||||
|
|
|
@ -625,6 +625,15 @@ int os_falloc_punch(int fd, unsigned long long offset, int len)
|
|||
return n;
|
||||
}
|
||||
|
||||
int os_falloc_zeroes(int fd, unsigned long long offset, int len)
|
||||
{
|
||||
int n = fallocate(fd, FALLOC_FL_ZERO_RANGE|FALLOC_FL_KEEP_SIZE, offset, len);
|
||||
|
||||
if (n < 0)
|
||||
return -errno;
|
||||
return n;
|
||||
}
|
||||
|
||||
int os_eventfd(unsigned int initval, int flags)
|
||||
{
|
||||
int fd = eventfd(initval, flags);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
|
@ -99,6 +100,10 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
|
|||
CATCH_EINTR(waitpid(pid, NULL, __WALL));
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
printk(UM_KERN_ERR "run_helper : failed to exec %s on host: %s\n",
|
||||
argv[0], strerror(-ret));
|
||||
|
||||
out_free2:
|
||||
kfree(data.buf);
|
||||
out_close:
|
||||
|
|
|
@ -18,12 +18,6 @@
|
|||
|
||||
static timer_t event_high_res_timer = 0;
|
||||
|
||||
static inline long long timeval_to_ns(const struct timeval *tv)
|
||||
{
|
||||
return ((long long) tv->tv_sec * UM_NSEC_PER_SEC) +
|
||||
tv->tv_usec * UM_NSEC_PER_USEC;
|
||||
}
|
||||
|
||||
static inline long long timespec_to_ns(const struct timespec *ts)
|
||||
{
|
||||
return ((long long) ts->tv_sec * UM_NSEC_PER_SEC) + ts->tv_nsec;
|
||||
|
|
|
@ -10,13 +10,12 @@
|
|||
#include <linux/msg.h>
|
||||
#include <linux/shm.h>
|
||||
|
||||
typedef long syscall_handler_t(void);
|
||||
typedef long syscall_handler_t(long, long, long, long, long, long);
|
||||
|
||||
extern syscall_handler_t *sys_call_table[];
|
||||
|
||||
#define EXECUTE_SYSCALL(syscall, regs) \
|
||||
(((long (*)(long, long, long, long, long, long)) \
|
||||
(*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(®s->regs), \
|
||||
(((*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(®s->regs), \
|
||||
UPT_SYSCALL_ARG2(®s->regs), \
|
||||
UPT_SYSCALL_ARG3(®s->regs), \
|
||||
UPT_SYSCALL_ARG4(®s->regs), \
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include <asm/prctl.h> /* XXX This should get the constants from libc */
|
||||
#include <registers.h>
|
||||
#include <os.h>
|
||||
#include <registers.h>
|
||||
|
||||
long arch_prctl(struct task_struct *task, int option,
|
||||
unsigned long __user *arg2)
|
||||
|
|
|
@ -68,7 +68,7 @@ int logic_iomem_add_region(struct resource *resource,
|
|||
}
|
||||
EXPORT_SYMBOL(logic_iomem_add_region);
|
||||
|
||||
#ifndef CONFIG_LOGIC_IOMEM_FALLBACK
|
||||
#ifndef CONFIG_INDIRECT_IOMEM_FALLBACK
|
||||
static void __iomem *real_ioremap(phys_addr_t offset, size_t size)
|
||||
{
|
||||
WARN(1, "invalid ioremap(0x%llx, 0x%zx)\n",
|
||||
|
@ -81,7 +81,7 @@ static void real_iounmap(volatile void __iomem *addr)
|
|||
WARN(1, "invalid iounmap for addr 0x%llx\n",
|
||||
(unsigned long long)(uintptr_t __force)addr);
|
||||
}
|
||||
#endif /* CONFIG_LOGIC_IOMEM_FALLBACK */
|
||||
#endif /* CONFIG_INDIRECT_IOMEM_FALLBACK */
|
||||
|
||||
void __iomem *ioremap(phys_addr_t offset, size_t size)
|
||||
{
|
||||
|
@ -168,7 +168,7 @@ void iounmap(volatile void __iomem *addr)
|
|||
}
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
|
||||
#ifndef CONFIG_LOGIC_IOMEM_FALLBACK
|
||||
#ifndef CONFIG_INDIRECT_IOMEM_FALLBACK
|
||||
#define MAKE_FALLBACK(op, sz) \
|
||||
static u##sz real_raw_read ## op(const volatile void __iomem *addr) \
|
||||
{ \
|
||||
|
@ -213,7 +213,7 @@ static void real_memcpy_toio(volatile void __iomem *addr, const void *buffer,
|
|||
WARN(1, "Invalid memcpy_toio at address 0x%llx\n",
|
||||
(unsigned long long)(uintptr_t __force)addr);
|
||||
}
|
||||
#endif /* CONFIG_LOGIC_IOMEM_FALLBACK */
|
||||
#endif /* CONFIG_INDIRECT_IOMEM_FALLBACK */
|
||||
|
||||
#define MAKE_OP(op, sz) \
|
||||
u##sz __raw_read ## op(const volatile void __iomem *addr) \
|
||||
|
|
Загрузка…
Ссылка в новой задаче