Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 9788
b: refs/heads/master
c: ec384d2
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Oct 10, 2005
1 parent 0d70a91 commit d422fb1
Show file tree
Hide file tree
Showing 17 changed files with 242 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 71e2b2ecc1c44cb4f2f3e68827af8b90246becac
refs/heads/master: ec384d297c2c47611cae835284fe970073d41783
6 changes: 5 additions & 1 deletion trunk/arch/i386/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
esp = (unsigned long) ka->sa.sa_restorer;
}

return (void __user *)((esp - frame_size) & -8ul);
esp -= frame_size;
/* Align the stack pointer according to the i386 ABI,
* i.e. so that on function entry ((sp + 4) & 15) == 0. */
esp = ((esp + 4) & -16ul) - 4;
return (void __user *) esp;
}

/* These symbols are defined with the addresses in the vsyscall page.
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/sparc64/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <asm/atomic.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/sbus.h>
#include <asm/iommu.h>
#include <asm/upa.h>
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/um/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ archclean:
$(SYMLINK_HEADERS):
@echo ' SYMLINK $@'
ifneq ($(KBUILD_SRC),)
ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
$(Q)ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@
else
$(Q)cd $(TOPDIR)/$(dir $@) ; \
ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@)
Expand Down
39 changes: 32 additions & 7 deletions trunk/arch/um/drivers/cow.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,40 @@

#include <asm/types.h>

#if defined(__BIG_ENDIAN)
# define ntohll(x) (x)
# define htonll(x) (x)
#elif defined(__LITTLE_ENDIAN)
# define ntohll(x) bswap_64(x)
# define htonll(x) bswap_64(x)
#if defined(__KERNEL__)

# include <asm/byteorder.h>

# if defined(__BIG_ENDIAN)
# define ntohll(x) (x)
# define htonll(x) (x)
# elif defined(__LITTLE_ENDIAN)
# define ntohll(x) be64_to_cpu(x)
# define htonll(x) cpu_to_be64(x)
# else
# error "Could not determine byte order"
# endif

#else
#error "__BYTE_ORDER not defined"
/* For the definition of ntohl, htonl and __BYTE_ORDER */
#include <endian.h>
#include <netinet/in.h>
#if defined(__BYTE_ORDER)

# if __BYTE_ORDER == __BIG_ENDIAN
# define ntohll(x) (x)
# define htonll(x) (x)
# elif __BYTE_ORDER == __LITTLE_ENDIAN
# define ntohll(x) bswap_64(x)
# define htonll(x) bswap_64(x)
# else
# error "Could not determine byte order: __BYTE_ORDER uncorrectly defined"
# endif

#else /* ! defined(__BYTE_ORDER) */
# error "Could not determine byte order: __BYTE_ORDER not defined"
#endif
#endif /* ! defined(__KERNEL__) */

extern int init_cow_file(int fd, char *cow_file, char *backing_file,
int sectorsize, int alignment, int *bitmap_offset_out,
Expand Down
1 change: 0 additions & 1 deletion trunk/arch/um/drivers/cow_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include <sys/time.h>
#include <sys/param.h>
#include <sys/user.h>
#include <netinet/in.h>

#include "os.h"

Expand Down
11 changes: 11 additions & 0 deletions trunk/arch/um/os-Linux/start_up.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,22 @@ static int __init skas0_cmd_param(char *str, int* add)
return 0;
}

/* The two __uml_setup would conflict, without this stupid alias. */

static int __init mode_skas0_cmd_param(char *str, int* add)
__attribute__((alias("skas0_cmd_param")));

__uml_setup("skas0", skas0_cmd_param,
"skas0\n"
" Disables SKAS3 usage, so that SKAS0 is used, unless \n"
" you specify mode=tt.\n\n");

__uml_setup("mode=skas0", mode_skas0_cmd_param,
"mode=skas0\n"
" Disables SKAS3 usage, so that SKAS0 is used, unless you \n"
" specify mode=tt. Note that this was recently added - on \n"
" older kernels you must use simply \"skas0\".\n\n");

static int force_sysemu_disabled = 0;

static int __init nosysemu_cmd_param(char *str, int* add)
Expand Down
4 changes: 2 additions & 2 deletions trunk/arch/um/scripts/Makefile.rules
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ USER_SINGLE_OBJS := \
USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS))
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))

