pc,pci,vhost,virtio: misc fixes

Just a bunch of bugfixes all over the place.
 
 Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 
 iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAl+cCq8PHG1zdEByZWRo
 YXQuY29tAAoJECgfDbjSjVRpKWkH/0qq+u2z/q0KYzmodcdW2eFNsvKF2e+Dz3Af
 zZGMREH93DsKAQ2k3t84sz2RAaAP45cCqrq+v8kSzmpaC7GqKYA/VceeLwy8e6Eu
 YKvu5QixrOVTpNg2QV/w44ywgtA4NbWy5Fr9S4qhzPyyD/gtE609weZ1vQnSFT7B
 Gg4vr1lcqskwYTH7sh+bpsDTUeANr7QaknWKnaomroz+IUO8m9ig6RKtegaXhQCj
 xswI4458S3nklqnoGMa56j46VYwft8YHO1lBiR1WefTHylknyng9Tdvf9G5mnzVg
 wyrMTuT36lMXIa5KcSZeECIt2ZUT6KSSjWzEKZNXL5lS3gfUo7o=
 =powp
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging

pc,pci,vhost,virtio: misc fixes

Just a bunch of bugfixes all over the place.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

# gpg: Signature made Fri 30 Oct 2020 12:44:31 GMT
# gpg:                using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469
# gpg:                issuer "mst@redhat.com"
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full]
# gpg:                 aka "Michael S. Tsirkin <mst@redhat.com>" [full]
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17  0970 C350 3912 AFBE 8E67
#      Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA  8A0D 281F 0DB8 D28D 5469

* remotes/mst/tags/for_upstream:
  intel_iommu: Fix two misuse of "0x%u" prints
  virtio: skip guest index check on device load
  vhost-blk: set features before setting inflight feature
  pci: Disallow improper BAR registration for type 1
  pci: Change error_report to assert(3)
  pci: advertise a page aligned ATS
  pc: Implement -no-hpet as sugar for -machine hpet=on
  vhost: Don't special case vq->used_phys in vhost_get_log_size()
  pci: Assert irqnum is between 0 and bus->nirqs in pci_bus_change_irq_level
  hw/pci: Extract pci_bus_change_irq_level() from pci_change_irq_level()
  hw/virtio/vhost-vdpa: Fix Coverity CID 1432864
  acpi/crs: Support ranges > 32b for hosts
  acpi/crs: Prevent bad ranges for host bridges
  vhost-vsock: set vhostfd to non-blocking mode
  vhost-vdpa: negotiate VIRTIO_NET_F_STATUS with driver

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2020-11-01 14:02:19 +00:00
commit 700d20b49e
16 changed files with 123 additions and 57 deletions

View File

