Il 28/08/2013 22:58, Chris Metcalf ha scritto:
> This change enables support for a virtio-based console,
> network support, and block driver support.
> 
> We remove some debug code in relocate_kernel_64.S that made raw
> calls to the hv_console_putc Tilera hypervisor API, since everything
> now should funnel through the early_hv_write() API.
> 
> Signed-off-by: Chris Metcalf <cmetc...@tilera.com>

Why couldn't this use the "regular" virtio-mmio interface?

> diff --git a/arch/tile/include/asm/kvm_virtio.h 
> b/arch/tile/include/asm/kvm_virtio.h
> new file mode 100644
> index 0000000..8faa959
> --- /dev/null
> +++ b/arch/tile/include/asm/kvm_virtio.h
> @@ -0,0 +1,26 @@
> +/*
> + * Copyright 2013 Tilera Corporation. All Rights Reserved.
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +#ifndef _ASM_TILE_KVM_VIRTIO_H
> +#define _ASM_TILE_KVM_VIRTIO_H
> +
> +#include <uapi/asm/kvm_virtio.h>
> +
> +
> +struct kvm_device {
> +     struct virtio_device vdev;
> +     struct kvm_device_desc *desc;
> +     unsigned long desc_pa;
> +};
> +
> +#endif /* _ASM_TILE_KVM_VIRTIO_H */
> diff --git a/arch/tile/include/uapi/asm/Kbuild 
> b/arch/tile/include/uapi/asm/Kbuild
> index 89022a5..f07cc24 100644
> --- a/arch/tile/include/uapi/asm/Kbuild
> +++ b/arch/tile/include/uapi/asm/Kbuild
> @@ -8,6 +8,7 @@ header-y += cachectl.h
>  header-y += hardwall.h
>  header-y += kvm.h
>  header-y += kvm_para.h
> +header-y += kvm_virtio.h
>  header-y += mman.h
>  header-y += ptrace.h
>  header-y += setup.h
> diff --git a/arch/tile/include/uapi/asm/kvm.h 
> b/arch/tile/include/uapi/asm/kvm.h
> index aa7b97f..4346520 100644
> --- a/arch/tile/include/uapi/asm/kvm.h
> +++ b/arch/tile/include/uapi/asm/kvm.h
> @@ -149,6 +149,9 @@
>   */
>  #define KVM_OTHER_HCALL                  128
>  
> +/* Hypercall index for virtio. */
> +#define KVM_HCALL_virtio                 128
> +
>  /* One greater than the maximum hypercall number. */
>  #define KVM_NUM_HCALLS                   256
>  
> @@ -256,6 +259,8 @@ struct kvm_sync_regs {
>       KVM_EMULATE(get_ipi_pte) \
>       KVM_EMULATE(set_pte_super_shift) \
>       KVM_EMULATE(set_speed) \
> +     /* For others */ \
> +     USER_HCALL(virtio)

Ah, here it is. :)