$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
$(CFLAGS_$(notdir $@))
$(USER_OBJS) $(USER_OBJS:.o=.i) $(USER_OBJS:.o=.s) $(USER_OBJS:.o=.lst): \
c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@))
$(USER_OBJS): cmd_checksrc =
$(USER_OBJS): quiet_cmd_checksrc =
$(USER_OBJS): cmd_force_checksrc =
Expand Down
37 changes: 28 additions & 9 deletions trunk/arch/um/sys-x86_64/stub_segv.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,42 @@
#include "uml-config.h"
#include "sysdep/sigcontext.h"
#include "sysdep/faultinfo.h"
#include <stddef.h>

/* Copied from sys-x86_64/signal.c - Can't find an equivalent definition
* in the libc headers anywhere.
*/
struct rt_sigframe
{
char *pretcode;
struct ucontext uc;
struct siginfo info;
};

/* Copied here from <linux/kernel.h> - we're userspace. */
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})

void __attribute__ ((__section__ (".__syscall_stub")))
stub_segv_handler(int sig)
{
struct ucontext *uc;

__asm__("movq %%rdx, %0" : "=g" (uc) :);
GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
&uc->uc_mcontext);
GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
&uc->uc_mcontext);

__asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid));
__asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid));
__asm__("movq %%rax, %%rdi ; movq %0, %%rax ; movq %1, %%rsi ;"
"syscall": : "g" (__NR_kill), "g" (SIGUSR1));
/* Two popqs to restore the stack to the state just before entering
* the handler, one pops the return address, the other pops the frame
* pointer.
"syscall": : "g" (__NR_kill), "g" (SIGUSR1) :
"%rdi", "%rax", "%rsi");
/* sys_sigreturn expects that the stack pointer will be 8 bytes into
* the signal frame. So, we use the ucontext pointer, which we know
* already, to get the signal frame pointer, and add 8 to that.
*/
__asm__("popq %%rax ; popq %%rax ; movq %0, %%rax ; syscall" : : "g"
(__NR_rt_sigreturn));
__asm__("movq %0, %%rsp": :
"g" ((unsigned long) container_of(uc, struct rt_sigframe,
uc) + 8));
__asm__("movq %0, %%rax ; syscall" : : "g" (__NR_rt_sigreturn));
}
6 changes: 5 additions & 1 deletion trunk/arch/x86_64/ia32/ia32_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,11 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
rsp = (unsigned long) ka->sa.sa_restorer;
}

return (void __user *)((rsp - frame_size) & -8UL);
rsp -= frame_size;
/* Align the stack pointer according to the i386 ABI,
* i.e. so that on function entry ((sp + 4) & 15) == 0. */
rsp = ((rsp + 4) & -16ul) - 4;
return (void __user *) rsp;
}

int ia32_setup_frame(int sig, struct k_sigaction *ka,
Expand Down
127 changes: 127 additions & 0 deletions trunk/arch/x86_64/kernel/suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <linux/smp.h>
#include <linux/suspend.h>
#include <asm/proto.h>
#include <asm/page.h>
#include <asm/pgtable.h>

struct saved_context saved_context;

Expand Down Expand Up @@ -140,4 +142,129 @@ void fix_processor_context(void)

}

#ifdef CONFIG_SOFTWARE_SUSPEND
/* Defined in arch/x86_64/kernel/suspend_asm.S */
extern int restore_image(void);

pgd_t *temp_level4_pgt;

static void **pages;

static inline void *__add_page(void)
{
void **c;

c = (void **)get_usable_page(GFP_ATOMIC);
if (c) {
*c = pages;
pages = c;
}
return c;
}

static inline void *__next_page(void)
{
void **c;

c = pages;
if (c) {
pages = *c;
*c = NULL;
}
return c;
}

/*
* Try to allocate as many usable pages as needed and daisy chain them.
* If one allocation fails, free the pages allocated so far
*/
static int alloc_usable_pages(unsigned long n)
{
void *p;

pages = NULL;
do
if (!__add_page())
break;
while (--n);
if (n) {
p = __next_page();
while (p) {
free_page((unsigned long)p);
p = __next_page();
}
return -ENOMEM;
}
return 0;
}

static void res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
{
long i, j;

i = pud_index(address);
pud = pud + i;
for (; i < PTRS_PER_PUD; pud++, i++) {
unsigned long paddr;
pmd_t *pmd;

paddr = address + i*PUD_SIZE;
if (paddr >= end)
break;

pmd = (pmd_t *)__next_page();
set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE));
for (j = 0; j < PTRS_PER_PMD; pmd++, j++, paddr += PMD_SIZE) {
unsigned long pe;

if (paddr >= end)
break;
pe = _PAGE_NX | _PAGE_PSE | _KERNPG_TABLE | paddr;
pe &= __supported_pte_mask;
set_pmd(pmd, __pmd(pe));
}
}
}

