aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/char/sclp_config.c17
-rw-r--r--drivers/s390/cio/ccwgroup.c7
-rw-r--r--drivers/s390/cio/cio.c9
-rw-r--r--drivers/s390/cio/cio.h3
-rw-r--r--drivers/s390/cio/cmf.c11
-rw-r--r--drivers/s390/cio/css.c10
-rw-r--r--drivers/s390/cio/device.c17
-rw-r--r--drivers/s390/cio/device_fsm.c10
-rw-r--r--drivers/s390/cio/device_ops.c2
-rw-r--r--drivers/s390/cio/qdio.c8
-rw-r--r--drivers/s390/kvm/kvm_virtio.c23
11 files changed, 73 insertions, 44 deletions
diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c
index b8f35bc52b7b..9e784d5f7f57 100644
--- a/drivers/s390/char/sclp_config.c
+++ b/drivers/s390/char/sclp_config.c
@@ -10,6 +10,7 @@
10#include <linux/cpu.h> 10#include <linux/cpu.h>
11#include <linux/sysdev.h> 11#include <linux/sysdev.h>
12#include <linux/workqueue.h> 12#include <linux/workqueue.h>
13#include <asm/smp.h>
13#include "sclp.h" 14#include "sclp.h"
14 15
15#define TAG "sclp_config: " 16#define TAG "sclp_config: "
@@ -19,9 +20,11 @@ struct conf_mgm_data {
19 u8 ev_qualifier; 20 u8 ev_qualifier;
20} __attribute__((packed)); 21} __attribute__((packed));
21 22
23#define EV_QUAL_CPU_CHANGE 1
22#define EV_QUAL_CAP_CHANGE 3 24#define EV_QUAL_CAP_CHANGE 3
23 25
24static struct work_struct sclp_cpu_capability_work; 26static struct work_struct sclp_cpu_capability_work;
27static struct work_struct sclp_cpu_change_work;
25 28
26static void sclp_cpu_capability_notify(struct work_struct *work) 29static void sclp_cpu_capability_notify(struct work_struct *work)
27{ 30{
@@ -37,13 +40,24 @@ static void sclp_cpu_capability_notify(struct work_struct *work)
37 put_online_cpus(); 40 put_online_cpus();
38} 41}
39 42
43static void sclp_cpu_change_notify(struct work_struct *work)
44{
45 smp_rescan_cpus();
46}
47
40static void sclp_conf_receiver_fn(struct evbuf_header *evbuf) 48static void sclp_conf_receiver_fn(struct evbuf_header *evbuf)
41{ 49{
42 struct conf_mgm_data *cdata; 50 struct conf_mgm_data *cdata;
43 51
44 cdata = (struct conf_mgm_data *)(evbuf + 1); 52 cdata = (struct conf_mgm_data *)(evbuf + 1);
45 if (cdata->ev_qualifier == EV_QUAL_CAP_CHANGE) 53 switch (cdata->ev_qualifier) {
54 case EV_QUAL_CPU_CHANGE:
55 schedule_work(&sclp_cpu_change_work);
56 break;
57 case EV_QUAL_CAP_CHANGE:
46 schedule_work(&sclp_cpu_capability_work); 58 schedule_work(&sclp_cpu_capability_work);
59 break;
60 }
47} 61}
48 62
49static struct sclp_register sclp_conf_register = 63static struct sclp_register sclp_conf_register =
@@ -57,6 +71,7 @@ static int __init sclp_conf_init(void)
57 int rc; 71 int rc;
58 72
59 INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); 73 INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify);
74 INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify);
60 75
61 rc = sclp_register(&sclp_conf_register); 76 rc = sclp_register(&sclp_conf_register);
62 if (rc) { 77 if (rc) {
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index fe1ad1722158..85b2e51a42ae 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -318,7 +318,7 @@ ccwgroup_online_store (struct device *dev, struct device_attribute *attr, const
318{ 318{
319 struct ccwgroup_device *gdev; 319 struct ccwgroup_device *gdev;
320 struct ccwgroup_driver *gdrv; 320 struct ccwgroup_driver *gdrv;
321 unsigned int value; 321 unsigned long value;
322 int ret; 322 int ret;
323 323
324 gdev = to_ccwgroupdev(dev); 324 gdev = to_ccwgroupdev(dev);
@@ -329,7 +329,9 @@ ccwgroup_online_store (struct device *dev, struct device_attribute *attr, const
329 if (!try_module_get(gdrv->owner)) 329 if (!try_module_get(gdrv->owner))
330 return -EINVAL; 330 return -EINVAL;
331 331
332 value = simple_strtoul(buf, NULL, 0); 332 ret = strict_strtoul(buf, 0, &value);
333 if (ret)
334 goto out;
333 ret = count; 335 ret = count;
334 if (value == 1) 336 if (value == 1)
335 ccwgroup_set_online(gdev); 337 ccwgroup_set_online(gdev);
@@ -337,6 +339,7 @@ ccwgroup_online_store (struct device *dev, struct device_attribute *attr, const
337 ccwgroup_set_offline(gdev); 339 ccwgroup_set_offline(gdev);
338 else 340 else
339 ret = -EINVAL; 341 ret = -EINVAL;
342out:
340 module_put(gdrv->owner); 343 module_put(gdrv->owner);
341 return ret; 344 return ret;
342} 345}
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 23ffcc4768a7..08a578161306 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -407,8 +407,7 @@ cio_modify (struct subchannel *sch)
407/* 407/*
408 * Enable subchannel. 408 * Enable subchannel.
409 */ 409 */
410int cio_enable_subchannel(struct subchannel *sch, unsigned int isc, 410int cio_enable_subchannel(struct subchannel *sch, u32 intparm)
411 u32 intparm)
412{ 411{
413 char dbf_txt[15]; 412 char dbf_txt[15];
414 int ccode; 413 int ccode;
@@ -426,7 +425,7 @@ int cio_enable_subchannel(struct subchannel *sch, unsigned int isc,
426 425
427 for (retry = 5, ret = 0; retry > 0; retry--) { 426 for (retry = 5, ret = 0; retry > 0; retry--) {
428 sch->schib.pmcw.ena = 1; 427 sch->schib.pmcw.ena = 1;
429 sch->schib.pmcw.isc = isc; 428 sch->schib.pmcw.isc = sch->isc;
430 sch->schib.pmcw.intparm = intparm; 429 sch->schib.pmcw.intparm = intparm;
431 ret = cio_modify(sch); 430 ret = cio_modify(sch);
432 if (ret == -ENODEV) 431 if (ret == -ENODEV)
@@ -600,6 +599,7 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
600 else 599 else
601 sch->opm = chp_get_sch_opm(sch); 600 sch->opm = chp_get_sch_opm(sch);
602 sch->lpm = sch->schib.pmcw.pam & sch->opm; 601 sch->lpm = sch->schib.pmcw.pam & sch->opm;
602 sch->isc = 3;
603 603
604 CIO_DEBUG(KERN_INFO, 0, 604 CIO_DEBUG(KERN_INFO, 0,
605 "Detected device %04x on subchannel 0.%x.%04X" 605 "Detected device %04x on subchannel 0.%x.%04X"
@@ -610,13 +610,11 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid)
610 610
611 /* 611 /*
612 * We now have to initially ... 612 * We now have to initially ...
613 * ... set "interruption subclass"
614 * ... enable "concurrent sense" 613 * ... enable "concurrent sense"
615 * ... enable "multipath mode" if more than one 614 * ... enable "multipath mode" if more than one
616 * CHPID is available. This is done regardless 615 * CHPID is available. This is done regardless
617 * whether multiple paths are available for us. 616 * whether multiple paths are available for us.
618 */ 617 */
619 sch->schib.pmcw.isc = 3; /* could be smth. else */
620 sch->schib.pmcw.csense = 1; /* concurrent sense */ 618 sch->schib.pmcw.csense = 1; /* concurrent sense */
621 sch->schib.pmcw.ena = 0; 619 sch->schib.pmcw.ena = 0;
622 if ((sch->lpm & (sch->lpm - 1)) != 0) 620 if ((sch->lpm & (sch->lpm - 1)) != 0)
@@ -812,6 +810,7 @@ cio_probe_console(void)
812 * enable console I/O-interrupt subclass 7 810 * enable console I/O-interrupt subclass 7
813 */ 811 */
814 ctl_set_bit(6, 24); 812 ctl_set_bit(6, 24);
813 console_subchannel.isc = 7;
815 console_subchannel.schib.pmcw.isc = 7; 814 console_subchannel.schib.pmcw.isc = 7;
816 console_subchannel.schib.pmcw.intparm = 815 console_subchannel.schib.pmcw.intparm =
817 (u32)(addr_t)&console_subchannel; 816 (u32)(addr_t)&console_subchannel;
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h
index 08f2235c5a6f..3c75412904dc 100644
--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -74,6 +74,7 @@ struct subchannel {
74 __u8 lpm; /* logical path mask */ 74 __u8 lpm; /* logical path mask */
75 __u8 opm; /* operational path mask */ 75 __u8 opm; /* operational path mask */
76 struct schib schib; /* subchannel information block */ 76 struct schib schib; /* subchannel information block */
77 int isc; /* desired interruption subclass */
77 struct chsc_ssd_info ssd_info; /* subchannel description */ 78 struct chsc_ssd_info ssd_info; /* subchannel description */
78 struct device dev; /* entry in device tree */ 79 struct device dev; /* entry in device tree */
79 struct css_driver *driver; 80 struct css_driver *driver;
@@ -85,7 +86,7 @@ struct subchannel {
85#define to_subchannel(n) container_of(n, struct subchannel, dev) 86#define to_subchannel(n) container_of(n, struct subchannel, dev)
86 87
87extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id); 88extern int cio_validate_subchannel (struct subchannel *, struct subchannel_id);
88extern int cio_enable_subchannel(struct subchannel *, unsigned int, u32); 89extern int cio_enable_subchannel(struct subchannel *, u32);
89extern int cio_disable_subchannel (struct subchannel *); 90extern int cio_disable_subchannel (struct subchannel *);
90extern int cio_cancel (struct subchannel *); 91extern int cio_cancel (struct subchannel *);
91extern int cio_clear (struct subchannel *); 92extern int cio_clear (struct subchannel *);
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index f4c132ab39ed..2808b6833b9e 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -1219,16 +1219,21 @@ static ssize_t cmb_enable_store(struct device *dev,
1219{ 1219{
1220 struct ccw_device *cdev; 1220 struct ccw_device *cdev;
1221 int ret; 1221 int ret;
1222 unsigned long val;
1223
1224 ret = strict_strtoul(buf, 16, &val);
1225 if (ret)
1226 return ret;
1222 1227
1223 cdev = to_ccwdev(dev); 1228 cdev = to_ccwdev(dev);
1224 1229
1225 switch (buf[0]) { 1230 switch (val) {
1226 case '0': 1231 case 0:
1227 ret = disable_cmf(cdev); 1232 ret = disable_cmf(cdev);
1228 if (ret) 1233 if (ret)
1229 dev_info(&cdev->dev, "disable_cmf failed (%d)\n", ret); 1234 dev_info(&cdev->dev, "disable_cmf failed (%d)\n", ret);
1230 break; 1235 break;
1231 case '1': 1236 case 1:
1232 ret = enable_cmf(cdev); 1237 ret = enable_cmf(cdev);
1233 if (ret && ret != -EBUSY) 1238 if (ret && ret != -EBUSY)
1234 dev_info(&cdev->dev, "enable_cmf failed (%d)\n", ret); 1239 dev_info(&cdev->dev, "enable_cmf failed (%d)\n", ret);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index c1afab5f72d6..595e327d2f76 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -705,13 +705,17 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr,
705{ 705{
706 struct channel_subsystem *css = to_css(dev); 706 struct channel_subsystem *css = to_css(dev);
707 int ret; 707 int ret;
708 unsigned long val;
708 709
710 ret = strict_strtoul(buf, 16, &val);
711 if (ret)
712 return ret;
709 mutex_lock(&css->mutex); 713 mutex_lock(&css->mutex);
710 switch (buf[0]) { 714 switch (val) {
711 case '0': 715 case 0:
712 ret = css->cm_enabled ? chsc_secm(css, 0) : 0; 716 ret = css->cm_enabled ? chsc_secm(css, 0) : 0;
713 break; 717 break;
714 case '1': 718 case 1:
715 ret = css->cm_enabled ? 0 : chsc_secm(css, 1); 719 ret = css->cm_enabled ? 0 : chsc_secm(css, 1);
716 break; 720 break;
717 default: 721 default:
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index e0c7adb8958e..abfd601d237a 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -512,8 +512,8 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr,
512 const char *buf, size_t count) 512 const char *buf, size_t count)
513{ 513{
514 struct ccw_device *cdev = to_ccwdev(dev); 514 struct ccw_device *cdev = to_ccwdev(dev);
515 int i, force; 515 int force, ret;
516 char *tmp; 516 unsigned long i;
517 517
518 if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0) 518 if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
519 return -EAGAIN; 519 return -EAGAIN;
@@ -525,25 +525,30 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr,
525 if (!strncmp(buf, "force\n", count)) { 525 if (!strncmp(buf, "force\n", count)) {
526 force = 1; 526 force = 1;
527 i = 1; 527 i = 1;
528 ret = 0;
528 } else { 529 } else {
529 force = 0; 530 force = 0;
530 i = simple_strtoul(buf, &tmp, 16); 531 ret = strict_strtoul(buf, 16, &i);
531 } 532 }
532 533 if (ret)
534 goto out;
533 switch (i) { 535 switch (i) {
534 case 0: 536 case 0:
535 online_store_handle_offline(cdev); 537 online_store_handle_offline(cdev);
538 ret = count;
536 break; 539 break;
537 case 1: 540 case 1:
538 online_store_handle_online(cdev, force); 541 online_store_handle_online(cdev, force);
542 ret = count;
539 break; 543 break;
540 default: 544 default:
541 count = -EINVAL; 545 ret = -EINVAL;
542 } 546 }
547out:
543 if (cdev->drv) 548 if (cdev->drv)
544 module_put(cdev->drv->owner); 549 module_put(cdev->drv->owner);
545 atomic_set(&cdev->private->onoff, 0); 550 atomic_set(&cdev->private->onoff, 0);
546 return count; 551 return ret;
547} 552}
548 553
549static ssize_t 554static ssize_t
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 4b92c84fb438..99403b0a97a7 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -555,8 +555,7 @@ ccw_device_recognition(struct ccw_device *cdev)
555 (cdev->private->state != DEV_STATE_BOXED)) 555 (cdev->private->state != DEV_STATE_BOXED))
556 return -EINVAL; 556 return -EINVAL;
557 sch = to_subchannel(cdev->dev.parent); 557 sch = to_subchannel(cdev->dev.parent);
558 ret = cio_enable_subchannel(sch, sch->schib.pmcw.isc, 558 ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
559 (u32)(addr_t)sch);
560 if (ret != 0) 559 if (ret != 0)
561 /* Couldn't enable the subchannel for i/o. Sick device. */ 560 /* Couldn't enable the subchannel for i/o. Sick device. */
562 return ret; 561 return ret;
@@ -667,8 +666,7 @@ ccw_device_online(struct ccw_device *cdev)
667 sch = to_subchannel(cdev->dev.parent); 666 sch = to_subchannel(cdev->dev.parent);
668 if (css_init_done && !get_device(&cdev->dev)) 667 if (css_init_done && !get_device(&cdev->dev))
669 return -ENODEV; 668 return -ENODEV;
670 ret = cio_enable_subchannel(sch, sch->schib.pmcw.isc, 669 ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
671 (u32)(addr_t)sch);
672 if (ret != 0) { 670 if (ret != 0) {
673 /* Couldn't enable the subchannel for i/o. Sick device. */ 671 /* Couldn't enable the subchannel for i/o. Sick device. */
674 if (ret == -ENODEV) 672 if (ret == -ENODEV)
@@ -1048,8 +1046,7 @@ ccw_device_start_id(struct ccw_device *cdev, enum dev_event dev_event)
1048 struct subchannel *sch; 1046 struct subchannel *sch;
1049 1047
1050 sch = to_subchannel(cdev->dev.parent); 1048 sch = to_subchannel(cdev->dev.parent);
1051 if (cio_enable_subchannel(sch, sch->schib.pmcw.isc, 1049 if (cio_enable_subchannel(sch, (u32)(addr_t)sch) != 0)
1052 (u32)(addr_t)sch) != 0)
1053 /* Couldn't enable the subchannel for i/o. Sick device. */ 1050 /* Couldn't enable the subchannel for i/o. Sick device. */
1054 return; 1051 return;
1055 1052
@@ -1082,7 +1079,6 @@ device_trigger_reprobe(struct subchannel *sch)
1082 */ 1079 */
1083 sch->lpm = sch->schib.pmcw.pam & sch->opm; 1080 sch->lpm = sch->schib.pmcw.pam & sch->opm;
1084 /* Re-set some bits in the pmcw that were lost. */ 1081 /* Re-set some bits in the pmcw that were lost. */
1085 sch->schib.pmcw.isc = 3;
1086 sch->schib.pmcw.csense = 1; 1082 sch->schib.pmcw.csense = 1;
1087 sch->schib.pmcw.ena = 0; 1083 sch->schib.pmcw.ena = 0;
1088 if ((sch->lpm & (sch->lpm - 1)) != 0) 1084 if ((sch->lpm & (sch->lpm - 1)) != 0)
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index a1718a0aa539..f308ad55a6d5 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -508,7 +508,7 @@ ccw_device_stlck(struct ccw_device *cdev)
508 return -ENOMEM; 508 return -ENOMEM;
509 } 509 }
510 spin_lock_irqsave(sch->lock, flags); 510 spin_lock_irqsave(sch->lock, flags);
511 ret = cio_enable_subchannel(sch, 3, (u32)(addr_t)sch); 511 ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
512 if (ret) 512 if (ret)
513 goto out_unlock; 513 goto out_unlock;
514 /* 514 /*
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 43876e287370..445cf364e461 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -3663,11 +3663,11 @@ qdio_performance_stats_show(struct bus_type *bus, char *buf)
3663static ssize_t 3663static ssize_t
3664qdio_performance_stats_store(struct bus_type *bus, const char *buf, size_t count) 3664qdio_performance_stats_store(struct bus_type *bus, const char *buf, size_t count)
3665{ 3665{
3666 char *tmp; 3666 unsigned long i;
3667 int i; 3667 int ret;
3668 3668
3669 i = simple_strtoul(buf, &tmp, 16); 3669 ret = strict_strtoul(buf, 16, &i);
3670 if ((i == 0) || (i == 1)) { 3670 if (!ret && ((i == 0) || (i == 1))) {
3671 if (i == qdio_performance_stats) 3671 if (i == qdio_performance_stats)
3672 return count; 3672 return count;
3673 qdio_performance_stats = i; 3673 qdio_performance_stats = i;
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index bbef3764fbf8..47a7e6200b26 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -17,6 +17,7 @@
17#include <linux/virtio_config.h> 17#include <linux/virtio_config.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/virtio_ring.h> 19#include <linux/virtio_ring.h>
20#include <linux/pfn.h>
20#include <asm/io.h> 21#include <asm/io.h>
21#include <asm/kvm_para.h> 22#include <asm/kvm_para.h>
22#include <asm/kvm_virtio.h> 23#include <asm/kvm_virtio.h>
@@ -180,11 +181,10 @@ static struct virtqueue *kvm_find_vq(struct virtio_device *vdev,
180 181
181 config = kvm_vq_config(kdev->desc)+index; 182 config = kvm_vq_config(kdev->desc)+index;
182 183
183 if (add_shared_memory(config->address, 184 err = vmem_add_mapping(config->address,
184 vring_size(config->num, PAGE_SIZE))) { 185 vring_size(config->num, PAGE_SIZE));
185 err = -ENOMEM; 186 if (err)
186 goto out; 187 goto out;
187 }
188 188
189 vq = vring_new_virtqueue(config->num, vdev, (void *) config->address, 189 vq = vring_new_virtqueue(config->num, vdev, (void *) config->address,
190 kvm_notify, callback); 190 kvm_notify, callback);
@@ -202,8 +202,8 @@ static struct virtqueue *kvm_find_vq(struct virtio_device *vdev,
202 vq->priv = config; 202 vq->priv = config;
203 return vq; 203 return vq;
204unmap: 204unmap:
205 remove_shared_memory(config->address, vring_size(config->num, 205 vmem_remove_mapping(config->address,
206 PAGE_SIZE)); 206 vring_size(config->num, PAGE_SIZE));
207out: 207out:
208 return ERR_PTR(err); 208 return ERR_PTR(err);
209} 209}
@@ -213,8 +213,8 @@ static void kvm_del_vq(struct virtqueue *vq)
213 struct kvm_vqconfig *config = vq->priv; 213 struct kvm_vqconfig *config = vq->priv;
214 214
215 vring_del_virtqueue(vq); 215 vring_del_virtqueue(vq);
216 remove_shared_memory(config->address, 216 vmem_remove_mapping(config->address,
217 vring_size(config->num, PAGE_SIZE)); 217 vring_size(config->num, PAGE_SIZE));
218} 218}
219 219
220/* 220/*
@@ -318,12 +318,13 @@ static int __init kvm_devices_init(void)
318 return rc; 318 return rc;
319 } 319 }
320 320
321 if (add_shared_memory((max_pfn) << PAGE_SHIFT, PAGE_SIZE)) { 321 rc = vmem_add_mapping(PFN_PHYS(max_pfn), PAGE_SIZE);
322 if (rc) {
322 device_unregister(&kvm_root); 323 device_unregister(&kvm_root);
323 return -ENOMEM; 324 return rc;
324 } 325 }
325 326
326 kvm_devices = (void *) (max_pfn << PAGE_SHIFT); 327 kvm_devices = (void *) PFN_PHYS(max_pfn);
327 328
328 ctl_set_bit(0, 9); 329 ctl_set_bit(0, 9);
329 register_external_interrupt(0x2603, kvm_extint_handler); 330 register_external_interrupt(0x2603, kvm_extint_handler);