>  
>  #endif
>  
> diff --git a/arch/tile/include/uapi/asm/kvm_virtio.h 
> b/arch/tile/include/uapi/asm/kvm_virtio.h
> new file mode 100644
> index 0000000..d94f535
> --- /dev/null
> +++ b/arch/tile/include/uapi/asm/kvm_virtio.h
> @@ -0,0 +1,60 @@
> +/*
> + * Copyright 2013 Tilera Corporation. All Rights Reserved.
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +
> +#ifndef _UAPI_ASM_TILE_KVM_VIRTIO_H
> +#define _UAPI_ASM_TILE_KVM_VIRTIO_H
> +
> +#include <linux/types.h>
> +
> +#define KVM_VIRTIO_UNKNOWN   0
> +#define KVM_VIRTIO_NOTIFY    1
> +#define KVM_VIRTIO_RESET     2
> +#define KVM_VIRTIO_SET_STATUS        3
> +
> +struct kvm_device_desc {
> +     /* The device type: console, network, disk etc.  Type 0 terminates. */
> +     __u8 type;
> +     /* The number of virtqueues (first in config array) */
> +     __u8 num_vq;
> +     /*
> +      * The number of bytes of feature bits.  Multiply by 2: one for host
> +      * features and one for Guest acknowledgements.
> +      */
> +     __u8 feature_len;
> +     /* The number of bytes of the config array after virtqueues. */
> +     __u8 config_len;
> +     /* A status byte, written by the Guest. */
> +     __u8 status;
> +     __u64 config[0];
> +};
> +
> +struct kvm_vqinfo {
> +     /* Pointer to the information contained in the device config. */
> +     struct kvm_vqconfig *config;
> +     /* The address where we mapped the virtio ring, so we can unmap it. */
> +     void *pages;
> +};
> +
> +struct kvm_vqconfig {
> +     /* The physical address of the virtio ring */
> +     __u64 pa;
> +     /* The number of entries in the virtio_ring */
> +     __u64 num;
> +     /* The interrupt we get when something happens. Set by the guest. */
> +     __u32 irq;
> +
> +};
> +
> +
> +#endif /* _UAPI_ASM_TILE_KVM_VIRTIO_H */
> diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile
> index b7c8b5e..b638d3e 100644
> --- a/arch/tile/kernel/Makefile
> +++ b/arch/tile/kernel/Makefile
> @@ -29,5 +29,6 @@ obj-$(CONFIG_TILE_USB)              += usb.o
>  obj-$(CONFIG_TILE_HVGLUE_TRACE)      += hvglue_trace.o
>  obj-$(CONFIG_FUNCTION_TRACER)        += ftrace.o mcount_64.o
>  obj-$(CONFIG_KPROBES)                += kprobes.o
> +obj-$(CONFIG_KVM_GUEST)              += kvm_virtio.o
>  
>  obj-y                                += vdso/
> diff --git a/arch/tile/kernel/early_printk.c b/arch/tile/kernel/early_printk.c
> index b608e00..53f2be4 100644
> --- a/arch/tile/kernel/early_printk.c
> +++ b/arch/tile/kernel/early_printk.c
> @@ -18,11 +18,26 @@
>  #include <linux/string.h>
>  #include <linux/irqflags.h>
>  #include <linux/printk.h>
> +#ifdef CONFIG_KVM_GUEST
> +#include <linux/virtio_console.h>
> +#include <linux/kvm_para.h>
> +#include <asm/kvm_virtio.h>
> +#endif
>  #include <asm/setup.h>
>  #include <hv/hypervisor.h>
>  
>  static void early_hv_write(struct console *con, const char *s, unsigned n)
>  {
> +#ifdef CONFIG_KVM_GUEST
> +     char buf[512];
> +
> +     if (n > sizeof(buf) - 1)
> +             n = sizeof(buf) - 1;
> +     memcpy(buf, s, n);
> +     buf[n] = '\0';
> +
> +     hcall_virtio(KVM_VIRTIO_NOTIFY, __pa(buf));

How can userspace know the difference between KVM_VIRTIO_NOTIFY with a
string buffer, and KVM_VIRTIO_NOTIFY with a config space pointer?

In fact, this looks like a completely separate hypercall, why not keep
hv_console_putc?

> index 0000000..c6b6c6a
> --- /dev/null
> +++ b/arch/tile/kernel/kvm_virtio.c
> @@ -0,0 +1,430 @@
> +/*
> + * Copyright 2013 Tilera Corporation. All Rights Reserved.
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +
> +/* Referred lguest & s390 implemenation */
> +/*
> + * kvm_virtio.c - virtio for kvm on s390
> + *
> + * Copyright IBM Corp. 2008
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License (version 2 only)
> + * as published by the Free Software Foundation.
> + *
> + *    Author(s): Christian Borntraeger <borntrae...@de.ibm.com>
> + */

This has the same problem as the old s390 implementation (there is a new
one that emulates the usual s390 I/O instead of using
paravirtualization); it doesn't raise an interrupt on config space writes.

Apart from this it looks good, but I'm not sure why it is necessary.

> +#include <linux/bootmem.h>
> +#include <linux/io.h>
> +#include <linux/vmalloc.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/export.h>
> +#include <linux/virtio.h>
> +#include <linux/virtio_config.h>
> +#include <linux/virtio_console.h>
> +#include <linux/virtio_ring.h>
> +#include <linux/virtio_pci.h>
> +
> +#include <linux/kvm_para.h>
> +#include <asm/kvm_virtio.h>
> +
> +static void *kvm_devices;
> +
> +/*
> + * TODO: We actually does not use PCI virtio here. We use this
> + * because qemu: virtqueue_init() uses VIRTIO_PCI_VRING_ALIGN.
> + * Maybe we should change them to generic definitions in both qemu & Linux.
> + * Besides, Let's check whether the alignment value (4096, i.e. default
> + * x86 page size) affects performance later.
> + */
> +#define KVM_TILE_VIRTIO_RING_ALIGN   VIRTIO_PCI_VRING_ALIGN
> +#define to_kvmdev(vd)        container_of(vd, struct kvm_device, vdev)
> +
> +/*
> + * memory layout: (Total: PAGE_SIZE)
> + * <device 0>
> + * - kvm device descriptor
> + *        struct kvm_device_desc
> + * - vqueue configuration (totally desc->num_vq)
> + *        struct kvm_vqconfig
> + *        ......
> + *        struct kvm_vqconfig
> + * - feature bits (size: desc->feature_len * 2)
> + * - config space (size: desc->config_len)
> + * <device 1>
> + * ......
> + */
> +static struct kvm_vqconfig *kvm_vq_config(const struct kvm_device_desc *desc)
> +{
> +     return (struct kvm_vqconfig *)(desc + 1);
> +}
> +
> +static u8 *kvm_vq_features(const struct kvm_device_desc *desc)
> +{
> +     return (u8 *)(kvm_vq_config(desc) + desc->num_vq);
> +}
> +
> +static u8 *kvm_vq_configspace(const struct kvm_device_desc *desc)
> +{
> +     return kvm_vq_features(desc) + desc->feature_len * 2;
> +}
> +
> +/*
> + * The total size of the config page used by this device (incl. desc)
> + */
> +static unsigned desc_size(const struct kvm_device_desc *desc)
> +{
> +     return sizeof(*desc)
> +             + desc->num_vq * sizeof(struct kvm_vqconfig)
> +             + desc->feature_len * 2
> +             + desc->config_len;
> +}
> +
> +/* This gets the device's feature bits. */
> +static u32 kvm_get_features(struct virtio_device *vdev)
> +{
> +     unsigned int i;
> +     u32 features = 0;
> +     struct kvm_device_desc *desc = to_kvmdev(vdev)->desc;
> +     u8 *in_features = kvm_vq_features(desc);
> +
> +     for (i = 0; i < min(desc->feature_len * 8, 32); i++)
> +             if (in_features[i / 8] & (1 << (i % 8)))
> +                     features |= (1 << i);
> +     return features;
> +}
> +
> +static void kvm_finalize_features(struct virtio_device *vdev)
> +{
> +     unsigned int i, bits;
> +     struct kvm_device_desc *desc = to_kvmdev(vdev)->desc;
> +     /* Second half of bitmap is features we accept. */
> +     u8 *out_features = kvm_vq_features(desc) + desc->feature_len;
> +
> +     /* Give virtio_ring a chance to accept features. */
> +     vring_transport_features(vdev);
> +
> +     memset(out_features, 0, desc->feature_len);
> +     bits = min_t(unsigned, desc->feature_len, sizeof(vdev->features)) * 8;
> +     for (i = 0; i < bits; i++) {
> +             if (test_bit(i, vdev->features))
> +                     out_features[i / 8] |= (1 << (i % 8));
> +     }
> +}
> +
> +/*
> + * Reading and writing elements in config space
> + */
> +static void kvm_get(struct virtio_device *vdev, unsigned int offset,
> +                void *buf, unsigned len)
> +{
> +     struct kvm_device_desc *desc = to_kvmdev(vdev)->desc;
> +
> +     BUG_ON(offset + len > desc->config_len);
> +     memcpy(buf, kvm_vq_configspace(desc) + offset, len);
> +}
> +
> +static void kvm_set(struct virtio_device *vdev, unsigned int offset,
> +                const void *buf, unsigned len)
> +{
> +     struct kvm_device_desc *desc = to_kvmdev(vdev)->desc;
> +
> +     BUG_ON(offset + len > desc->config_len);
> +     memcpy(kvm_vq_configspace(desc) + offset, buf, len);
> +}
> +
> +/*
> + * The operations to get and set the status word just access
> + * the status field of the device descriptor. set_status will also
> + * make a hypercall to the host, to tell about status changes
> + */
> +static u8 kvm_get_status(struct virtio_device *vdev)
> +{
> +     return to_kvmdev(vdev)->desc->status;
> +}
> +
> +static void kvm_set_status(struct virtio_device *vdev, u8 status)
> +{
> +     BUG_ON(!status);
> +     to_kvmdev(vdev)->desc->status = status;
> +     hcall_virtio(KVM_VIRTIO_SET_STATUS, to_kvmdev(vdev)->desc_pa);
> +}
> +
> +/*
> + * To reset the device, we use the KVM_VIRTIO_RESET hypercall, using the
> + * descriptor address. The Host will zero the status and all the
> + * features.
> + */
> +static void kvm_reset(struct virtio_device *vdev)
> +{
> +     hcall_virtio(KVM_VIRTIO_RESET, to_kvmdev(vdev)->desc_pa);
> +}
> +
> +/*
> + * When the virtio_ring code wants to notify the Host, it calls us here and 
> we
> + * make a hypercall.  We hand the address  of the virtqueue so the Host
> + * knows which virtqueue we're talking about.
> + */
> +static void kvm_notify(struct virtqueue *vq)
> +{
> +     struct kvm_vqinfo *vqi = vq->priv;
> +
> +     hcall_virtio(KVM_VIRTIO_NOTIFY, vqi->config->pa);
> +}
> +
> +/*
> + * Must set some caching mode to keep set_pte() happy.
> + * It doesn't matter what we choose, because the PFN
> + * is illegal, so we're going to take a page fault anyway.
> + */
> +static inline pgprot_t io_prot(void)
> +{
> +     return hv_pte_set_mode(PAGE_KERNEL, HV_PTE_MODE_UNCACHED);
> +}
> +
> +/*
> + * This routine finds the first virtqueue described in the configuration of
> + * this device and sets it up.
> + */
> +static struct virtqueue *kvm_find_vq(struct virtio_device *vdev,
> +                                  unsigned index,
> +                                  void (*callback)(struct virtqueue *vq),
> +                                  const char *name)
> +{
> +     struct kvm_device *kdev = to_kvmdev(vdev);
> +     struct kvm_vqinfo *vqi;
> +     struct kvm_vqconfig *config;
> +     struct virtqueue *vq;
> +     long irq;
> +     int err = -EINVAL;
> +
> +     if (index >= kdev->desc->num_vq)
> +             return ERR_PTR(-ENOENT);
> +
> +     vqi = kzalloc(sizeof(*vqi), GFP_KERNEL);
> +     if (!vqi)
> +             return ERR_PTR(-ENOMEM);
> +
> +     config = kvm_vq_config(kdev->desc)+index;
> +
> +     vqi->config = config;
> +     vqi->pages = generic_remap_prot(config->pa,
> +                             vring_size(config->num,
> +                                     KVM_TILE_VIRTIO_RING_ALIGN),
> +                                     0, io_prot());
> +     if (!vqi->pages) {
> +             err = -ENOMEM;
> +             goto out;
> +     }
> +
> +     vq = vring_new_virtqueue(index, config->num, KVM_TILE_VIRTIO_RING_ALIGN,
> +                              vdev, 0, vqi->pages,
> +                              kvm_notify, callback, name);
> +     if (!vq) {
> +             err = -ENOMEM;
> +             goto unmap;
> +     }
> +
> +     /*
> +      * Trigger the IPI interrupt in SW way.
> +      * TODO: We do not need to create one irq for each vq. A bit wasteful.
> +      */
> +     irq = create_irq();
> +     if (irq < 0) {
> +             err = -ENXIO;
> +             goto del_virtqueue;
> +     }
> +
> +     tile_irq_activate(irq, TILE_IRQ_SW_CLEAR);
> +
> +     if (request_irq(irq, vring_interrupt, 0, dev_name(&vdev->dev), vq)) {
> +             err = -ENXIO;
> +             destroy_irq(irq);
> +             goto del_virtqueue;
> +     }
> +
> +     config->irq = irq;
> +
> +     vq->priv = vqi;
> +     return vq;
> +
> +del_virtqueue:
> +     vring_del_virtqueue(vq);
> +unmap:
> +     vunmap(vqi->pages);
> +out:
> +     return ERR_PTR(err);
> +}
> +
> +static void kvm_del_vq(struct virtqueue *vq)
> +{
> +     struct kvm_vqinfo *vqi = vq->priv;
> +
> +     vring_del_virtqueue(vq);
> +     vunmap(vqi->pages);
> +     kfree(vqi);
> +}
> +
> +static void kvm_del_vqs(struct virtio_device *vdev)
> +{
> +     struct virtqueue *vq, *n;
> +
> +     list_for_each_entry_safe(vq, n, &vdev->vqs, list)
> +             kvm_del_vq(vq);
> +}
> +
> +static int kvm_find_vqs(struct virtio_device *vdev, unsigned nvqs,
> +                     struct virtqueue *vqs[],
> +                     vq_callback_t *callbacks[],
> +                     const char *names[])
> +{
> +     struct kvm_device *kdev = to_kvmdev(vdev);
> +     int i;
> +
> +     /* We must have this many virtqueues. */
> +     if (nvqs > kdev->desc->num_vq)
> +             return -ENOENT;
> +
> +     for (i = 0; i < nvqs; ++i) {
> +             vqs[i] = kvm_find_vq(vdev, i, callbacks[i], names[i]);
> +             if (IS_ERR(vqs[i]))
> +                     goto error;
> +     }
> +     return 0;
> +
> +error:
> +     kvm_del_vqs(vdev);
> +     return PTR_ERR(vqs[i]);
> +}
> +
> +/*
> + * The config ops structure as defined by virtio config
> + */
> +static struct virtio_config_ops kvm_vq_config_ops = {
> +     .get_features = kvm_get_features,
> +     .finalize_features = kvm_finalize_features,
> +     .get = kvm_get,
> +     .set = kvm_set,
> +     .get_status = kvm_get_status,
> +     .set_status = kvm_set_status,
> +     .reset = kvm_reset,
> +     .find_vqs = kvm_find_vqs,
> +     .del_vqs = kvm_del_vqs,
> +};
> +
> +/*
> + * The root device for the kvm virtio devices.
> + * This makes them appear as /sys/devices/kvm_tile/0,1,2 not 
> /sys/devices/0,1,2.
> + */
> +static struct device *kvm_root;
> +
> +/*
> + * adds a new device and register it with virtio
> + * appropriate drivers are loaded by the device model
> + */
> +static void add_kvm_device(struct kvm_device_desc *d, unsigned int offset)
> +{
> +     struct kvm_device *kdev;
> +
> +     kdev = kzalloc(sizeof(*kdev), GFP_KERNEL);
> +     if (!kdev) {
> +             pr_emerg("Cannot allocate kvm dev %u type %u\n",
> +                      offset, d->type);
> +             return;
> +     }
> +
> +     kdev->vdev.dev.parent = kvm_root;
> +     kdev->vdev.id.device = d->type;
> +     kdev->vdev.config = &kvm_vq_config_ops;
> +     kdev->desc = d;
> +     kdev->desc_pa = PFN_PHYS(max_pfn) + offset;
> +
> +     if (register_virtio_device(&kdev->vdev) != 0) {
> +             pr_err("Failed to register kvm device %u type %u\n",
> +                    offset, d->type);
> +             kfree(kdev);
> +     }
> +}
> +
> +/*
> + * scan_devices() simply iterates through the device page.
> + * The type 0 is reserved to mean "end of devices".
> + */
> +static void scan_devices(void)
> +{
> +     unsigned int i;
> +     struct kvm_device_desc *d;
> +
> +     for (i = 0; i < PAGE_SIZE; i += desc_size(d)) {
> +             d = kvm_devices + i;
> +
> +             if (d->type == 0)
> +                     break;
> +
> +             add_kvm_device(d, i);
> +     }
> +}
> +
> +/*
> + * Init function for virtio.
> + * devices are in a single page above the top of "normal" mem.
> + */
> +static int __init kvm_devices_init(void)
> +{
> +     int rc = -ENOMEM;
> +
> +     kvm_root = root_device_register("kvm_tile");
> +     if (IS_ERR(kvm_root)) {
> +             rc = PTR_ERR(kvm_root);
> +             pr_err("Could not register kvm_tile root device");
> +             return rc;
> +     }
> +
> +     kvm_devices = generic_remap_prot(PFN_PHYS(max_pfn), PAGE_SIZE,
> +                                      0, io_prot());
> +     if (!kvm_devices) {
> +             kvm_devices = NULL;
> +             root_device_unregister(kvm_root);
> +             return rc;
> +     }
> +
> +     scan_devices();
> +     return 0;
> +}
> +
> +/* code for early console output with virtio_console */
> +static __init int early_put_chars(u32 vtermno, const char *buf, int len)
> +{
> +     char scratch[512];
> +
> +     if (len > sizeof(scratch) - 1)
> +             len = sizeof(scratch) - 1;
> +     scratch[len] = '\0';
> +     memcpy(scratch, buf, len);
> +     hcall_virtio(KVM_VIRTIO_NOTIFY, __pa(scratch));
> +
> +     return len;
> +}
> +
> +static int __init tile_virtio_console_init(void)
> +{
> +     return virtio_cons_early_init(early_put_chars);
> +}
> +console_initcall(tile_virtio_console_init);
> +
> +/*
> + * We do this after core stuff, but before the drivers.
> + */
> +postcore_initcall(kvm_devices_init);
> diff --git a/arch/tile/kernel/relocate_kernel_64.S 
> b/arch/tile/kernel/relocate_kernel_64.S
> index 1c09a4f..02bc446 100644
> --- a/arch/tile/kernel/relocate_kernel_64.S
> +++ b/arch/tile/kernel/relocate_kernel_64.S
> @@ -34,11 +34,11 @@ STD_ENTRY(relocate_new_kernel)
>       addi    sp, sp, -8
>       /* we now have a stack (whether we need one or not) */
>  
> +#ifdef RELOCATE_NEW_KERNEL_VERBOSE
>       moveli  r40, hw2_last(hv_console_putc)
>       shl16insli r40, r40, hw1(hv_console_putc)
>       shl16insli r40, r40, hw0(hv_console_putc)
>  
> -#ifdef RELOCATE_NEW_KERNEL_VERBOSE
>       moveli  r0, 'r'
>       jalr    r40
>  
> @@ -176,10 +176,12 @@ STD_ENTRY(relocate_new_kernel)
>  
>       /* we should not get here */
>  
> +#ifdef RELOCATE_NEW_KERNEL_VERBOSE
>       moveli  r0, '?'
>       jalr    r40
>       moveli  r0, '\n'
>       jalr    r40
> +#endif
>  
>       j       .Lhalt
>  
> @@ -237,7 +239,9 @@ STD_ENTRY(relocate_new_kernel)
>       j       .Lloop
>  
>  
> -.Lerr:       moveli  r0, 'e'
> +.Lerr:
> +#ifdef RELOCATE_NEW_KERNEL_VERBOSE
> +     moveli  r0, 'e'
>       jalr    r40
>       moveli  r0, 'r'
>       jalr    r40
> @@ -245,6 +249,7 @@ STD_ENTRY(relocate_new_kernel)
>       jalr    r40
>       moveli  r0, '\n'
>       jalr    r40
> +#endif
>  .Lhalt:
>       moveli r41, hw2_last(hv_halt)
>       shl16insli r41, r41, hw1(hv_halt)
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to