static void set_up_temporary_mappings(void)
{
unsigned long start, end, next;

temp_level4_pgt = (pgd_t *)__next_page();

/* It is safe to reuse the original kernel mapping */
set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map),
init_level4_pgt[pgd_index(__START_KERNEL_map)]);

/* Set up the direct mapping from scratch */
start = (unsigned long)pfn_to_kaddr(0);
end = (unsigned long)pfn_to_kaddr(end_pfn);

for (; start < end; start = next) {
pud_t *pud = (pud_t *)__next_page();
next = start + PGDIR_SIZE;
if (next > end)
next = end;
res_phys_pud_init(pud, __pa(start), __pa(next));
set_pgd(temp_level4_pgt + pgd_index(start),
mk_kernel_pgd(__pa(pud)));
}
}

int swsusp_arch_resume(void)
{
unsigned long n;

n = ((end_pfn << PAGE_SHIFT) + PUD_SIZE - 1) >> PUD_SHIFT;
n += (n + PTRS_PER_PUD - 1) / PTRS_PER_PUD + 1;
pr_debug("swsusp_arch_resume(): pages needed = %lu\n", n);
if (alloc_usable_pages(n)) {
free_eaten_memory();
return -ENOMEM;
}
/* We have got enough memory and from now on we cannot recover */
set_up_temporary_mappings();
restore_image();
return 0;
}
#endif /* CONFIG_SOFTWARE_SUSPEND */
17 changes: 11 additions & 6 deletions trunk/arch/x86_64/kernel/suspend_asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ ENTRY(swsusp_arch_suspend)
call swsusp_save
ret

ENTRY(swsusp_arch_resume)
/* set up cr3 */
leaq init_level4_pgt(%rip),%rax
subq $__START_KERNEL_map,%rax
movq %rax,%cr3

ENTRY(restore_image)
/* switch to temporary page tables */
movq $__PAGE_OFFSET, %rdx
movq temp_level4_pgt(%rip), %rax
subq %rdx, %rax
movq %rax, %cr3
/* Flush TLB */
movq mmu_cr4_features(%rip), %rax
movq %rax, %rdx
andq $~(1<<7), %rdx # PGE
Expand All @@ -69,6 +70,10 @@ loop:
movq pbe_next(%rdx), %rdx
jmp loop
done:
/* go back to the original page tables */
leaq init_level4_pgt(%rip), %rax
subq $__START_KERNEL_map, %rax
movq %rax, %cr3
/* Flush TLB, including "global" things (vmalloc) */
movq mmu_cr4_features(%rip), %rax
movq %rax, %rdx
Expand Down
8 changes: 8 additions & 0 deletions trunk/drivers/ide/ide-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1101,6 +1101,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
ide_hwif_t *hwif;
struct request *rq;
ide_startstop_t startstop;
int loops = 0;

/* for atari only: POSSIBLY BROKEN HERE(?) */
ide_get_lock(ide_intr, hwgroup);
Expand Down Expand Up @@ -1153,6 +1154,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
/* no more work for this hwgroup (for now) */
return;
}
again:
hwif = HWIF(drive);
if (hwgroup->hwif->sharing_irq &&
hwif != hwgroup->hwif &&
Expand Down Expand Up @@ -1192,8 +1194,14 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
* though. I hope that doesn't happen too much, hopefully not
* unless the subdriver triggers such a thing in its own PM
* state machine.
*
* We count how many times we loop here to make sure we service
* all drives in the hwgroup without looping for ever
*/
if (drive->blocked && !blk_pm_request(rq) && !(rq->flags & REQ_PREEMPT)) {
drive = drive->next ? drive->next : hwgroup->drive;
if (loops++ < 4 && !blk_queue_plugged(drive->queue))
goto again;
/* We clear busy, there should be no pending ATA command at this point. */
hwgroup->busy = 0;
break;
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/pcmcia/cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,9 @@ static int pccardd(void *__skt)
schedule();
try_to_freeze();
}
/* make sure we are running before we exit */
set_current_state(TASK_RUNNING);

remove_wait_queue(&skt->thread_wait, &wait);

/* remove from the device core */
Expand Down
Loading

0 comments on commit d422fb1

Please sign in to comment.