@ -131,6 +131,12 @@ static int vhost_user_blk_start(VirtIODevice *vdev)
s->dev.acked_features = vdev->guest_features; s->dev.acked_features = vdev->guest_features;
ret = vhost_dev_prepare_inflight(&s->dev);
if (ret < 0) {
error_report("Error set inflight format: %d", -ret);
goto err_guest_notifiers;
}
if (!s->inflight->addr) { if (!s->inflight->addr) {
ret = vhost_dev_get_inflight(&s->dev, s->queue_size, s->inflight); ret = vhost_dev_get_inflight(&s->dev, s->queue_size, s->inflight);
if (ret < 0) { if (ret < 0) {

View File

@ -786,10 +786,16 @@ static Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
crs_range_insert(temp_range_set.io_ranges, crs_range_insert(temp_range_set.io_ranges,
range_base, range_limit); range_base, range_limit);
} else { /* "memory" */ } else { /* "memory" */
crs_range_insert(temp_range_set.mem_ranges, uint64_t length = range_limit - range_base + 1;
if (range_limit <= UINT32_MAX && length <= UINT32_MAX) {
crs_range_insert(temp_range_set.mem_ranges, range_base,
range_limit);
} else {
crs_range_insert(temp_range_set.mem_64bit_ranges,
range_base, range_limit); range_base, range_limit);
} }
} }
}
type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION; type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
if (type == PCI_HEADER_TYPE_BRIDGE) { if (type == PCI_HEADER_TYPE_BRIDGE) {
@ -866,6 +872,8 @@ static Aml *build_crs(PCIHostState *host, CrsRangeSet *range_set)
crs_range_merge(temp_range_set.mem_ranges); crs_range_merge(temp_range_set.mem_ranges);
for (i = 0; i < temp_range_set.mem_ranges->len; i++) { for (i = 0; i < temp_range_set.mem_ranges->len; i++) {
entry = g_ptr_array_index(temp_range_set.mem_ranges, i); entry = g_ptr_array_index(temp_range_set.mem_ranges, i);
assert(entry->limit <= UINT32_MAX &&
(entry->limit - entry->base + 1) <= UINT32_MAX);
aml_append(crs, aml_append(crs,
aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED,
AML_MAX_FIXED, AML_NON_CACHEABLE, AML_MAX_FIXED, AML_NON_CACHEABLE,

View File

@ -2665,7 +2665,7 @@ static uint64_t vtd_mem_read(void *opaque, hwaddr addr, unsigned size)
if (addr + size > DMAR_REG_SIZE) { if (addr + size > DMAR_REG_SIZE) {
error_report_once("%s: MMIO over range: addr=0x%" PRIx64 error_report_once("%s: MMIO over range: addr=0x%" PRIx64
" size=0x%u", __func__, addr, size); " size=0x%x", __func__, addr, size);
return (uint64_t)-1; return (uint64_t)-1;
} }
@ -2716,7 +2716,7 @@ static void vtd_mem_write(void *opaque, hwaddr addr,
if (addr + size > DMAR_REG_SIZE) { if (addr + size > DMAR_REG_SIZE) {
error_report_once("%s: MMIO over range: addr=0x%" PRIx64 error_report_once("%s: MMIO over range: addr=0x%" PRIx64
" size=0x%u", __func__, addr, size); " size=0x%x", __func__, addr, size);
return; return;
} }

View File

@ -1142,9 +1142,13 @@ void pc_basic_device_init(struct PCMachineState *pcms,
* Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT * Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT
* when the HPET wants to take over. Thus we have to disable the latter. * when the HPET wants to take over. Thus we have to disable the latter.
*/ */
if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) { if (pcms->hpet_enabled && (!kvm_irqchip_in_kernel() ||
kvm_has_pit_state2())) {
hpet = qdev_try_new(TYPE_HPET); hpet = qdev_try_new(TYPE_HPET);
if (hpet) { if (!hpet) {
error_report("couldn't create HPET device");
exit(1);
}
/* For pc-piix-*, hpet's intcap is always IRQ2. For pc-q35-1.7 /* For pc-piix-*, hpet's intcap is always IRQ2. For pc-q35-1.7
* and earlier, use IRQ2 for compat. Otherwise, use IRQ16~23, * and earlier, use IRQ2 for compat. Otherwise, use IRQ16~23,
* IRQ8 and IRQ2. * IRQ8 and IRQ2.
@ -1164,7 +1168,6 @@ void pc_basic_device_init(struct PCMachineState *pcms,
pit_alt_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_PIT_INT); pit_alt_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_PIT_INT);
rtc_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_RTC_INT); rtc_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_RTC_INT);
} }
}
*rtc_state = mc146818_rtc_init(isa_bus, 2000, rtc_irq); *rtc_state = mc146818_rtc_init(isa_bus, 2000, rtc_irq);
qemu_register_boot_set(pc_boot_set, *rtc_state); qemu_register_boot_set(pc_boot_set, *rtc_state);
@ -1529,6 +1532,20 @@ static void pc_machine_set_pit(Object *obj, bool value, Error **errp)
pcms->pit_enabled = value; pcms->pit_enabled = value;
} }
static bool pc_machine_get_hpet(Object *obj, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
return pcms->hpet_enabled;
}
static void pc_machine_set_hpet(Object *obj, bool value, Error **errp)
{
PCMachineState *pcms = PC_MACHINE(obj);
pcms->hpet_enabled = value;
}
static void pc_machine_get_max_ram_below_4g(Object *obj, Visitor *v, static void pc_machine_get_max_ram_below_4g(Object *obj, Visitor *v,
const char *name, void *opaque, const char *name, void *opaque,
Error **errp) Error **errp)
@ -1579,6 +1596,9 @@ static void pc_machine_initfn(Object *obj)
pcms->smbus_enabled = true; pcms->smbus_enabled = true;
pcms->sata_enabled = true; pcms->sata_enabled = true;
pcms->pit_enabled = true; pcms->pit_enabled = true;
#ifdef CONFIG_HPET
pcms->hpet_enabled = true;
#endif
pc_system_flash_create(pcms); pc_system_flash_create(pcms);
pcms->pcspk = isa_new(TYPE_PC_SPEAKER); pcms->pcspk = isa_new(TYPE_PC_SPEAKER);
@ -1699,6 +1719,9 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
object_class_property_add_bool(oc, PC_MACHINE_PIT, object_class_property_add_bool(oc, PC_MACHINE_PIT,
pc_machine_get_pit, pc_machine_set_pit); pc_machine_get_pit, pc_machine_set_pit);
object_class_property_add_bool(oc, "hpet",
pc_machine_get_hpet, pc_machine_set_hpet);
} }
static const TypeInfo pc_machine_info = { static const TypeInfo pc_machine_info = {

View File

@ -216,7 +216,7 @@ static void pc_init1(MachineState *machine,
i440fx_state = NULL; i440fx_state = NULL;
isa_bus = isa_bus_new(NULL, get_system_memory(), system_io, isa_bus = isa_bus_new(NULL, get_system_memory(), system_io,
&error_abort); &error_abort);
no_hpet = 1; pcms->hpet_enabled = false;
} }
isa_bus_irqs(isa_bus, x86ms->gsi); isa_bus_irqs(isa_bus, x86ms->gsi);

View File

@ -248,6 +248,14 @@ static inline void pci_set_irq_state(PCIDevice *d, int irq_num, int level)
d->irq_state |= level << irq_num; d->irq_state |= level << irq_num;
} }
static void pci_bus_change_irq_level(PCIBus *bus, int irq_num, int change)
{
assert(irq_num >= 0);
assert(irq_num < bus->nirq);
bus->irq_count[irq_num] += change;
bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
}
static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change) static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change)
{ {
PCIBus *bus; PCIBus *bus;
@ -258,8 +266,7 @@ static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change)
break; break;
pci_dev = bus->parent_dev; pci_dev = bus->parent_dev;
} }
bus->irq_count[irq_num] += change; pci_bus_change_irq_level(bus, irq_num, change);
bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
} }
int pci_bus_get_irq_level(PCIBus *bus, int irq_num) int pci_bus_get_irq_level(PCIBus *bus, int irq_num)
@ -1141,14 +1148,16 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
uint32_t addr; /* offset in pci config space */ uint32_t addr; /* offset in pci config space */
uint64_t wmask; uint64_t wmask;
pcibus_t size = memory_region_size(memory); pcibus_t size = memory_region_size(memory);
uint8_t hdr_type;
assert(region_num >= 0); assert(region_num >= 0);
assert(region_num < PCI_NUM_REGIONS); assert(region_num < PCI_NUM_REGIONS);
if (size & (size-1)) { assert(is_power_of_2(size));
error_report("ERROR: PCI region size must be pow2 "
"type=0x%x, size=0x%"FMT_PCIBUS"", type, size); /* A PCI bridge device (with Type 1 header) may only have at most 2 BARs */
exit(1); hdr_type =
} pci_dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
assert(hdr_type != PCI_HEADER_TYPE_BRIDGE || region_num < 2);
r = &pci_dev->io_regions[region_num]; r = &pci_dev->io_regions[region_num];
r->addr = PCI_BAR_UNMAPPED; r->addr = PCI_BAR_UNMAPPED;

View File

@ -971,8 +971,9 @@ void pcie_ats_init(PCIDevice *dev, uint16_t offset)
dev->exp.ats_cap = offset; dev->exp.ats_cap = offset;
/* Invalidate Queue Depth 0, Page Aligned Request 0 */ /* Invalidate Queue Depth 0, Page Aligned Request 1 */
pci_set_word(dev->config + offset + PCI_ATS_CAP, 0); pci_set_word(dev->config + offset + PCI_ATS_CAP,
PCI_ATS_CAP_PAGE_ALIGNED);
/* STU 0, Disabled by default */ /* STU 0, Disabled by default */
pci_set_word(dev->config + offset + PCI_ATS_CTRL, 0); pci_set_word(dev->config + offset + PCI_ATS_CTRL, 0);

View File

@ -90,7 +90,7 @@ static void vhost_vdpa_listener_begin(MemoryListener *listener)
{ {
struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener); struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
struct vhost_dev *dev = v->dev; struct vhost_dev *dev = v->dev;
struct vhost_msg_v2 msg; struct vhost_msg_v2 msg = {};
int fd = v->device_fd; int fd = v->device_fd;
if (!(dev->backend_cap & (0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH))) { if (!(dev->backend_cap & (0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH))) {
@ -110,7 +110,7 @@ static void vhost_vdpa_listener_commit(MemoryListener *listener)
{ {
struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener); struct vhost_vdpa *v = container_of(listener, struct vhost_vdpa, listener);
struct vhost_dev *dev = v->dev; struct vhost_dev *dev = v->dev;
struct vhost_msg_v2 msg; struct vhost_msg_v2 msg = {};
int fd = v->device_fd; int fd = v->device_fd;
if (!(dev->backend_cap & (0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH))) { if (!(dev->backend_cap & (0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH))) {

View File

@ -16,6 +16,7 @@
#include "qapi/error.h" #include "qapi/error.h"
#include "hw/virtio/virtio-access.h" #include "hw/virtio/virtio-access.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "qemu/sockets.h"
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "hw/virtio/vhost-vsock.h" #include "hw/virtio/vhost-vsock.h"
#include "monitor/monitor.h" #include "monitor/monitor.h"
@ -148,6 +149,13 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp)
error_prepend(errp, "vhost-vsock: unable to parse vhostfd: "); error_prepend(errp, "vhost-vsock: unable to parse vhostfd: ");
return; return;
} }
ret = qemu_try_set_nonblock(vhostfd);
if (ret < 0) {
error_setg_errno(errp, -ret,
"vhost-vsock: unable to set non-blocking mode");
return;
}
} else { } else {
vhostfd = open("/dev/vhost-vsock", O_RDWR); vhostfd = open("/dev/vhost-vsock", O_RDWR);
if (vhostfd < 0) { if (vhostfd < 0) {
@ -155,6 +163,8 @@ static void vhost_vsock_device_realize(DeviceState *dev, Error **errp)
"vhost-vsock: failed to open vhost device"); "vhost-vsock: failed to open vhost device");
return; return;
} }
qemu_set_nonblock(vhostfd);
} }
vhost_vsock_common_realize(vdev, "vhost-vsock"); vhost_vsock_common_realize(vdev, "vhost-vsock");

View File

@ -172,16 +172,6 @@ static uint64_t vhost_get_log_size(struct vhost_dev *dev)
reg->memory_size); reg->memory_size);
log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1); log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1);
} }
for (i = 0; i < dev->nvqs; ++i) {
struct vhost_virtqueue *vq = dev->vqs + i;
if (!vq->used_phys && !vq->used_size) {
continue;
}
uint64_t last = vq->used_phys + vq->used_size - 1;
log_size = MAX(log_size, last / VHOST_LOG_CHUNK + 1);
}
return log_size; return log_size;
} }
@ -1655,6 +1645,24 @@ int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f)
return 0; return 0;
} }
int vhost_dev_prepare_inflight(struct vhost_dev *hdev)
{
int r;
if (hdev->vhost_ops->vhost_get_inflight_fd == NULL ||
hdev->vhost_ops->vhost_set_inflight_fd == NULL) {
return 0;
}
r = vhost_dev_set_features(hdev, hdev->log_enabled);
if (r < 0) {
VHOST_OPS_DEBUG("vhost_dev_prepare_inflight failed");
return r;
}
return 0;
}
int vhost_dev_set_inflight(struct vhost_dev *dev, int vhost_dev_set_inflight(struct vhost_dev *dev,
struct vhost_inflight *inflight) struct vhost_inflight *inflight)
{ {

View File

@ -17,6 +17,7 @@
#include "trace.h" #include "trace.h"
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "hw/virtio/virtio.h" #include "hw/virtio/virtio.h"
@ -3160,12 +3161,12 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
nheads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx; nheads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx;
/* Check it isn't doing strange things with descriptor numbers. */ /* Check it isn't doing strange things with descriptor numbers. */
if (nheads > vdev->vq[i].vring.num) { if (nheads > vdev->vq[i].vring.num) {
error_report("VQ %d size 0x%x Guest index 0x%x " qemu_log_mask(LOG_GUEST_ERROR,
"VQ %d size 0x%x Guest index 0x%x "
"inconsistent with Host index 0x%x: delta 0x%x", "inconsistent with Host index 0x%x: delta 0x%x",
i, vdev->vq[i].vring.num, i, vdev->vq[i].vring.num,
vring_avail_idx(&vdev->vq[i]), vring_avail_idx(&vdev->vq[i]),
vdev->vq[i].last_avail_idx, nheads); vdev->vq[i].last_avail_idx, nheads);
return -1;
} }
vdev->vq[i].used_idx = vring_used_idx(&vdev->vq[i]); vdev->vq[i].used_idx = vring_used_idx(&vdev->vq[i]);
vdev->vq[i].shadow_avail_idx = vring_avail_idx(&vdev->vq[i]); vdev->vq[i].shadow_avail_idx = vring_avail_idx(&vdev->vq[i]);

View File

@ -43,6 +43,7 @@ typedef struct PCMachineState {
bool smbus_enabled; bool smbus_enabled;
bool sata_enabled; bool sata_enabled;
bool pit_enabled; bool pit_enabled;
bool hpet_enabled;
/* NUMA information: */ /* NUMA information: */
uint64_t numa_nodes; uint64_t numa_nodes;

View File

@ -126,7 +126,4 @@ qemu_irq x86_allocate_cpu_irq(void);
void gsi_handler(void *opaque, int n, int level); void gsi_handler(void *opaque, int n, int level);
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name); void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
/* hpet.c */
extern int no_hpet;
#endif #endif

View File

@ -141,6 +141,7 @@ void vhost_dev_reset_inflight(struct vhost_inflight *inflight);
void vhost_dev_free_inflight(struct vhost_inflight *inflight); void vhost_dev_free_inflight(struct vhost_inflight *inflight);
void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f); void vhost_dev_save_inflight(struct vhost_inflight *inflight, QEMUFile *f);
int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f); int vhost_dev_load_inflight(struct vhost_inflight *inflight, QEMUFile *f);
int vhost_dev_prepare_inflight(struct vhost_dev *hdev);
int vhost_dev_set_inflight(struct vhost_dev *dev, int vhost_dev_set_inflight(struct vhost_dev *dev,
struct vhost_inflight *inflight); struct vhost_inflight *inflight);
int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size, int vhost_dev_get_inflight(struct vhost_dev *dev, uint16_t queue_size,

View File

@ -55,6 +55,7 @@ const int vdpa_feature_bits[] = {
VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_IOMMU_PLATFORM,
VIRTIO_F_RING_PACKED, VIRTIO_F_RING_PACKED,
VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_GUEST_ANNOUNCE,
VIRTIO_NET_F_STATUS,
VHOST_INVALID_FEATURE_BIT VHOST_INVALID_FEATURE_BIT
}; };

View File

@ -146,7 +146,6 @@ static Chardev **serial_hds;
Chardev *parallel_hds[MAX_PARALLEL_PORTS]; Chardev *parallel_hds[MAX_PARALLEL_PORTS];
int win2k_install_hack = 0; int win2k_install_hack = 0;
int singlestep = 0; int singlestep = 0;
int no_hpet = 0;
int fd_bootchk = 1; int fd_bootchk = 1;
static int no_reboot; static int no_reboot;
int no_shutdown = 0; int no_shutdown = 0;
@ -3562,7 +3561,8 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_opts_parse_noisily(olist, "acpi=off", false); qemu_opts_parse_noisily(olist, "acpi=off", false);
break; break;
case QEMU_OPTION_no_hpet: case QEMU_OPTION_no_hpet:
no_hpet = 1; olist = qemu_find_opts("machine");
qemu_opts_parse_noisily(olist, "hpet=off", false);
break; break;
case QEMU_OPTION_no_reboot: case QEMU_OPTION_no_reboot:
no_reboot = 1; no_reboot = 1;