s390/sclp: do not use static sccbs
The sccbs for init/read/sdias/early have to be located below 2 GB, and they are currently defined as a static buffer. With a relocatable kernel that could reside at any place in memory, this will no longer guarantee the location below 2 GB, so use a dynamic GFP_DMA allocation instead. The sclp_early_sccb buffer needs special handling, as it can be used very early, and by both the decompressor and also the decompressed kernel. Therefore, a fixed 4 KB buffer is introduced at 0x11000, the former PARMAREA_END. The new PARMAREA_END is now 0x12000, and it is renamed to HEAD_END, as it is rather the end of head.S and not the end of the parmarea. Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> Reviewed-by: Philipp Rudo <prudo@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
这个提交包含在:
@@ -45,8 +45,8 @@ static struct list_head sclp_req_queue;
|
||||
/* Data for read and and init requests. */
|
||||
static struct sclp_req sclp_read_req;
|
||||
static struct sclp_req sclp_init_req;
|
||||
static char sclp_read_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
|
||||
static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
|
||||
static void *sclp_read_sccb;
|
||||
static struct init_sccb *sclp_init_sccb;
|
||||
|
||||
/* Suspend request */
|
||||
static DECLARE_COMPLETION(sclp_request_queue_flushed);
|
||||
@@ -753,9 +753,8 @@ EXPORT_SYMBOL(sclp_remove_processed);
|
||||
static inline void
|
||||
__sclp_make_init_req(sccb_mask_t receive_mask, sccb_mask_t send_mask)
|
||||
{
|
||||
struct init_sccb *sccb;
|
||||
struct init_sccb *sccb = sclp_init_sccb;
|
||||
|
||||
sccb = (struct init_sccb *) sclp_init_sccb;
|
||||
clear_page(sccb);
|
||||
memset(&sclp_init_req, 0, sizeof(struct sclp_req));
|
||||
sclp_init_req.command = SCLP_CMDW_WRITE_EVENT_MASK;
|
||||
@@ -782,7 +781,7 @@ static int
|
||||
sclp_init_mask(int calculate)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct init_sccb *sccb = (struct init_sccb *) sclp_init_sccb;
|
||||
struct init_sccb *sccb = sclp_init_sccb;
|
||||
sccb_mask_t receive_mask;
|
||||
sccb_mask_t send_mask;
|
||||
int retry;
|
||||
@@ -1175,6 +1174,9 @@ sclp_init(void)
|
||||
if (sclp_init_state != sclp_init_state_uninitialized)
|
||||
goto fail_unlock;
|
||||
sclp_init_state = sclp_init_state_initializing;
|
||||
sclp_read_sccb = (void *) __get_free_page(GFP_ATOMIC | GFP_DMA);
|
||||
sclp_init_sccb = (void *) __get_free_page(GFP_ATOMIC | GFP_DMA);
|
||||
BUG_ON(!sclp_read_sccb || !sclp_init_sccb);
|
||||
/* Set up variables */
|
||||
INIT_LIST_HEAD(&sclp_req_queue);
|
||||
INIT_LIST_HEAD(&sclp_reg_list);
|
||||
@@ -1207,6 +1209,8 @@ fail_unregister_reboot_notifier:
|
||||
unregister_reboot_notifier(&sclp_reboot_notifier);
|
||||
fail_init_state_uninitialized:
|
||||
sclp_init_state = sclp_init_state_uninitialized;
|
||||
free_page((unsigned long) sclp_read_sccb);
|
||||
free_page((unsigned long) sclp_init_sccb);
|
||||
fail_unlock:
|
||||
spin_unlock_irqrestore(&sclp_lock, flags);
|
||||
return rc;
|
||||
|
在新工单中引用
屏蔽一个用户